Merge "Fix bug with portrait-fold devices animating app pairs launch wrongly" into main
diff --git a/Android.bp b/Android.bp
index eca0778..61042f6 100644
--- a/Android.bp
+++ b/Android.bp
@@ -108,6 +108,7 @@
     ],
     srcs: [
         "tests/multivalentTests/tapl/**/*.java",
+        "tests/multivalentTests/tapl/**/*.kt",
     ],
     resource_dirs: [],
     manifest: "tests/multivalentTests/tapl/AndroidManifest.xml",
diff --git a/quickstep/res/layout/task.xml b/quickstep/res/layout/task.xml
index 823a86e..9d599c9 100644
--- a/quickstep/res/layout/task.xml
+++ b/quickstep/res/layout/task.xml
@@ -19,6 +19,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     xmlns:launcher="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/task"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:clipChildren="false"
diff --git a/quickstep/res/layout/task_desktop.xml b/quickstep/res/layout/task_desktop.xml
index 60827cd..3cafcfd 100644
--- a/quickstep/res/layout/task_desktop.xml
+++ b/quickstep/res/layout/task_desktop.xml
@@ -19,6 +19,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     xmlns:launcher="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/task"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:clipChildren="true"
diff --git a/quickstep/res/layout/task_grouped.xml b/quickstep/res/layout/task_grouped.xml
index d20afd3..e91e773 100644
--- a/quickstep/res/layout/task_grouped.xml
+++ b/quickstep/res/layout/task_grouped.xml
@@ -24,6 +24,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     xmlns:launcher="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/task"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:clipChildren="false"
diff --git a/quickstep/res/values/config.xml b/quickstep/res/values/config.xml
index 8a3ffb5..e45d9fd 100644
--- a/quickstep/res/values/config.xml
+++ b/quickstep/res/values/config.xml
@@ -53,5 +53,5 @@
     <string name="setup_wizard_pkg" translatable="false" />
 
     <!-- This is a float because it is converted to dp later in DeviceProfile -->
-    <item name="taskbar_icon_size" type="dimen" format="float">48.4</item>
+    <item name="taskbar_icon_size" type="dimen" format="float">44</item>
 </resources>
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index b23c283..325c255 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -267,7 +267,7 @@
     <string name="taskbar_edu_features">Do more with the Taskbar</string>
     <!-- Title in dialog that shows a user how to pin the Taskbar. [CHAR_LIMIT 60] -->
     <string name="taskbar_edu_pinning_title">Always show the Taskbar</string>
-    <!-- Text in dialog that shows a user how to pin the Taskbar. [CHAR_LIMIT 60] -->
+    <!-- Text in dialog that shows a user how to pin the Taskbar. [CHAR_LIMIT 150] -->
     <string name="taskbar_edu_pinning_standalone">To always show the Taskbar on the bottom of your screen, touch &amp; hold the divider</string>
     <!-- Text on button to exit a tutorial [CHAR_LIMIT=16] -->
     <string name="taskbar_edu_close">Close</string>
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index ac0e53e..a70e7f3 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -1355,7 +1355,7 @@
 
     @Override
     public boolean handleIncorrectSplitTargetSelection() {
-        if (enableSplitContextually() && !mSplitSelectStateController.isSplitSelectActive()) {
+        if (!enableSplitContextually() || !mSplitSelectStateController.isSplitSelectActive()) {
             return false;
         }
         mSplitSelectStateController.getSplitInstructionsView().goBoing();
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java
index d98e608..74ba006 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java
@@ -31,6 +31,8 @@
 import android.view.Window;
 import android.view.WindowManager;
 
+import androidx.annotation.VisibleForTesting;
+
 import com.android.launcher3.AbstractFloatingView;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Launcher;
@@ -51,12 +53,12 @@
 
     private final Launcher mLauncher;
     private final SystemUiProxy mSystemUiProxy;
-    private final float mTouchSlop;
+    @VisibleForTesting final float mTouchSlop;
     private int mLastAction;
     private final SparseArray<PointF> mDownEvents;
 
     /* If {@code false}, this controller should not handle the input {@link MotionEvent}.*/
-    private boolean mCanIntercept;
+    @VisibleForTesting boolean mCanIntercept;
 
     private boolean mIsTrackpadReverseScroll;
 
@@ -85,9 +87,9 @@
 
     @Override
     public final boolean onControllerInterceptTouchEvent(MotionEvent ev) {
-        int action = ev.getActionMasked();
-        int idx = ev.getActionIndex();
-        int pid = ev.getPointerId(idx);
+        final int action = ev.getActionMasked();
+        final int idx = ev.getActionIndex();
+        final int pid = ev.getPointerId(idx);
         if (action == ACTION_DOWN) {
             mCanIntercept = canInterceptTouch(ev);
             if (!mCanIntercept) {
@@ -135,7 +137,6 @@
                     .log(LAUNCHER_SWIPE_DOWN_WORKSPACE_NOTISHADE_OPEN);
             setWindowSlippery(false);
             mIsTrackpadReverseScroll = false;
-            return true;
         }
         return true;
     }
@@ -149,7 +150,8 @@
      * Touches can slide out of the window but they cannot necessarily slide
      * back in (unless the other window with touch focus permits it).
      */
-    private void setWindowSlippery(boolean enable) {
+    @VisibleForTesting
+    void setWindowSlippery(boolean enable) {
         Window w = mLauncher.getWindow();
         WindowManager.LayoutParams wlp = w.getAttributes();
         if (enable) {
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
index c8c7dc2..0f8ceba 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
@@ -154,6 +154,7 @@
         mSquaredTouchSlop = mDeviceState.getSquaredTouchSlop();
 
         mPassedPilferInputSlop = mPassedWindowMoveSlop = continuingPreviousGesture;
+        mStartDisplacement = continuingPreviousGesture ? 0 : -mTouchSlop;
         mDisableHorizontalSwipe = !mPassedPilferInputSlop && disableHorizontalSwipe;
         mRotationTouchHelper = mDeviceState.getRotationTouchHelper();
     }
@@ -280,7 +281,7 @@
                         if (mGestureState.isTrackpadGesture() || Math.abs(displacement)
                                 > mTouchSlop) {
                             mPassedWindowMoveSlop = true;
-                            mStartDisplacement = Math.min(displacement, -mTouchSlop);
+                            mStartDisplacement = -mTouchSlop;
                         }
                     }
                 }
@@ -336,7 +337,7 @@
                         }
                         if (!mPassedWindowMoveSlop) {
                             mPassedWindowMoveSlop = true;
-                            mStartDisplacement = Math.min(displacement, -mTouchSlop);
+                            mStartDisplacement = -mTouchSlop;
                         }
                         notifyGestureStarted(isLikelyToStartNewTask);
                     }
diff --git a/quickstep/src/com/android/quickstep/orientation/LandscapePagedViewHandler.java b/quickstep/src/com/android/quickstep/orientation/LandscapePagedViewHandler.java
index e41832b..a7ca515 100644
--- a/quickstep/src/com/android/quickstep/orientation/LandscapePagedViewHandler.java
+++ b/quickstep/src/com/android/quickstep/orientation/LandscapePagedViewHandler.java
@@ -36,6 +36,7 @@
 import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_TYPE_MAIN;
 
 import android.content.res.Resources;
+import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.RectF;
@@ -533,34 +534,52 @@
         int dividerBar = Math.round(totalThumbnailHeight * (splitBoundsConfig.appsStackedVertically
                 ? splitBoundsConfig.dividerHeightPercent
                 : splitBoundsConfig.dividerWidthPercent));
-        int primarySnapshotHeight;
-        int primarySnapshotWidth;
-        int secondarySnapshotHeight;
-        int secondarySnapshotWidth;
 
-        float taskPercent = splitBoundsConfig.appsStackedVertically ?
-                splitBoundsConfig.topTaskPercent : splitBoundsConfig.leftTaskPercent;
-        primarySnapshotWidth = parentWidth;
-        primarySnapshotHeight = (int) (totalThumbnailHeight * (taskPercent));
+        Pair<Point, Point> taskViewSizes =
+                getGroupedTaskViewSizes(dp, splitBoundsConfig, parentWidth, parentHeight);
 
-        secondarySnapshotWidth = parentWidth;
-        secondarySnapshotHeight = totalThumbnailHeight - primarySnapshotHeight - dividerBar;
-
-        int translationY = primarySnapshotHeight + spaceAboveSnapshot + dividerBar;
+        int translationY = taskViewSizes.first.y + spaceAboveSnapshot + dividerBar;
         primarySnapshot.setTranslationY(spaceAboveSnapshot);
         secondarySnapshot.setTranslationY(translationY - spaceAboveSnapshot);
 
         primarySnapshot.measure(
-                View.MeasureSpec.makeMeasureSpec(primarySnapshotWidth, View.MeasureSpec.EXACTLY),
-                View.MeasureSpec.makeMeasureSpec(primarySnapshotHeight, View.MeasureSpec.EXACTLY)
+                View.MeasureSpec.makeMeasureSpec(taskViewSizes.first.x, View.MeasureSpec.EXACTLY),
+                View.MeasureSpec.makeMeasureSpec(taskViewSizes.first.y, View.MeasureSpec.EXACTLY)
         );
         secondarySnapshot.measure(
-                View.MeasureSpec.makeMeasureSpec(secondarySnapshotWidth, View.MeasureSpec.EXACTLY),
-                View.MeasureSpec.makeMeasureSpec(secondarySnapshotHeight, View.MeasureSpec.EXACTLY)
+                View.MeasureSpec.makeMeasureSpec(taskViewSizes.second.x, View.MeasureSpec.EXACTLY),
+                View.MeasureSpec.makeMeasureSpec(taskViewSizes.second.y, View.MeasureSpec.EXACTLY)
         );
     }
 
     @Override
+    public Pair<Point, Point> getGroupedTaskViewSizes(
+            DeviceProfile dp,
+            SplitBounds splitBoundsConfig,
+            int parentWidth,
+            int parentHeight) {
+        int spaceAboveSnapshot = dp.overviewTaskThumbnailTopMarginPx;
+        int totalThumbnailHeight = parentHeight - spaceAboveSnapshot;
+        int dividerBar = Math.round(totalThumbnailHeight * (splitBoundsConfig.appsStackedVertically
+                ? splitBoundsConfig.dividerHeightPercent
+                : splitBoundsConfig.dividerWidthPercent));
+        float taskPercent = splitBoundsConfig.appsStackedVertically
+                ? splitBoundsConfig.topTaskPercent
+                : splitBoundsConfig.leftTaskPercent;
+
+        Point firstTaskViewSize = new Point(
+                parentWidth,
+                (int) (totalThumbnailHeight * taskPercent)
+        );
+        Point secondTaskViewSize = new Point(
+                parentWidth,
+                totalThumbnailHeight - firstTaskViewSize.y - dividerBar
+        );
+
+        return new Pair<>(firstTaskViewSize, secondTaskViewSize);
+    }
+
+    @Override
     public void setTaskIconParams(FrameLayout.LayoutParams iconParams, int taskIconMargin,
             int taskIconHeight, int thumbnailTopMargin, boolean isRtl) {
         if (enableOverviewIconMenu()) {
diff --git a/quickstep/src/com/android/quickstep/orientation/PortraitPagedViewHandler.java b/quickstep/src/com/android/quickstep/orientation/PortraitPagedViewHandler.java
index 3d7065b..5d9a668 100644
--- a/quickstep/src/com/android/quickstep/orientation/PortraitPagedViewHandler.java
+++ b/quickstep/src/com/android/quickstep/orientation/PortraitPagedViewHandler.java
@@ -34,6 +34,7 @@
 import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_TYPE_MAIN;
 
 import android.graphics.Matrix;
+import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.RectF;
@@ -530,25 +531,16 @@
         float dividerScale = splitBoundsConfig.appsStackedVertically
                 ? splitBoundsConfig.dividerHeightPercent
                 : splitBoundsConfig.dividerWidthPercent;
-        int primarySnapshotHeight;
-        int primarySnapshotWidth;
-        int secondarySnapshotHeight;
-        int secondarySnapshotWidth;
-        float taskPercent = splitBoundsConfig.appsStackedVertically ?
-                splitBoundsConfig.topTaskPercent : splitBoundsConfig.leftTaskPercent;
+        Pair<Point, Point> taskViewSizes =
+                getGroupedTaskViewSizes(dp, splitBoundsConfig, parentWidth, parentHeight);
         if (dp.isLeftRightSplit) {
             int scaledDividerBar = Math.round(parentWidth * dividerScale);
-            primarySnapshotHeight = totalThumbnailHeight;
-            primarySnapshotWidth = Math.round(parentWidth * taskPercent);
-
-            secondarySnapshotHeight = totalThumbnailHeight;
-            secondarySnapshotWidth = parentWidth - primarySnapshotWidth - scaledDividerBar;
             if (isRtl) {
-                int translationX = secondarySnapshotWidth + scaledDividerBar;
+                int translationX = taskViewSizes.second.x + scaledDividerBar;
                 primarySnapshot.setTranslationX(-translationX);
                 secondarySnapshot.setTranslationX(0);
             } else {
-                int translationX = primarySnapshotWidth + scaledDividerBar;
+                int translationX = taskViewSizes.first.x + scaledDividerBar;
                 secondarySnapshot.setTranslationX(translationX);
                 primarySnapshot.setTranslationX(0);
             }
@@ -557,18 +549,8 @@
             // Reset unused translations
             primarySnapshot.setTranslationY(0);
         } else {
-            int taskbarHeight = dp.isTransientTaskbar ? 0 : dp.taskbarHeight;
-            float scale = (float) totalThumbnailHeight / (dp.availableHeightPx - taskbarHeight);
-            float topTaskHeight = dp.availableHeightPx * taskPercent;
             float finalDividerHeight = Math.round(totalThumbnailHeight * dividerScale);
-            float scaledTopTaskHeight = topTaskHeight * scale;
-            primarySnapshotWidth = parentWidth;
-            primarySnapshotHeight = Math.round(scaledTopTaskHeight);
-
-            secondarySnapshotWidth = parentWidth;
-            secondarySnapshotHeight = Math.round(totalThumbnailHeight - primarySnapshotHeight
-                    - finalDividerHeight);
-            float translationY = primarySnapshotHeight + spaceAboveSnapshot + finalDividerHeight;
+            float translationY = taskViewSizes.first.y + spaceAboveSnapshot + finalDividerHeight;
             secondarySnapshot.setTranslationY(translationY);
 
             FrameLayout.LayoutParams primaryParams =
@@ -584,11 +566,11 @@
             primarySnapshot.setTranslationX(0);
         }
         primarySnapshot.measure(
-                View.MeasureSpec.makeMeasureSpec(primarySnapshotWidth, View.MeasureSpec.EXACTLY),
-                View.MeasureSpec.makeMeasureSpec(primarySnapshotHeight, View.MeasureSpec.EXACTLY));
+                View.MeasureSpec.makeMeasureSpec(taskViewSizes.first.x, View.MeasureSpec.EXACTLY),
+                View.MeasureSpec.makeMeasureSpec(taskViewSizes.first.y, View.MeasureSpec.EXACTLY));
         secondarySnapshot.measure(
-                View.MeasureSpec.makeMeasureSpec(secondarySnapshotWidth, View.MeasureSpec.EXACTLY),
-                View.MeasureSpec.makeMeasureSpec(secondarySnapshotHeight,
+                View.MeasureSpec.makeMeasureSpec(taskViewSizes.second.x, View.MeasureSpec.EXACTLY),
+                View.MeasureSpec.makeMeasureSpec(taskViewSizes.second.y,
                         View.MeasureSpec.EXACTLY));
         primarySnapshot.setScaleX(1);
         secondarySnapshot.setScaleX(1);
@@ -597,6 +579,48 @@
     }
 
     @Override
+    public Pair<Point, Point> getGroupedTaskViewSizes(
+            DeviceProfile dp,
+            SplitBounds splitBoundsConfig,
+            int parentWidth,
+            int parentHeight) {
+        int spaceAboveSnapshot = dp.overviewTaskThumbnailTopMarginPx;
+        int totalThumbnailHeight = parentHeight - spaceAboveSnapshot;
+        float dividerScale = splitBoundsConfig.appsStackedVertically
+                ? splitBoundsConfig.dividerHeightPercent
+                : splitBoundsConfig.dividerWidthPercent;
+        float taskPercent = splitBoundsConfig.appsStackedVertically
+                ? splitBoundsConfig.topTaskPercent
+                : splitBoundsConfig.leftTaskPercent;
+
+        Point firstTaskViewSize = new Point();
+        Point secondTaskViewSize = new Point();
+
+        if (dp.isLeftRightSplit) {
+            int scaledDividerBar = Math.round(parentWidth * dividerScale);
+            firstTaskViewSize.x = Math.round(parentWidth * taskPercent);
+            firstTaskViewSize.y = totalThumbnailHeight;
+
+            secondTaskViewSize.x = parentWidth - firstTaskViewSize.x - scaledDividerBar;
+            secondTaskViewSize.y = totalThumbnailHeight;
+        } else {
+            int taskbarHeight = dp.isTransientTaskbar ? 0 : dp.taskbarHeight;
+            float scale = (float) totalThumbnailHeight / (dp.availableHeightPx - taskbarHeight);
+            float topTaskHeight = dp.availableHeightPx * taskPercent;
+            float finalDividerHeight = Math.round(totalThumbnailHeight * dividerScale);
+            float scaledTopTaskHeight = topTaskHeight * scale;
+            firstTaskViewSize.x = parentWidth;
+            firstTaskViewSize.y = Math.round(scaledTopTaskHeight);
+
+            secondTaskViewSize.x = parentWidth;
+            secondTaskViewSize.y = Math.round(totalThumbnailHeight - firstTaskViewSize.y
+                    - finalDividerHeight);
+        }
+
+        return new Pair<>(firstTaskViewSize, secondTaskViewSize);
+    }
+
+    @Override
     public void setTaskIconParams(FrameLayout.LayoutParams iconParams, int taskIconMargin,
             int taskIconHeight, int thumbnailTopMargin, boolean isRtl) {
         if (enableOverviewIconMenu()) {
diff --git a/quickstep/src/com/android/quickstep/orientation/RecentsPagedOrientationHandler.java b/quickstep/src/com/android/quickstep/orientation/RecentsPagedOrientationHandler.java
index 34756b4..9084297 100644
--- a/quickstep/src/com/android/quickstep/orientation/RecentsPagedOrientationHandler.java
+++ b/quickstep/src/com/android/quickstep/orientation/RecentsPagedOrientationHandler.java
@@ -17,6 +17,7 @@
 package com.android.quickstep.orientation;
 
 
+import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.RectF;
@@ -135,6 +136,15 @@
             int parentWidth, int parentHeight,
             SplitBounds splitBoundsConfig, DeviceProfile dp, boolean isRtl);
 
+    /**
+     * Creates two Points representing the dimensions of the two tasks in a GroupedTaskView
+     *
+     * @return first -> primary task snapshot, second -> secondary task snapshot.
+     * x -> width, y -> height
+     */
+    Pair<Point, Point> getGroupedTaskViewSizes(DeviceProfile dp, SplitBounds splitBoundsConfig,
+            int parentWidth, int parentHeight);
+
     // Overview TaskMenuView methods
     void setTaskIconParams(FrameLayout.LayoutParams iconParams,
             int taskIconMargin, int taskIconHeight, int thumbnailTopMargin, boolean isRtl);
diff --git a/quickstep/src/com/android/quickstep/orientation/SeascapePagedViewHandler.java b/quickstep/src/com/android/quickstep/orientation/SeascapePagedViewHandler.java
index 7e53cf1..f3001fc 100644
--- a/quickstep/src/com/android/quickstep/orientation/SeascapePagedViewHandler.java
+++ b/quickstep/src/com/android/quickstep/orientation/SeascapePagedViewHandler.java
@@ -31,6 +31,7 @@
 import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_TYPE_MAIN;
 
 import android.content.res.Resources;
+import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.util.Pair;
@@ -342,31 +343,52 @@
         int dividerBar = Math.round(totalThumbnailHeight * (splitBoundsConfig.appsStackedVertically
                 ? splitBoundsConfig.dividerHeightPercent
                 : splitBoundsConfig.dividerWidthPercent));
-        int primarySnapshotHeight;
-        int primarySnapshotWidth;
-        int secondarySnapshotHeight;
-        int secondarySnapshotWidth;
 
-        float taskPercent = splitBoundsConfig.appsStackedVertically ?
-                splitBoundsConfig.topTaskPercent : splitBoundsConfig.leftTaskPercent;
-        primarySnapshotWidth = parentWidth;
-        primarySnapshotHeight = (int) (totalThumbnailHeight * (taskPercent));
+        Pair<Point, Point> taskViewSizes =
+                getGroupedTaskViewSizes(dp, splitBoundsConfig, parentWidth, parentHeight);
 
-        secondarySnapshotWidth = parentWidth;
-        secondarySnapshotHeight = totalThumbnailHeight - primarySnapshotHeight - dividerBar;
         secondarySnapshot.setTranslationY(0);
-        primarySnapshot.setTranslationY(secondarySnapshotHeight + spaceAboveSnapshot + dividerBar);
+        primarySnapshot.setTranslationY(taskViewSizes.second.y + spaceAboveSnapshot + dividerBar);
 
         primarySnapshot.measure(
-                View.MeasureSpec.makeMeasureSpec(primarySnapshotWidth, View.MeasureSpec.EXACTLY),
-                View.MeasureSpec.makeMeasureSpec(primarySnapshotHeight, View.MeasureSpec.EXACTLY)
+                View.MeasureSpec.makeMeasureSpec(taskViewSizes.first.x, View.MeasureSpec.EXACTLY),
+                View.MeasureSpec.makeMeasureSpec(taskViewSizes.first.y, View.MeasureSpec.EXACTLY)
         );
         secondarySnapshot.measure(
-                View.MeasureSpec.makeMeasureSpec(secondarySnapshotWidth, View.MeasureSpec.EXACTLY),
-                View.MeasureSpec.makeMeasureSpec(secondarySnapshotHeight, View.MeasureSpec.EXACTLY)
+                View.MeasureSpec.makeMeasureSpec(taskViewSizes.second.x, View.MeasureSpec.EXACTLY),
+                View.MeasureSpec.makeMeasureSpec(taskViewSizes.second.y, View.MeasureSpec.EXACTLY)
         );
     }
 
+    @Override
+    public Pair<Point, Point> getGroupedTaskViewSizes(
+            DeviceProfile dp,
+            SplitBounds splitBoundsConfig,
+            int parentWidth,
+            int parentHeight) {
+        // Measure and layout the thumbnails bottom up, since the primary is on the visual left
+        // (portrait bottom) and secondary is on the right (portrait top)
+        int spaceAboveSnapshot = dp.overviewTaskThumbnailTopMarginPx;
+        int totalThumbnailHeight = parentHeight - spaceAboveSnapshot;
+        int dividerBar = Math.round(totalThumbnailHeight * (splitBoundsConfig.appsStackedVertically
+                ? splitBoundsConfig.dividerHeightPercent
+                : splitBoundsConfig.dividerWidthPercent));
+        float taskPercent = splitBoundsConfig.appsStackedVertically
+                ? splitBoundsConfig.topTaskPercent
+                : splitBoundsConfig.leftTaskPercent;
+
+        Point firstTaskViewSize = new Point(
+                parentWidth,
+                (int) (totalThumbnailHeight * taskPercent)
+        );
+        Point secondTaskViewSize = new Point(
+                parentWidth,
+                totalThumbnailHeight - firstTaskViewSize.y - dividerBar
+        );
+
+        return new Pair<>(firstTaskViewSize, secondTaskViewSize);
+    }
+
     /* ---------- The following are only used by TaskViewTouchHandler. ---------- */
 
     @Override
diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
index 2ae64ff..66c67e7 100644
--- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
@@ -7,11 +7,14 @@
 import static com.android.quickstep.util.SplitScreenUtils.convertLauncherSplitBoundsToShell;
 
 import android.content.Context;
+import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.util.AttributeSet;
+import android.util.Pair;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.ViewStub;
 
 import androidx.annotation.NonNull;
@@ -37,10 +40,11 @@
 import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
 import com.android.wm.shell.common.split.SplitScreenConstants.PersistentSnapPosition;
 
+import kotlin.Unit;
+
 import java.util.HashMap;
 import java.util.function.Consumer;
 
-import kotlin.Unit;
 
 /**
  * TaskView that contains and shows thumbnails for not one, BUT TWO(!!) tasks
@@ -374,18 +378,7 @@
         }
         if (!enableOverviewIconMenu()) {
             updateIconPlacement();
-            return;
         }
-
-        if (getRecentsView() == null) {
-            return;
-        }
-
-        int iconMargins = getResources().getDimensionPixelSize(
-                R.dimen.task_thumbnail_icon_menu_start_margin) * 2;
-        ((IconAppChipView) mIconView).setMaxWidth(mSnapshotView.getMeasuredWidth() - iconMargins);
-        ((IconAppChipView) mIconView2).setMaxWidth(mSnapshotView2.getMeasuredWidth() - iconMargins);
-        setOrientationState(getRecentsView().getPagedViewOrientedState());
     }
 
     @Override
@@ -395,8 +388,25 @@
 
     @Override
     public void setOrientationState(RecentsOrientedState orientationState) {
-        super.setOrientationState(orientationState);
         DeviceProfile deviceProfile = mActivity.getDeviceProfile();
+        if (enableOverviewIconMenu() && mSplitBoundsConfig != null) {
+            ViewGroup.LayoutParams layoutParams = getLayoutParams();
+            Pair<Point, Point> groupedTaskViewSizes =
+                    orientationState.getOrientationHandler().getGroupedTaskViewSizes(
+                            deviceProfile,
+                            mSplitBoundsConfig,
+                            layoutParams.width,
+                            layoutParams.height
+                    );
+            int iconMargins = getResources().getDimensionPixelSize(
+                    R.dimen.task_thumbnail_icon_menu_start_margin) * 2;
+            ((IconAppChipView) mIconView).setMaxWidth(groupedTaskViewSizes.first.x - iconMargins);
+            ((IconAppChipView) mIconView2).setMaxWidth(groupedTaskViewSizes.second.x - iconMargins);
+        }
+        // setMaxWidth() needs to be called before mIconView.setIconOrientation which is called in
+        // the super below.
+        super.setOrientationState(orientationState);
+
         boolean isGridTask = deviceProfile.isTablet && !isFocusedTask();
         mIconView2.setIconOrientation(orientationState, isGridTask);
         updateIconPlacement();
@@ -412,10 +422,27 @@
         int taskIconHeight = deviceProfile.overviewTaskIconSizePx;
         boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
 
-        getPagedOrientationHandler().setSplitIconParams(mIconView.asView(), mIconView2.asView(),
-                taskIconHeight, mSnapshotView.getMeasuredWidth(), mSnapshotView.getMeasuredHeight(),
-                getMeasuredHeight(), getMeasuredWidth(), isRtl, deviceProfile,
-                mSplitBoundsConfig);
+        if (enableOverviewIconMenu()) {
+            ViewGroup.LayoutParams layoutParams = getLayoutParams();
+            Pair<Point, Point> groupedTaskViewSizes =
+                    getPagedOrientationHandler()
+                            .getGroupedTaskViewSizes(
+                                    deviceProfile,
+                                    mSplitBoundsConfig,
+                                    layoutParams.width,
+                                    layoutParams.height
+                            );
+
+            getPagedOrientationHandler().setSplitIconParams(mIconView.asView(), mIconView2.asView(),
+                    taskIconHeight, groupedTaskViewSizes.first.x, groupedTaskViewSizes.first.y,
+                    getLayoutParams().height, getLayoutParams().width, isRtl, deviceProfile,
+                    mSplitBoundsConfig);
+        } else {
+            getPagedOrientationHandler().setSplitIconParams(mIconView.asView(), mIconView2.asView(),
+                    taskIconHeight, mSnapshotView.getMeasuredWidth(),
+                    mSnapshotView.getMeasuredHeight(), getMeasuredHeight(), getMeasuredWidth(),
+                    isRtl, deviceProfile, mSplitBoundsConfig);
+        }
     }
 
     private void updateSecondaryDwbPlacement() {
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index d10541a..fecbf08 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -1811,9 +1811,7 @@
         mFocusedTaskViewId = newFocusedTaskView != null && !enableGridOnlyOverview()
                 ? newFocusedTaskView.getTaskViewId() : INVALID_TASK_ID;
         updateTaskSize();
-        if (newFocusedTaskView != null) {
-            newFocusedTaskView.setOrientationState(mOrientationState);
-        }
+        updateChildTaskOrientations();
 
         TaskView newRunningTaskView = null;
         if (hasAnyValidTaskIds(runningTaskId)) {
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index b971f67..1b3e3c4 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -1720,12 +1720,11 @@
         int expectedWidth;
         int expectedHeight;
         DeviceProfile deviceProfile = mActivity.getDeviceProfile();
+        final int thumbnailPadding = deviceProfile.overviewTaskThumbnailTopMarginPx;
+        final Rect lastComputedTaskSize = getRecentsView().getLastComputedTaskSize();
+        final int taskWidth = lastComputedTaskSize.width();
+        final int taskHeight = lastComputedTaskSize.height();
         if (deviceProfile.isTablet) {
-            final int thumbnailPadding = deviceProfile.overviewTaskThumbnailTopMarginPx;
-            final Rect lastComputedTaskSize = getRecentsView().getLastComputedTaskSize();
-            final int taskWidth = lastComputedTaskSize.width();
-            final int taskHeight = lastComputedTaskSize.height();
-
             int boxWidth;
             int boxHeight;
             boolean isFocusedTask = isFocusedTask();
@@ -1758,8 +1757,10 @@
         } else {
             nonGridScale = 1f;
             boxTranslationY = 0f;
-            expectedWidth = ViewGroup.LayoutParams.MATCH_PARENT;
-            expectedHeight = ViewGroup.LayoutParams.MATCH_PARENT;
+            expectedWidth = enableOverviewIconMenu() ? taskWidth : LayoutParams.MATCH_PARENT;
+            expectedHeight = enableOverviewIconMenu()
+                    ? taskHeight + thumbnailPadding
+                    : LayoutParams.MATCH_PARENT;
         }
 
         setNonGridScale(nonGridScale);
diff --git a/quickstep/tests/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchControllerTest.kt b/quickstep/tests/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchControllerTest.kt
new file mode 100644
index 0000000..119b862
--- /dev/null
+++ b/quickstep/tests/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchControllerTest.kt
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.uioverrides.touchcontrollers
+
+import android.view.MotionEvent
+import android.view.WindowManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.launcher3.Launcher
+import com.android.launcher3.ui.AbstractLauncherUiTest
+import junit.framework.Assert.assertEquals
+import junit.framework.Assert.assertFalse
+import junit.framework.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class StatusBarTouchControllerTest : AbstractLauncherUiTest() {
+    @Before
+    @Throws(Exception::class)
+    fun setup() {
+        super.setUp()
+        initialize(this)
+    }
+
+    @Test
+    fun interceptActionDown_canIntercept() {
+        executeOnLauncher { launcher ->
+            val underTest = StatusBarTouchController(launcher)
+            assertFalse(underTest.mCanIntercept)
+            val downEvent = MotionEvent.obtain(1, 1, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
+
+            underTest.onControllerInterceptTouchEvent(downEvent)
+
+            assertTrue(underTest.mCanIntercept)
+        }
+    }
+
+    @Test
+    fun interceptVerticalActionMove_handledAndSetSlippery() {
+        executeOnLauncher { launcher ->
+            val underTest = StatusBarTouchController(launcher)
+            val downEvent = MotionEvent.obtain(1, 1, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
+            underTest.onControllerInterceptTouchEvent(downEvent)
+            val w = launcher.window
+            assertEquals(0, w.attributes.flags and WindowManager.LayoutParams.FLAG_SLIPPERY)
+            val moveEvent =
+                MotionEvent.obtain(
+                    2,
+                    2,
+                    MotionEvent.ACTION_MOVE,
+                    underTest.mTouchSlop,
+                    underTest.mTouchSlop + 10,
+                    0
+                )
+
+            val handled = underTest.onControllerInterceptTouchEvent(moveEvent)
+
+            assertTrue(handled)
+            assertEquals(
+                WindowManager.LayoutParams.FLAG_SLIPPERY,
+                w.attributes.flags and WindowManager.LayoutParams.FLAG_SLIPPERY
+            )
+        }
+    }
+
+    @Test
+    fun interceptHorizontalActionMove_not_handled() {
+        executeOnLauncher { launcher ->
+            val underTest = StatusBarTouchController(launcher)
+            val downEvent = MotionEvent.obtain(1, 1, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
+            underTest.onControllerInterceptTouchEvent(downEvent)
+            val moveEvent =
+                MotionEvent.obtain(
+                    2,
+                    2,
+                    MotionEvent.ACTION_MOVE,
+                    underTest.mTouchSlop + 10,
+                    underTest.mTouchSlop,
+                    0
+                )
+
+            val handled = underTest.onControllerInterceptTouchEvent(moveEvent)
+
+            assertFalse(handled)
+        }
+    }
+
+    @Test
+    fun interceptActionMoveAsFirstGestureEvent_notCrashedNorHandled() {
+        executeOnLauncher { launcher ->
+            val underTest = StatusBarTouchController(launcher)
+            underTest.mCanIntercept = true
+            val moveEvent = MotionEvent.obtain(2, 2, MotionEvent.ACTION_MOVE, 10f, 10f, 0)
+
+            val handled = underTest.onControllerInterceptTouchEvent(moveEvent)
+
+            assertFalse(handled)
+        }
+    }
+
+    @Test
+    fun handleActionUp_setNotSlippery() {
+        executeOnLauncher { launcher: Launcher ->
+            val underTest = StatusBarTouchController(launcher)
+            underTest.mCanIntercept = true
+            underTest.setWindowSlippery(true)
+            val moveEvent = MotionEvent.obtain(2, 2, MotionEvent.ACTION_UP, 10f, 10f, 0)
+
+            val handled = underTest.onControllerTouchEvent(moveEvent)
+
+            assertTrue(handled)
+            assertEquals(
+                0,
+                launcher.window.attributes.flags and WindowManager.LayoutParams.FLAG_SLIPPERY
+            )
+        }
+    }
+
+    @Test
+    fun handleActionCancel_setNotSlippery() {
+        executeOnLauncher { launcher ->
+            val underTest = StatusBarTouchController(launcher)
+            underTest.mCanIntercept = true
+            underTest.setWindowSlippery(true)
+            val moveEvent = MotionEvent.obtain(2, 2, MotionEvent.ACTION_CANCEL, 10f, 10f, 0)
+
+            val handled = underTest.onControllerTouchEvent(moveEvent)
+
+            assertTrue(handled)
+            assertEquals(
+                0,
+                launcher.window.attributes.flags and WindowManager.LayoutParams.FLAG_SLIPPERY
+            )
+        }
+    }
+}
diff --git a/quickstep/tests/src/com/android/quickstep/TaplOverviewIconTest.java b/quickstep/tests/src/com/android/quickstep/TaplOverviewIconTest.java
index 3f806d1..7c1b7f3 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplOverviewIconTest.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplOverviewIconTest.java
@@ -15,7 +15,6 @@
  */
 package com.android.quickstep;
 
-import static com.android.launcher3.ui.AbstractLauncherUiTest.initialize;
 import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL;
 import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT;
 
@@ -25,6 +24,7 @@
 import android.content.Intent;
 import android.platform.test.annotations.PlatinumTest;
 
+import com.android.launcher3.tapl.OverviewTask.OverviewSplitTask;
 import com.android.launcher3.tapl.OverviewTaskMenu;
 import com.android.launcher3.ui.AbstractLauncherUiTest;
 import com.android.launcher3.util.rule.TestStabilityRule;
@@ -86,7 +86,8 @@
         taskMenu.touchOutsideTaskMenuToDismiss();
 
         OverviewTaskMenu splitMenu =
-                mLauncher.goHome().switchToOverview().getCurrentTask().tapSplitTaskMenu();
+                mLauncher.goHome().switchToOverview().getCurrentTask().tapMenu(
+                        OverviewSplitTask.SPLIT_BOTTOM_OR_RIGHT);
         assertTrue("App info item not appearing in expanded split task's menu.",
                 splitMenu.hasMenuItem("App info"));
         splitMenu.touchOutsideTaskMenuToDismiss();
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsKeyboardQuickSwitch.java b/quickstep/tests/src/com/android/quickstep/TaplTestsKeyboardQuickSwitch.java
index 36c591e..a050464 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsKeyboardQuickSwitch.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsKeyboardQuickSwitch.java
@@ -22,6 +22,8 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.launcher3.tapl.KeyboardQuickSwitch;
+import com.android.launcher3.tapl.LaunchedAppState;
+import com.android.launcher3.tapl.Taskbar;
 import com.android.launcher3.taskbar.KeyboardQuickSwitchController;
 import com.android.launcher3.ui.AbstractLauncherUiTest;
 
@@ -36,6 +38,7 @@
     private enum TestSurface {
         HOME(true),
         LAUNCHED_APP(false),
+        TASKBAR_ALL_APPS(false),
         HOME_ALL_APPS(true),
         WIDGETS(true);
 
@@ -82,6 +85,11 @@
     }
 
     @Test
+    public void testDismiss_fromTaskbarAllApps() {
+        runTest(TestSurface.TASKBAR_ALL_APPS, TestCase.DISMISS);
+    }
+
+    @Test
     public void testDismiss_fromHomeAllApps() {
         runTest(TestSurface.HOME_ALL_APPS, TestCase.DISMISS);
     }
@@ -102,6 +110,11 @@
     }
 
     @Test
+    public void testLaunchLastTask_fromTaskbarAllApps() {
+        runTest(TestSurface.TASKBAR_ALL_APPS, TestCase.LAUNCH_LAST_APP);
+    }
+
+    @Test
     public void testLaunchLastTask_fromHomeAllApps() {
         runTest(TestSurface.HOME_ALL_APPS, TestCase.LAUNCH_LAST_APP);
     }
@@ -122,6 +135,11 @@
     }
 
     @Test
+    public void testLaunchSelectedTask_fromTaskbarAllApps() {
+        runTest(TestSurface.TASKBAR_ALL_APPS, TestCase.LAUNCH_SELECTED_APP);
+    }
+
+    @Test
     public void testLaunchSelectedTask_fromHomeAllApps() {
         runTest(TestSurface.HOME_ALL_APPS, TestCase.LAUNCH_SELECTED_APP);
     }
@@ -142,6 +160,11 @@
     }
 
     @Test
+    public void testLaunchOverviewTask_fromTaskbarAllApps() {
+        runTest(TestSurface.TASKBAR_ALL_APPS, TestCase.LAUNCH_OVERVIEW);
+    }
+
+    @Test
     public void testLaunchOverviewTask_fromHomeAllApps() {
         runTest(TestSurface.HOME_ALL_APPS, TestCase.LAUNCH_OVERVIEW);
     }
@@ -165,6 +188,12 @@
                 mLauncher.setIgnoreTaskbarVisibility(true);
                 kqs = mLauncher.getLaunchedAppState().showQuickSwitchView();
                 break;
+            case TASKBAR_ALL_APPS:
+                LaunchedAppState launchedApp = mLauncher.getLaunchedAppState();
+                Taskbar taskbar = mLauncher.isTransientTaskbar()
+                        ? launchedApp.swipeUpToUnstashTaskbar() : launchedApp.getTaskbar();
+                kqs = taskbar.openAllApps().showQuickSwitchView();
+                break;
             case HOME_ALL_APPS:
                 kqs = mLauncher.goHome().switchToAllApps().showQuickSwitchView();
                 break;
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java b/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
index 1e33635..c472ef2 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
@@ -16,6 +16,7 @@
 package com.android.quickstep;
 
 
+import static com.android.launcher3.config.FeatureFlags.enableSplitContextually;
 import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL;
 import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT;
 
@@ -40,6 +41,7 @@
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -103,10 +105,18 @@
                 .getSplitScreenMenuItem()
                 .click();
 
-        mLauncher.getLaunchedAppState()
-                .getTaskbar()
-                .getAppIcon(CALCULATOR_APP_NAME)
-                .launchIntoSplitScreen();
+        if (enableSplitContextually()) {
+            // We're staying in all apps, use same instance
+            mLauncher.getAllApps()
+                    .getAppIcon(CALCULATOR_APP_NAME)
+                    .launch(CALCULATOR_APP_PACKAGE);
+        } else {
+            // We're in overview, use taskbar instance
+            mLauncher.getLaunchedAppState()
+                    .getTaskbar()
+                    .getAppIcon(CALCULATOR_APP_NAME)
+                    .launchIntoSplitScreen();
+        }
     }
 
     @Test
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 798b238..496cb4e 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -411,8 +411,6 @@
     private final SettingsCache.OnChangeListener mNaturalScrollingChangedListener =
             enabled -> mIsNaturalScrollingEnabled = enabled;
 
-    private int mActivityStopCount; // Used only by tests
-
     public static Launcher getLauncher(Context context) {
         return fromContext(context);
     }
@@ -1054,18 +1052,10 @@
         mAppWidgetHolder.setActivityStarted(false);
         NotificationListener.removeNotificationsChangedListener(getPopupDataProvider());
         FloatingIconView.resetIconLoadResult();
-        ++mActivityStopCount;
         AccessibilityManagerCompat.sendTestProtocolEventToTest(
                 this, LAUNCHER_ACTIVITY_STOPPED_MESSAGE);
     }
 
-    /** Return activity stop count and reset it. Used only by tests. */
-    public int getAndResetActivityStopCount() {
-        final int activityStopCount = mActivityStopCount;
-        mActivityStopCount = 0;
-        return activityStopCount;
-    }
-
     @Override
     protected void onStart() {
         TraceHelper.INSTANCE.beginSection(ON_START_EVT);
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 1b2cebd..c3cbd2b 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -34,6 +34,7 @@
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
 import android.content.pm.LauncherApps;
+import android.content.pm.LauncherApps.ArchiveCompatibilityParams;
 import android.os.UserHandle;
 import android.util.Log;
 
@@ -109,8 +110,9 @@
         mOnTerminateCallback.add(() ->
                 mContext.getSystemService(LauncherApps.class).unregisterCallback(callbacks));
         if (Flags.enableSupportForArchiving()) {
-            launcherApps.setArchiveCompatibilityOptions(/* enableIconOverlay= */ true,
-                    /* enableUnarchivalConfirmation= */ false);
+            ArchiveCompatibilityParams params = new ArchiveCompatibilityParams();
+            params.setEnableUnarchivalConfirmation(false);
+            launcherApps.setArchiveCompatibility(params);
         }
 
         SimpleBroadcastReceiver modelChangeReceiver =
diff --git a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
index e65e614..a846e68 100644
--- a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
@@ -415,6 +415,8 @@
                         screenId, coordinates[0], coordinates[1]);
                 bindItem(info, accessibility);
             } else if (item instanceof FolderInfo fi) {
+                Workspace<?> workspace = mContext.getWorkspace();
+                workspace.snapToPage(workspace.getPageIndexForScreenId(screenId));
                 mContext.getModelWriter().addItemToDatabase(fi,
                         LauncherSettings.Favorites.CONTAINER_DESKTOP, screenId, coordinates[0],
                         coordinates[1]);
diff --git a/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewController.java b/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewController.java
index bc55597..fcdfaa6 100644
--- a/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewController.java
+++ b/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewController.java
@@ -55,6 +55,9 @@
         assert quietModeButton != null;
         addQuietModeButton(quietModeButton);
 
+        //Trigger lock/unlock action from header.
+        addHeaderOnClickListener(parent);
+
         //Add image and action for private space settings button
         ImageButton settingsButton = parent.findViewById(R.id.ps_settings_button);
         assert settingsButton != null;
@@ -71,26 +74,35 @@
             case STATE_ENABLED -> {
                 quietModeButton.setVisibility(View.VISIBLE);
                 quietModeButton.setImageResource(R.drawable.bg_ps_lock_button);
-                quietModeButton.setOnClickListener(
-                        view -> {
-                            mPrivateProfileManager.logEvents(LAUNCHER_PRIVATE_SPACE_LOCK_TAP);
-                            mPrivateProfileManager.lockPrivateProfile();
-                        });
+                quietModeButton.setOnClickListener(view -> lockAction());
             }
             case STATE_DISABLED -> {
                 quietModeButton.setVisibility(View.VISIBLE);
                 quietModeButton.setImageResource(R.drawable.bg_ps_unlock_button);
-                quietModeButton.setOnClickListener(
-                        view -> {
-                            mPrivateProfileManager.logEvents(LAUNCHER_PRIVATE_SPACE_UNLOCK_TAP);
-                            mPrivateProfileManager.unlockPrivateProfile((this::
-                                    onPrivateProfileUnlocked));
-                        });
+                quietModeButton.setOnClickListener(view -> unLockAction());
             }
             default -> quietModeButton.setVisibility(View.GONE);
         }
     }
 
+    private void addHeaderOnClickListener(RelativeLayout header) {
+        if (mPrivateProfileManager.getCurrentState() == STATE_DISABLED) {
+            header.setOnClickListener(view -> unLockAction());
+        } else {
+            header.setOnClickListener(null);
+        }
+    }
+
+    private void unLockAction() {
+        mPrivateProfileManager.logEvents(LAUNCHER_PRIVATE_SPACE_UNLOCK_TAP);
+        mPrivateProfileManager.unlockPrivateProfile((this::onPrivateProfileUnlocked));
+    }
+
+    private void lockAction() {
+        mPrivateProfileManager.logEvents(LAUNCHER_PRIVATE_SPACE_LOCK_TAP);
+        mPrivateProfileManager.lockPrivateProfile();
+    }
+
     private void addPrivateSpaceSettingsButton(ImageButton settingsButton) {
         if (mPrivateProfileManager.getCurrentState() == STATE_ENABLED
                 && mPrivateProfileManager.isPrivateSpaceSettingsAvailable()) {
diff --git a/src/com/android/launcher3/testing/TestInformationHandler.java b/src/com/android/launcher3/testing/TestInformationHandler.java
index 27a153b..5636405 100644
--- a/src/com/android/launcher3/testing/TestInformationHandler.java
+++ b/src/com/android/launcher3/testing/TestInformationHandler.java
@@ -214,16 +214,6 @@
                                 .forceAllowRotationForTesting(Boolean.parseBoolean(arg)));
                 return response;
 
-            case TestProtocol.REQUEST_GET_AND_RESET_ACTIVITY_STOP_COUNT: {
-                final Bundle bundle = getLauncherUIProperty(Bundle::putInt,
-                        launcher -> launcher.getAndResetActivityStopCount());
-                if (bundle != null) return bundle;
-
-                // If Launcher activity wasn't created, 'it' was stopped 0 times.
-                response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, 0);
-                return response;
-            }
-
             case TestProtocol.REQUEST_WORKSPACE_CELL_LAYOUT_SIZE:
                 return getLauncherUIProperty(Bundle::putIntArray, launcher -> {
                     final Workspace<?> workspace = launcher.getWorkspace();
diff --git a/tests/multivalentTests/shared/com/android/launcher3/testing/shared/TestProtocol.java b/tests/multivalentTests/shared/com/android/launcher3/testing/shared/TestProtocol.java
index 187daca..2f9945d 100644
--- a/tests/multivalentTests/shared/com/android/launcher3/testing/shared/TestProtocol.java
+++ b/tests/multivalentTests/shared/com/android/launcher3/testing/shared/TestProtocol.java
@@ -178,9 +178,6 @@
     public static final String REQUEST_UNSTASH_BUBBLE_BAR_IF_STASHED =
             "unstash-bubble-bar-if-stashed";
 
-    public static final String REQUEST_GET_AND_RESET_ACTIVITY_STOP_COUNT =
-            "get-and-reset-activity-stops";
-
     /** Logs {@link Log#d(String, String)} if {@link #sDebugTracing} is true. */
     public static void testLogD(String tag, String message) {
         if (!sDebugTracing) {
diff --git a/tests/multivalentTests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/multivalentTests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index dcf56f8..f0d2e20 100644
--- a/tests/multivalentTests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/multivalentTests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -599,9 +599,6 @@
         Wait.atMost("Launcher activity didn't stop",
                 () -> !launcherInstrumentation.isLauncherActivityStarted(),
                 DEFAULT_ACTIVITY_TIMEOUT, launcherInstrumentation);
-
-        // Reset activity stop count.
-        launcherInstrumentation.getAndResetActivityStopCount();
     }
 
     public static ActivityInfo resolveSystemAppInfo(String category) {
diff --git a/tests/multivalentTests/src/com/android/launcher3/util/rule/TestIsolationRule.java b/tests/multivalentTests/src/com/android/launcher3/util/rule/TestIsolationRule.java
index e98dcf4..2b45902 100644
--- a/tests/multivalentTests/src/com/android/launcher3/util/rule/TestIsolationRule.java
+++ b/tests/multivalentTests/src/com/android/launcher3/util/rule/TestIsolationRule.java
@@ -44,15 +44,11 @@
         return new Statement() {
             @Override
             public void evaluate() throws Throwable {
-                // Reset activity stop count.
-                mLauncher.getAndResetActivityStopCount();
-
                 base.evaluate();
-
                 // Make sure that Launcher workspace looks correct.
+
                 UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()).pressHome();
                 AbstractLauncherUiTest.checkDetectedLeaks(mLauncher, mRequireOneActiveActivity);
-                mLauncher.assertNoUnexpectedStops();
             }
         };
     }
diff --git a/tests/multivalentTests/tapl/com/android/launcher3/tapl/Background.java b/tests/multivalentTests/tapl/com/android/launcher3/tapl/Background.java
index 9f2ce22..988aa94 100644
--- a/tests/multivalentTests/tapl/com/android/launcher3/tapl/Background.java
+++ b/tests/multivalentTests/tapl/com/android/launcher3/tapl/Background.java
@@ -16,6 +16,7 @@
 
 package com.android.launcher3.tapl;
 
+import static com.android.launcher3.tapl.BaseOverview.TASK_RES_ID;
 import static com.android.launcher3.tapl.OverviewTask.TASK_START_EVENT;
 import static com.android.launcher3.testing.shared.TestProtocol.OVERVIEW_STATE_ORDINAL;
 
@@ -116,10 +117,10 @@
                         // non-tablet overview, snapshots can be on either side of the swiped
                         // task, but we still check that they become visible after swiping and
                         // pausing.
-                        mLauncher.waitForOverviewObject("snapshot");
+                        mLauncher.waitForOverviewObject(TASK_RES_ID);
                         if (mLauncher.isTablet()) {
                             List<UiObject2> tasks = mLauncher.getDevice().findObjects(
-                                    mLauncher.getOverviewObjectSelector("snapshot"));
+                                    mLauncher.getOverviewObjectSelector(TASK_RES_ID));
                             final int centerX = mLauncher.getDevice().getDisplayWidth() / 2;
                             mLauncher.assertTrue(
                                     "All tasks not to the left of the swiped task",
diff --git a/tests/multivalentTests/tapl/com/android/launcher3/tapl/BaseOverview.java b/tests/multivalentTests/tapl/com/android/launcher3/tapl/BaseOverview.java
index d337b91..ad95ecf 100644
--- a/tests/multivalentTests/tapl/com/android/launcher3/tapl/BaseOverview.java
+++ b/tests/multivalentTests/tapl/com/android/launcher3/tapl/BaseOverview.java
@@ -44,6 +44,7 @@
  * Common overview panel for both Launcher and fallback recents
  */
 public class BaseOverview extends LauncherInstrumentation.VisibleContainer {
+    protected static final String TASK_RES_ID = "task";
 
     private static final Pattern EVENT_ALT_ESC_DOWN = Pattern.compile(
             "Key event: KeyEvent.*?action=ACTION_DOWN.*?keyCode=KEYCODE_ESCAPE.*?metaState=0");
@@ -281,10 +282,10 @@
 
         // The widest, and most top-right task should be the current task
         UiObject2 currentTask = Collections.max(taskViews,
-                Comparator.comparingInt((UiObject2 t) -> t.getParent().getVisibleBounds().width())
-                        .thenComparingInt((UiObject2 t) -> t.getParent().getVisibleCenter().x)
+                Comparator.comparingInt((UiObject2 t) -> t.getVisibleBounds().width())
+                        .thenComparingInt((UiObject2 t) -> t.getVisibleCenter().x)
                         .thenComparing(Comparator.comparing(
-                                (UiObject2 t) -> t.getParent().getVisibleCenter().y).reversed()));
+                                (UiObject2 t) -> t.getVisibleCenter().y).reversed()));
         return new OverviewTask(mLauncher, currentTask, this);
     }
 
@@ -329,10 +330,11 @@
                 "want to get overview tasks")) {
             verifyActiveContainer();
             return mLauncher.getDevice().findObjects(
-                    mLauncher.getOverviewObjectSelector("snapshot"));
+                    mLauncher.getOverviewObjectSelector(TASK_RES_ID));
         }
     }
 
+
     int getTaskCount() {
         return getTasks().size();
     }
diff --git a/tests/multivalentTests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/multivalentTests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 90ca990..6c9f5ed 100644
--- a/tests/multivalentTests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/multivalentTests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -207,7 +207,6 @@
 
     private TrackpadGestureType mTrackpadGestureType = TrackpadGestureType.NONE;
     private int mPointerCount = 0;
-    private final boolean mIsLauncherTest;
 
     private static Pattern getKeyEventPattern(String action, String keyCode) {
         return Pattern.compile("Key event: KeyEvent.*action=" + action + ".*keyCode=" + keyCode);
@@ -244,7 +243,6 @@
      */
     @Deprecated
     public LauncherInstrumentation(Instrumentation instrumentation, boolean isLauncherTest) {
-        mIsLauncherTest = isLauncherTest;
         mInstrumentation = instrumentation;
         mDevice = UiDevice.getInstance(instrumentation);
 
@@ -417,11 +415,6 @@
                 TestProtocol.TEST_INFO_RESPONSE_FIELD);
     }
 
-    public int getAndResetActivityStopCount() {
-        return getTestInfo(TestProtocol.REQUEST_GET_AND_RESET_ACTIVITY_STOP_COUNT).getInt(
-                TestProtocol.TEST_INFO_RESPONSE_FIELD);
-    }
-
     Rect getGridTaskRectForTablet() {
         return ((Rect) getTestInfo(TestProtocol.REQUEST_GET_GRID_TASK_SIZE_RECT_FOR_TABLET)
                 .getParcelable(TestProtocol.TEST_INFO_RESPONSE_FIELD));
@@ -635,19 +628,10 @@
 
     public void onTestStart() {
         mTestStartTime = System.currentTimeMillis();
-        assertNoUnexpectedStops();
     }
 
     public void onTestFinish() {
         mTestStartTime = -1;
-        assertNoUnexpectedStops();
-    }
-
-    /** Verify that the activity stop count is zero. */
-    public void assertNoUnexpectedStops() {
-        if (mIsLauncherTest) {
-            assertEquals("Unexpected activity stops", 0, getAndResetActivityStopCount());
-        }
     }
 
     private String formatSystemHealthMessage(String message) {
@@ -1021,9 +1005,6 @@
                 event -> TestProtocol.LAUNCHER_ACTIVITY_STOPPED_MESSAGE
                         .equals(event.getClassName().toString()),
                 () -> "Launcher activity didn't stop", actionName);
-
-        // Reset activity stop count.
-        getAndResetActivityStopCount();
     }
 
     /**
@@ -2276,7 +2257,6 @@
     }
 
     public Closable eventsCheck() {
-        assertNoUnexpectedStops();
         Assert.assertTrue("Nested event checking", mEventChecker == null);
         disableSensorRotation();
         final Integer initialPid = getPid();
@@ -2284,7 +2264,6 @@
         if (eventChecker.start()) mEventChecker = eventChecker;
 
         return () -> {
-            assertNoUnexpectedStops();
             if (initialPid != null && initialPid.intValue() != getPid()) {
                 if (mOnLauncherCrashed != null) mOnLauncherCrashed.run();
                 checkForAnomaly();
diff --git a/tests/multivalentTests/tapl/com/android/launcher3/tapl/OverviewTask.java b/tests/multivalentTests/tapl/com/android/launcher3/tapl/OverviewTask.java
index f383e99..afe5722 100644
--- a/tests/multivalentTests/tapl/com/android/launcher3/tapl/OverviewTask.java
+++ b/tests/multivalentTests/tapl/com/android/launcher3/tapl/OverviewTask.java
@@ -16,6 +16,10 @@
 
 package com.android.launcher3.tapl;
 
+import static com.android.launcher3.tapl.OverviewTask.OverviewSplitTask.DEFAULT;
+import static com.android.launcher3.tapl.OverviewTask.OverviewSplitTask.SPLIT_BOTTOM_OR_RIGHT;
+import static com.android.launcher3.tapl.OverviewTask.OverviewSplitTask.SPLIT_TOP_OR_LEFT;
+
 import android.graphics.Rect;
 
 import androidx.annotation.NonNull;
@@ -34,9 +38,6 @@
  */
 public final class OverviewTask {
     private static final String SYSTEMUI_PACKAGE = "com.android.systemui";
-    private static final String TASK_SNAPSHOT_1 = "snapshot";
-    private static final String TASK_SNAPSHOT_2 = "bottomright_snapshot";
-
     static final Pattern TASK_START_EVENT = Pattern.compile("startActivityFromRecentsAsync");
     static final Pattern SPLIT_SELECT_EVENT = Pattern.compile("enterSplitSelect");
     static final Pattern SPLIT_START_EVENT = Pattern.compile("launchSplitTasks");
@@ -64,15 +65,16 @@
             return getCombinedSplitTaskHeight();
         }
 
-        return mTask.getVisibleBounds().height();
+        UiObject2 taskSnapshot1 = findObjectInTask(DEFAULT.snapshotRes);
+        return taskSnapshot1.getVisibleBounds().height();
     }
 
     /**
      * Calculates the visible height for split tasks, containing 2 snapshot tiles and a divider.
      */
     private int getCombinedSplitTaskHeight() {
-        UiObject2 taskSnapshot1 = findObjectInTask(TASK_SNAPSHOT_1);
-        UiObject2 taskSnapshot2 = findObjectInTask(TASK_SNAPSHOT_2);
+        UiObject2 taskSnapshot1 = findObjectInTask(SPLIT_TOP_OR_LEFT.snapshotRes);
+        UiObject2 taskSnapshot2 = findObjectInTask(SPLIT_BOTTOM_OR_RIGHT.snapshotRes);
 
         // If the split task is partly off screen, taskSnapshot1 can be invisible.
         if (taskSnapshot1 == null) {
@@ -96,15 +98,16 @@
             return getCombinedSplitTaskWidth();
         }
 
-        return mTask.getVisibleBounds().width();
+        UiObject2 taskSnapshot1 = findObjectInTask(DEFAULT.snapshotRes);
+        return taskSnapshot1.getVisibleBounds().width();
     }
 
     /**
      * Calculates the visible width for split tasks, containing 2 snapshot tiles and a divider.
      */
     private int getCombinedSplitTaskWidth() {
-        UiObject2 taskSnapshot1 = findObjectInTask(TASK_SNAPSHOT_1);
-        UiObject2 taskSnapshot2 = findObjectInTask(TASK_SNAPSHOT_2);
+        UiObject2 taskSnapshot1 = findObjectInTask(SPLIT_TOP_OR_LEFT.snapshotRes);
+        UiObject2 taskSnapshot2 = findObjectInTask(SPLIT_BOTTOM_OR_RIGHT.snapshotRes);
 
         int left = Math.min(
                 taskSnapshot1.getVisibleBounds().left, taskSnapshot2.getVisibleBounds().left);
@@ -115,15 +118,15 @@
     }
 
     int getTaskCenterX() {
-        return mTask.getParent().getVisibleCenter().x;
+        return mTask.getVisibleCenter().x;
     }
 
     int getTaskCenterY() {
-        return mTask.getParent().getVisibleCenter().y;
+        return mTask.getVisibleCenter().y;
     }
 
     float getExactCenterX() {
-        return mTask.getParent().getVisibleBounds().exactCenterX();
+        return mTask.getVisibleBounds().exactCenterX();
     }
 
     UiObject2 getUiObject() {
@@ -225,11 +228,17 @@
     /** Taps the task menu. Returns the task menu object. */
     @NonNull
     public OverviewTaskMenu tapMenu() {
+        return tapMenu(DEFAULT);
+    }
+
+    /** Taps the task menu of the split task. Returns the split task's menu object. */
+    @NonNull
+    public OverviewTaskMenu tapMenu(OverviewSplitTask task) {
         try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
              LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
                      "want to tap the task menu")) {
             mLauncher.clickLauncherObject(
-                    mLauncher.waitForObjectInContainer(mTask.getParent(), "icon"));
+                    mLauncher.waitForObjectInContainer(mTask, task.iconAppRes));
 
             try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
                     "tapped the task menu")) {
@@ -238,27 +247,31 @@
         }
     }
 
-    /** Taps the task menu of the split task. Returns the split task's menu object. */
-    @NonNull
-    public OverviewTaskMenu tapSplitTaskMenu() {
-        try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
-             LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
-                     "want to tap the split task's menu")) {
-            mLauncher.clickLauncherObject(
-                    mLauncher.waitForObjectInContainer(mTask.getParent(), "bottomRight_icon"));
-
-            try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
-                    "tapped the split task's menu")) {
-                return new OverviewTaskMenu(mLauncher);
-            }
-        }
-    }
-
     boolean isTaskSplit() {
-        return findObjectInTask(TASK_SNAPSHOT_2) != null;
+        return findObjectInTask(SPLIT_BOTTOM_OR_RIGHT.snapshotRes) != null;
     }
 
     private UiObject2 findObjectInTask(String resName) {
-        return mTask.getParent().findObject(mLauncher.getOverviewObjectSelector(resName));
+        return mTask.findObject(mLauncher.getOverviewObjectSelector(resName));
+    }
+
+    /**
+     * Enum used to specify  which task is retrieved when it is a split task.
+     */
+    public enum OverviewSplitTask {
+        // The main task when the task is not split.
+        DEFAULT("snapshot", "icon"),
+        // The first task in split task.
+        SPLIT_TOP_OR_LEFT("snapshot", "icon"),
+        // The second task in split task.
+        SPLIT_BOTTOM_OR_RIGHT("bottomright_snapshot", "bottomRight_icon");
+
+        public final String snapshotRes;
+        public final String iconAppRes;
+
+        OverviewSplitTask(String snapshotRes, String iconAppRes) {
+            this.snapshotRes = snapshotRes;
+            this.iconAppRes = iconAppRes;
+        }
     }
 }