Merge "Bubbles CTS to test excluding a channel when app has "all"" into rvc-dev
diff --git a/apps/CameraITS/pymodules/its/caps.py b/apps/CameraITS/pymodules/its/caps.py
index 9acbb3c..ccbaa65 100644
--- a/apps/CameraITS/pymodules/its/caps.py
+++ b/apps/CameraITS/pymodules/its/caps.py
@@ -597,6 +597,12 @@
            props['android.control.zoomRatioRange'] is not None
 
 
+def jpeg_quality(props):
+    """Returns whether a device supports JPEG quality."""
+    return props.has_key('camera.characteristics.requestKeys') and \
+              'android.jpeg.quality' in props['camera.characteristics.requestKeys']
+
+
 class __UnitTest(unittest.TestCase):
     """Run a suite of unit tests on this module.
     """
diff --git a/apps/CameraITS/tests/scene2_a/test_jpeg_quality.py b/apps/CameraITS/tests/scene2_a/test_jpeg_quality.py
index b52fb1e..d8acb2a 100644
--- a/apps/CameraITS/tests/scene2_a/test_jpeg_quality.py
+++ b/apps/CameraITS/tests/scene2_a/test_jpeg_quality.py
@@ -209,6 +209,7 @@
 
     with its.device.ItsSession() as cam:
         props = cam.get_camera_properties()
+        its.caps.skip_unless(its.caps.jpeg_quality(props))
         cam.do_3a()
 
         # do captures over jpeg quality range
diff --git a/hostsidetests/securitybulletin/securityPatch/Bug-137282168/Android.bp b/hostsidetests/securitybulletin/securityPatch/Bug-137282168/Android.bp
index 0f298fb..e6fd1de 100644
--- a/hostsidetests/securitybulletin/securityPatch/Bug-137282168/Android.bp
+++ b/hostsidetests/securitybulletin/securityPatch/Bug-137282168/Android.bp
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 The Android Open Source Project
+// Copyright (C) 2020 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.
@@ -14,27 +14,13 @@
 
 cc_test {
     name: "Bug-137282168",
+    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
     srcs: ["poc.cpp"],
-    compile_multilib: "both",
-    multilib: {
-        lib32: {
-            suffix: "32",
-        },
-        lib64: {
-            suffix: "64",
-        },
-    },
-    test_suites: ["cts"],
     shared_libs: [
         "libbinder",
         "liblog",
         "libutils",
     ],
-    arch: {
-        arm: {
-            instruction_set: "arm",
-        },
-    },
     cflags: [
         "-Wall",
         "-Werror",
diff --git a/hostsidetests/securitybulletin/securityPatch/Bug-137878930/Android.bp b/hostsidetests/securitybulletin/securityPatch/Bug-137878930/Android.bp
index d82e171..700999c 100644
--- a/hostsidetests/securitybulletin/securityPatch/Bug-137878930/Android.bp
+++ b/hostsidetests/securitybulletin/securityPatch/Bug-137878930/Android.bp
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 The Android Open Source Project
+// Copyright (C) 2020 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.
@@ -14,17 +14,8 @@
 
 cc_test {
     name: "Bug-137878930",
+    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
     srcs: ["poc.cpp"],
-    compile_multilib: "both",
-    multilib: {
-        lib32: {
-            suffix: "32",
-        },
-        lib64: {
-            suffix: "64",
-        },
-    },
-    test_suites: ["cts"],
     shared_libs: [
         "android.hardware.drm@1.0",
         "android.hardware.drm@1.1",
@@ -32,11 +23,6 @@
         "liblog",
         "libutils",
     ],
-    arch: {
-        arm: {
-            instruction_set: "arm",
-        },
-    },
     cflags: [
         "-Wall",
         "-Werror",
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9536/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9536/Android.bp
new file mode 100644
index 0000000..16f9474
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9536/Android.bp
@@ -0,0 +1,27 @@
+// Copyright (C) 2020 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.
+
+cc_test {
+    name: "CVE-2018-9536",
+    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+    srcs: ["poc.cpp"],
+    include_dirs: [
+        "external/aac/libFDK/include",
+        "external/aac/libSYS/include",
+        "cts/hostsidetests/securitybulletin/securityPatch/includes",
+    ],
+    shared_libs: [
+        "libbluetooth"
+    ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9536/Android.mk b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9536/Android.mk
deleted file mode 100644
index 541c961..0000000
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9536/Android.mk
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (C) 2020 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.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := CVE-2018-9536
-LOCAL_MULTILIB := both
-LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
-LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
-LOCAL_SRC_FILES := poc.cpp
-LOCAL_C_INCLUDES := $(TOP)/external/aac/libFDK/include
-LOCAL_C_INCLUDES += $(TOP)/external/aac/libSYS/include
-LOCAL_C_INCLUDES += $(TOP)/cts/hostsidetests/securitybulletin/securityPatch/includes
-LOCAL_SHARED_LIBRARIES := libbluetooth
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts sts
-LOCAL_CTS_TEST_PACKAGE := android.security.cts
-
-LOCAL_ARM_MODE := arm
-LOCAL_CPPFLAGS += -Wall -Werror
-include $(BUILD_CTS_EXECUTABLE)
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/AnrTests.java b/tests/framework/base/windowmanager/src/android/server/wm/AnrTests.java
index 608a760..effa21f 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/AnrTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/AnrTests.java
@@ -26,7 +26,9 @@
 import static android.view.Display.DEFAULT_DISPLAY;
 
 import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
 
+import android.app.ActivityTaskManager;
 import android.content.ComponentName;
 import android.os.SystemClock;
 import android.platform.test.annotations.Presubmit;
@@ -67,6 +69,8 @@
     @Before
     public void setup() throws Exception {
         super.setUp();
+        assumeTrue(mAtm.currentUiModeSupportsErrorDialogs(mContext));
+
         mLogSeparator = separateLogs(); // add a new separator for logs
         mHideDialogSetting = new SettingsSession<>(
                 Settings.Global.getUriFor(Settings.Global.HIDE_ERROR_DIALOGS),
@@ -76,7 +80,7 @@
 
     @After
     public void teardown() {
-        mHideDialogSetting.close();
+        if (mHideDialogSetting != null) mHideDialogSetting.close();
         stopTestPackage(UNRESPONSIVE_ACTIVITY.getPackageName());
         stopTestPackage(HOST_ACTIVITY.getPackageName());
     }
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/SplitScreenTests.java b/tests/framework/base/windowmanager/src/android/server/wm/SplitScreenTests.java
index aa0ea524..7075f4c 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/SplitScreenTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/SplitScreenTests.java
@@ -95,6 +95,11 @@
                         + " task size");
     }
 
+
+// TODO: Add test to make sure you can't register to split-windowing mode organization if test
+//  doesn't support it.
+
+
     @Test
     public void testStackList() throws Exception {
         launchActivity(TEST_ACTIVITY);
@@ -182,7 +187,7 @@
 
         // Exit split-screen mode and ensure we only get 1 multi-window mode changed callback.
         separateTestJournal();
-        removeStacksInWindowingModes(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+        SystemUtil.runWithShellPermissionIdentity(() -> mTaskOrganizer.dismissedSplitScreen());
         final ActivityLifecycleCounts lifecycleCounts = waitForOnMultiWindowModeChanged(
                 TEST_ACTIVITY);
         assertEquals(1, lifecycleCounts.getCount(ActivityCallback.ON_MULTI_WINDOW_MODE_CHANGED));
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/SurfaceControlViewHostTests.java b/tests/framework/base/windowmanager/src/android/server/wm/SurfaceControlViewHostTests.java
index ff719ab..bcb3456 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/SurfaceControlViewHostTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/SurfaceControlViewHostTests.java
@@ -26,10 +26,15 @@
 import static org.junit.Assert.assertTrue;
 
 import android.app.Activity;
+import android.app.ActivityManager;
 import android.app.Instrumentation;
+import android.content.Context;
+import android.content.pm.ConfigurationInfo;
+import android.content.pm.FeatureInfo;
 import android.graphics.PixelFormat;
 import android.graphics.Point;
 import android.graphics.Rect;
+import android.platform.test.annotations.RequiresDevice;
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
@@ -150,6 +155,41 @@
         assertTrue(mClicked);
     }
 
+    private static int getGlEsVersion(Context context) {
+        ActivityManager activityManager =
+                (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+        ConfigurationInfo configInfo = activityManager.getDeviceConfigurationInfo();
+        if (configInfo.reqGlEsVersion != ConfigurationInfo.GL_ES_VERSION_UNDEFINED) {
+            return getMajorVersion(configInfo.reqGlEsVersion);
+        } else {
+            return 1; // Lack of property means OpenGL ES version 1
+        }
+    }
+
+    /** @see FeatureInfo#getGlEsVersion() */
+    private static int getMajorVersion(int glEsVersion) {
+        return ((glEsVersion & 0xffff0000) >> 16);
+    }
+
+    @Test
+    @RequiresDevice
+    @FlakyTest(bugId = 152103238)
+    public void testEmbeddedViewIsHardwareAccelerated() throws Throwable {
+        // Hardware accel may not be supported on devices without GLES 2.0
+        if (getGlEsVersion(mActivity) < 2) {
+            return;
+        }
+        mEmbeddedView = new Button(mActivity);
+        mEmbeddedView.setOnClickListener((View v) -> {
+            mClicked = true;
+        });
+
+        addSurfaceView(DEFAULT_SURFACE_VIEW_WIDTH, DEFAULT_SURFACE_VIEW_HEIGHT);
+        mInstrumentation.waitForIdleSync();
+
+        assertTrue(mEmbeddedView.isHardwareAccelerated());
+    }
+
     @Test
     public void testEmbeddedViewResizes() throws Throwable {
         mEmbeddedView = new Button(mActivity);
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleKeyguardTests.java b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleKeyguardTests.java
index 6c337ac..9fbd1da 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleKeyguardTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleKeyguardTests.java
@@ -85,6 +85,9 @@
         assumeTrue(supportsSecureLock());
         assumeTrue(supportsSplitScreenMultiWindow());
 
+        // TODO(b/149338177): Fix test to pass with organizer API.
+        mUseTaskOrganizer = false;
+
         final Activity firstActivity = launchActivityAndWait(FirstActivity.class);
 
         // Enter split screen
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecyclePipTests.java b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecyclePipTests.java
index faebece..142b8ac 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecyclePipTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecyclePipTests.java
@@ -218,6 +218,8 @@
 
     @Test
     public void testSplitScreenBelowPip() throws Exception {
+        // TODO(b/149338177): Fix test to pass with organizer API.
+        mUseTaskOrganizer = false;
         // Launch Pip-capable activity and enter Pip immediately
         new Launcher(PipActivity.class)
                 .setExpectedState(ON_PAUSE)
@@ -253,6 +255,8 @@
 
     @Test
     public void testPipAboveSplitScreen() throws Exception {
+        // TODO(b/149338177): Fix test to pass with organizer API.
+        mUseTaskOrganizer = false;
         // Launch first activity
         final Activity firstActivity = launchActivityAndWait(FirstActivity.class);
 
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleSplitScreenTests.java b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleSplitScreenTests.java
index 8acde84..a9ecab2 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleSplitScreenTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleSplitScreenTests.java
@@ -69,6 +69,8 @@
     public void setUp() throws Exception {
         super.setUp();
         assumeTrue(supportsSplitScreenMultiWindow());
+        // TODO(b/149338177): Fix test to pass with organizer API.
+        mUseTaskOrganizer = false;
     }
 
     @FlakyTest(bugId = 137329632)
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleTopResumedStateTests.java b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleTopResumedStateTests.java
index 0a2cf35..3d33cfc 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleTopResumedStateTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/lifecycle/ActivityLifecycleTopResumedStateTests.java
@@ -58,6 +58,7 @@
 import androidx.test.filters.FlakyTest;
 import androidx.test.filters.MediumTest;
 
+import org.junit.Before;
 import org.junit.Test;
 
 import java.util.Arrays;
@@ -74,6 +75,13 @@
 @android.server.wm.annotation.Group3
 public class ActivityLifecycleTopResumedStateTests extends ActivityLifecycleClientTestBase {
 
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        // TODO(b/149338177): Fix test to pass with organizer API.
+        mUseTaskOrganizer = false;
+    }
+
     @Test
     public void testTopPositionAfterLaunch() throws Exception {
         launchActivityAndWait(CallbackTrackingActivity.class);
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java b/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java
index 884615c..279f74d 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java
@@ -293,6 +293,10 @@
     }
 
     protected WindowManagerStateHelper mWmState = new WindowManagerStateHelper();
+    TestTaskOrganizer mTaskOrganizer = new TestTaskOrganizer();
+    // If the specific test should run using the task organizer or older API.
+    // TODO(b/149338177): Fix all places setting this to fail to be able to use organizer API.
+    public boolean mUseTaskOrganizer = true;
 
     public WindowManagerStateHelper getWmState() {
         return mWmState;
@@ -476,6 +480,8 @@
     private void tearDownBase() {
         mObjectTracker.tearDown(mPostAssertionRule::addError);
 
+        SystemUtil.runWithShellPermissionIdentity(
+                () -> mTaskOrganizer.unregisterOrganizerIfNeeded());
         // Synchronous execution of removeStacksWithActivityTypes() ensures that all activities but
         // home are cleaned up from the stack at the end of each test. Am force stop shell commands
         // might be asynchronous and could interrupt the stack cleanup process if executed first.
@@ -774,10 +780,14 @@
         SystemUtil.runWithShellPermissionIdentity(() -> {
             launchActivity(activityName);
             final int taskId = mWmState.getTaskByActivity(activityName).mTaskId;
-            mAtm.setTaskWindowingModeSplitScreenPrimary(taskId,
-                    SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
-                    true /* onTop */, false /* animate */,
-                    null /* initialBounds */, true /* showRecents */);
+            if (mUseTaskOrganizer) {
+                mTaskOrganizer.putTaskInSplitPrimary(taskId);
+            } else {
+                mAtm.setTaskWindowingModeSplitScreenPrimary(taskId,
+                        SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
+                        true /* onTop */, false /* animate */,
+                        null /* initialBounds */, true /* showRecents */);
+            }
 
             mWmState.waitForValidState(
                     new WaitForValidActivityState.Builder(activityName)
@@ -803,10 +813,15 @@
     public void moveTaskToPrimarySplitScreen(int taskId, boolean showSideActivity) {
         final boolean isHomeRecentsComponent = mWmState.isHomeRecentsComponent();
         SystemUtil.runWithShellPermissionIdentity(() -> {
-            mAtm.setTaskWindowingModeSplitScreenPrimary(taskId,
-                    SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, true /* onTop */,
-                    false /* animate */,
-                    null /* initialBounds */, showSideActivity && !isHomeRecentsComponent);
+            if (mUseTaskOrganizer) {
+                mTaskOrganizer.putTaskInSplitPrimary(taskId);
+            } else {
+                mAtm.setTaskWindowingModeSplitScreenPrimary(taskId,
+                        SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, true /* onTop */,
+                        false /* animate */, null /* initialBounds */,
+                        showSideActivity && !isHomeRecentsComponent);
+            }
+
             mWmState.waitForRecentsActivityVisible();
 
             if (showSideActivity) {
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/TestTaskOrganizer.java b/tests/framework/base/windowmanager/util/src/android/server/wm/TestTaskOrganizer.java
new file mode 100644
index 0000000..5dec9e9
--- /dev/null
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/TestTaskOrganizer.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.server.wm;
+
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import android.app.ActivityManager;
+import android.view.Display;
+import android.window.TaskOrganizer;
+import android.window.WindowContainerTransaction;
+
+import androidx.annotation.NonNull;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+class TestTaskOrganizer extends TaskOrganizer {
+
+    private boolean mRegistered;
+    final HashMap<Integer, ActivityManager.RunningTaskInfo> mKnownTasks = new HashMap<>();
+    private ActivityManager.RunningTaskInfo mRootPrimary;
+    private boolean mRootPrimaryHasChild;
+    private ActivityManager.RunningTaskInfo mRootSecondary;
+
+    private void registerOrganizerIfNeeded() {
+        if (mRegistered) return;
+
+        registerOrganizer(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+        registerOrganizer(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
+        mRegistered = true;
+    }
+
+    void unregisterOrganizerIfNeeded() {
+        if (!mRegistered) return;
+        mRegistered = false;
+
+        dismissedSplitScreen();
+        super.unregisterOrganizer();
+    }
+
+    void putTaskInSplitPrimary(int taskId) {
+        registerOrganizerIfNeeded();
+        ActivityManager.RunningTaskInfo taskInfo = getTaskInfo(taskId);
+        final WindowContainerTransaction t = new WindowContainerTransaction();
+        t.reparent(taskInfo.getToken(), mRootPrimary.getToken(), true /* onTop */);
+        applyTransaction(t);
+    }
+
+    void dismissedSplitScreen() {
+        // Re-set default launch root.
+        TaskOrganizer.setLaunchRoot(Display.DEFAULT_DISPLAY, null);
+
+        // Re-parent everything back to the display from the splits so that things are as they were.
+        final List<ActivityManager.RunningTaskInfo> children = new ArrayList<>();
+        final List<ActivityManager.RunningTaskInfo> primaryChildren =
+                getChildTasks(mRootPrimary.getToken(), null /* activityTypes */);
+        if (primaryChildren != null && !primaryChildren.isEmpty()) {
+            children.addAll(primaryChildren);
+        }
+        final List<ActivityManager.RunningTaskInfo> secondaryChildren =
+                getChildTasks(mRootSecondary.getToken(), null /* activityTypes */);
+        if (secondaryChildren != null && !secondaryChildren.isEmpty()) {
+            children.addAll(secondaryChildren);
+        }
+        if (children.isEmpty()) {
+            return;
+        }
+
+        final WindowContainerTransaction t = new WindowContainerTransaction();
+        for (ActivityManager.RunningTaskInfo task : children) {
+            t.reparent(task.getToken(), null /* parent */, true /* onTop */);
+        }
+        applyTransaction(t);
+    }
+
+    /** Also completes the process of entering split mode. */
+    private void processRootPrimaryTaskInfoChanged() {
+        List<ActivityManager.RunningTaskInfo> children =
+                getChildTasks(mRootPrimary.getToken(), null /* activityTypes */);
+        final boolean hasChild = !children.isEmpty();
+        if (mRootPrimaryHasChild == hasChild) return;
+        mRootPrimaryHasChild = hasChild;
+        if (!hasChild) return;
+
+        // Finish entering split-screen mode
+
+        // Set launch root for the default display to secondary...for no good reason...
+        setLaunchRoot(DEFAULT_DISPLAY, mRootSecondary.getToken());
+
+        List<ActivityManager.RunningTaskInfo> rootTasks =
+                getRootTasks(DEFAULT_DISPLAY, null /* activityTypes */);
+        if (rootTasks.isEmpty()) return;
+        // Move all root fullscreen task to secondary split.
+        final WindowContainerTransaction t = new WindowContainerTransaction();
+        for (int i = rootTasks.size() - 1; i >= 0; --i) {
+            final ActivityManager.RunningTaskInfo task = rootTasks.get(i);
+            if (task.getConfiguration().windowConfiguration.getWindowingMode()
+                    == WINDOWING_MODE_FULLSCREEN) {
+                t.reparent(task.getToken(), mRootSecondary.getToken(), true /* onTop */);
+            }
+        }
+        // Move the secondary split-forward.
+        t.reorder(mRootSecondary.getToken(), true /* onTop */);
+        applyTransaction(t);
+    }
+
+    private ActivityManager.RunningTaskInfo getTaskInfo(int taskId) {
+        ActivityManager.RunningTaskInfo taskInfo = mKnownTasks.get(taskId);
+        if (taskInfo != null) return taskInfo;
+
+        final List<ActivityManager.RunningTaskInfo> rootTasks = getRootTasks(DEFAULT_DISPLAY, null);
+        for (ActivityManager.RunningTaskInfo info : rootTasks) {
+            addTask(info);
+        }
+
+        return mKnownTasks.get(taskId);
+    }
+
+    @Override
+    public void onTaskAppeared(@NonNull ActivityManager.RunningTaskInfo taskInfo) {
+        addTask(taskInfo);
+    }
+
+    @Override
+    public void onTaskVanished(@NonNull ActivityManager.RunningTaskInfo taskInfo) {
+        removeTask(taskInfo);
+    }
+
+    @Override
+    public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) {
+        addTask(taskInfo);
+    }
+
+    private void addTask(ActivityManager.RunningTaskInfo taskInfo) {
+        mKnownTasks.put(taskInfo.taskId, taskInfo);
+
+        final int windowingMode =
+                taskInfo.getConfiguration().windowConfiguration.getWindowingMode();
+        if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
+            mRootPrimary = taskInfo;
+            processRootPrimaryTaskInfoChanged();
+        }
+
+        if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) {
+            mRootSecondary = taskInfo;
+        }
+    }
+
+    private void removeTask(ActivityManager.RunningTaskInfo taskInfo) {
+        final int taskId = taskInfo.taskId;
+        mKnownTasks.remove(taskId);
+
+        if (taskId == mRootPrimary.taskId) mRootPrimary = null;
+        if (taskId == mRootSecondary.taskId) mRootSecondary = null;
+    }
+}
diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/BasicAdapterTest.java b/tests/tests/bluetooth/src/android/bluetooth/cts/BasicAdapterTest.java
index fa126ff..8616a6d 100644
--- a/tests/tests/bluetooth/src/android/bluetooth/cts/BasicAdapterTest.java
+++ b/tests/tests/bluetooth/src/android/bluetooth/cts/BasicAdapterTest.java
@@ -140,7 +140,7 @@
         assertTrue(BluetoothAdapter.checkBluetoothAddress(adapter.getAddress()));
     }
 
-    public void test_setName_getName() {
+    public void test_getName() {
         if (!mHasBluetooth) {
             // Skip the test if bluetooth is not present.
             return;
@@ -150,10 +150,6 @@
 
         String name = adapter.getName();
         assertNotNull(name);
-
-        String genericName = "Generic Device 1";
-        assertTrue(adapter.setName(genericName));
-        assertEquals(genericName, adapter.getName());
     }
 
     public void test_getBondedDevices() {
diff --git a/tests/tests/car/src/android/car/cts/CarUserManagerTest.java b/tests/tests/car/src/android/car/cts/CarUserManagerTest.java
index 93072fa..d5b5ea9 100644
--- a/tests/tests/car/src/android/car/cts/CarUserManagerTest.java
+++ b/tests/tests/car/src/android/car/cts/CarUserManagerTest.java
@@ -183,15 +183,20 @@
             } else if (actualUserHandle.getIdentifier() != newUserId) {
                 errors.add("wrong user: expected " + newUserId + ", got " + actualUserHandle);
             }
-
-            // TODO(b/144120654): check for previous handle (not set yet)
-            if (false) {
-                UserHandle previousUserHandle = event.getPreviousUserHandle();
-                if (previousUserHandle == null) {
-                    errors.add("no previous user handle");
-                } else if (previousUserHandle.getIdentifier() != oldUserId) {
-                    errors.add("wrong previous user: expected " + oldUserId + ", got "
-                            + previousUserHandle);
+            UserHandle previousUserHandle = null;
+            if (actualType == CarUserManager.USER_LIFECYCLE_EVENT_TYPE_SWITCHING) {
+                try {
+                    previousUserHandle = event.getPreviousUserHandle();
+                    if (previousUserHandle == null) {
+                        errors.add("no previous user handle");
+                    } else if (previousUserHandle.getIdentifier() != oldUserId) {
+                        errors.add("wrong previous user: expected " + oldUserId + ", got "
+                                + previousUserHandle);
+                    }        
+                } catch (Exception e) {
+                    String msg = "failed to get previous user handle: ";
+                    errors.add(msg + e);
+                    Log.d(TAG, msg, e);
                 }
             }
 
diff --git a/tests/tests/media/res/raw/sinesweepid3v23ext.mp3 b/tests/tests/media/res/raw/sinesweepid3v23ext.mp3
new file mode 100644
index 0000000..8249f4a
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweepid3v23ext.mp3
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweepid3v23extbe.mp3 b/tests/tests/media/res/raw/sinesweepid3v23extbe.mp3
new file mode 100644
index 0000000..8d04b44
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweepid3v23extbe.mp3
Binary files differ
diff --git a/tests/tests/media/res/raw/sinesweepid3v24ext.mp3 b/tests/tests/media/res/raw/sinesweepid3v24ext.mp3
new file mode 100644
index 0000000..40b392f
--- /dev/null
+++ b/tests/tests/media/res/raw/sinesweepid3v24ext.mp3
Binary files differ
diff --git a/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java b/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
index cdfa22f..adcead5 100644
--- a/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
@@ -333,6 +333,49 @@
                 mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_WRITER));
     }
 
+    public void testID3v2Unsynchronization() {
+        setDataSourceFd(R.raw.testmp3_4);
+        assertEquals("Mime type was other than expected",
+                "audio/mpeg",
+                mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_MIMETYPE));
+    }
+
+    public void testID3v240ExtHeader() {
+        setDataSourceFd(R.raw.sinesweepid3v24ext);
+        assertEquals("Mime type was other than expected",
+                "audio/mpeg",
+                mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_MIMETYPE));
+        assertEquals("Title was other than expected",
+                "sinesweep",
+                mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE));
+        assertNotNull("no album art",
+                mRetriever.getEmbeddedPicture());
+    }
+
+    public void testID3v230ExtHeader() {
+        setDataSourceFd(R.raw.sinesweepid3v23ext);
+        assertEquals("Mime type was other than expected",
+                "audio/mpeg",
+                mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_MIMETYPE));
+        assertEquals("Title was other than expected",
+                "sinesweep",
+                mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE));
+        assertNotNull("no album art",
+                mRetriever.getEmbeddedPicture());
+    }
+
+    public void testID3v230ExtHeaderBigEndian() {
+        setDataSourceFd(R.raw.sinesweepid3v23extbe);
+        assertEquals("Mime type was other than expected",
+                "audio/mpeg",
+                mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_MIMETYPE));
+        assertEquals("Title was other than expected",
+                "sinesweep",
+                mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE));
+        assertNotNull("no album art",
+                mRetriever.getEmbeddedPicture());
+    }
+
     public void testGenreParsing() {
         Object [][] genres = {
             { R.raw.id3test0, null },
diff --git a/tests/tests/mediaparser/assets/ts/sample_h264_no_access_unit_delimiters.ts b/tests/tests/mediaparser/assets/ts/sample_h264_no_access_unit_delimiters.ts
new file mode 100644
index 0000000..a1cc40b
--- /dev/null
+++ b/tests/tests/mediaparser/assets/ts/sample_h264_no_access_unit_delimiters.ts
Binary files differ
diff --git a/tests/tests/mediaparser/src/android/media/mediaparser/cts/MediaParserTest.java b/tests/tests/mediaparser/src/android/media/mediaparser/cts/MediaParserTest.java
index 8893336..9bceb45 100644
--- a/tests/tests/mediaparser/src/android/media/mediaparser/cts/MediaParserTest.java
+++ b/tests/tests/mediaparser/src/android/media/mediaparser/cts/MediaParserTest.java
@@ -38,6 +38,8 @@
 import org.junit.runner.RunWith;
 
 import java.io.IOException;
+import java.util.Collections;
+import java.util.Map;
 
 @RunWith(AndroidJUnit4.class)
 public class MediaParserTest {
@@ -458,6 +460,13 @@
     }
 
     @Test
+    public void testTsWithH264DetectAccessUnits() throws IOException, InterruptedException {
+        testExtractAsset(
+                "ts/sample_h264_no_access_unit_delimiters.ts",
+                Collections.singletonMap(MediaParser.PARAMETER_TS_DETECT_ACCESS_UNITS, true));
+    }
+
+    @Test
     public void testTsWithLatm() throws IOException, InterruptedException {
         testExtractAsset("ts/sample_latm.ts");
     }
@@ -577,15 +586,21 @@
 
     private static void testSniffAsset(String assetPath, String expectedParserName)
             throws IOException, InterruptedException {
-        extractAsset(assetPath, expectedParserName);
+        extractAsset(assetPath, Collections.emptyMap(), expectedParserName);
     }
 
     private static void testExtractAsset(String assetPath)
             throws IOException, InterruptedException {
-        extractAsset(assetPath, /* expectedParserName= */ null);
+        testExtractAsset(assetPath, Collections.emptyMap());
     }
 
-    private static void extractAsset(String assetPath, String expectedParserName)
+    private static void testExtractAsset(String assetPath, Map<String, Object> parameters)
+            throws IOException, InterruptedException {
+        extractAsset(assetPath, parameters, /* expectedParserName= */ null);
+    }
+
+    private static void extractAsset(
+            String assetPath, Map<String, Object> parameters, String expectedParserName)
             throws IOException, InterruptedException {
         byte[] assetBytes =
                 TestUtil.getByteArray(
@@ -596,6 +611,9 @@
         MockMediaParserOutputConsumer outputConsumer =
                 new MockMediaParserOutputConsumer(new FakeExtractorOutput());
         MediaParser mediaParser = MediaParser.create(outputConsumer);
+        for (Map.Entry<String, Object> entry : parameters.entrySet()) {
+            mediaParser.setParameter(entry.getKey(), entry.getValue());
+        }
 
         mediaParser.advance(mockInput);
         if (expectedParserName != null) {
diff --git a/tests/tests/uirendering/AndroidManifest.xml b/tests/tests/uirendering/AndroidManifest.xml
index d7adaf7..f43818a 100644
--- a/tests/tests/uirendering/AndroidManifest.xml
+++ b/tests/tests/uirendering/AndroidManifest.xml
@@ -32,7 +32,8 @@
                   android:theme="@style/DefaultTheme"
                   android:screenOrientation="locked"
                   android:resizeableActivity="false"
-                  android:configChanges="uiMode" />
+                  android:configChanges="uiMode"
+                  android:requestLegacyExternalStorage="true" />
         <uses-library android:name="android.test.runner" />
     </application>
 
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/runner/UiRenderingRunner.java b/tests/tests/uirendering/src/android/uirendering/cts/runner/UiRenderingRunner.java
index a238699..0215e16 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/runner/UiRenderingRunner.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/runner/UiRenderingRunner.java
@@ -16,10 +16,10 @@
 
 package android.uirendering.cts.runner;
 
+import android.content.Intent;
 import android.os.Bundle;
 import android.support.test.uiautomator.UiDevice;
 
-import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnitRunner;
 
 /**
@@ -36,10 +36,11 @@
     public void onCreate(Bundle arguments) {
         super.onCreate(arguments);
 
-        final UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+        final UiDevice device = UiDevice.getInstance(this);
         try {
             device.wakeUp();
             device.executeShellCommand("wm dismiss-keyguard");
+            getContext().sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
         } catch (Exception e) {
         }
     }