Merge "RootlessGpuDebug: Change Activity to Service" into sc-v2-dev
diff --git a/apps/CameraITS/tests/scene3/test_lens_movement_reporting.py b/apps/CameraITS/tests/scene3/test_lens_movement_reporting.py
index 61e8647..3e638d6 100644
--- a/apps/CameraITS/tests/scene3/test_lens_movement_reporting.py
+++ b/apps/CameraITS/tests/scene3/test_lens_movement_reporting.py
@@ -71,7 +71,7 @@
   caps = cam.do_capture(reqs, fmt)
   caps = caps[START_FRAME:]
   for i, cap in enumerate(caps):
-    data = {'fd': fds[i]}
+    data = {'fd': fds[i+START_FRAME]}
     data['loc'] = cap['metadata']['android.lens.focusDistance']
     data['lens_moving'] = (cap['metadata']['android.lens.state']
                            == 1)
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 1f7a904..597ab61 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="12L_r1">
+          android:versionName="12.1_r1">
 
     <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="31"/>
 
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 0044efa..4e6b1ac 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -2320,9 +2320,9 @@
     <string name="np_start_security_settings">Launch Security Settings</string>
     <string name="np_start_notif_settings">Launch Notification Settings</string>
     <string name="np_when_locked_see_redacted">Lock the screen and find the NotifPrivacyTest notification.\n
-        Pass the test if the notification content is REDACTED and the icon is B.</string>
+        Pass the test if the notification content is REDACTED.</string>
     <string name="np_when_locked_see_private">Lock the screen and find the NotifPrivacyTest notification.\n
-        Pass the test if the notification content is EXPOSED and the icon is A.</string>
+        Pass the test if the notification content is EXPOSED.</string>
     <string name="np_when_locked_hidden">Lock the screen and look for the NotifPrivacyTest notification.\n
         Fail the test if it can be found without unlocking the device.</string>
     <string name="np_start_occluding">Launch CallSimulator</string>
@@ -2331,13 +2331,13 @@
         \n\n(Like a call, this screen will be visible even when the device is locked.)
         \n\nLock the screen, then come back here without unlocking.
         \nPull down the notification shade and find the NotifPrivacyTest notification.
-        \nPass the test if the notification content is REDACTED and the icon is B.
+        \nPass the test if the notification content is REDACTED.
         \n\nGo back when ready to Pass/Fail the step.</string>
     <string name="np_occluding_see_private">CallSimulator
         \n\n(Like a call, this screen will be visible even when the device is locked.)
         \n\nLock the screen, then come back here without unlocking.
         \nPull down the notification shade and find the NotifPrivacyTest notification.
-        \nPass the test if the notification content is EXPOSED and the icon is A.
+        \nPass the test if the notification content is EXPOSED.
         \n\nGo back when ready to Pass/Fail the step.</string>
     <string name="np_occluding_hidden">CallSimulator
         \n\n(Like a call, this screen will be visible even when the device is locked.)
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationPrivacyVerifierActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationPrivacyVerifierActivity.java
index ce4d631..760bd71 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationPrivacyVerifierActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationPrivacyVerifierActivity.java
@@ -162,7 +162,7 @@
 
         Notification publicVersion = new Notification.Builder(mContext, NOTIFICATION_CHANNEL_ID)
                 .setContentTitle(getString(R.string.np_public_version_text))
-                .setSmallIcon(R.drawable.ic_stat_bob)
+                .setSmallIcon(R.drawable.ic_stat_alice)
                 .setWhen(when)
                 .build();
         Notification privateVersion = new Notification.Builder(mContext, NOTIFICATION_CHANNEL_ID)
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/CtsTouchUtils.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/CtsTouchUtils.java
index aa0379b..66e3b20 100644
--- a/common/device-side/util-axt/src/com/android/compatibility/common/util/CtsTouchUtils.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/CtsTouchUtils.java
@@ -20,6 +20,7 @@
 import android.app.UiAutomation;
 import android.graphics.Point;
 import android.os.SystemClock;
+import android.util.Log;
 import android.util.SparseArray;
 import android.view.InputDevice;
 import android.view.MotionEvent;
@@ -35,6 +36,9 @@
  * Test utilities for touch emulation.
  */
 public final class CtsTouchUtils {
+
+    private static final String TAG = CtsTouchUtils.class.getSimpleName();
+
     /**
      * Interface definition for a callback to be invoked when an event has been injected.
      */
@@ -288,7 +292,52 @@
      */
     public static void emulateDragGesture(Instrumentation instrumentation,
             ActivityTestRule<?> activityTestRule, SparseArray<Point> coordinates) {
-        emulateDragGesture(instrumentation, activityTestRule, coordinates, 2000, 20);
+        final int moveEventCount = 20;
+        int dragDurationMs = 2000;
+
+        final int touchSlop = ViewConfiguration.get(
+                activityTestRule.getActivity()).getScaledTouchSlop();
+        final long longPressTimeoutMs = ViewConfiguration.getLongPressTimeout();
+        final int maxDragDurationMs = getMaxDragDuration(touchSlop, longPressTimeoutMs, coordinates,
+                moveEventCount);
+        if (dragDurationMs > maxDragDurationMs) {
+            Log.d(TAG, "emulateDragGesture: Lowering standard drag duration from " + dragDurationMs
+                    + " ms to " + maxDragDurationMs + " ms to avoid triggering a long press ");
+            dragDurationMs = maxDragDurationMs;
+        }
+
+        emulateDragGesture(instrumentation, activityTestRule, coordinates, dragDurationMs,
+                moveEventCount);
+    }
+
+    /**
+     * Gets the maximal drag duration that assures not triggering a long press during a drag gesture
+     * considering long press timeout and touch slop.
+     *
+     * The calculation is based on the distance between the first and the second point of provided
+     * coordinates.
+     */
+    private static int getMaxDragDuration(int touchSlop, long longPressTimeoutMs,
+            SparseArray<Point> coordinates, int moveEventCount) {
+        final int coordinatesSize = coordinates.size();
+        if (coordinatesSize < 2) {
+            throw new IllegalArgumentException("Need at least 2 points for emulating drag");
+        }
+
+        final int deltaX = coordinates.get(0).x - coordinates.get(1).x;
+        final int deltaY = coordinates.get(0).y - coordinates.get(1).y;
+        final double dragDistance = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));
+        final double moveEventDistance = (double) dragDistance / moveEventCount;
+
+        // Number of move events needed to drag outside of the touch slop.
+        // The initial sleep before the drag gesture begins is considered by adding one extra event.
+        final double neededMoveEventsToExceedTouchSlop = touchSlop / moveEventDistance + 1;
+
+        // Get maximal drag duration that assures a drag speed that does not trigger a long press.
+        // Multiply with 0.9 to be on the safe side.
+        int maxDragDuration = (int) (longPressTimeoutMs * 0.9 * moveEventCount
+                / neededMoveEventsToExceedTouchSlop);
+        return maxDragDuration;
     }
 
     private static void emulateDragGesture(Instrumentation instrumentation,
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/DirectBootHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/DirectBootHostTest.java
index e513aa7..ab51c75 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/DirectBootHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/DirectBootHostTest.java
@@ -51,7 +51,7 @@
     private static final String CLASS = PKG + ".EncryptionAppTest";
     private static final String APK = "CtsEncryptionApp.apk";
 
-    private static final String OTHER_APK = "CtsSplitApp.apk";
+    private static final String OTHER_APK = "CtsSplitApp29.apk";
     private static final String OTHER_PKG = "com.android.cts.splitapp";
 
     private static final String MODE_NATIVE = "native";
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/ResumeOnRebootHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/ResumeOnRebootHostTest.java
index dcf30b4..c5fad14 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/ResumeOnRebootHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/ResumeOnRebootHostTest.java
@@ -55,7 +55,7 @@
     private static final String CLASS = PKG + ".EncryptionAppTest";
     private static final String APK = "CtsEncryptionApp.apk";
 
-    private static final String OTHER_APK = "CtsSplitApp.apk";
+    private static final String OTHER_APK = "CtsSplitApp29.apk";
     private static final String OTHER_PKG = "com.android.cts.splitapp";
 
     private static final String FEATURE_REBOOT_ESCROW = "feature:android.hardware.reboot_escrow";
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/Android.bp b/hostsidetests/appsecurity/test-apps/SplitApp/Android.bp
index 1a02f52..c42fd09 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/Android.bp
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/Android.bp
@@ -36,6 +36,7 @@
         "android.test.runner.stubs",
         "android.test.base.stubs",
     ],
+    target_sdk_version: "current"
 }
 
 android_test_helper_app {
@@ -66,6 +67,35 @@
     ],
 }
 
+android_test_helper_app {
+    name: "CtsSplitApp29",
+    defaults: ["CtsSplitAppDefaults"],
+    package_splits: [
+        "mdpi-v4",
+        "hdpi-v4",
+        "xhdpi-v4",
+        "xxhdpi-v4",
+        "v7",
+        "v23",
+        "fr",
+        "de",
+    ],
+    certificate: ":cts-testkey1",
+    aaptflags: [
+        "--version-code 100",
+        "--version-name OneHundred",
+        "--replace-version",
+    ],
+    // Feature splits are dependent on this base, so it must be exported.
+    export_package_resources: true,
+    test_suites: [
+        "cts",
+        "general-tests",
+        "mts-mainline-infra",
+    ],
+    target_sdk_version: "29"
+}
+
 // Define a variant with a different revision code
 android_test_helper_app {
     name: "CtsSplitAppDiffRevision",
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/SplitApp/AndroidManifest.xml
index 97a02e7..f61bc16 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/AndroidManifest.xml
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/AndroidManifest.xml
@@ -21,8 +21,7 @@
 
     <!-- The androidx test libraries uses minSdkVersion 14. Applies an overrideLibrary rule here
          to pass the build error, since tests need to use minSdkVersion 4. -->
-    <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="29" tools:overrideLibrary=
-        "androidx.test.runner, androidx.test.rules, androidx.test.monitor, androidx.test.services.storage"/>
+    <uses-sdk android:minSdkVersion="4" tools:overrideLibrary="androidx.test.runner, androidx.test.rules, androidx.test.monitor, androidx.test.services.storage"/>
 
     <uses-permission android:name="android.permission.CAMERA"/>
     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
diff --git a/hostsidetests/trustedvoice/Android.bp b/hostsidetests/trustedvoice/Android.bp
deleted file mode 100644
index faa94df..0000000
--- a/hostsidetests/trustedvoice/Android.bp
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (C) 2016 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 {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-java_test_host {
-    name: "CtsTrustedVoiceHostTestCases",
-    defaults: ["cts_defaults"],
-    srcs: ["src/**/*.java"],
-    // Must match the package name in CtsTestCaseList.mk
-    libs: [
-        "cts-tradefed",
-        "ddmlib-prebuilt",
-        "tradefed",
-    ],
-    // Tag this module as a cts test artifact
-    test_suites: [
-        "cts",
-        "general-tests",
-    ],
-}
diff --git a/hostsidetests/trustedvoice/AndroidTest.xml b/hostsidetests/trustedvoice/AndroidTest.xml
deleted file mode 100644
index bb5970b..0000000
--- a/hostsidetests/trustedvoice/AndroidTest.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<configuration description="Config for CTS Trustedvoice host test cases">
-    <option name="test-suite-tag" value="cts" />
-    <option name="config-descriptor:metadata" key="component" value="framework" />
-    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
-    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
-    <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
-    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="CtsTrustedVoiceApp.apk" />
-    </target_preparer>
-    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
-        <option name="jar" value="CtsTrustedVoiceHostTestCases.jar" />
-        <option name="runtime-hint" value="12m" />
-    </test>
-</configuration>
diff --git a/hostsidetests/trustedvoice/OWNERS b/hostsidetests/trustedvoice/OWNERS
deleted file mode 100644
index f96bd04..0000000
--- a/hostsidetests/trustedvoice/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 174421
-sharmneha@google.com
\ No newline at end of file
diff --git a/hostsidetests/trustedvoice/TEST_MAPPING b/hostsidetests/trustedvoice/TEST_MAPPING
deleted file mode 100644
index fb71ad2..0000000
--- a/hostsidetests/trustedvoice/TEST_MAPPING
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "presubmit": [
-    {
-      "name": "CtsTrustedVoiceHostTestCases"
-    }
-  ]
-}
diff --git a/hostsidetests/trustedvoice/app/Android.bp b/hostsidetests/trustedvoice/app/Android.bp
deleted file mode 100644
index b8c7922..0000000
--- a/hostsidetests/trustedvoice/app/Android.bp
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (C) 2016 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 {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-android_test_helper_app {
-    name: "CtsTrustedVoiceApp",
-    defaults: ["cts_support_defaults"],
-    srcs: ["src/**/*.java"],
-    // Tag this module as a cts test artifact
-    test_suites: [
-        "cts",
-        "general-tests",
-    ],
-    sdk_version: "current",
-}
diff --git a/hostsidetests/trustedvoice/app/AndroidManifest.xml b/hostsidetests/trustedvoice/app/AndroidManifest.xml
deleted file mode 100755
index 7a0d23c..0000000
--- a/hostsidetests/trustedvoice/app/AndroidManifest.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-     package="android.trustedvoice.app">
-
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
-    <application>
-        <activity android:name=".TrustedVoiceActivity"
-             android:turnScreenOn="true"
-             android:exported="true">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.LAUNCHER"/>
-            </intent-filter>
-        </activity>
-    </application>
-
-</manifest>
diff --git a/hostsidetests/trustedvoice/app/src/android/trustedvoice/app/TrustedVoiceActivity.java b/hostsidetests/trustedvoice/app/src/android/trustedvoice/app/TrustedVoiceActivity.java
deleted file mode 100644
index 32cc42c..0000000
--- a/hostsidetests/trustedvoice/app/src/android/trustedvoice/app/TrustedVoiceActivity.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2016 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.trustedvoice.app;
-
-import android.app.Activity;
-import android.app.KeyguardManager;
-import android.app.KeyguardManager.KeyguardDismissCallback;
-import android.content.Context;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.WindowManager.LayoutParams;
-
-/**
- * This activity when in foreground sets the FLAG_DISMISS_KEYGUARD.
- * It then confirms that the keyguard was successfully dismissed
- * and logs a string to logcat on success.
- */
-public class TrustedVoiceActivity extends Activity {
-
-  private static final String TAG = TrustedVoiceActivity.class.getSimpleName();
-  /**
-   * The test string to log.
-   */
-  private static final String TEST_STRING = "TrustedVoiceTestString";
-
-  private KeyguardManager mkeyguardManager;
-
-  @Override
-  public void onCreate(Bundle icicle) {
-    super.onCreate(icicle);
-    mkeyguardManager =
-            (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
-
-    // Unlock the keyguard.
-    getWindow().addFlags(LayoutParams.FLAG_TURN_SCREEN_ON
-            | LayoutParams.FLAG_KEEP_SCREEN_ON);
-    mkeyguardManager.requestDismissKeyguard(this, null);
-  }
-
-  @Override
-  public void onWindowFocusChanged(boolean hasFocus) {
-    super.onWindowFocusChanged(hasFocus);
-    if (hasFocus) {
-      // Confirm that the keyguard was successfully unlocked.
-      if (!mkeyguardManager.isKeyguardLocked()) {
-        // Log the test string.
-        Log.i(TAG, TEST_STRING);
-      }
-    }
-  }
-}
-
diff --git a/hostsidetests/trustedvoice/src/android/trustedvoice/cts/TrustedVoiceHostTest.java b/hostsidetests/trustedvoice/src/android/trustedvoice/cts/TrustedVoiceHostTest.java
deleted file mode 100644
index 9420124..0000000
--- a/hostsidetests/trustedvoice/src/android/trustedvoice/cts/TrustedVoiceHostTest.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2016 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.trustedvoice.cts;
-
-import com.android.tradefed.testtype.DeviceTestCase;
-
-import java.io.File;
-import java.lang.String;
-import java.util.Scanner;
-
-/**
- * Test to check the APK logs to Logcat.
- * This test first locks the device screen and then runs the associated app to run the test.
- *
- * When this test builds, it also builds {@see android.trustedvoice.app.TrustedVoiceActivity}
- * into an APK which it then installs at runtime. TrustedVoiceActivity sets the
- * FLAG_DISMISS_KEYGUARD, prints a message to Logcat and then gets uninstalled.
- */
-public class TrustedVoiceHostTest extends DeviceTestCase {
-
-    /**
-     * The package name of the APK.
-     */
-    private static final String PACKAGE = "android.trustedvoice.app";
-
-    /**
-     * Lock screen key event code.
-     */
-    private static final int SLEEP_KEYEVENT = 223;
-
-    /**
-     * Lock screen key event code.
-     */
-    private static final int AWAKE_KEYEVENT = 224;
-
-    /**
-     * The file name of the APK.
-     */
-    private static final String APK = "CtsTrustedVoiceApp.apk";
-
-    /**
-     * The class name of the main activity in the APK.
-     */
-    private static final String CLASS = "TrustedVoiceActivity";
-
-    /**
-     * The command to launch the main activity.
-     */
-    private static final String START_COMMAND = String.format(
-            "am start -W -a android.intent.action.MAIN -n %s/%s.%s", PACKAGE, PACKAGE, CLASS);
-
-    /**
-     * The command to put the device to sleep.
-     */
-    private static final String SLEEP_COMMAND = String.format(
-            "input keyevent %d", SLEEP_KEYEVENT);
-
-    /**
-     * The command to wake the device up.
-     */
-    private static final String AWAKE_COMMAND = String.format(
-            "input keyevent %d", AWAKE_KEYEVENT);
-
-    /**
-     * The command to dismiss the keyguard.
-     */
-    private static final String DISMISS_KEYGUARD_COMMAND = "wm dismiss-keyguard";
-
-    /**
-     * The test string to look for.
-     */
-    private static final String TEST_STRING = "TrustedVoiceTestString";
-
-    /**
-     * Tests the app successfully unlocked the device.
-     *
-     * @throws Exception
-     */
-    public void testUnlock() throws Exception {
-        Scanner in = null;
-        try {
-            // Clear logcat.
-            getDevice().executeAdbCommand("logcat", "-c");
-            // Lock the device
-            getDevice().executeShellCommand(SLEEP_COMMAND);
-            // Add a delay to allow the device to go to sleep.
-            Thread.sleep(1000);
-            // Start the APK and wait for it to complete.
-            getDevice().executeShellCommand(START_COMMAND);
-            // Adding delay for OEM specific features which could delay the time of printing the
-            // test log. Please refer to b/62075150 for additional details.
-            Thread.sleep(1000);
-            // Dump logcat.
-            String logs = getDevice().executeAdbCommand(
-                    "logcat", "-v", "brief", "-d", CLASS + ":I", "*:S");
-            // Search for string.
-            in = new Scanner(logs);
-            String testString = "";
-
-            while (in.hasNextLine()) {
-                String line = in.nextLine();
-                if(line.contains(TEST_STRING)) {
-                    // Retrieve the test string.
-                    testString = line.split(":")[1].trim();
-                    break;
-                }
-            }
-            // Assert the logged string matches the test string.
-            assertNotNull("Test string must not be null", testString);
-            assertEquals("Test string does not match", TEST_STRING, testString);
-        } finally {
-            if (in != null) {
-                in.close();
-            }
-            // Unlock the device
-            getDevice().executeShellCommand(AWAKE_COMMAND);
-            getDevice().executeShellCommand(DISMISS_KEYGUARD_COMMAND);
-        }
-    }
-}
diff --git a/tests/accessibility/AndroidTest.xml b/tests/accessibility/AndroidTest.xml
index 6fe3f3b..0cf252a 100644
--- a/tests/accessibility/AndroidTest.xml
+++ b/tests/accessibility/AndroidTest.xml
@@ -19,6 +19,7 @@
     <option name="config-descriptor:metadata" key="parameter" value="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="no_foldable_states" />
     <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" />
diff --git a/tests/accessibilityservice/AndroidTest.xml b/tests/accessibilityservice/AndroidTest.xml
index d79d927..48aea2c 100644
--- a/tests/accessibilityservice/AndroidTest.xml
+++ b/tests/accessibilityservice/AndroidTest.xml
@@ -19,6 +19,7 @@
     <option name="config-descriptor:metadata" key="parameter" value="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="no_foldable_states" />
     <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" />
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
index ecdab0f..e83c370 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
@@ -572,52 +572,6 @@
         }
     }
 
-    @MediumTest
-    @Test
-    public void testToggleSplitScreen() throws Exception {
-        assumeTrue(
-                "Skipping test: no multi-window support",
-                ActivityTaskManager.supportsSplitScreenMultiWindow(mActivity));
-
-        final int initialWindowingMode =
-                mActivity.getResources().getConfiguration().windowConfiguration.getWindowingMode();
-
-        assertTrue(
-                sUiAutomation.performGlobalAction(
-                        AccessibilityService.GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN));
-
-        TestUtils.waitUntil(
-                "waiting until activity becomes split screen windowing mode",
-                () -> {
-                    final int windowingMode =
-                            mActivity
-                                    .getResources()
-                                    .getConfiguration()
-                                    .windowConfiguration
-                                    .getWindowingMode();
-                    return windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
-                            || windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
-                });
-
-        sUiAutomation.waitForIdle(TIMEOUT_WINDOW_STATE_IDLE, DEFAULT_TIMEOUT_MS);
-
-        assertTrue(
-                sUiAutomation.performGlobalAction(
-                        AccessibilityService.GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN));
-
-        TestUtils.waitUntil(
-                "waiting until activity goes back to default screen windowing mode",
-                () -> {
-                    final int windowingMode =
-                            mActivity
-                                    .getResources()
-                                    .getConfiguration()
-                                    .windowConfiguration
-                                    .getWindowingMode();
-                    return windowingMode == initialWindowingMode;
-                });
-    }
-
     @Test
     public void testFindPictureInPictureWindow() throws Exception {
         if (!sInstrumentation.getContext().getPackageManager()
@@ -729,7 +683,7 @@
                                 WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG);
                         params.accessibilityTitle = windowTitle;
 
-                        SystemUtil.runWithShellPermissionIdentity(
+                        SystemUtil.runWithShellPermissionIdentity(sUiAutomation,
                                 () -> wm.addView(view, params),
                                 "android.permission.INTERNAL_SYSTEM_WINDOW");
                     }),
diff --git a/tests/accessibilityservice/testsdk29/AndroidTest.xml b/tests/accessibilityservice/testsdk29/AndroidTest.xml
index cbf1922..4cc15b6 100644
--- a/tests/accessibilityservice/testsdk29/AndroidTest.xml
+++ b/tests/accessibilityservice/testsdk29/AndroidTest.xml
@@ -19,6 +19,7 @@
     <option name="config-descriptor:metadata" key="parameter" value="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="no_foldable_states" />
     <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" />
diff --git a/tests/app/src/android/app/people/cts/PeopleManagerTest.java b/tests/app/src/android/app/people/cts/PeopleManagerTest.java
index 776a0c5..8b67eb4 100644
--- a/tests/app/src/android/app/people/cts/PeopleManagerTest.java
+++ b/tests/app/src/android/app/people/cts/PeopleManagerTest.java
@@ -164,6 +164,7 @@
                 .setSmallIcon(android.R.drawable.sym_def_app_icon);
         return nb;
     }
+
     public void testIsConversationWithoutPermission() throws Exception {
         try {
             mPeopleManager.isConversation(mContext.getPackageName(), SHARE_SHORTCUT_ID);
@@ -190,6 +191,23 @@
         }
     }
 
+    public void testAddOrUpdateStatus_withExpiration() throws Exception {
+        long expirationDuration = 1000;
+        ConversationStatus cs = new ConversationStatus.Builder("id", ACTIVITY_GAME)
+                .setAvailability(AVAILABILITY_AVAILABLE)
+                .setEndTimeMillis(System.currentTimeMillis() + expirationDuration)
+                .build();
+        mPeopleManager.addOrUpdateStatus(SHARE_SHORTCUT_ID, cs);
+
+        List<ConversationStatus> statuses = mPeopleManager.getStatuses(SHARE_SHORTCUT_ID);
+
+        assertTrue(statuses.contains(cs));
+        Thread.sleep(expirationDuration * 2);
+
+        statuses = mPeopleManager.getStatuses(SHARE_SHORTCUT_ID);
+        assertTrue(statuses.isEmpty());
+    }
+
     public void testAddOrUpdateStatus_add() throws Exception {
         ConversationStatus cs = new ConversationStatus.Builder("id", ACTIVITY_GAME)
                 .setAvailability(AVAILABILITY_AVAILABLE)
diff --git a/tests/framework/base/biometrics/src/android/server/biometrics/BiometricActivityTests.java b/tests/framework/base/biometrics/src/android/server/biometrics/BiometricActivityTests.java
index cf8010c..07d6cc8 100644
--- a/tests/framework/base/biometrics/src/android/server/biometrics/BiometricActivityTests.java
+++ b/tests/framework/base/biometrics/src/android/server/biometrics/BiometricActivityTests.java
@@ -51,6 +51,7 @@
 
     @Test
     public void testBiometricOnly_authenticateFromForegroundActivity() throws Exception {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         for (SensorProperties prop : mSensorProperties) {
             if (prop.getSensorStrength() == SensorProperties.STRENGTH_CONVENIENCE) {
                 continue;
@@ -103,6 +104,7 @@
 
     @Test
     public void testBiometricOnly_rejectThenErrorFromForegroundActivity() throws Exception {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         for (SensorProperties prop : mSensorProperties) {
             if (prop.getSensorStrength() == SensorProperties.STRENGTH_CONVENIENCE) {
                 continue;
@@ -169,6 +171,7 @@
 
     @Test
     public void testBiometricOnly_rejectThenAuthenticate() throws Exception {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         for (SensorProperties prop : mSensorProperties) {
             if (prop.getSensorStrength() == SensorProperties.STRENGTH_CONVENIENCE) {
                 continue;
@@ -236,6 +239,7 @@
 
     @Test
     public void testBiometricOnly_negativeButtonInvoked() throws Exception {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         for (SensorProperties prop : mSensorProperties) {
             if (prop.getSensorStrength() == SensorProperties.STRENGTH_CONVENIENCE) {
                 continue;
@@ -284,6 +288,7 @@
     @Test
     public void testBiometricOrCredential_credentialButtonInvoked_biometricEnrolled()
             throws Exception {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         // Test behavior for each sensor when biometrics are enrolled
         try (CredentialSession credentialSession = new CredentialSession()) {
             credentialSession.setCredential();
@@ -307,6 +312,7 @@
     @Test
     public void testBiometricOrCredential_credentialButtonInvoked_biometricNotEnrolled()
             throws Exception {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         // Test behavior for each sensor when biometrics are not enrolled
         try (CredentialSession credentialSession = new CredentialSession()) {
             credentialSession.setCredential();
@@ -326,6 +332,7 @@
     @Test
     public void testBiometricOrCredential_credentialButtonInvoked_noBiometricSensor()
             throws Exception {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         assumeTrue(mSensorProperties.isEmpty());
         try (CredentialSession credentialSession = new CredentialSession()) {
             credentialSession.setCredential();
diff --git a/tests/framework/base/biometrics/src/android/server/biometrics/BiometricCryptoTests.java b/tests/framework/base/biometrics/src/android/server/biometrics/BiometricCryptoTests.java
index baa3bd2..2d66100 100644
--- a/tests/framework/base/biometrics/src/android/server/biometrics/BiometricCryptoTests.java
+++ b/tests/framework/base/biometrics/src/android/server/biometrics/BiometricCryptoTests.java
@@ -17,6 +17,7 @@
 package android.server.biometrics;
 
 import static org.junit.Assert.assertThrows;
+import static org.junit.Assume.assumeTrue;
 
 import android.hardware.biometrics.BiometricPrompt;
 import android.hardware.biometrics.BiometricTestSession;
@@ -38,6 +39,7 @@
 
     @Test
     public void testGenerateKeyWithoutDeviceCredential_throwsException() {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         assertThrows("Key shouldn't be generatable before device credentials are enrolled",
                 Exception.class,
                 () -> Utils.generateBiometricBoundKey("keyBeforeCredentialEnrolled",
@@ -47,6 +49,7 @@
     @Test
     public void testGenerateKeyWithoutBiometricEnrolled_throwsInvalidAlgorithmParameterException()
             throws Exception {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         try (CredentialSession session = new CredentialSession()){
             session.setCredential();
             assertThrows("Key shouldn't be generatable before biometrics are enrolled",
@@ -58,6 +61,7 @@
 
     @Test
     public void testGenerateKeyWhenCredentialAndBiometricEnrolled() throws Exception {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         try (CredentialSession credentialSession = new CredentialSession()) {
             credentialSession.setCredential();
 
diff --git a/tests/framework/base/biometrics/src/android/server/biometrics/BiometricSecurityTests.java b/tests/framework/base/biometrics/src/android/server/biometrics/BiometricSecurityTests.java
index 9b30fa6..b5f3760 100644
--- a/tests/framework/base/biometrics/src/android/server/biometrics/BiometricSecurityTests.java
+++ b/tests/framework/base/biometrics/src/android/server/biometrics/BiometricSecurityTests.java
@@ -76,6 +76,7 @@
      */
     @Test
     public void testBiometricStrength_StrongSensor() throws Exception {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         final List<Integer> sensors = getSensorsOfTargetStrength(SensorProperties.STRENGTH_STRONG);
         assumeTrue("testBiometricStrength_StrongSensor: numSensors=" + sensors.size(),
                 sensors.size() > 0);
@@ -113,6 +114,7 @@
      */
     @Test
     public void testBiometricStrength_WeakSensor() throws Exception {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         final List<Integer> sensors = getSensorsOfTargetStrength(SensorProperties.STRENGTH_WEAK);
         assumeTrue("testBiometricStrength_WeakSensor: numSensors: " + sensors.size(),
                 sensors.size() > 0);
@@ -144,6 +146,7 @@
      */
     @Test
     public void testBiometricStrength_ConvenienceSensor() throws Exception {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         final List<Integer> sensors =
                 getSensorsOfTargetStrength(SensorProperties.STRENGTH_CONVENIENCE);
         assumeTrue("testBiometricStrength_ConvenienceSensor: numSensors=" + sensors.size(),
@@ -277,6 +280,7 @@
      */
     @Test
     public void testBiometricStrengthDowngraded_StrongSensor() throws Exception {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         final List<Integer> sensors = getSensorsOfTargetStrength(SensorProperties.STRENGTH_STRONG);
         assumeTrue("testBiometricStrengthDowngraded_StrongSensor: numSensors=" + sensors.size(),
                 sensors.size() > 0);
@@ -325,6 +329,7 @@
      */
     @Test
     public void testBiometricStrengthDowngraded_WeakSensor() throws Exception {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         final List<Integer> sensors = getSensorsOfTargetStrength(SensorProperties.STRENGTH_WEAK);
         assumeTrue("testBiometricStrengthDowngraded_WeakSensor: numSensors: " + sensors.size(),
                 sensors.size() > 0);
@@ -439,6 +444,7 @@
      */
     @Test
     public void testBiometricStrengthUpgraded_WeakSensor() throws Exception {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         final List<Integer> sensors = getSensorsOfTargetStrength(SensorProperties.STRENGTH_WEAK);
         assumeTrue("testBiometricStrengthUpgraded_WeakSensor: numSensors: " + sensors.size(),
                 sensors.size() > 0);
@@ -479,6 +485,7 @@
      */
     @Test
     public void testBiometricStrengthUpgraded_ConvenienceSensor() throws Exception {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         final List<Integer> sensors =
                 getSensorsOfTargetStrength(SensorProperties.STRENGTH_CONVENIENCE);
         assumeTrue("testBiometricStrengthUpgraded_ConvenienceSensor: numSensors=" + sensors.size(),
diff --git a/tests/framework/base/biometrics/src/android/server/biometrics/BiometricServiceTests.java b/tests/framework/base/biometrics/src/android/server/biometrics/BiometricServiceTests.java
index 8a5da86..023ffaa 100644
--- a/tests/framework/base/biometrics/src/android/server/biometrics/BiometricServiceTests.java
+++ b/tests/framework/base/biometrics/src/android/server/biometrics/BiometricServiceTests.java
@@ -48,6 +48,7 @@
         // On devices with multiple strong sensors, adding enrollments to one strong sensor
         // must cause authenticatorIds for all other strong sensors to be invalidated, if they
         // (the other strong sensors) have enrollments.
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         final List<Integer> strongSensors = new ArrayList<>();
         for (SensorProperties prop : mSensorProperties) {
             if (prop.getSensorStrength() == SensorProperties.STRENGTH_STRONG) {
@@ -118,6 +119,7 @@
         // ResetLockout only really needs to be applied when enrollments exist. Furthermore, some
         // interfaces may take this a step further and ignore resetLockout requests when no
         // enrollments exist.
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         List<BiometricTestSession> biometricSessions = new ArrayList<>();
         for (SensorProperties prop : mSensorProperties) {
             BiometricTestSession session = mBiometricManager.createTestSession(prop.getSensorId());
@@ -161,6 +163,7 @@
 
     @Test
     public void testLockoutResetRequestedAfterBiometricUnlock_whenStrong() throws Exception {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         assumeTrue(mSensorProperties.size() > 1);
 
         // ResetLockout only really needs to be applied when enrollments exist. Furthermore, some
@@ -255,6 +258,7 @@
 
     @Test
     public void testLockoutResetNotRequestedAfterBiometricUnlock_whenNotStrong() throws Exception {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         assumeTrue(mSensorProperties.size() > 1);
 
         // ResetLockout only really needs to be applied when enrollments exist. Furthermore, some
@@ -318,6 +322,7 @@
     public void testBiometricsRemovedWhenCredentialRemoved() throws Exception {
         // Manually keep track of sessions and do not use autocloseable, since we do not want the
         // test session to automatically cleanup and remove enrollments once we leave scope.
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         final List<BiometricTestSession> biometricSessions = new ArrayList<>();
 
         try (CredentialSession session = new CredentialSession()) {
diff --git a/tests/framework/base/biometrics/src/android/server/biometrics/BiometricSimpleTests.java b/tests/framework/base/biometrics/src/android/server/biometrics/BiometricSimpleTests.java
index 379b732..e3d2bff 100644
--- a/tests/framework/base/biometrics/src/android/server/biometrics/BiometricSimpleTests.java
+++ b/tests/framework/base/biometrics/src/android/server/biometrics/BiometricSimpleTests.java
@@ -21,6 +21,7 @@
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyObject;
@@ -62,6 +63,7 @@
      */
     @Test
     public void testEnroll() throws Exception {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         for (SensorProperties prop : mSensorProperties) {
             try (BiometricTestSession session =
                          mBiometricManager.createTestSession(prop.getSensorId())){
@@ -76,6 +78,7 @@
      */
     @Test
     public void testSensorPropertiesAndDumpsysMatch() throws Exception {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         final BiometricServiceState state = getCurrentState();
 
         assertEquals(mSensorProperties.size(), state.mSensorStates.sensorStates.size());
@@ -89,6 +92,7 @@
      */
     @Test
     public void testPackageManagerAndDumpsysMatch() throws Exception {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         final BiometricServiceState state = getCurrentState();
         final PackageManager pm = mContext.getPackageManager();
         if (mSensorProperties.isEmpty()) {
@@ -111,6 +115,7 @@
 
     @Test
     public void testCanAuthenticate_whenNoSensors() {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         if (mSensorProperties.isEmpty()) {
             assertEquals(BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE,
                     mBiometricManager.canAuthenticate(Authenticators.BIOMETRIC_WEAK));
@@ -121,6 +126,7 @@
 
     @Test
     public void testInvalidInputs() {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         for (int i = 0; i < 32; i++) {
             final int authenticator = 1 << i;
             // If it's a public constant, no need to test
@@ -150,6 +156,7 @@
      */
     @Test
     public void testWhenCredentialNotEnrolled() throws Exception {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         // First case above
         final int result = mBiometricManager.canAuthenticate(BiometricManager
                 .Authenticators.DEVICE_CREDENTIAL);
@@ -187,6 +194,7 @@
      */
     @Test
     public void testWhenCredentialEnrolled() throws Exception {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         try (CredentialSession session = new CredentialSession()) {
             session.setCredential();
 
@@ -275,6 +283,7 @@
      */
     @Test
     public void testSimpleBiometricAuth_nonConvenience() throws Exception {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         for (SensorProperties props : mSensorProperties) {
             if (props.getSensorStrength() == SensorProperties.STRENGTH_CONVENIENCE) {
                 continue;
@@ -344,6 +353,7 @@
      */
     @Test
     public void testSimpleCredentialAuth() throws Exception {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         try (CredentialSession session = new CredentialSession()){
             session.setCredential();
 
@@ -385,6 +395,7 @@
      */
     @Test
     public void testBiometricCancellation() throws Exception {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         for (SensorProperties props : mSensorProperties) {
             if (props.getSensorStrength() == SensorProperties.STRENGTH_CONVENIENCE) {
                 continue;
diff --git a/tests/framework/base/biometrics/src/android/server/biometrics/Utils.java b/tests/framework/base/biometrics/src/android/server/biometrics/Utils.java
index 2d2dea7..91e31ab 100644
--- a/tests/framework/base/biometrics/src/android/server/biometrics/Utils.java
+++ b/tests/framework/base/biometrics/src/android/server/biometrics/Utils.java
@@ -22,6 +22,7 @@
 import android.hardware.biometrics.BiometricManager;
 import android.hardware.biometrics.BiometricPrompt;
 import android.hardware.biometrics.SensorProperties;
+import android.os.SystemProperties;
 import android.os.ParcelFileDescriptor;
 import android.security.keystore.KeyGenParameterSpec;
 import android.security.keystore.KeyProperties;
@@ -264,4 +265,12 @@
                         + testApiStrength);
         }
     }
+
+    public static boolean isFirstApiLevel29orGreater() {
+        int firstApiLevel = SystemProperties.getInt("ro.product.first_api_level", 0);
+        if (firstApiLevel >= 29) {
+            return true;
+        }
+        return false;
+    }
 }
diff --git a/tests/framework/base/biometrics/src/android/server/biometrics/fingerprint/FingerprintServiceTest.java b/tests/framework/base/biometrics/src/android/server/biometrics/fingerprint/FingerprintServiceTest.java
index 43725f2..a81d5c6 100644
--- a/tests/framework/base/biometrics/src/android/server/biometrics/fingerprint/FingerprintServiceTest.java
+++ b/tests/framework/base/biometrics/src/android/server/biometrics/fingerprint/FingerprintServiceTest.java
@@ -144,6 +144,7 @@
 
     @Test
     public void testEnroll() throws Exception {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         for (SensorProperties prop : mSensorProperties) {
             try (BiometricTestSession session
                          = mFingerprintManager.createTestSession(prop.getSensorId())){
@@ -172,6 +173,7 @@
 
     @Test
     public void testAuthenticateFromForegroundActivity() throws Exception {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         // Turn screen on and dismiss keyguard
         UiDeviceUtils.pressWakeupButton();
         UiDeviceUtils.pressUnlockButton();
@@ -231,6 +233,7 @@
 
     @Test
     public void testRejectThenErrorFromForegroundActivity() throws Exception {
+        assumeTrue(Utils.isFirstApiLevel29orGreater());
         // Turn screen on and dismiss keyguard
         UiDeviceUtils.pressWakeupButton();
         UiDeviceUtils.pressUnlockButton();
@@ -323,4 +326,4 @@
         final BiometricServiceState state = Utils.getBiometricServiceCurrentState();
         return state.mSensorStates.containsModalityFlag(SensorStateProto.FINGERPRINT_UDFPS);
     }
-}
\ No newline at end of file
+}
diff --git a/tests/framework/base/windowmanager/AndroidManifest.xml b/tests/framework/base/windowmanager/AndroidManifest.xml
index 14856b3..b765cb0 100644
--- a/tests/framework/base/windowmanager/AndroidManifest.xml
+++ b/tests/framework/base/windowmanager/AndroidManifest.xml
@@ -446,12 +446,6 @@
                   android:screenOrientation="portrait"
                   android:exported="true"/>
 
-        <activity android:name="android.server.wm.CompatChangeTests$ResizeableLargeAspectRatioActivity"
-                  android:resizeableActivity="true"
-                  android:screenOrientation="portrait"
-                  android:minAspectRatio="3"
-                  android:exported="true"/>
-
         <activity android:name="android.server.wm.CompatChangeTests$NonResizeablePortraitActivity"
                   android:resizeableActivity="false"
                   android:screenOrientation="portrait"
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/CompatChangeTests.java b/tests/framework/base/windowmanager/src/android/server/wm/CompatChangeTests.java
index f0eea79..043b298 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/CompatChangeTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/CompatChangeTests.java
@@ -19,8 +19,10 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE;
 import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_MEDIUM_VALUE;
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
 import static android.provider.DeviceConfig.NAMESPACE_CONSTRAIN_DISPLAY_APIS;
 import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Surface.ROTATION_90;
 
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
 
@@ -45,7 +47,6 @@
 import android.util.Size;
 
 import androidx.annotation.Nullable;
-import androidx.test.filters.FlakyTest;
 
 import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
 import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
@@ -70,12 +71,9 @@
  * atest CtsWindowManagerDeviceTestCases:CompatChangeTests
  */
 @Presubmit
-@FlakyTest(bugId = 190609681)
 public final class CompatChangeTests extends MultiDisplayTestBase {
     private static final ComponentName RESIZEABLE_PORTRAIT_ACTIVITY =
             component(ResizeablePortraitActivity.class);
-    private static final ComponentName RESIZEABLE_LARGE_ASPECT_RATIO_ACTIVITY =
-            component(ResizeableLargeAspectRatioActivity.class);
     private static final ComponentName NON_RESIZEABLE_PORTRAIT_ACTIVITY =
             component(NonResizeablePortraitActivity.class);
     private static final ComponentName NON_RESIZEABLE_LANDSCAPE_ACTIVITY =
@@ -191,10 +189,19 @@
      */
     @Test
     public void testSandboxForNonResizableAspectRatioActivity() {
-        runSandboxTest(NON_RESIZEABLE_LARGE_ASPECT_RATIO_ACTIVITY, WINDOWING_MODE_FULLSCREEN,
+        runSizeCompatModeSandboxTest(NON_RESIZEABLE_LARGE_ASPECT_RATIO_ACTIVITY,
                 /* isSandboxed= */ true);
+        assertSandboxedByBounds(NON_RESIZEABLE_LARGE_ASPECT_RATIO_ACTIVITY, /* isSandboxed= */
+                true);
     }
 
+     // =================
+     // NEVER_SANDBOX test cases
+     // =================
+     // Validates that an activity forced into size compat mode never has sandboxing applied to the
+     // max bounds. It is expected that an activity in size compat mode normally always has
+     // sandboxing applied.
+
     /**
      * Test that a min aspect ratio activity eligible for size compat mode does not have the Display
      * APIs sandboxed when the {@link ActivityInfo#NEVER_SANDBOX_DISPLAY_APIS} compat change is
@@ -203,7 +210,7 @@
     @Test
     @EnableCompatChanges({ActivityInfo.NEVER_SANDBOX_DISPLAY_APIS})
     public void testSandboxForNonResizableAspectRatioActivityNeverSandboxDisplayApisEnabled() {
-        runSandboxTest(NON_RESIZEABLE_LARGE_ASPECT_RATIO_ACTIVITY, WINDOWING_MODE_FULLSCREEN,
+        runSizeCompatModeSandboxTest(NON_RESIZEABLE_LARGE_ASPECT_RATIO_ACTIVITY,
                 /* isSandboxed= */ false);
     }
 
@@ -217,7 +224,7 @@
         setNeverConstrainDisplayApisAllPackagesFlag("true");
         // Setting 'never_constrain_display_apis' as well to make sure it is ignored.
         setNeverConstrainDisplayApisFlag("com.android.other::");
-        runSandboxTest(NON_RESIZEABLE_LARGE_ASPECT_RATIO_ACTIVITY, WINDOWING_MODE_FULLSCREEN,
+        runSizeCompatModeSandboxTest(NON_RESIZEABLE_LARGE_ASPECT_RATIO_ACTIVITY,
                 /* isSandboxed= */ false);
     }
 
@@ -231,8 +238,7 @@
         ComponentName activity = NON_RESIZEABLE_LARGE_ASPECT_RATIO_ACTIVITY;
         setNeverConstrainDisplayApisFlag(
                 "com.android.other::," + activity.getPackageName() + "::");
-        runSandboxTest(activity, WINDOWING_MODE_FULLSCREEN,
-                /* isSandboxed= */ false);
+        runSizeCompatModeSandboxTest(activity, /* isSandboxed= */ false);
     }
 
     /**
@@ -247,7 +253,7 @@
         setNeverConstrainDisplayApisFlag(
                 "com.android.other::," + activity.getPackageName() + ":" + String.valueOf(
                         version - 1) + ":" + String.valueOf(version + 1));
-        runSandboxTest(activity, WINDOWING_MODE_FULLSCREEN,/* isSandboxed= */ false);
+        runSizeCompatModeSandboxTest(activity, /* isSandboxed= */ false);
     }
 
     /**
@@ -262,7 +268,7 @@
         setNeverConstrainDisplayApisFlag(
                 "com.android.other::," + activity.getPackageName() + ":" + String.valueOf(
                         version + 1) + ":");
-        runSandboxTest(activity, WINDOWING_MODE_FULLSCREEN, /* isSandboxed= */ true);
+        runSizeCompatModeSandboxTest(activity, /* isSandboxed= */ true);
     }
 
     /**
@@ -273,7 +279,7 @@
     @Test
     public void testSandboxForNonResizableActivityPackageNotInNeverSandboxDeviceConfigFlag() {
         setNeverConstrainDisplayApisFlag("com.android.other::,com.android.other2::");
-        runSandboxTest(NON_RESIZEABLE_LARGE_ASPECT_RATIO_ACTIVITY, WINDOWING_MODE_FULLSCREEN,
+        runSizeCompatModeSandboxTest(NON_RESIZEABLE_LARGE_ASPECT_RATIO_ACTIVITY,
                 /* isSandboxed= */ true);
     }
 
@@ -284,7 +290,7 @@
     @Test
     public void testSandboxForNonResizableActivityNeverSandboxDeviceConfigFlagEmpty() {
         setNeverConstrainDisplayApisFlag("");
-        runSandboxTest(NON_RESIZEABLE_LARGE_ASPECT_RATIO_ACTIVITY, WINDOWING_MODE_FULLSCREEN,
+        runSizeCompatModeSandboxTest(NON_RESIZEABLE_LARGE_ASPECT_RATIO_ACTIVITY,
                 /* isSandboxed= */ true);
     }
 
@@ -298,44 +304,48 @@
         ComponentName activity = NON_RESIZEABLE_LARGE_ASPECT_RATIO_ACTIVITY;
         setNeverConstrainDisplayApisFlag(
                 "com.android.other::," + activity.getPackageName() + ":::");
-        runSandboxTest(activity, WINDOWING_MODE_FULLSCREEN, /* isSandboxed= */ true);
+        runSizeCompatModeSandboxTest(activity, /* isSandboxed= */ true);
     }
 
+    // =================
+    // ALWAYS_SANDBOX test cases
+    // =================
+    // Validates that an activity simply in letterbox mode has sandboxing applied to the max
+    // bounds when ALWAYS_SANDBOX is set. Without the flag, we would not expect a letterbox activity
+    // to be sandboxed, unless it is also eligible for size compat mode.
+
     /**
-     * Test that a min aspect ratio activity not eligible for size compat mode does have the
+     * Test that a portrait activity not eligible for size compat mode does have the
      * Display APIs sandboxed when the {@link ActivityInfo#ALWAYS_SANDBOX_DISPLAY_APIS} compat
      * change is enabled.
      */
     @Test
     @EnableCompatChanges({ActivityInfo.ALWAYS_SANDBOX_DISPLAY_APIS})
-    public void testSandboxForResizableAspectRatioActivityAlwaysSandboxDisplayApisEnabled() {
-        runSandboxTest(RESIZEABLE_LARGE_ASPECT_RATIO_ACTIVITY, WINDOWING_MODE_FULLSCREEN,
-                /* isSandboxed= */true, /* inSizeCompatModeAfterResize= */ false);
+    public void testSandboxForResizableActivityAlwaysSandboxDisplayApisEnabled() {
+        runLetterboxSandboxTest(RESIZEABLE_PORTRAIT_ACTIVITY, /* isSandboxed= */ true);
     }
 
     /**
-     * Test that a min aspect ratio activity non eligible for size compat mode does not have the
+     * Test that a portrait activity not eligible for size compat mode does not have the
      * Display APIs sandboxed when the 'always_constrain_display_apis' Device Config flag is empty.
      */
     @Test
     public void testSandboxResizableActivityAlwaysSandboxDeviceConfigFlagEmpty() {
         setAlwaysConstrainDisplayApisFlag("");
-        runSandboxTest(RESIZEABLE_LARGE_ASPECT_RATIO_ACTIVITY, WINDOWING_MODE_FULLSCREEN,
-                /* isSandboxed= */false, /* inSizeCompatModeAfterResize= */ false);
+        runLetterboxSandboxTest(RESIZEABLE_PORTRAIT_ACTIVITY, /* isSandboxed= */ false);
     }
 
     /**
-     * Test that a min aspect ratio activity eligible for size compat mode does have the Display
+     * Test that a portrait activity not eligible for size compat mode does have the Display
      * APIs sandboxed when the 'always_constrain_display_apis' Device Config flag contains the test
      * package.
      */
     @Test
     public void testSandboxResizableActivityPackageInAlwaysSandboxDeviceConfigFlag() {
-        ComponentName activity = RESIZEABLE_LARGE_ASPECT_RATIO_ACTIVITY;
+        ComponentName activity = RESIZEABLE_PORTRAIT_ACTIVITY;
         setAlwaysConstrainDisplayApisFlag(
                 "com.android.other::," + activity.getPackageName() + "::");
-        runSandboxTest(activity, WINDOWING_MODE_FULLSCREEN,/* isSandboxed= */ true,
-                /* inSizeCompatModeAfterResize= */ false);
+        runLetterboxSandboxTest(activity, /* isSandboxed= */ true);
     }
 
     /**
@@ -499,6 +509,9 @@
      */
     private void runSizeCompatTest(ComponentName activity, int windowingMode, double resizeRatio,
             boolean inSizeCompatModeAfterResize) {
+        // TODO(b/208918131): Remove once real cause is found.
+        assumeFalse(ENABLE_SHELL_TRANSITIONS);
+
         launchActivity(activity, windowingMode);
 
         assertSizeCompatMode(activity, /* expectedInSizeCompatMode= */ false);
@@ -520,8 +533,10 @@
         }
     }
 
-    private void runSandboxTest(ComponentName activity, int windowingMode, boolean isSandboxed) {
-        runSandboxTest(activity, windowingMode, isSandboxed, /* inSizeCompatModeAfterResize= */ true);
+    private void runSizeCompatModeSandboxTest(ComponentName activity,
+            boolean isSandboxed) {
+        runSizeCompatModeSandboxTest(activity, isSandboxed,
+                /* inSizeCompatModeAfterResize= */ true);
     }
 
     /**
@@ -529,26 +544,58 @@
      * expected to be in size compat mode after resizing the display.
      *
      * @param activity                    the activity under test
-     * @param windowingMode               the launch windowing mode for the activity
-     * @param isSandboxed                 when {@code true}, {@link android.app.WindowConfiguration#getMaxBounds()}
-     *                                    are sandboxed to the activity bounds. Otherwise, they inherit the
+     * @param isSandboxed                 when {@code true},
+     * {@link android.app.WindowConfiguration#getMaxBounds()}
+     *                                    are sandboxed to the activity bounds. Otherwise, they
+     *                                    inherit the
      *                                    DisplayArea bounds
      * @param inSizeCompatModeAfterResize if the activity should be in size compat mode after
      *                                    resizing the display
      */
-    private void runSandboxTest(ComponentName activity, int windowingMode, boolean isSandboxed,
+    private void runSizeCompatModeSandboxTest(ComponentName activity, boolean isSandboxed,
             boolean inSizeCompatModeAfterResize) {
         assertThat(getInitialDisplayAspectRatio()).isLessThan(ACTIVITY_LARGE_MIN_ASPECT_RATIO);
-        runSizeCompatTest(activity, windowingMode, /* resizeRatio= */ 0.5,
+        runSizeCompatTest(activity, WINDOWING_MODE_FULLSCREEN, /* resizeRatio= */ 0.5,
                 inSizeCompatModeAfterResize);
-        assertSandboxed(activity, isSandboxed);
+        assertSandboxedByProvidesMaxBounds(activity, isSandboxed);
         restoreDisplay(activity);
-        runSizeCompatTest(activity, windowingMode, /* resizeRatio= */ 2,
+        runSizeCompatTest(activity, WINDOWING_MODE_FULLSCREEN, /* resizeRatio= */ 2,
                 inSizeCompatModeAfterResize);
-        assertSandboxed(activity, isSandboxed);
+        assertSandboxedByProvidesMaxBounds(activity, isSandboxed);
     }
 
-    private void assertSandboxed(ComponentName activityName, boolean expectedSandboxed) {
+    /**
+     * Similar to {@link #runSizeCompatModeSandboxTest(ComponentName, boolean)}, but the
+     * activity is put into letterbox mode after resizing the display.
+     *
+     * @param activityName the activity under test
+     * @param isSandboxed  when {@code true}, {@link android.app.WindowConfiguration#getMaxBounds()}
+     *                     are sandboxed to the activity bounds. Otherwise, they inherit the
+     *                     DisplayArea bounds
+     */
+    private void runLetterboxSandboxTest(ComponentName activityName, boolean isSandboxed) {
+        assertThat(getInitialDisplayAspectRatio()).isLessThan(ACTIVITY_LARGE_MIN_ASPECT_RATIO);
+        // Initialize display to portrait orientation.
+        final RotationSession rotationSession = createManagedRotationSession();
+        Size originalDisplaySize = mDisplayMetricsSession.getInitialDisplayMetrics().getSize();
+        if (originalDisplaySize.getHeight() < originalDisplaySize.getWidth()) {
+            // Device is landscape
+            rotationSession.set(ROTATION_90);
+        } else if (originalDisplaySize.getHeight() == originalDisplaySize.getWidth()) {
+            // Device is square, so skip this test case (portrait activity will never be
+            // letterboxed)
+            return;
+        }
+
+        // Launch portrait activity
+        launchActivity(activityName, WINDOWING_MODE_FULLSCREEN);
+
+        // Change display to landscape should force portrait resizeable activity into letterbox.
+        changeDisplayAspectRatioAndWait(activityName, /* aspectRatio= */ 2);
+        assertSandboxedByProvidesMaxBounds(activityName, isSandboxed);
+    }
+
+    private void assertSandboxedByBounds(ComponentName activityName, boolean isSandboxed) {
         mWmState.computeState(new WaitForValidActivityState(activityName));
         final WindowManagerState.Activity activity = mWmState.getActivity(activityName);
         assertNotNull(activity);
@@ -556,17 +603,32 @@
         final Rect maxBounds = activity.getMaxBounds();
         WindowManagerState.DisplayArea tda = mWmState.getTaskDisplayArea(activityName);
         assertNotNull(tda);
-        if (expectedSandboxed) {
+        if (isSandboxed) {
             assertEquals(
-                    "The Window has max bounds sandboxed to the window bounds",
+                    "The window has max bounds sandboxed to the window bounds",
                     activityBounds, maxBounds);
         } else {
             assertEquals(
-                    "The Window is not sandboxed, with max bounds reflecting the DisplayArea",
+                    "The window is not sandboxed, with max bounds reflecting the DisplayArea",
                     tda.getBounds(), maxBounds);
         }
     }
 
+    private void assertSandboxedByProvidesMaxBounds(ComponentName activityName, boolean isSandboxed) {
+        mWmState.computeState(new WaitForValidActivityState(activityName));
+        final WindowManagerState.Activity activity = mWmState.getActivity(activityName);
+        assertNotNull(activity);
+        if (isSandboxed) {
+            assertTrue(
+                    "The window should have max bounds sandboxed to the window bounds",
+                    activity.providesMaxBounds());
+        } else {
+            assertFalse(
+                    "The window should not be sandboxed; max bounds should reflect the DisplayArea",
+                    activity.providesMaxBounds());
+        }
+    }
+
     private class ConstrainDisplayApisFlagsSession implements AutoCloseable {
         private Properties mInitialProperties;
 
@@ -640,10 +702,10 @@
      * Restore the display size and ensure configuration changes are complete.
      */
     private void restoreDisplay(ComponentName activity) {
-        final Rect originalTaskBounds = mWmState.getTaskByActivity(activity).getBounds();
+        final Rect originalBounds = mWmState.getActivity(activity).getBounds();
         mDisplayMetricsSession.restoreDisplayMetrics();
         // Ensure configuration changes are complete after resizing the display.
-        waitForTaskBoundsChanged(activity, originalTaskBounds);
+        waitForActivityBoundsChanged(activity, originalBounds);
     }
 
     /**
@@ -651,26 +713,46 @@
      */
     private void resizeDisplay(ComponentName activity, double sizeRatio) {
         Size originalDisplaySize = mDisplayMetricsSession.getInitialDisplayMetrics().getSize();
-        final Rect originalTaskBounds = mWmState.getTaskByActivity(activity).getBounds();
+        final Rect originalBounds = mWmState.getActivity(activity).getBounds();
         mDisplayMetricsSession.changeDisplayMetrics(sizeRatio, /* densityRatio= */ 1);
         mWmState.computeState(new WaitForValidActivityState(activity));
 
         Size currentDisplaySize = mDisplayMetricsSession.getDisplayMetrics().getSize();
         assumeFalse("If a display size is capped, resizing may be a no-op",
-            originalDisplaySize.equals(currentDisplaySize));
+                originalDisplaySize.equals(currentDisplaySize));
 
         // Ensure configuration changes are complete after resizing the display.
-        waitForTaskBoundsChanged(activity, originalTaskBounds);
+        waitForActivityBoundsChanged(activity, originalBounds);
+    }
+
+    /**
+     * Resize the display to given aspect ratio in landscape orientation, and ensure configuration
+     * changes are complete.
+     */
+    private void changeDisplayAspectRatioAndWait(ComponentName activity, double aspectRatio) {
+        mWmState.computeState(new WaitForValidActivityState(activity));
+        Size originalDisplaySize = mDisplayMetricsSession.getInitialDisplayMetrics().getSize();
+        final Rect originalBounds = mWmState.getActivity(activity).getBounds();
+        mDisplayMetricsSession.changeAspectRatio(aspectRatio,
+                /* orientation= */ ORIENTATION_LANDSCAPE);
+        mWmState.computeState(new WaitForValidActivityState(activity));
+
+        Size currentDisplaySize = mDisplayMetricsSession.getDisplayMetrics().getSize();
+        assumeFalse("If a display size is capped, resizing may be a no-op",
+                originalDisplaySize.equals(currentDisplaySize));
+
+        // Ensure configuration changes are complete after resizing the display.
+        waitForActivityBoundsChanged(activity, originalBounds);
     }
 
     /**
      * Waits until the given activity has updated task bounds.
      */
-    private void waitForTaskBoundsChanged(ComponentName activityName, Rect priorTaskBounds) {
+    private void waitForActivityBoundsChanged(ComponentName activityName, Rect priorActivityBounds) {
         mWmState.waitForWithAmState(wmState -> {
-            WindowManagerState.Task task = wmState.getTaskByActivity(activityName);
-            return task != null && !task.getBounds().equals(priorTaskBounds);
-        }, "checking task bounds updated");
+            WindowManagerState.Activity activity = wmState.getActivity(activityName);
+            return activity != null && !activity.getBounds().equals(priorActivityBounds);
+        }, "checking activity bounds updated");
     }
 
     private float getInitialDisplayAspectRatio() {
@@ -709,9 +791,6 @@
     public static class ResizeablePortraitActivity extends FocusableActivity {
     }
 
-    public static class ResizeableLargeAspectRatioActivity extends FocusableActivity {
-    }
-
     public static class NonResizeablePortraitActivity extends FocusableActivity {
     }
 
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityStarterTests.java b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityStarterTests.java
index 0496bd6..7571a56 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityStarterTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityStarterTests.java
@@ -720,7 +720,7 @@
 
     /**
      * This test case tests behavior of activity with relinquishTaskIdentify attribute. Ensure the
-     * relinquishTaskIdentity doesn't work if the app is not installed in the system partition.
+     * relinquishTaskIdentity work if the activities are in the same app.
      */
     @Test
     public void testActivityWithRelinquishTaskIdentity() {
@@ -741,9 +741,9 @@
 
         // verify the activities are in the same task
         assertEquals("Activity must be in the same task.", taskId, taskId2);
-        // verify the relinquishTaskIdentify function is ignored since it isn't a app that in system
-        // partition
-        assertEquals("Affinity should be same with the package name.",
+        // verify the relinquishTaskIdentify function should work since the activities are in the
+        // same app
+        assertNotEquals("Affinity should not be same with the package name.",
                 RELINQUISHTASKIDENTITY_ACTIVITY.getPackageName(), affinity);
     }
 
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java b/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java
index a95ea95..2308932 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/WindowManagerState.java
@@ -1545,6 +1545,7 @@
         boolean frontOfTask;
         boolean inSizeCompatMode;
         float minAspectRatio;
+        boolean providesMaxBounds;
         int procId = -1;
         public boolean translucent;
         private WindowContainer mParent;
@@ -1557,6 +1558,7 @@
             frontOfTask = proto.frontOfTask;
             inSizeCompatMode = proto.inSizeCompatMode;
             minAspectRatio = proto.minAspectRatio;
+            providesMaxBounds = proto.providesMaxBounds;
             if (proto.procId != 0) {
                 procId = proto.procId;
             }
@@ -1596,6 +1598,10 @@
             return minAspectRatio;
         }
 
+        public boolean providesMaxBounds() {
+            return providesMaxBounds;
+        }
+
         @Override
         public Rect getBounds() {
             if (mBounds == null) {
diff --git a/tests/media/src/android/mediav2/cts/AdaptivePlaybackTest.java b/tests/media/src/android/mediav2/cts/AdaptivePlaybackTest.java
index e803863..ae9054f 100644
--- a/tests/media/src/android/mediav2/cts/AdaptivePlaybackTest.java
+++ b/tests/media/src/android/mediav2/cts/AdaptivePlaybackTest.java
@@ -219,6 +219,7 @@
             queueEOS();
             waitForAllOutputs();
             mCodec.reset();
+            mCodec.release();
         }
         tearDownSurface();
     }
diff --git a/tests/tests/uiautomation/AndroidTest.xml b/tests/tests/uiautomation/AndroidTest.xml
index d5b2c92..563a6d7 100644
--- a/tests/tests/uiautomation/AndroidTest.xml
+++ b/tests/tests/uiautomation/AndroidTest.xml
@@ -19,6 +19,7 @@
     <option name="config-descriptor:metadata" key="parameter" value="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="no_foldable_states" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsUiAutomationTestCases.apk" />
diff --git a/tests/tests/view/src/android/view/cts/FrameMetricsListenerTest.java b/tests/tests/view/src/android/view/cts/FrameMetricsListenerTest.java
index c6476bf..a7a3a6a 100644
--- a/tests/tests/view/src/android/view/cts/FrameMetricsListenerTest.java
+++ b/tests/tests/view/src/android/view/cts/FrameMetricsListenerTest.java
@@ -19,6 +19,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
+import android.animation.ValueAnimator;
 import android.app.Activity;
 import android.app.Instrumentation;
 import android.os.Handler;
@@ -37,6 +38,7 @@
 import com.android.compatibility.common.util.PollingCheck;
 import com.android.compatibility.common.util.WidgetTestUtils;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -50,6 +52,7 @@
 public class FrameMetricsListenerTest {
     private Instrumentation mInstrumentation;
     private Activity mActivity;
+    private float mPreviousDurationScale;
 
     @Rule
     public ActivityTestRule<MockActivity> mActivityRule =
@@ -59,6 +62,14 @@
     public void setup() {
         mInstrumentation = InstrumentationRegistry.getInstrumentation();
         mActivity = mActivityRule.getActivity();
+        mPreviousDurationScale = ValueAnimator.getDurationScale();
+        ValueAnimator.setDurationScale(0.0f); // Disable animations during frame metrics tests
+    }
+
+    @After
+    public void tearDown() {
+        // Restore animations to previous animation scale after tests are run
+        ValueAnimator.setDurationScale(mPreviousDurationScale);
     }
 
     private void layout(final int layoutId) throws Throwable {
diff --git a/tests/tests/widget/src/android/widget/cts/RemoteViewsTest.java b/tests/tests/widget/src/android/widget/cts/RemoteViewsTest.java
index 0cadd73..ac9e140 100644
--- a/tests/tests/widget/src/android/widget/cts/RemoteViewsTest.java
+++ b/tests/tests/widget/src/android/widget/cts/RemoteViewsTest.java
@@ -119,6 +119,7 @@
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.Function;
 
 /**
@@ -597,6 +598,23 @@
     }
 
     @Test
+    public void testSetImageViewBitmap_afterCopying() throws Throwable {
+        Bitmap bitmap =
+                BitmapFactory.decodeResource(mContext.getResources(), R.drawable.testimage);
+        RemoteViews original =
+                new RemoteViews(mContext.getPackageName(), R.layout.remoteviews_good);
+        original.setImageViewBitmap(R.id.remoteView_image, bitmap);
+        RemoteViews copy = new RemoteViews(original);
+
+        AtomicReference<View> view = new AtomicReference<>();
+        mActivityRule.runOnUiThread(() -> view.set(copy.apply(mContext, null)));
+
+        ImageView image = view.get().findViewById(R.id.remoteView_image);
+        assertNotNull(image.getDrawable());
+        WidgetTestUtils.assertEquals(bitmap, ((BitmapDrawable) image.getDrawable()).getBitmap());
+    }
+
+    @Test
     public void testSetBitmap() throws Throwable {
         ImageView image = (ImageView) mResult.findViewById(R.id.remoteView_image);
         assertNull(image.getDrawable());
diff --git a/tools/cts-tradefed/Android.bp b/tools/cts-tradefed/Android.bp
index f0b8e3d..dee557e 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: "12L_r1",
+    version: "12.1_r1",
     static_libs: ["cts-tradefed-harness"],
     required: ["compatibility-host-util"],
 }