Merge "Don't run AR tests in instant mode" into sc-dev
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 9ed0b6f..f216cf4 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -3855,6 +3855,7 @@
                 <action android:name="android.intent.action.MAIN" />
                 <action android:name="com.android.cts.verifier.managedprovisioning.action.CHECK_DEVICE_OWNER" />
                 <action android:name="com.android.cts.verifier.managedprovisioning.action.CHECK_PROFILE_OWNER" />
+                <action android:name="com.android.cts.verifier.managedprovisioning.action.CHECK_USER_AFFILIATED" />
                 <category android:name="android.intent.category.DEFAULT" />
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
             </intent-filter>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 51a1287..9dffc50 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -3479,8 +3479,10 @@
     <string name="remove_device_owner_button">Remove device owner</string>
     <string name="device_owner_check_device_owner_test">Check device owner</string>
     <string name="device_owner_check_profile_owner_test">Check profile owner</string>
+    <string name="device_owner_check_user_affiliation_test">Check user affiliation</string>
     <string name="device_owner_incorrect_device_owner">Missing or incorrect device owner: CTSVerifier is not DO for user %1$d!</string>
     <string name="device_owner_incorrect_profile_owner">Missing or incorrect profile owner: CTSVerifier is not PO for user %1$d!</string>
+    <string name="device_owner_user_not_affiliated">User %1$d! is not affiliated</string>
     <string name="device_owner_wifi_lockdown_test">WiFi configuration lockdown</string>
     <string name="device_owner_wifi_lockdown_info">
             Please enter the SSID and auth method of an available WiFi Access Point and press the button to create a
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
index 0044e5c..00ae3b5 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
@@ -53,10 +53,14 @@
             "com.android.cts.verifier.managedprovisioning.action.CHECK_DEVICE_OWNER";
     private static final String ACTION_CHECK_PROFILE_OWNER =
             "com.android.cts.verifier.managedprovisioning.action.CHECK_PROFILE_OWNER";
+    private static final String ACTION_CHECK_CURRENT_USER_AFFILIATED =
+            "com.android.cts.verifier.managedprovisioning.action.CHECK_USER_AFFILIATED";
+
     static final String EXTRA_TEST_ID = "extra-test-id";
 
     private static final String CHECK_DEVICE_OWNER_TEST_ID = "CHECK_DEVICE_OWNER";
     private static final String CHECK_PROFILE_OWNER_TEST_ID = "CHECK_PROFILE_OWNER";
+    private static final String CHECK_USER_AFFILIATED_TEST_ID = "CHECK_USER_AFFILIATED";
     private static final String DEVICE_ADMIN_SETTINGS_ID = "DEVICE_ADMIN_SETTINGS";
     private static final String WIFI_LOCKDOWN_TEST_ID = WifiLockdownTestActivity.class.getName();
     private static final String DISABLE_STATUS_BAR_TEST_ID = "DISABLE_STATUS_BAR";
@@ -119,6 +123,18 @@
             finish();
             return;
         }
+        if (ACTION_CHECK_CURRENT_USER_AFFILIATED.equals(getIntent().getAction())) {
+            DevicePolicyManager dpm = getSystemService(DevicePolicyManager.class);
+            if (dpm.isAffiliatedUser()) {
+                TestResult.setPassedResult(this, getIntent().getStringExtra(EXTRA_TEST_ID),
+                        null, null);
+            } else {
+                TestResult.setFailedResult(this, getIntent().getStringExtra(EXTRA_TEST_ID),
+                        getString(R.string.device_owner_user_not_affiliated, getUserId()), null);
+            }
+            finish();
+            return;
+        }
 
         setContentView(R.layout.positive_device_owner);
         setInfoResources(R.string.device_owner_positive_tests,
@@ -169,6 +185,7 @@
         switch(action) {
             case ACTION_CHECK_DEVICE_OWNER:
             case ACTION_CHECK_PROFILE_OWNER:
+            case ACTION_CHECK_CURRENT_USER_AFFILIATED:
                 // If this activity was started for checking device / profile owner status, then no
                 // need to do any tear down.
                 Log.d(TAG, "NOT starting createTearDownIntent() due to " + action);
@@ -193,6 +210,10 @@
                     R.string.device_owner_check_profile_owner_test,
                     new Intent(ACTION_CHECK_PROFILE_OWNER)
                             .putExtra(EXTRA_TEST_ID, getIntent().getStringExtra(EXTRA_TEST_ID))));
+            adapter.add(createTestItem(this, CHECK_USER_AFFILIATED_TEST_ID,
+                    R.string.device_owner_check_user_affiliation_test,
+                    new Intent(ACTION_CHECK_CURRENT_USER_AFFILIATED)
+                            .putExtra(EXTRA_TEST_ID, getIntent().getStringExtra(EXTRA_TEST_ID))));
         }
 
         // device admin settings
diff --git a/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/DeviceOwnerHelper.java b/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/DeviceOwnerHelper.java
index ed99c17..6989bab 100644
--- a/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/DeviceOwnerHelper.java
+++ b/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/DeviceOwnerHelper.java
@@ -68,7 +68,10 @@
         String action = intent.getAction();
         Log.d(TAG, "runManagerMethod(): user=" + context.getUserId() + ", action=" + action);
 
-        if (!action.equals(ACTION_WRAPPED_MANAGER_CALL)) return false;
+        if (!action.equals(ACTION_WRAPPED_MANAGER_CALL)) {
+            if (VERBOSE) Log.v(TAG, "ignoring, it's not " + ACTION_WRAPPED_MANAGER_CALL);
+            return false;
+        }
 
         try {
             String className = intent.getStringExtra(EXTRA_CLASS);
@@ -86,9 +89,8 @@
                 for (int i = 0; i < numberArgs; i++) {
                     getArg(extras, args, parameterTypes, i);
                 }
-                Log.d(TAG, "runManagerMethod(): args=" + Arrays.toString(args) + ", types="
-                        + Arrays.toString(parameterTypes));
-
+                Log.d(TAG, "converted args: " + Arrays.toString(args) + " (with types "
+                        + Arrays.toString(parameterTypes) + ")");
             } else {
                 args = null;
             }
diff --git a/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/DevicePolicyManagerWrapper.java b/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/DevicePolicyManagerWrapper.java
index 377439e..634364e 100644
--- a/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/DevicePolicyManagerWrapper.java
+++ b/common/device-side/bedstead/dpmwrapper/src/main/java/com/android/bedstead/dpmwrapper/DevicePolicyManagerWrapper.java
@@ -177,6 +177,38 @@
             doAnswer(answer).when(spy).getGlobalPrivateDnsMode(any());
             doAnswer(answer).when(spy).setGlobalPrivateDnsModeSpecifiedHost(any(), any());
 
+            // Used by StorageEncryptionTest
+            doAnswer(answer).when(spy).getStorageEncryptionStatus();
+            doAnswer(answer).when(spy).setStorageEncryption(any(), anyBoolean());
+
+            // Used by AdminConfiguredNetworksTest
+            doAnswer(answer).when(spy).setConfiguredNetworksLockdownState(any(), anyBoolean());
+
+            // Used by SecurityLoggingTest
+            doAnswer(answer).when(spy).isSecurityLoggingEnabled(any());
+            doAnswer(answer).when(spy).setDelegatedScopes(any(), any(), any());
+            doAnswer(answer).when(spy).retrieveSecurityLogs(any());
+
+            // Used by TimeManagementTest
+            doAnswer(answer).when(spy).setAutoTimeZoneEnabled(any(), anyBoolean());
+            doAnswer(answer).when(spy).setAutoTimeEnabled(any(), anyBoolean());
+            doAnswer(answer).when(spy).getAutoTimeZoneEnabled(any());
+
+            // Used by WifiTest
+            doAnswer(answer).when(spy).getWifiMacAddress(any());
+
+            // Used by AdminConfiguredNetworksTest
+            doAnswer(answer).when(spy).hasLockdownAdminConfiguredNetworks(any());
+
+            // Used by DevicePolicyLoggingTest
+            doAnswer(answer).when(spy).getAutoTimeEnabled(any());
+
+            // Used by InstallUpdateTest
+            doAnswer(answer).when(spy).installSystemUpdate(any(), any(), any(), any());
+
+            // Used by FactoryResetProtectionPolicyTest
+            doAnswer(answer).when(spy).getFactoryResetProtectionPolicy(any());
+
             // TODO(b/176993670): add more methods below as tests are converted
         } catch (Exception e) {
             // Should never happen, but needs to be catch as some methods declare checked exceptions
diff --git a/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/BaseDeviceAdminTest.java b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/BaseDeviceAdminTest.java
index 454f7bf..bd0cdbd 100644
--- a/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/BaseDeviceAdminTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/BaseDeviceAdminTest.java
@@ -23,12 +23,10 @@
 import android.test.AndroidTestCase;
 import android.util.Log;
 
-import com.android.bedstead.dpmwrapper.TestAppSystemServiceFactory;
-
 public class BaseDeviceAdminTest extends AndroidTestCase {
     private static final String TAG = BaseDeviceAdminTest.class.getSimpleName();
 
-    public static class AdminReceiver extends DeviceAdminReceiver {
+    public static final class AdminReceiver extends DeviceAdminReceiver {
     }
 
     protected String mPackageName;
@@ -41,13 +39,15 @@
     protected void setUp() throws Exception {
         super.setUp();
 
-        dpm = TestAppSystemServiceFactory.getDevicePolicyManager(mContext, AdminReceiver.class);
+        dpm = getContext().getSystemService(DevicePolicyManager.class);
         int userId = mContext.getUserId();
 
         mAdminComponent = new ComponentName(mContext, AdminReceiver.class);
         mHasSecureLockScreen = mContext.getPackageManager()
                 .hasSystemFeature(PackageManager.FEATURE_SECURE_LOCK_SCREEN);
-        Log.d(TAG, "setUp(): userId=" + userId + ", admin=" + mAdminComponent);
+        Log.d(TAG, "setUp(): userId=" + userId + ", admin=" + mAdminComponent
+                + ", isDO=" + dpm.isDeviceOwnerApp(mContext.getPackageName())
+                + ", isPO=" + dpm.isProfileOwnerApp(mContext.getPackageName()));
     }
 
     /**
diff --git a/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/WipeDataTest.java b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/WipeDataTest.java
index ea010f4..003081e 100644
--- a/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/WipeDataTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/WipeDataTest.java
@@ -15,15 +15,21 @@
  */
 package com.android.cts.deviceadmin;
 
-public class WipeDataTest extends BaseDeviceAdminTest {
+import android.util.Log;
+
+public final class WipeDataTest extends BaseDeviceAdminTest {
+
+    private static final String TAG = WipeDataTest.class.getSimpleName();
 
     // Caution: this test will wipe the device's data if it fails
     public void testWipeDataThrowsSecurityException() {
         try {
-            dpm.wipeData(0);
+            Log.i(TAG, "Calling wipeData() on " + dpm);
+            dpm.wipeData(/* flags= */ 0);
             fail("wipeData didn't throw expected SecurityException. Managed to kick off factory"
                     + " reset process");
         } catch (SecurityException expected) {
+            Log.v(TAG, "Got exception as expected: " + expected);
         }
     }
 }
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SetPolicyActivity.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SetPolicyActivity.java
index 5637912..706a9c4 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SetPolicyActivity.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SetPolicyActivity.java
@@ -18,18 +18,19 @@
 import android.app.Activity;
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
-import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.Process;
 import android.util.Log;
 
+import com.android.bedstead.dpmwrapper.TestAppSystemServiceFactory;
+
 /**
  * Simple activity that adds or clears a user restriction depending on the value of the extras.
  */
-public class SetPolicyActivity extends Activity {
+public final class SetPolicyActivity extends Activity {
 
-    private static final String TAG = SetPolicyActivity.class.getName();
+    private static final String TAG = SetPolicyActivity.class.getSimpleName();
 
     private static final String EXTRA_RESTRICTION_KEY = "extra-restriction-key";
     private static final String EXTRA_COMMAND = "extra-command";
@@ -51,10 +52,10 @@
     }
 
     private void handleIntent(Intent intent) {
-        DevicePolicyManager dpm = (DevicePolicyManager)
-                getSystemService(Context.DEVICE_POLICY_SERVICE);
+        DevicePolicyManager dpm = TestAppSystemServiceFactory.getDevicePolicyManager(this,
+                BasicAdminReceiver.class);
         String command = intent.getStringExtra(EXTRA_COMMAND);
-        Log.i(TAG, "Command: \"" + command);
+        Log.i(TAG, "Command: \"" + command + " DPM: " + dpm);
         ComponentName admin = BasicAdminReceiver.getComponentName(this);
         if (ADD_RESTRICTION_COMMAND.equals(command)) {
             String restrictionKey = intent.getStringExtra(EXTRA_RESTRICTION_KEY);
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
index 9e852a5..41ed185 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
@@ -1199,15 +1199,18 @@
         // (DPMS.manageUserUnchecked(), which don't grant it (as this is a privileged permission
         // that's not available to 3rd party apps). If we get rid of DevicePolicyManagerWrapper,
         // we won't need to grant it anymore.
-        CLog.i("Granting INTERACT_ACROSS_USERS to DO %s on user %d as it will need to send ordered "
-                + "broadcasts to user 0", deviceAdminPkg, userId);
+        CLog.i("Granting INTERACT_ACROSS_USERS package (%s) on user %d as its PO will need to "
+                + "send ordered broadcasts to user 0", deviceAdminPkg, userId);
         executeShellCommand("pm grant --user %d %s android.permission.INTERACT_ACROSS_USERS",
                 userId, deviceAdminPkg);
 
-        CLog.i("Granting WRITE_SECURE_SETTINGS package (%s) on user %d as some tests might need it",
-                deviceAdminPkg, userId);
+        CLog.i("Granting WRITE_SECURE_SETTINGS to admin package (%s) on user %d as some tests need "
+                + "it", deviceAdminPkg, userId);
         executeShellCommand("pm grant --user %d %s android.permission.WRITE_SECURE_SETTINGS",
                 userId, deviceAdminPkg);
+
+        CLog.i("Granting ALLOW_TEST_API_ACCESS to package %s", deviceAdminPkg);
+        executeShellCommand("am compat enable ALLOW_TEST_API_ACCESS %s", deviceAdminPkg);
     }
 
     /** Find effective restriction for user */
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
index 60a397e..0851291 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
@@ -581,20 +581,25 @@
     @Test
     public void testDisallowFactoryReset() throws Exception {
         int adminVersion = 24;
-        changeUserRestrictionOrFail("no_factory_reset", true, mPrimaryUserId,
-                DEVICE_OWNER_PKG);
+        // NOTE: the restriction must be set on primary user as it will launch SetPolicyActivity,
+        // but the admin must be installed on USER_SYSTEM, otherwise wipeData() on headless system
+        // user mode would wipe the current user (instead of factory resetting the device)
+        changeUserRestrictionOrFail("no_factory_reset", true, mPrimaryUserId, DEVICE_OWNER_PKG);
+        int adminUserId = USER_SYSTEM;
+
+        String deviceAdminPkg = DeviceAdminHelper.getDeviceAdminApkPackage(adminVersion);
+        String deviceAdminReceiver = DeviceAdminHelper.getAdminReceiverComponent(adminVersion);
         try {
             installAppAsUser(DeviceAdminHelper.getDeviceAdminApkFileName(adminVersion),
-                    mPrimaryUserId);
-            setDeviceAdmin(DeviceAdminHelper.getAdminReceiverComponent(adminVersion),
-                    mPrimaryUserId);
+                    adminUserId);
+            setDeviceAdmin(deviceAdminReceiver, adminUserId);
             runDeviceTestsAsUser(
-                    DeviceAdminHelper.getDeviceAdminApkPackage(adminVersion),
+                    deviceAdminPkg,
                     DeviceAdminHelper.getDeviceAdminJavaPackage() + ".WipeDataTest",
-                    "testWipeDataThrowsSecurityException", mPrimaryUserId);
+                    "testWipeDataThrowsSecurityException", adminUserId);
         } finally {
-            removeAdmin(DeviceAdminHelper.getAdminReceiverComponent(adminVersion), mPrimaryUserId);
-            getDevice().uninstallPackage(DeviceAdminHelper.getDeviceAdminApkPackage(adminVersion));
+            removeAdmin(deviceAdminReceiver, adminUserId);
+            getDevice().uninstallPackage(deviceAdminPkg);
         }
     }
 
@@ -609,7 +614,8 @@
     @Test
     public void testDeviceOwnerCanGetDeviceIdentifiers() throws Exception {
         // The Device Owner should have access to all device identifiers.
-        executeDeviceTestMethod(".DeviceIdentifiersTest",
+
+        executeDeviceOwnerTestMethod(".DeviceIdentifiersTest",
                 "testDeviceOwnerCanGetDeviceIdentifiersWithPermission");
     }
 
@@ -624,7 +630,6 @@
             // Install the package in primary user
             runDeviceTestsAsUser(DEVICE_OWNER_PKG, ".PackageInstallTest",
                     "testPackageInstall", mPrimaryUserId);
-
             assertMetricsLogged(getDevice(), () -> {
                 runDeviceTestsAsUser(DEVICE_OWNER_PKG, ".PackageInstallTest",
                         "testKeepPackageCache", mPrimaryUserId);
@@ -926,7 +931,7 @@
             installAppAsUser(DEVICE_OWNER_APK, userId);
             setProfileOwnerOrFail(DEVICE_OWNER_COMPONENT, userId);
         } else {
-            grantDpmWrapperPermissions(DEVICE_OWNER_APK, userId);
+            grantDpmWrapperPermissions(DEVICE_OWNER_PKG, userId);
         }
         wakeupAndDismissKeyguard();
 
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedProfileOwnerTest.java
index d370b3f..ba2eda4 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedProfileOwnerTest.java
@@ -18,6 +18,7 @@
 
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
 
 import android.platform.test.annotations.FlakyTest;
 import android.platform.test.annotations.LargeTest;
@@ -112,4 +113,11 @@
         // Profile owner cannot set auto time zone unless it is called by the profile
         // owner of an organization-owned managed profile or a profile owner on user 0.
     }
+
+    @Override
+    @Test
+    public void testSetAutoTimeEnabled() {
+        // This test should be skipped when profile owner is set on secondary user.
+        assumeTrue("Skipping test: profile owner is not on system user", mUserId == USER_SYSTEM);
+    }
 }
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 55acbda..56016cd 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/CompatChangeTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/CompatChangeTests.java
@@ -16,19 +16,24 @@
 
 package android.server.wm;
 
+import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 import static android.view.Display.DEFAULT_DISPLAY;
 
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
 
 import android.app.Activity;
 import android.compat.testing.PlatformCompatChangeRule;
 import android.content.ComponentName;
 import android.content.pm.ActivityInfo;
+import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
+import android.server.wm.WindowManagerTestBase.FocusableActivity;
 import android.server.wm.app.AbstractLifecycleLogActivity;
 
 import androidx.test.filters.FlakyTest;
@@ -52,7 +57,7 @@
  * The behavior without enabling a compatibility change is also tested as a baseline.
  *
  * <p>Build/Install/Run:
- *     atest CtsWindowManagerDeviceTestCases:CompatChangeTests
+ * atest CtsWindowManagerDeviceTestCases:CompatChangeTests
  */
 @Presubmit
 @FlakyTest(bugId = 182185145)
@@ -140,12 +145,77 @@
                 SUPPORTS_SIZE_CHANGES_PORTRAIT_ACTIVITY, /* inSizeCompatModeAfterResize= */ true);
     }
 
+    /**
+     * Test that a min aspect ratio activity in letterbox results in sandboxed Display APIs.
+     */
+    @Test
+    public void testSandboxForNonResizablePortraitActivity() {
+        runSandboxTest(NON_RESIZEABLE_PORTRAIT_ACTIVITY, /* isSandboxed= */ true);
+    }
+
+    /**
+     * Test that a min aspect ratio activity in letterbox does not have the Display APIs sandboxed
+     * when the {@link ActivityInfo#NEVER_SANDBOX_DISPLAY_APIS} compat change is enabled.
+     */
+    @Test
+    @EnableCompatChanges({ActivityInfo.NEVER_SANDBOX_DISPLAY_APIS})
+    public void testSandboxForNonResizablePortraitActivityNeverSandboxDisplayApisEnabled() {
+        runSandboxTest(NON_RESIZEABLE_PORTRAIT_ACTIVITY, /* isSandboxed= */ false);
+    }
+
+    /**
+     * Test that a min aspect ratio activity in letterbox 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 testSandboxForNonResizablePortraitActivityAlwaysSandboxDisplayApisEnabled() {
+        runSandboxTest(NON_RESIZEABLE_PORTRAIT_ACTIVITY, /* isSandboxed= */ true);
+    }
+
+    /**
+     * Test that a resizable portrait activity in split screen 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 testSandboxForResizablePortraitActivityAlwaysSandboxDisplayApisEnabled() {
+        assumeTrue("Skipping test: no split multi-window support",
+                supportsSplitScreenMultiWindow());
+
+        // Launch a resizable activity into split screen.
+        launchActivityOnDisplay(RESIZEABLE_PORTRAIT_ACTIVITY, DEFAULT_DISPLAY);
+        putActivityInPrimarySplit(RESIZEABLE_PORTRAIT_ACTIVITY);
+        mWmState.computeState(RESIZEABLE_PORTRAIT_ACTIVITY);
+
+        // The resizable activity is sandboxed, due to the config being enabled.
+        assertSandboxed(RESIZEABLE_PORTRAIT_ACTIVITY, /* expectedSandboxed= */ true);
+    }
+
+    /**
+     * Launches the provided activity into size compat mode twice. The first time, the display
+     * is resized to be half the size. The second time, the display is resized to be twice the
+     * original size.
+     *
+     * @param activity                    the activity under test.
+     * @param inSizeCompatModeAfterResize if the activity should be in size compat mode after
+     *                                    resizing the display
+     */
     private void runSizeCompatTest(ComponentName activity, boolean inSizeCompatModeAfterResize) {
         runSizeCompatTest(activity, /* resizeRatio= */ 0.5, inSizeCompatModeAfterResize);
         mDisplayMetricsSession.restoreDisplayMetrics();
         runSizeCompatTest(activity, /* resizeRatio= */ 2, inSizeCompatModeAfterResize);
     }
 
+    /**
+     * Launches the provided activity on the default display, initially not in size compat mode.
+     * After resizing the display, verifies if activity is in size compat mode or not
+     *
+     * @param activity                    the activity under test
+     * @param resizeRatio                 the ratio to resize the display
+     * @param inSizeCompatModeAfterResize if the activity should be in size compat mode after
+     *                                    resizing the display
+     */
     private void runSizeCompatTest(ComponentName activity, double resizeRatio,
             boolean inSizeCompatModeAfterResize) {
         launchActivityOnDisplay(activity, DEFAULT_DISPLAY);
@@ -161,14 +231,49 @@
         WindowManagerState.Activity activityContainer = mWmState.getActivity(activity);
         assertNotNull(activityContainer);
         if (expectedInSizeCompatMode) {
-            assertTrue("The Window should be in size compat mode",
+            assertTrue("The Window must be in size compat mode",
                     activityContainer.inSizeCompatMode());
         } else {
-            assertFalse("The Window should not be in size compat mode",
+            assertFalse("The Window must not be in size compat mode",
                     activityContainer.inSizeCompatMode());
         }
     }
 
+    /**
+     * Similar to {@link #runSizeCompatTest(ComponentName, boolean)}, but the activity is expected
+     * to be in size compat mode after resizing the display.
+     *
+     * @param activity    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 runSandboxTest(ComponentName activity, boolean isSandboxed) {
+        runSizeCompatTest(activity, /* resizeRatio= */ 0.5, /* inSizeCompatModeAfterResize=*/ true);
+        assertSandboxed(activity, isSandboxed);
+        mDisplayMetricsSession.restoreDisplayMetrics();
+        runSizeCompatTest(activity, /* resizeRatio= */ 2, /* inSizeCompatModeAfterResize=*/ true);
+        assertSandboxed(activity, isSandboxed);
+    }
+
+    private void assertSandboxed(ComponentName activity, boolean expectedSandboxed) {
+        mWmState.computeState(new WaitForValidActivityState(activity));
+        final WindowManagerState.ActivityTask activityTask = mWmState.getTaskByActivity(activity);
+        assertNotNull(activityTask);
+        final Rect activityBounds = activityTask.getBounds();
+        final Rect maxBounds = activityTask.mFullConfiguration.windowConfiguration.getMaxBounds();
+        WindowManagerState.DisplayArea tda = mWmState.getTaskDisplayArea(activity);
+        if (expectedSandboxed) {
+            assertEquals(
+                    "The Window has max bounds sandboxed to the window bounds",
+                    activityBounds, maxBounds);
+        } else if (tda != null) {
+            assertEquals(
+                    "The Window is not sandboxed, with max bounds reflecting the DisplayArea",
+                    tda.mFullConfiguration.windowConfiguration.getBounds(), maxBounds);
+        }
+    }
+
     private void resizeDisplay(ComponentName activity, double sizeRatio) {
         mDisplayMetricsSession.changeDisplayMetrics(sizeRatio, /* densityRatio= */ 1);
         mWmState.computeState(new WaitForValidActivityState(activity));
@@ -178,7 +283,7 @@
         return new ComponentName(getInstrumentation().getContext(), activity);
     }
 
-    public static class ResizeablePortraitActivity extends AbstractLifecycleLogActivity {
+    public static class ResizeablePortraitActivity extends FocusableActivity {
     }
 
     public static class NonResizeablePortraitActivity extends AbstractLifecycleLogActivity {
diff --git a/tests/signature/api-check/system-annotation/src/java/android/signature/cts/api/AnnotationTest.java b/tests/signature/api-check/system-annotation/src/java/android/signature/cts/api/AnnotationTest.java
index 7adc3e3..a3c46d5 100644
--- a/tests/signature/api-check/system-annotation/src/java/android/signature/cts/api/AnnotationTest.java
+++ b/tests/signature/api-check/system-annotation/src/java/android/signature/cts/api/AnnotationTest.java
@@ -27,6 +27,7 @@
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
+import java.util.function.Predicate;
 
 /**
  * Checks that parts of the device's API that are annotated (e.g. with android.annotation.SystemApi)
@@ -45,6 +46,15 @@
         mAnnotationForExactMatch = instrumentationArgs.getString("annotation-for-exact-match");
     }
 
+    private Predicate<? super JDiffClassDescription> androidAutoClassesFilter() {
+        if (getInstrumentation().getContext().getPackageManager().hasSystemFeature(
+                "android.hardware.type.automotive")) {
+            return clz -> true;
+        } else {
+            return clz -> !clz.getAbsoluteClassName().startsWith("android.car.");
+        }
+    }
+
     /**
      * Tests that the parts of the device's API that are annotated (e.g. with
      * android.annotation.SystemApi) match the API definition.
@@ -81,6 +91,7 @@
             ApiDocumentParser apiDocumentParser = new ApiDocumentParser(TAG);
 
             parseApiResourcesAsStream(apiDocumentParser, mExpectedApiFiles)
+                    .filter(androidAutoClassesFilter())
                     .forEach(complianceChecker::checkSignatureCompliance);
 
             // After done parsing all expected API files, perform any deferred checks.
diff --git a/tests/signature/lib/common/src/android/signature/cts/AnnotationChecker.java b/tests/signature/lib/common/src/android/signature/cts/AnnotationChecker.java
index 3f14dad..1567f16 100644
--- a/tests/signature/lib/common/src/android/signature/cts/AnnotationChecker.java
+++ b/tests/signature/lib/common/src/android/signature/cts/AnnotationChecker.java
@@ -27,7 +27,7 @@
 /**
  * Checks that the runtime representation of a class matches the API representation of a class.
  */
-public class AnnotationChecker extends AbstractApiChecker {
+public class AnnotationChecker extends ApiPresenceChecker {
 
     private final String annotationSpec;
 
@@ -39,7 +39,7 @@
     private final Map<String, Set<Field>> annotatedFieldsMap = new HashMap<>();
 
     /**
-     * @param annotationName name of the annotation class for the API type (e.g.
+     * @param annotationSpec name of the annotation class for the API type (e.g.
      *      android.annotation.SystemApi)
      */
     public AnnotationChecker(
@@ -82,7 +82,6 @@
         public boolean skip(Field f);
     }
 
-    @Override
     public void checkDeferred() {
         for (Class<?> clazz : annotatedClassesMap.values()) {
             if (filter != null && filter.skip(clazz)) continue;
@@ -117,17 +116,6 @@
     }
 
     @Override
-    protected boolean allowMissingClass(JDiffClassDescription classDescription) {
-        // A class that exist in the API document is not found in the runtime.
-        // This can happen for classes that are optional (e.g. classes for
-        // Android Auto). This, however, should not be considered as a test
-        // failure, because the purpose of this test is to ensure that every
-        // runtime classes found in the device have more annotations than
-        // the documented.
-        return true;
-    }
-
-    @Override
     protected boolean checkClass(JDiffClassDescription classDescription, Class<?> runtimeClass) {
         // remove the class from the set if found
         annotatedClassesMap.remove(runtimeClass.getName());
diff --git a/tests/signature/lib/common/src/android/signature/cts/ApiComplianceChecker.java b/tests/signature/lib/common/src/android/signature/cts/ApiComplianceChecker.java
index f1c812e..fe67157 100644
--- a/tests/signature/lib/common/src/android/signature/cts/ApiComplianceChecker.java
+++ b/tests/signature/lib/common/src/android/signature/cts/ApiComplianceChecker.java
@@ -29,7 +29,7 @@
 /**
  * Checks that the runtime representation of a class matches the API representation of a class.
  */
-public class ApiComplianceChecker extends AbstractApiChecker {
+public class ApiComplianceChecker extends ApiPresenceChecker {
 
     /**
      * A set of method signatures whose abstract modifier should be ignored.
@@ -73,7 +73,6 @@
         interfaceChecker = new InterfaceChecker(resultObserver, classProvider);
     }
 
-    @Override
     public void checkDeferred() {
         interfaceChecker.checkQueued();
     }
diff --git a/tests/signature/lib/common/src/android/signature/cts/AbstractApiChecker.java b/tests/signature/lib/common/src/android/signature/cts/ApiPresenceChecker.java
similarity index 86%
rename from tests/signature/lib/common/src/android/signature/cts/AbstractApiChecker.java
rename to tests/signature/lib/common/src/android/signature/cts/ApiPresenceChecker.java
index 03c4a85..fc4335c 100644
--- a/tests/signature/lib/common/src/android/signature/cts/AbstractApiChecker.java
+++ b/tests/signature/lib/common/src/android/signature/cts/ApiPresenceChecker.java
@@ -27,13 +27,13 @@
  * Base class for those that process a set of API definition files and perform some checking on
  * them.
  */
-public abstract class AbstractApiChecker {
+public class ApiPresenceChecker {
 
     final ResultObserver resultObserver;
 
     final ClassProvider classProvider;
 
-    AbstractApiChecker(ClassProvider classProvider, ResultObserver resultObserver) {
+    public ApiPresenceChecker(ClassProvider classProvider, ResultObserver resultObserver) {
         this.classProvider = classProvider;
         this.resultObserver = resultObserver;
     }
@@ -63,14 +63,10 @@
                     .findRequiredClass(classDescription, classProvider);
 
             if (runtimeClass == null) {
-                // No class found, notify the observer according to the class type,
-                // if missing a class isn't acceptable.
-                if (!allowMissingClass(classDescription)) {
-                    resultObserver.notifyFailure(FailureType.missing(classDescription),
-                            classDescription.getAbsoluteClassName(),
-                            "Classloader is unable to find " + classDescription
-                                    .getAbsoluteClassName());
-                }
+                resultObserver.notifyFailure(FailureType.missing(classDescription),
+                        classDescription.getAbsoluteClassName(),
+                        "Classloader is unable to find " + classDescription
+                                .getAbsoluteClassName());
                 return null;
             }
 
@@ -90,11 +86,6 @@
     }
 
     /**
-     * Perform any additional checks that can only be done after all api files have been processed.
-     */
-    public abstract void checkDeferred();
-
-    /**
      * Implement to provide custom check of the supplied class description.
      *
      * <p>This should not peform checks on the members, those will be done separately depending
@@ -104,21 +95,12 @@
      * @param runtimeClass the runtime class corresponding to the class description.
      * @return true if the checks passed and the members should now be checked.
      */
-    protected abstract boolean checkClass(JDiffClassDescription classDescription,
-            Class<?> runtimeClass);
-
-
-    /**
-     * Checks that a class that exists in the API xml file but that does not exist
-     * in the runtime is allowed or not.
-     *
-     * @param classDescription the class description that is missing.
-     * @return true if missing the class is acceptable.
-     */
-    protected boolean allowMissingClass(JDiffClassDescription classDescription) {
-        return false;
+    protected boolean checkClass(JDiffClassDescription classDescription,
+            Class<?> runtimeClass) {
+        return true;
     }
 
+
     /**
      * Checks all fields in test class for compliance with the API xml.
      *
@@ -175,9 +157,10 @@
         return fieldMap;
     }
 
-    protected abstract void checkField(JDiffClassDescription classDescription,
+    protected void checkField(JDiffClassDescription classDescription,
             Class<?> runtimeClass,
-            JDiffClassDescription.JDiffField fieldDescription, Field field);
+            JDiffClassDescription.JDiffField fieldDescription, Field field) {
+    }
 
 
     /**
@@ -217,9 +200,10 @@
         }
     }
 
-    protected abstract void checkConstructor(JDiffClassDescription classDescription,
+    protected void checkConstructor(JDiffClassDescription classDescription,
             Class<?> runtimeClass,
-            JDiffClassDescription.JDiffConstructor ctorDescription, Constructor<?> ctor);
+            JDiffClassDescription.JDiffConstructor ctorDescription, Constructor<?> ctor) {
+    }
 
     /**
      * Checks that the method found through reflection matches the
@@ -260,7 +244,8 @@
         }
     }
 
-    protected abstract void checkMethod(JDiffClassDescription classDescription,
+    protected void checkMethod(JDiffClassDescription classDescription,
             Class<?> runtimeClass,
-            JDiffClassDescription.JDiffMethod methodDescription, Method method);
+            JDiffClassDescription.JDiffMethod methodDescription, Method method) {
+    }
 }
diff --git a/tests/signature/tests/src/android/signature/cts/tests/AnnotationCheckerTest.java b/tests/signature/tests/src/android/signature/cts/tests/AnnotationCheckerTest.java
index a981be7..3e18522 100644
--- a/tests/signature/tests/src/android/signature/cts/tests/AnnotationCheckerTest.java
+++ b/tests/signature/tests/src/android/signature/cts/tests/AnnotationCheckerTest.java
@@ -21,8 +21,9 @@
 import android.signature.cts.FailureType;
 import android.signature.cts.JDiffClassDescription;
 import android.signature.cts.ResultObserver;
-import android.signature.cts.tests.data.ApiAnnotation;
+
 import java.lang.reflect.Modifier;
+import java.util.function.Consumer;
 
 import org.junit.Test;
 import org.junit.runners.JUnit4;
@@ -32,7 +33,7 @@
  * Test class for {@link android.signature.cts.AnnotationChecker}.
  */
 @RunWith(JUnit4.class)
-public class AnnotationCheckerTest extends AbstractApiCheckerTest<AnnotationChecker> {
+public class AnnotationCheckerTest extends ApiPresenceCheckerTest<AnnotationChecker> {
 
     @Override
     protected AnnotationChecker createChecker(ResultObserver resultObserver,
@@ -41,6 +42,18 @@
                 "@android.signature.cts.tests.data.ApiAnnotation()", null);
     }
 
+    @Override
+    void runWithApiChecker(ResultObserver resultObserver, Consumer<AnnotationChecker> consumer,
+            String... excludedRuntimeClasses) {
+        super.runWithApiChecker(
+                resultObserver,
+                checker -> {
+                    consumer.accept(checker);
+                    checker.checkDeferred();
+                },
+                excludedRuntimeClasses);
+    }
+
     private static void addConstructor(JDiffClassDescription clz, String... paramTypes) {
         JDiffClassDescription.JDiffConstructor constructor = new JDiffClassDescription.JDiffConstructor(
                 clz.getShortClassName(), Modifier.PUBLIC);
diff --git a/tests/signature/tests/src/android/signature/cts/tests/ApiComplianceCheckerTest.java b/tests/signature/tests/src/android/signature/cts/tests/ApiComplianceCheckerTest.java
index 405f5b2..c4c87f5 100644
--- a/tests/signature/tests/src/android/signature/cts/tests/ApiComplianceCheckerTest.java
+++ b/tests/signature/tests/src/android/signature/cts/tests/ApiComplianceCheckerTest.java
@@ -18,6 +18,7 @@
 
 import static org.junit.Assert.assertEquals;
 
+import android.signature.cts.AnnotationChecker;
 import android.signature.cts.ApiComplianceChecker;
 import android.signature.cts.ClassProvider;
 import android.signature.cts.FailureType;
@@ -28,8 +29,8 @@
 import android.signature.cts.tests.data.NormalClass;
 import android.signature.cts.tests.data.NormalInterface;
 import java.lang.reflect.Modifier;
+import java.util.function.Consumer;
 
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runners.JUnit4;
 import org.junit.runner.RunWith;
@@ -38,7 +39,7 @@
  * Test class for JDiffClassDescription.
  */
 @RunWith(JUnit4.class)
-public class ApiComplianceCheckerTest extends AbstractApiCheckerTest<ApiComplianceChecker> {
+public class ApiComplianceCheckerTest extends ApiPresenceCheckerTest<ApiComplianceChecker> {
 
     @Override
     protected ApiComplianceChecker createChecker(ResultObserver resultObserver,
@@ -46,6 +47,18 @@
         return new ApiComplianceChecker(resultObserver, provider);
     }
 
+    @Override
+    void runWithApiChecker(
+            ResultObserver resultObserver, Consumer<ApiComplianceChecker> consumer, String... excludedRuntimeClasses) {
+        super.runWithApiChecker(
+                resultObserver,
+                checker -> {
+                    consumer.accept(checker);
+                    checker.checkDeferred();
+                },
+                excludedRuntimeClasses);
+    }
+
     @Test
     public void testNormalClassCompliance() {
         JDiffClassDescription clz = createClass(NormalClass.class.getSimpleName());
diff --git a/tests/signature/tests/src/android/signature/cts/tests/AbstractApiCheckerTest.java b/tests/signature/tests/src/android/signature/cts/tests/ApiPresenceCheckerTest.java
similarity index 95%
rename from tests/signature/tests/src/android/signature/cts/tests/AbstractApiCheckerTest.java
rename to tests/signature/tests/src/android/signature/cts/tests/ApiPresenceCheckerTest.java
index 901b424..719be91 100644
--- a/tests/signature/tests/src/android/signature/cts/tests/AbstractApiCheckerTest.java
+++ b/tests/signature/tests/src/android/signature/cts/tests/ApiPresenceCheckerTest.java
@@ -15,7 +15,7 @@
  */
 package android.signature.cts.tests;
 
-import android.signature.cts.AbstractApiChecker;
+import android.signature.cts.ApiPresenceChecker;
 import android.signature.cts.ClassProvider;
 import android.signature.cts.ExcludingClassProvider;
 import android.signature.cts.FailureType;
@@ -28,9 +28,9 @@
 import org.junit.Assert;
 
 /**
- * Base class for tests of implementations of {@link AbstractApiChecker}.
+ * Base class for tests of implementations of {@link ApiPresenceChecker}.
  */
-public abstract class AbstractApiCheckerTest<T extends AbstractApiChecker> {
+public abstract class ApiPresenceCheckerTest<T extends ApiPresenceChecker> {
 
     static final String VALUE = "VALUE";
 
@@ -79,7 +79,6 @@
         ClassProvider provider = createClassProvider(excludedRuntimeClasses);
         T checker = createChecker(resultObserver, provider);
         consumer.accept(checker);
-        checker.checkDeferred();
     }
 
     protected abstract T createChecker(ResultObserver resultObserver, ClassProvider provider);
diff --git a/tests/smartspace/src/android/smartspace/cts/SmartspaceManagerTest.java b/tests/smartspace/src/android/smartspace/cts/SmartspaceManagerTest.java
index 936a835..8177a99 100644
--- a/tests/smartspace/src/android/smartspace/cts/SmartspaceManagerTest.java
+++ b/tests/smartspace/src/android/smartspace/cts/SmartspaceManagerTest.java
@@ -101,7 +101,7 @@
     @After
     public void tearDown() throws Exception {
         Log.d(TAG, "Starting tear down, watcher is: " + mWatcher);
-        mClient.destroy();
+        mClient.close();
         setService(null);
         await(mWatcher.destroyed, "Waiting for onDestroy()");
 
@@ -118,7 +118,7 @@
     @Test
     public void testDestroySession() {
         SmartspaceSession localClient = createSmartspaceSession(createSmartspaceConfig("surface"));
-        localClient.destroy();
+        localClient.close();
         await(mWatcher.destroyed, "Waiting for onDestroy()");
     }
 
@@ -131,7 +131,7 @@
                 SmartspaceTargetEvent.EVENT_TARGET_INTERACTION).setSmartspaceTarget(
                 testTarget).setSmartspaceActionId("id").build();
         mClient.notifySmartspaceEvent(testEvent);
-        mClient.registerSmartspaceUpdates(Executors.newSingleThreadExecutor(),
+        mClient.addOnTargetsAvailableListener(Executors.newSingleThreadExecutor(),
                 targets -> {
                     if (targets.size() > 0 && targets.get(0).equals(testTarget)) {
                         mWatcher.queried.countDown();
@@ -156,14 +156,14 @@
         SmartspaceSession client1 = createSmartspaceSession(config1);
         SmartspaceConfig config2 = createSmartspaceConfig("surface 2");
         SmartspaceSession client2 = createSmartspaceSession(config2);
-        client1.registerSmartspaceUpdates(Executors.newSingleThreadExecutor(),
+        client1.addOnTargetsAvailableListener(Executors.newSingleThreadExecutor(),
                 targets -> {
                     // Counting down only if the returned list only contains test target.
                     if (targets.size() > 0 && targets.get(0).equals(testTarget)) {
                         mWatcher.queriedTwice.countDown();
                     }
                 });
-        client2.registerSmartspaceUpdates(Executors.newSingleThreadExecutor(),
+        client2.addOnTargetsAvailableListener(Executors.newSingleThreadExecutor(),
                 targets -> {
                     // Counting down only if the returned list is empty.
                     if (targets.isEmpty()) {
@@ -267,7 +267,7 @@
         }
     }
 
-    private static class RequestVerifier implements SmartspaceSession.Callback {
+    private static class RequestVerifier implements SmartspaceSession.OnTargetsAvailableListener {
         @Override
         public void onTargetsAvailable(List<SmartspaceTarget> targets) {
 
diff --git a/tests/tests/media/src/android/media/cts/MediaSessionTest.java b/tests/tests/media/src/android/media/cts/MediaSessionTest.java
index 8a51982..016c9ba 100644
--- a/tests/tests/media/src/android/media/cts/MediaSessionTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaSessionTest.java
@@ -23,7 +23,7 @@
 import static android.media.cts.MediaSessionTestService.STEP_CLEAN_UP;
 import static android.media.cts.MediaSessionTestService.STEP_SET_UP;
 import static android.media.cts.MediaSessionTestService.TEST_SERIES_OF_SET_QUEUE;
-import static android.media.cts.MediaSessionTestService.TEST_SET_QUEUE_WITH_LARGE_NUMBER_OF_ITEMS;
+import static android.media.cts.MediaSessionTestService.TEST_SET_QUEUE;
 import static android.media.cts.Utils.compareRemoteUserInfo;
 
 import android.app.PendingIntent;
@@ -54,6 +54,7 @@
 import android.view.KeyEvent;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
@@ -941,7 +942,7 @@
         }
 
         try (RemoteService.Invoker invoker = new RemoteService.Invoker(mContext,
-                MediaSessionTestService.class, TEST_SET_QUEUE_WITH_LARGE_NUMBER_OF_ITEMS)) {
+                MediaSessionTestService.class, TEST_SET_QUEUE)) {
             Bundle args = new Bundle();
             args.putParcelable(KEY_SESSION_TOKEN, mSession.getSessionToken());
             args.putInt(KEY_EXPECTED_QUEUE_SIZE, queueSize);
@@ -952,6 +953,19 @@
         }
     }
 
+    public void testSetQueueWithEmptyQueue() throws Exception {
+        try (RemoteService.Invoker invoker = new RemoteService.Invoker(mContext,
+                MediaSessionTestService.class, TEST_SET_QUEUE)) {
+            Bundle args = new Bundle();
+            args.putParcelable(KEY_SESSION_TOKEN, mSession.getSessionToken());
+            args.putInt(KEY_EXPECTED_QUEUE_SIZE, 0);
+            invoker.run(STEP_SET_UP, args);
+            mSession.setQueue(Collections.emptyList());
+            invoker.run(STEP_CHECK);
+            invoker.run(STEP_CLEAN_UP);
+        }
+    }
+
     /**
      * Verifies that a new session hasn't had any configuration bits set yet.
      *
diff --git a/tests/tests/media/src/android/media/cts/MediaSessionTestService.java b/tests/tests/media/src/android/media/cts/MediaSessionTestService.java
index 1b82872..08476ba 100644
--- a/tests/tests/media/src/android/media/cts/MediaSessionTestService.java
+++ b/tests/tests/media/src/android/media/cts/MediaSessionTestService.java
@@ -33,7 +33,7 @@
 
 public class MediaSessionTestService extends RemoteService {
     public static final int TEST_SERIES_OF_SET_QUEUE = 0;
-    public static final int TEST_SET_QUEUE_WITH_LARGE_NUMBER_OF_ITEMS = 1;
+    public static final int TEST_SET_QUEUE = 1;
 
     public static final int STEP_SET_UP = 0;
     public static final int STEP_CHECK = 1;
@@ -80,7 +80,7 @@
         mAllItemsNotified = null;
     }
 
-    private void testSetQueueWithLargeNumberOfItems_setUp(Bundle args) {
+    private void testSetQueue_setUp(Bundle args) {
         MediaSession.Token token = args.getParcelable(KEY_SESSION_TOKEN);
         int expectedQueueSize = args.getInt(KEY_EXPECTED_QUEUE_SIZE);
 
@@ -98,11 +98,11 @@
                 new Handler(Looper.getMainLooper()));
     }
 
-    private void testSetQueueWithLargeNumberOfItems_check() throws Exception {
+    private void testSetQueue_check() throws Exception {
         assertTrue(mQueueNotified.await(TIMEOUT_MS, MILLISECONDS));
     }
 
-    private void testSetQueueWithLargeNumberOfItems_cleanUp() {
+    private void testSetQueue_cleanUp() {
         mMediaController.unregisterCallback(mMediaControllerCallback);
         mMediaController = null;
         mMediaControllerCallback = null;
@@ -121,13 +121,13 @@
             } else {
                 throw new IllegalArgumentException("Unknown step=" + step);
             }
-        } else if (testId == TEST_SET_QUEUE_WITH_LARGE_NUMBER_OF_ITEMS) {
+        } else if (testId == TEST_SET_QUEUE) {
             if (step == STEP_SET_UP) {
-                testSetQueueWithLargeNumberOfItems_setUp(args);
+                testSetQueue_setUp(args);
             } else if (step == STEP_CHECK) {
-                testSetQueueWithLargeNumberOfItems_check();
+                testSetQueue_check();
             } else if (step == STEP_CLEAN_UP) {
-                testSetQueueWithLargeNumberOfItems_cleanUp();
+                testSetQueue_cleanUp();
             } else {
                 throw new IllegalArgumentException("Unknown step=" + step);
             }
diff --git a/tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt b/tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt
index 0d4558ec0..3f71f46 100644
--- a/tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt
+++ b/tests/tests/permission4/src/android/permission4/cts/CameraMicIndicatorsPermissionTest.kt
@@ -179,12 +179,12 @@
         }
         eventually {
             if (useMic) {
-                val appView = uiDevice.findObject(UiSelector().textContains(micLabel))
-                assertTrue("View with text $APP_LABEL not found", appView.exists())
+                val iconView = uiDevice.findObject(UiSelector().descriptionContains(micLabel))
+                assertTrue("View with description $micLabel not found", iconView.exists())
             }
             if (useCamera) {
-                val appView = uiDevice.findObject(UiSelector().textContains(cameraLabel))
-                assertTrue("View with text $APP_LABEL not found", appView.exists())
+                val iconView = uiDevice.findObject(UiSelector().descriptionContains(cameraLabel))
+                assertTrue("View with text $APP_LABEL not found", iconView.exists())
             }
             val appView = uiDevice.findObject(UiSelector().textContains(APP_LABEL))
             assertTrue("View with text $APP_LABEL not found", appView.exists())
diff --git a/tests/tests/permission5/Android.bp b/tests/tests/permission5/Android.bp
index 242f4d1..d7cb067 100644
--- a/tests/tests/permission5/Android.bp
+++ b/tests/tests/permission5/Android.bp
@@ -28,6 +28,7 @@
         "compatibility-device-util-axt",
         "truth-prebuilt",
         "ctstestrunner-axt",
+        "platform-test-annotations",
     ],
     data: [
         ":CtsBlamedPermissionApp",
diff --git a/tests/tests/permission5/src/android/permission5/cts/RenouncedPermissionsTest.kt b/tests/tests/permission5/src/android/permission5/cts/RenouncedPermissionsTest.kt
index 30d795e..98f73af 100644
--- a/tests/tests/permission5/src/android/permission5/cts/RenouncedPermissionsTest.kt
+++ b/tests/tests/permission5/src/android/permission5/cts/RenouncedPermissionsTest.kt
@@ -24,6 +24,7 @@
 import android.content.pm.PackageManager
 import android.os.Process
 import android.permission.PermissionManager
+import android.platform.test.annotations.AppModeFull
 import android.provider.CalendarContract
 import android.provider.ContactsContract
 import android.util.ArraySet
@@ -41,6 +42,7 @@
 
     @Test
     @Throws(Exception::class)
+    @AppModeFull(reason="Instant apps cannot hold READ_CALENDAR/READ_CONTACTS permissions")
     fun testRenouncePermissionsChain() {
         val receiverAttributionSource = getShellAttributionSourceWithRenouncedPermissions()
         val activity = createActivityWithAttributionContext(receiverAttributionSource)
diff --git a/tests/tests/permission5/src/android/permission5/cts/RuntimePermissionsAppOpTrackingTest.kt b/tests/tests/permission5/src/android/permission5/cts/RuntimePermissionsAppOpTrackingTest.kt
index b5cfdcb..a0cd93e 100644
--- a/tests/tests/permission5/src/android/permission5/cts/RuntimePermissionsAppOpTrackingTest.kt
+++ b/tests/tests/permission5/src/android/permission5/cts/RuntimePermissionsAppOpTrackingTest.kt
@@ -29,6 +29,7 @@
 import android.os.Process
 import android.os.RemoteCallback
 import android.os.SystemClock
+import android.platform.test.annotations.AppModeFull
 import android.provider.CalendarContract
 import android.provider.CallLog
 import android.provider.ContactsContract
@@ -47,6 +48,7 @@
 import java.util.concurrent.locks.ReentrantLock
 import java.util.function.Consumer
 
+@AppModeFull(reason="Instant apps cannot hold READ_CONTACTS/READ_CALENDAR/READ_SMS/READ_CALL_LOG")
 class RuntimePermissionsAppOpTrackingTest {
 
     @Before
diff --git a/tests/tests/voiceinteraction/common/src/android/voiceinteraction/common/Utils.java b/tests/tests/voiceinteraction/common/src/android/voiceinteraction/common/Utils.java
index dd60884..4d8a54c 100644
--- a/tests/tests/voiceinteraction/common/src/android/voiceinteraction/common/Utils.java
+++ b/tests/tests/voiceinteraction/common/src/android/voiceinteraction/common/Utils.java
@@ -56,12 +56,15 @@
     public static final int VOICE_INTERACTION_SERVICE_NORMAL_TEST = 0;
     public static final int HOTWORD_DETECTION_SERVICE_TRIGGER_TEST = 1;
     public static final int HOTWORD_DETECTION_SERVICE_TRIGGER_WITHOUT_PERMISSION_TEST = 2;
+    public static final int HOTWORD_DETECTION_SERVICE_DSP_ONDETECT_TEST = 3;
 
     public static final int HOTWORD_DETECTION_SERVICE_TRIGGER_SUCCESS = 1;
     public static final int HOTWORD_DETECTION_SERVICE_TRIGGER_ILLEGAL_STATE_EXCEPTION = 2;
     public static final int HOTWORD_DETECTION_SERVICE_TRIGGER_SECURITY_EXCEPTION = 3;
     public static final int HOTWORD_DETECTION_SERVICE_TRIGGER_SHARED_MEMORY_NOT_READ_ONLY = 4;
 
+    public static final int HOTWORD_DETECTION_SERVICE_ONDETECT_SUCCESS = 1;
+
     public static final String TESTCASE_TYPE = "testcase_type";
     public static final String TESTINFO = "testinfo";
     public static final String BROADCAST_INTENT = "android.intent.action.VOICE_TESTAPP";
@@ -136,6 +139,8 @@
 
     public static final String BROADCAST_HOTWORD_DETECTION_SERVICE_TRIGGER_RESULT_INTENT =
             "android.intent.action.HOTWORD_DETECTION_SERVICE_TRIGGER_RESULT";
+    public static final String BROADCAST_HOTWORD_DETECTION_SERVICE_DSP_ONDETECT_RESULT_INTENT =
+            "android.intent.action.HOTWORD_DETECTION_SERVICE_DSP_ONDETECT_RESULT";
     public static final String KEY_SERVICE_TYPE = "serviceType";
     public static final String KEY_TEST_EVENT = "testEvent";
     public static final String KEY_TEST_RESULT = "testResult";
diff --git a/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/BasicVoiceInteractionService.java b/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/BasicVoiceInteractionService.java
index 2af7e13..5fb5e11 100644
--- a/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/BasicVoiceInteractionService.java
+++ b/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/BasicVoiceInteractionService.java
@@ -19,6 +19,7 @@
 import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
 
 import android.content.Intent;
+import android.media.AudioFormat;
 import android.os.PersistableBundle;
 import android.os.SharedMemory;
 import android.service.voice.AlwaysOnHotwordDetector;
@@ -30,6 +31,7 @@
 
 import java.nio.ByteBuffer;
 import java.util.Locale;
+import java.util.Objects;
 
 /**
  * This service included a basic HotwordDetectionService for testing.
@@ -43,6 +45,7 @@
     public static byte[] FAKE_BYTE_ARRAY_DATA = new byte[] {1, 2, 3};
 
     private boolean mReady = false;
+    private AlwaysOnHotwordDetector mAlwaysOnHotwordDetector = null;
 
     @Override
     public void onReady() {
@@ -61,21 +64,32 @@
         }
 
         final int testEvent = intent.getIntExtra(Utils.KEY_TEST_EVENT, -1);
+        Log.i(TAG, "testEvent = " + testEvent);
         if (testEvent == Utils.HOTWORD_DETECTION_SERVICE_TRIGGER_TEST) {
             runWithShellPermissionIdentity(() -> {
-                callCreateAlwaysOnHotwordDetector();
+                mAlwaysOnHotwordDetector = callCreateAlwaysOnHotwordDetector();
             });
         } else if (testEvent == Utils.HOTWORD_DETECTION_SERVICE_TRIGGER_WITHOUT_PERMISSION_TEST) {
             callCreateAlwaysOnHotwordDetector();
+        } else if (testEvent == Utils.HOTWORD_DETECTION_SERVICE_DSP_ONDETECT_TEST) {
+            runWithShellPermissionIdentity(() -> {
+                if (mAlwaysOnHotwordDetector != null) {
+                    mAlwaysOnHotwordDetector.triggerHardwareRecognitionEventForTest(/* status */ 0,
+                            /* soundModelHandle */ 100, /* captureAvailable */ true,
+                            /* captureSession */ 101, /* captureDelayMs */ 1000,
+                            /* capturePreambleMs */ 1001, /* triggerInData */ true,
+                            createFakeAudioFormat(), new byte[1024]);
+                }
+            });
         }
 
         return START_NOT_STICKY;
     }
 
-    private void callCreateAlwaysOnHotwordDetector() {
+    private AlwaysOnHotwordDetector callCreateAlwaysOnHotwordDetector() {
         Log.i(TAG, "callCreateAlwaysOnHotwordDetector()");
         try {
-            createAlwaysOnHotwordDetector(/* keyphrase */ "Hello Google",
+            return createAlwaysOnHotwordDetector(/* keyphrase */ "Hello Google",
                     Locale.forLanguageTag("en-US"),
                     createFakePersistableBundleData(),
                     createFakeSharedMemoryData(),
@@ -88,6 +102,7 @@
                         @Override
                         public void onDetected(AlwaysOnHotwordDetector.EventPayload eventPayload) {
                             Log.i(TAG, "onDetected");
+                            broadcastOnDetectedEvent();
                         }
 
                         @Override
@@ -121,6 +136,7 @@
                     Utils.BROADCAST_HOTWORD_DETECTION_SERVICE_TRIGGER_RESULT_INTENT,
                     Utils.HOTWORD_DETECTION_SERVICE_TRIGGER_SECURITY_EXCEPTION);
         }
+        return null;
     }
 
     private void broadcastIntentWithResult(String intentName, int result) {
@@ -150,6 +166,13 @@
         return persistableBundle;
     }
 
+    private AudioFormat createFakeAudioFormat() {
+        return new AudioFormat.Builder()
+                .setSampleRate(32000)
+                .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
+                .setChannelMask(AudioFormat.CHANNEL_IN_MONO).build();
+    }
+
     private void verifyHotwordDetectionServiceInitializedStatus(int status) {
         if (status == HotwordDetectionService.INITIALIZATION_STATUS_SUCCESS) {
             broadcastIntentWithResult(
@@ -157,4 +180,10 @@
                     Utils.HOTWORD_DETECTION_SERVICE_TRIGGER_SUCCESS);
         }
     }
+
+    private void broadcastOnDetectedEvent() {
+        broadcastIntentWithResult(
+                Utils.BROADCAST_HOTWORD_DETECTION_SERVICE_DSP_ONDETECT_RESULT_INTENT,
+                Utils.HOTWORD_DETECTION_SERVICE_ONDETECT_SUCCESS);
+    }
 }
diff --git a/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainHotwordDetectionService.java b/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainHotwordDetectionService.java
index e37ec08..8f2535f 100644
--- a/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainHotwordDetectionService.java
+++ b/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainHotwordDetectionService.java
@@ -28,6 +28,8 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.function.IntConsumer;
 
 public class MainHotwordDetectionService extends HotwordDetectionService {
@@ -44,7 +46,39 @@
             Log.w(TAG, "callback is null");
             return;
         }
-        callback.onDetected(null);
+        if (audioStream == null) {
+            Log.w(TAG, "audioStream is null");
+            return;
+        }
+
+        long startTime = System.currentTimeMillis();
+        try (InputStream fis =
+                     new ParcelFileDescriptor.AutoCloseInputStream(audioStream)) {
+
+            // We added the fake audio data and set "hotword!" string at the head. Then we simulated
+            // to verify the audio data with "hotword!" in HotwordDetectionService. If the audio
+            // data includes "hotword!", it means that the hotword is valid.
+            while (fis.available() < 8) {
+                try {
+                    Thread.sleep(10);
+                } catch (InterruptedException e) {
+                    // Nothing
+                }
+                if (System.currentTimeMillis() - startTime > timeoutMillis) {
+                    Log.w(TAG, "Over timeout");
+                    return;
+                }
+            }
+            Log.d(TAG, "fis.available() = " + fis.available());
+            byte[] buffer = new byte[8];
+            fis.read(buffer, 0, 8);
+            if(isSame(buffer, new byte[] {'h', 'o', 't', 'w', 'o', 'r', 'd', '!'}, buffer.length)) {
+                Log.d(TAG, "call callback.onDetected");
+                callback.onDetected(null);
+            }
+        } catch (IOException e) {
+            Log.w(TAG, "Failed to read data : ", e);
+        }
     }
 
     @Override
@@ -81,4 +115,19 @@
             statusCallback.accept(INITIALIZATION_STATUS_SUCCESS);
         }
     }
+
+    private boolean isSame(byte[] array1, byte[] array2, int length) {
+        if (length <= 0) {
+            return false;
+        }
+        if (array1 == null || array2 == null || array1.length < length || array2.length < length) {
+            return false;
+        }
+        for (int i = 0; i < length; i++) {
+            if (array1[i] != array2[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
 }
diff --git a/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/HotwordDetectionServiceBasicTest.java b/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/HotwordDetectionServiceBasicTest.java
index 6fe406e..700f891 100644
--- a/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/HotwordDetectionServiceBasicTest.java
+++ b/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/HotwordDetectionServiceBasicTest.java
@@ -80,6 +80,42 @@
         receiver.unregisterQuietly();
     }
 
+    @Test
+    public void testHotwordDetectionService_onDetectFromDsp_success()
+            throws Throwable {
+        // Create AlwaysOnHotwordDetector and wait the HotwordDetectionService ready
+        final BlockingBroadcastReceiver receiver = new BlockingBroadcastReceiver(mContext,
+                Utils.BROADCAST_HOTWORD_DETECTION_SERVICE_TRIGGER_RESULT_INTENT);
+        receiver.register();
+
+        mActivityTestRule.getScenario().onActivity(activity -> {
+            activity.triggerHotwordDetectionServiceTest(
+                    Utils.HOTWORD_DETECTION_SERVICE_BASIC,
+                    Utils.HOTWORD_DETECTION_SERVICE_TRIGGER_TEST);
+        });
+
+        receiver.awaitForBroadcast(TIMEOUT_MS);
+        receiver.unregisterQuietly();
+
+        // Use AlwaysOnHotwordDetector to test the onDetect function of HotwordDetectionService
+        final BlockingBroadcastReceiver onDetectReceiver = new BlockingBroadcastReceiver(mContext,
+                Utils.BROADCAST_HOTWORD_DETECTION_SERVICE_DSP_ONDETECT_RESULT_INTENT);
+        onDetectReceiver.register();
+
+        mActivityTestRule.getScenario().onActivity(activity -> {
+            activity.triggerHotwordDetectionServiceTest(
+                    Utils.HOTWORD_DETECTION_SERVICE_BASIC,
+                    Utils.HOTWORD_DETECTION_SERVICE_DSP_ONDETECT_TEST);
+        });
+
+        final Intent intent = onDetectReceiver.awaitForBroadcast(TIMEOUT_MS);
+        assertThat(intent).isNotNull();
+        assertThat(intent.getIntExtra(Utils.KEY_TEST_RESULT, -1)).isEqualTo(
+                Utils.HOTWORD_DETECTION_SERVICE_ONDETECT_SUCCESS);
+
+        onDetectReceiver.unregisterQuietly();
+    }
+
     @Override
     public String getVoiceInteractionService() {
         return "android.voiceinteraction.cts/"
diff --git a/tests/tests/widget/src/android/widget/cts/RemoteViewsFixedCollectionAdapterTest.java b/tests/tests/widget/src/android/widget/cts/RemoteViewsFixedCollectionAdapterTest.java
index e700530..50bff42 100644
--- a/tests/tests/widget/src/android/widget/cts/RemoteViewsFixedCollectionAdapterTest.java
+++ b/tests/tests/widget/src/android/widget/cts/RemoteViewsFixedCollectionAdapterTest.java
@@ -30,6 +30,7 @@
 import android.app.Activity;
 import android.app.Instrumentation;
 import android.app.PendingIntent;
+import android.appwidget.AppWidgetHostView;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -38,6 +39,7 @@
 import android.util.TypedValue;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
 import android.widget.Adapter;
 import android.widget.AdapterViewFlipper;
 import android.widget.CompoundButton;
@@ -89,9 +91,12 @@
         mActivity = mActivityRule.getActivity();
         mRemoteViews = new RemoteViews(PACKAGE_NAME, R.layout.remoteviews_adapters);
 
-        ViewGroup parent = (ViewGroup) mActivity.findViewById(R.id.remoteView_host);
-        mView = mRemoteViews.apply(mActivity, parent);
-        parent.addView(mView);
+        ViewGroup parent = mActivity.findViewById(R.id.remoteView_host);
+        AppWidgetHostView hostView = new AppWidgetHostView(mActivity);
+        parent.addView(hostView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
+
+        mView = mRemoteViews.apply(mActivity, hostView);
+        hostView.addView(mView);
 
         mListView = mView.findViewById(R.id.remoteView_list);
         mGridView = mView.findViewById(R.id.remoteView_grid);
diff --git a/tests/tests/widget/src/android/widget/cts/RemoteViewsTest.java b/tests/tests/widget/src/android/widget/cts/RemoteViewsTest.java
index 61a939b..689beaf 100644
--- a/tests/tests/widget/src/android/widget/cts/RemoteViewsTest.java
+++ b/tests/tests/widget/src/android/widget/cts/RemoteViewsTest.java
@@ -1171,6 +1171,23 @@
                     resolveDimenOffset(6.5f, COMPLEX_UNIT_DIP, displayMetrics));
         });
 
+        // Test that zeros resolve to 0
+        mRemoteViews.setViewLayoutMarginAttr(R.id.remoteView_text, MARGIN_LEFT, 0);
+        mRemoteViews.setViewLayoutMarginAttr(R.id.remoteView_text, MARGIN_TOP, 0);
+        mRemoteViews.setViewLayoutMarginAttr(R.id.remoteView_text, MARGIN_RIGHT, 0);
+        applyNightModeThenApplyAndTest(false, () -> {
+            View textView = mResult.findViewById(R.id.remoteView_text);
+            DisplayMetrics displayMetrics = textView.getResources().getDisplayMetrics();
+            assertMargins(textView, 0, 0, 0,
+                    resolveDimenOffset(4.5f, COMPLEX_UNIT_DIP, displayMetrics));
+        });
+        applyNightModeThenApplyAndTest(true, () -> {
+            View textView = mResult.findViewById(R.id.remoteView_text);
+            DisplayMetrics displayMetrics = textView.getResources().getDisplayMetrics();
+            assertMargins(textView, 0, 0, 0,
+                    resolveDimenOffset(6.5f, COMPLEX_UNIT_DIP, displayMetrics));
+        });
+
         mRemoteViews.setViewLayoutMarginAttr(
                 R.id.remoteView_text, MARGIN_LEFT, R.attr.themeColor);
         assertThrowsOnReapply(ActionException.class);
@@ -1244,6 +1261,10 @@
         assertEquals(
                 textView.getResources().getDimensionPixelSize(R.dimen.textview_fixed_width),
                 textView.getLayoutParams().width);
+
+        mRemoteViews.setViewLayoutWidthDimen(R.id.remoteView_text, 0);
+        mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
+        assertEquals(0, textView.getLayoutParams().width);
     }
 
     @Test
@@ -1256,6 +1277,10 @@
                         textView.getResources().getDisplayMetrics()),
                 textView.getLayoutParams().width);
 
+        mRemoteViews.setViewLayoutWidthAttr(R.id.remoteView_text, 0);
+        mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
+        assertEquals(0, textView.getLayoutParams().width);
+
         mRemoteViews.setViewLayoutWidthAttr(R.id.remoteView_text, R.attr.themeColor);
         assertThrowsOnReapply(ActionException.class);
     }
@@ -1289,6 +1314,10 @@
         assertEquals(
                 textView.getResources().getDimensionPixelSize(R.dimen.textview_fixed_height),
                 textView.getLayoutParams().height);
+
+        mRemoteViews.setViewLayoutHeightDimen(R.id.remoteView_text, 0);
+        mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
+        assertEquals(0, textView.getLayoutParams().height);
     }
 
     @Test
@@ -1301,6 +1330,10 @@
                         textView.getResources().getDisplayMetrics()),
                 textView.getLayoutParams().height);
 
+        mRemoteViews.setViewLayoutHeightAttr(R.id.remoteView_text, 0);
+        mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
+        assertEquals(0, textView.getLayoutParams().height);
+
         mRemoteViews.setViewLayoutHeightAttr(
                 R.id.remoteView_text, R.attr.themeColor);
         assertThrowsOnReapply(ActionException.class);
@@ -1316,6 +1349,11 @@
         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
         assertEquals(expectedValue, textView.getCompoundDrawablePadding());
 
+        // test that passing 0 for the dimen sets 0 on the method.
+        mRemoteViews.setIntDimen(R.id.remoteView_text, "setCompoundDrawablePadding", 0);
+        mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
+        assertEquals(0, textView.getCompoundDrawablePadding());
+
         mRemoteViews.setIntDimen(R.id.remoteView_text, "setCompoundDrawablePadding",
                 R.color.testcolor1);
         assertThrowsOnReapply(ActionException.class);
@@ -1367,6 +1405,18 @@
                     textView.getCompoundDrawablePadding());
         });
 
+        // test that 0 resolves to 0
+        mRemoteViews.setIntDimenAttr(R.id.remoteView_text, "setCompoundDrawablePadding", 0);
+        applyNightModeThenApplyAndTest(false, () -> {
+            TextView textView = (TextView) mResult.findViewById(R.id.remoteView_text);
+            assertEquals(0, textView.getCompoundDrawablePadding());
+        });
+
+        applyNightModeThenApplyAndTest(true, () -> {
+            TextView textView = (TextView) mResult.findViewById(R.id.remoteView_text);
+            assertEquals(0, textView.getCompoundDrawablePadding());
+        });
+
         mRemoteViews.setIntDimenAttr(R.id.remoteView_text, "setCompoundDrawablePadding",
                 R.attr.themeColor);
         assertThrowsOnReapply(ActionException.class);
@@ -1383,6 +1433,11 @@
         assertEquals(textView.getResources().getDimension(R.dimen.remoteviews_float_dimen),
                 textView.getTextScaleX(), 1e-4f);
 
+        // test that passing 0 for the dimen sets 0f on the method.
+        mRemoteViews.setFloatDimen(R.id.remoteView_text, "setTextScaleX", 0);
+        mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
+        assertEquals(0f, textView.getTextScaleX(), 1e-4f);
+
         mRemoteViews.setFloatDimen(R.id.remoteView_text, "setTextScaleX", R.color.testcolor1);
         assertThrowsOnReapply(ActionException.class);
     }
@@ -1431,6 +1486,18 @@
                     textView.getResources().getDisplayMetrics()), textView.getTextScaleX(), 1e-4f);
         });
 
+        // test that 0 resolves to 0
+        mRemoteViews.setFloatDimenAttr(R.id.remoteView_text, "setTextScaleX", 0);
+        applyNightModeThenApplyAndTest(false, () -> {
+            TextView textView = (TextView) mResult.findViewById(R.id.remoteView_text);
+            assertEquals(0f, textView.getTextScaleX(), 1e-4f);
+        });
+
+        applyNightModeThenApplyAndTest(true, () -> {
+            TextView textView = (TextView) mResult.findViewById(R.id.remoteView_text);
+            assertEquals(0f, textView.getTextScaleX(), 1e-4f);
+        });
+
         mRemoteViews.setFloatDimenAttr(R.id.remoteView_text, "setTextScaleX",
                 R.attr.themeColor);
         assertThrowsOnReapply(ActionException.class);
@@ -1445,6 +1512,10 @@
         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
         assertSameColorStateList(ColorStateList.valueOf(expectedValue), textView.getTextColors());
 
+        mRemoteViews.setColor(R.id.remoteView_text, "setTextColor", 0);
+        mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
+        assertSameColorStateList(ColorStateList.valueOf(0), textView.getTextColors());
+
         mRemoteViews.setColor(R.id.remoteView_text, "setTextColor", R.dimen.popup_row_height);
         assertThrowsOnReapply(ActionException.class);
     }
@@ -1465,6 +1536,20 @@
             assertSameColorStateList(ColorStateList.valueOf(0x0f00ffff), textView.getTextColors());
         });
 
+        // Set to 0 and test that the colors are set to 0
+        mRemoteViews.setColorAttr(R.id.remoteView_text, "setTextColor", 0);
+
+        applyNightModeThenApplyAndTest(false, () -> {
+            TextView textView = (TextView) mResult.findViewById(R.id.remoteView_text);
+            assertSameColorStateList(ColorStateList.valueOf(0), textView.getTextColors());
+        });
+
+        // Switch to night mode
+        applyNightModeThenApplyAndTest(true, () -> {
+            TextView textView = (TextView) mResult.findViewById(R.id.remoteView_text);
+            assertSameColorStateList(ColorStateList.valueOf(0), textView.getTextColors());
+        });
+
         mRemoteViews.setColorAttr(R.id.remoteView_text, "setTextColor", R.attr.themeDimension);
         assertThrowsOnReapply(ActionException.class);
     }
@@ -1511,7 +1596,19 @@
                     progressBar.getProgressTintList());
         });
 
-        mRemoteViews.setColorAttr(R.id.remoteView_text, "setTextColor", R.attr.themeDimension);
+        mRemoteViews.setColorStateListAttr(R.id.remoteView_progress, "setProgressTintList", 0);
+        applyNightModeThenApplyAndTest(false, () -> {
+            ProgressBar progressBar = mResult.findViewById(R.id.remoteView_progress);
+            assertSameColorStateList(null, progressBar.getProgressTintList());
+        });
+
+        applyNightModeThenApplyAndTest(true, () -> {
+            ProgressBar progressBar = mResult.findViewById(R.id.remoteView_progress);
+            assertSameColorStateList(null, progressBar.getProgressTintList());
+        });
+
+        mRemoteViews.setColorAttr(R.id.remoteView_progress,
+                "setProgressTintList", R.attr.themeDimension);
         assertThrowsOnReapply(ActionException.class);
     }
 
@@ -1534,22 +1631,27 @@
 
     @Test
     public void testSetColorStateList_fromResources() throws Throwable {
-        TextView textView = (TextView) mResult.findViewById(R.id.remoteView_text);
+        ProgressBar progressBar = (ProgressBar) mResult.findViewById(R.id.remoteView_progress);
         ColorStateList expectedValue = mContext.getColorStateList(R.color.testcolorstatelist1);
 
-        mRemoteViews.setColorStateList(R.id.remoteView_text, "setTextColor",
+        mRemoteViews.setColorStateList(R.id.remoteView_progress, "setProgressTintList",
                 R.color.testcolorstatelist1);
         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
-        assertSameColorStateList(expectedValue, textView.getTextColors());
+        assertSameColorStateList(expectedValue, progressBar.getProgressTintList());
 
-        mRemoteViews.setColorStateList(R.id.remoteView_text, "setTextColor",
+        mRemoteViews.setColorStateList(R.id.remoteView_progress, "setProgressTintList",
                 R.color.testcolor1);
         mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
         expectedValue = mContext.getResources().getColorStateList(R.color.testcolor1,
                 mContext.getTheme());
-        assertSameColorStateList(expectedValue, textView.getTextColors());
+        assertSameColorStateList(expectedValue, progressBar.getProgressTintList());
 
-        mRemoteViews.setColorStateList(R.id.remoteView_text, "setTextColor",
+        // 0 should resolve to null
+        mRemoteViews.setColorStateList(R.id.remoteView_progress, "setProgressTintList", 0);
+        mActivityRule.runOnUiThread(() -> mRemoteViews.reapply(mContext, mResult));
+        assertSameColorStateList(null, progressBar.getProgressTintList());
+
+        mRemoteViews.setColorStateList(R.id.remoteView_progress, "setProgressTintList",
                 R.dimen.popup_row_height);
         assertThrowsOnReapply(ActionException.class);
     }
@@ -1812,7 +1914,8 @@
     }
 
     private void assertSameColorStateList(ColorStateList expected, ColorStateList actual) {
-        assertEquals(expected.toString(), actual.toString());
+        assertEquals(expected == null ? null : expected.toString(),
+                actual == null ? null : actual.toString());
     }
 
     private <T extends Throwable>  void assertThrowsOnReapply(Class<T> klass) throws Throwable {
diff --git a/tests/translation/src/android/translation/cts/CtsTranslationService.java b/tests/translation/src/android/translation/cts/CtsTranslationService.java
index 33540b6..b60dce6 100644
--- a/tests/translation/src/android/translation/cts/CtsTranslationService.java
+++ b/tests/translation/src/android/translation/cts/CtsTranslationService.java
@@ -104,8 +104,15 @@
 
     @Override
     public void onCreateTranslationSession(@NonNull TranslationContext translationContext,
-            int sessionId) {
+            int sessionId, @NonNull Consumer<Boolean> callback) {
         Log.v(TAG, "onCreateTranslationSession");
+        callback.accept(true);
+    }
+
+    @Override
+    public void onCreateTranslationSession(@NonNull TranslationContext translationContext,
+            int sessionId) {
+        Log.v(TAG, "deprecated");
     }
 
     @Override