Merge "Fix NPE of TopTaskTracker" into tm-qpr-dev
diff --git a/protos/launcher_atom.proto b/protos/launcher_atom.proto
index 02460e4..b1064f7 100644
--- a/protos/launcher_atom.proto
+++ b/protos/launcher_atom.proto
@@ -128,6 +128,11 @@
 
   // Bit encoded value to capture pinned and predicted taskbar positions.
   optional int32 cardinality = 2;
+
+  // Container where taskbar was invoked.
+  oneof ParentContainer {
+    TaskSwitcherContainer task_switcher_container = 3;
+  }
 }
 
 // Next value 44
diff --git a/quickstep/res/drawable/ic_desktop.xml b/quickstep/res/drawable/ic_desktop.xml
index dfaf8b8..8de275d 100644
--- a/quickstep/res/drawable/ic_desktop.xml
+++ b/quickstep/res/drawable/ic_desktop.xml
@@ -25,7 +25,7 @@
         android:translateX="6.0"
         android:translateY="6.0">
         <path
-            android:fillColor="?android:attr/textColorPrimary"
+            android:fillColor="@android:color/black"
             android:pathData="M5.958,37.708Q4.458,37.708 3.354,36.604Q2.25,35.5 2.25,34V18.292Q2.25,16.792 3.354,15.688Q4.458,14.583 5.958,14.583H9.5V5.958Q9.5,4.458 10.625,3.354Q11.75,2.25 13.208,2.25H34Q35.542,2.25 36.646,3.354Q37.75,4.458 37.75,5.958V21.667Q37.75,23.167 36.646,24.271Q35.542,25.375 34,25.375H30.5V34Q30.5,35.5 29.396,36.604Q28.292,37.708 26.792,37.708ZM5.958,34H26.792Q26.792,34 26.792,34Q26.792,34 26.792,34V21.542H5.958V34Q5.958,34 5.958,34Q5.958,34 5.958,34ZM30.5,21.667H34Q34,21.667 34,21.667Q34,21.667 34,21.667V9.208H13.208V14.583H26.833Q28.375,14.583 29.438,15.667Q30.5,16.75 30.5,18.25Z"/>
     </group>
 </vector>
diff --git a/quickstep/res/drawable/ic_empty_desktop.xml b/quickstep/res/drawable/ic_empty_desktop.xml
deleted file mode 100644
index cbf1856..0000000
--- a/quickstep/res/drawable/ic_empty_desktop.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
-  ~ Copyright (C) 2023 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.
-  -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="92dp"
-    android:height="80dp"
-    android:tint="?android:attr/textColorPrimary"
-    android:viewportHeight="80.0"
-    android:viewportWidth="92.0">
-    <path
-        android:fillColor="#AAFFFFFF"
-        android:pathData="M 14.365954,80 Q 10.981668,80 8.4908345,77.509166 6,75.018332 6,71.634046 V 36.193807 q 0,-3.384286 2.4908345,-5.87512 2.4908335,-2.493091 5.8751195,-2.493091 H 22.35738 V 8.365954 q 0,-3.3842855 2.538217,-5.8751198 Q 27.433811,0 30.723337,0 h 46.910711 q 3.479041,0 5.969878,2.4908342 2.490834,2.4908343 2.490834,5.8751198 v 35.442495 q 0,3.384286 -2.490834,5.87512 -2.490837,2.490835 -5.969878,2.490835 h -7.896671 v 19.459642 q 0,3.384286 -2.49083,5.87512 Q 64.755713,80 61.371423,80 Z m 0,-8.365954 h 47.005469 q 0,0 0,0 0,0 0,0 V 43.526426 H 14.365954 v 28.10762 q 0,0 0,0 0,0 0,0 z M 69.737377,43.808449 h 7.896671 q 0,0 0,0 0,0 0,0 V 15.698573 H 30.723337 v 12.127023 h 30.740592 q 3.479048,0 5.877376,2.445711 2.396072,2.443454 2.396072,5.82774 z" />
-</vector>
diff --git a/quickstep/res/layout/task_desktop.xml b/quickstep/res/layout/task_desktop.xml
index f454835..2ec9d4c 100644
--- a/quickstep/res/layout/task_desktop.xml
+++ b/quickstep/res/layout/task_desktop.xml
@@ -32,19 +32,6 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent" />
 
-    <TextView
-        android:id="@+id/empty_view"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:layout_marginTop="@dimen/overview_task_margin"
-        android:drawablePadding="@dimen/recents_empty_message_text_padding"
-        android:text="@string/recents_empty_desktop_message"
-        android:textColor="?android:textColorPrimary"
-        android:textSize="@dimen/recents_empty_message_text_size"
-        android:drawableTop="@drawable/ic_empty_desktop"
-        android:drawableTint="?android:attr/textColorPrimary" />
-
     <!--
          TODO(b249371338): DesktopTaskView extends from TaskView. TaskView expects TaskThumbnailView
          and IconView with these ids to be present. Need to refactor RecentsView to accept child
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index 2b5975d..eb5fed2 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -30,9 +30,6 @@
     <!-- Recents: The empty recents string. [CHAR LIMIT=NONE] -->
     <string name="recents_empty_message">No recent items</string>
 
-    <!-- Recents: The empty recents desktop tile string. [CHAR LIMIT=NONE] -->
-    <string name="recents_empty_desktop_message">No desktop items</string>
-
     <!-- Content description for the recent apps's accessibility option that opens its usage settings. [CHAR LIMIT=NONE] -->
     <string name="accessibility_app_usage_settings">App usage settings</string>
 
@@ -278,6 +275,10 @@
     <string name="taskbar_button_quick_settings">Quick Settings</string>
     <!-- Accessibility title for the Taskbar window. [CHAR_LIMIT=NONE] -->
     <string name="taskbar_a11y_title">Taskbar</string>
+    <!-- Accessibility title for the Taskbar window appeared. [CHAR_LIMIT=NONE] -->
+    <string name="taskbar_a11y_shown_title">Taskbar shown</string>
+    <!-- Accessibility title for the Taskbar window being close. [CHAR_LIMIT=NONE] -->
+    <string name="taskbar_a11y_hidden_title">Taskbar hidden</string>
     <!-- Accessibility title for the Taskbar window on phones. [CHAR_LIMIT=NONE] -->
     <string name="taskbar_phone_a11y_title">Navigation bar</string>
 
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index 5ddf2a8..ea7eba3 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -634,7 +634,10 @@
         boolean appTargetsAreTranslucent = areAllTargetsTranslucent(appTargets);
 
         RectF launcherIconBounds = new RectF();
-        FloatingIconView floatingView = FloatingIconView.getFloatingIconView(mLauncher, v,
+        FloatingIconView floatingView = getFloatingIconView(mLauncher, v,
+                mLauncher.getTaskbarUIController() == null
+                        ? null
+                        : mLauncher.getTaskbarUIController().findMatchingView(v),
                 !appTargetsAreTranslucent, launcherIconBounds, true /* isOpening */);
         Rect crop = new Rect();
         Matrix matrix = new Matrix();
@@ -1350,6 +1353,9 @@
                     isTransluscent, fallbackBackgroundColor);
         } else if (launcherView != null) {
             floatingIconView = getFloatingIconView(mLauncher, launcherView,
+                    mLauncher.getTaskbarUIController() == null
+                            ? null
+                            : mLauncher.getTaskbarUIController().findMatchingView(launcherView),
                     true /* hideOriginal */, targetRect, false /* isOpening */);
         } else {
             targetRect.set(getDefaultWindowTargetRect());
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index 793c68e..95fea3e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -341,6 +341,11 @@
     }
 
     @Override
+    protected boolean isInOverview() {
+        return mTaskbarLauncherStateController.isInOverview();
+    }
+
+    @Override
     public RecentsView getRecentsView() {
         return mLauncher.getOverviewPanel();
     }
diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
index bafd5b4..84bf02e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
@@ -288,14 +288,9 @@
             updateButtonLayoutSpacing();
             updateStateForFlag(FLAG_SMALL_SCREEN, isPhoneButtonNavMode(mContext));
 
-            // Animate taskbar background when either..
-            // notification shade expanded AND not on keyguard
-            // back is visible for bouncer
             mPropertyHolders.add(new StatePropertyHolder(
                     mControllers.taskbarDragLayerController.getNavbarBackgroundAlpha(),
-                    flags -> ((flags & FLAG_NOTIFICATION_SHADE_EXPANDED) != 0
-                                && (flags & FLAG_KEYGUARD_VISIBLE) == 0)
-                            || (flags & FLAG_ONLY_BACK_FOR_BOUNCER_VISIBLE) != 0));
+                    flags -> (flags & FLAG_ONLY_BACK_FOR_BOUNCER_VISIBLE) != 0));
 
             // Rotation button
             RotationButton rotationButton = new RotationButtonImpl(
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 2864ac7..57e11de 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -432,11 +432,16 @@
         }
         LauncherAtom.ContainerInfo oldContainer = itemInfoBuilder.getContainerInfo();
 
+        LauncherAtom.TaskBarContainer.Builder taskbarBuilder =
+                LauncherAtom.TaskBarContainer.newBuilder();
+        if (mControllers.uiController.isInOverview()) {
+            taskbarBuilder.setTaskSwitcherContainer(
+                    LauncherAtom.TaskSwitcherContainer.newBuilder());
+        }
+
         if (oldContainer.hasPredictedHotseatContainer()) {
             LauncherAtom.PredictedHotseatContainer predictedHotseat =
                     oldContainer.getPredictedHotseatContainer();
-            LauncherAtom.TaskBarContainer.Builder taskbarBuilder =
-                    LauncherAtom.TaskBarContainer.newBuilder();
 
             if (predictedHotseat.hasIndex()) {
                 taskbarBuilder.setIndex(predictedHotseat.getIndex());
@@ -449,8 +454,6 @@
                     .setTaskBarContainer(taskbarBuilder));
         } else if (oldContainer.hasHotseat()) {
             LauncherAtom.HotseatContainer hotseat = oldContainer.getHotseat();
-            LauncherAtom.TaskBarContainer.Builder taskbarBuilder =
-                    LauncherAtom.TaskBarContainer.newBuilder();
 
             if (hotseat.hasIndex()) {
                 taskbarBuilder.setIndex(hotseat.getIndex());
@@ -462,8 +465,6 @@
             LauncherAtom.FolderContainer.Builder folderBuilder = oldContainer.getFolder()
                     .toBuilder();
             LauncherAtom.HotseatContainer hotseat = folderBuilder.getHotseat();
-            LauncherAtom.TaskBarContainer.Builder taskbarBuilder =
-                    LauncherAtom.TaskBarContainer.newBuilder();
 
             if (hotseat.hasIndex()) {
                 taskbarBuilder.setIndex(hotseat.getIndex());
@@ -476,11 +477,11 @@
         } else if (oldContainer.hasAllAppsContainer()) {
             itemInfoBuilder.setContainerInfo(LauncherAtom.ContainerInfo.newBuilder()
                     .setAllAppsContainer(oldContainer.getAllAppsContainer().toBuilder()
-                            .setTaskbarContainer(LauncherAtom.TaskBarContainer.newBuilder())));
+                            .setTaskbarContainer(taskbarBuilder)));
         } else if (oldContainer.hasPredictionContainer()) {
             itemInfoBuilder.setContainerInfo(LauncherAtom.ContainerInfo.newBuilder()
                     .setPredictionContainer(oldContainer.getPredictionContainer().toBuilder()
-                            .setTaskbarContainer(LauncherAtom.TaskBarContainer.newBuilder())));
+                            .setTaskbarContainer(taskbarBuilder)));
         }
     }
 
@@ -588,10 +589,8 @@
         AnimatorSet anim = new AnimatorSet();
         anim.play(mControllers.taskbarViewController.getTaskbarIconAlpha().get(
                 TaskbarViewController.ALPHA_INDEX_NOTIFICATION_EXPANDED).animateToValue(alpha));
-        if (!isThreeButtonNav()) {
-            anim.play(mControllers.taskbarDragLayerController.getNotificationShadeBgTaskbar()
-                    .animateToValue(alpha));
-        }
+        anim.play(mControllers.taskbarDragLayerController.getNotificationShadeBgTaskbar()
+                .animateToValue(alpha));
         anim.start();
         if (skipAnim) {
             anim.end();
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
index 5ac0570..4d163aa 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
@@ -406,6 +406,10 @@
         return mLauncherState != LauncherState.ALL_APPS;
     }
 
+    boolean isInOverview() {
+        return mLauncherState == LauncherState.OVERVIEW;
+    }
+
     private void playStateTransitionAnim(AnimatorSet animatorSet, long duration,
             boolean committed) {
         boolean isInStashedState = mLauncherState.isTaskbarStashed(mLauncher);
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index babafd5..f5d7f3b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -600,6 +600,7 @@
                 if (!mIsStashed) {
                     tryStartTaskbarTimeout();
                 }
+                mControllers.taskbarViewController.announceForAccessibility();
             }
         });
     }
@@ -722,8 +723,8 @@
                 skipInterpolator = FINAL_FRAME;
             }
         }
-        play(as, mControllers.taskbarViewController
-                .createRevealAnimToIsStashed(isStashed), 0, duration, EMPHASIZED);
+        mControllers.taskbarViewController.addRevealAnimToIsStashed(as, isStashed, duration,
+                EMPHASIZED);
 
         if (skipInterpolator != null) {
             as.setInterpolator(skipInterpolator);
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
index b552e9b..4c6d3fa 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
@@ -17,6 +17,8 @@
 
 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 
+import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT;
+import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
 import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_APP;
 
 import android.content.Intent;
@@ -166,6 +168,11 @@
         return true;
     }
 
+    /** Returns {@code true} if Taskbar is currently within overview. */
+    protected boolean isInOverview() {
+        return false;
+    }
+
     @CallSuper
     protected void dumpLogs(String prefix, PrintWriter pw) {
         pw.println(String.format(
@@ -277,4 +284,30 @@
      * No-op if the view is not yet open.
      */
     public void launchSplitTasks(@NonNull View taskview, @NonNull GroupTask groupTask) { }
+
+    /**
+     * Returns the matching view (if any) in the taskbar.
+     * @param view The view to match.
+     */
+    public @Nullable View findMatchingView(View view) {
+        if (!(view.getTag() instanceof ItemInfo)) {
+            return null;
+        }
+        ItemInfo info = (ItemInfo) view.getTag();
+        if (info.container != CONTAINER_HOTSEAT && info.container != CONTAINER_HOTSEAT_PREDICTION) {
+            return null;
+        }
+
+        // Taskbar has the same items as the hotseat and we can use screenId to find the match.
+        int screenId = info.screenId;
+        View[] views = mControllers.taskbarViewController.getIconViews();
+        for (int i = views.length - 1; i >= 0; --i) {
+            if (views[i] != null
+                    && views[i].getTag() instanceof ItemInfo
+                    && ((ItemInfo) views[i].getTag()).screenId == screenId) {
+                return views[i];
+            }
+        }
+        return null;
+    }
 }
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
index 3d5089f..11b07e8 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
@@ -16,15 +16,18 @@
 package com.android.launcher3.taskbar;
 
 import static android.content.pm.PackageManager.FEATURE_PC;
+import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED;
 
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.Rect;
+import android.os.Bundle;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.FrameLayout;
 
 import androidx.annotation.LayoutRes;
@@ -153,7 +156,26 @@
 
         // TODO: Disable touch events on QSB otherwise it can crash.
         mQsb = LayoutInflater.from(context).inflate(R.layout.search_container_hotseat, this, false);
+    }
 
+    @Override
+    public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
+        if (action == AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS) {
+            announceForAccessibility(mContext.getString(R.string.taskbar_a11y_shown_title));
+        } else if (action == AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS) {
+            announceForAccessibility(mContext.getString(R.string.taskbar_a11y_hidden_title));
+        }
+        return super.performAccessibilityActionInternal(action, arguments);
+
+    }
+
+    protected void announceAccessibilityChanges() {
+        this.performAccessibilityAction(
+                isVisibleToUser() ? AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS
+                        : AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS, null);
+
+        ActivityContext.lookupContext(getContext()).getDragLayer()
+                .sendAccessibilityEvent(TYPE_WINDOW_CONTENT_CHANGED);
     }
 
     private int getColorWithGivenLuminance(int color, float luminance) {
@@ -163,6 +185,13 @@
         return ColorUtils.HSLToColor(colorHSL);
     }
 
+    /**
+     * Returns the icon touch size.
+     */
+    public int getIconTouchSize() {
+        return mIconTouchSize;
+    }
+
     private int calculateThemeIconsBackground() {
         int color = ThemedIconDrawable.getColors(mContext)[0];
         if (Utilities.isDarkTheme(mContext)) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
index 3143f23..50dbcc7 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
@@ -63,7 +63,6 @@
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.touch.SingleAxisSwipeDetector;
 import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.HorizontalInsettableView;
 import com.android.launcher3.util.ItemInfoMatcher;
 import com.android.launcher3.util.LauncherBindableItemsContainer;
 import com.android.launcher3.util.MultiPropertyFactory;
@@ -91,6 +90,9 @@
     public static final int ALPHA_INDEX_SMALL_SCREEN = 6;
     private static final int NUM_ALPHA_CHANNELS = 7;
 
+    // This allows the icons on the edge to stay within the taskbar background bounds.
+    private static final float ICON_REVEAL_X_DURATION_MULTIPLIER = 0.8f;
+
     private final TaskbarActivityContext mActivity;
     private final TaskbarView mTaskbarView;
     private final MultiValueAlpha mTaskbarIconAlpha;
@@ -189,6 +191,13 @@
         mActivity.addOnDeviceProfileChangeListener(mDeviceProfileChangeListener);
     }
 
+    /**
+     * Announcement for Accessibility when Taskbar stashes/unstashes.
+     */
+    public void announceForAccessibility() {
+        mTaskbarView.announceAccessibilityChanges();
+    }
+
     public void onDestroy() {
         LauncherAppState.getInstance(mActivity).getModel().removeCallbacks(mModelCallbacks);
         mActivity.removeOnDeviceProfileChangeListener(mDeviceProfileChangeListener);
@@ -304,73 +313,87 @@
     /**
      * Creates and returns a {@link RevealOutlineAnimation} Animator that updates the icon shape
      * and size.
+     * @param as The AnimatorSet to add all animations to.
      * @param isStashed When true, the icon crops vertically to the size of the stashed handle.
      *                  When false, the reverse happens.
+     * @param duration The duration of the animation.
+     * @param interpolator The interpolator to use for all animations.
      */
-    public AnimatorSet createRevealAnimToIsStashed(boolean isStashed) {
-        AnimatorSet as = new AnimatorSet();
+    public void addRevealAnimToIsStashed(AnimatorSet as, boolean isStashed, long duration,
+            Interpolator interpolator) {
+        AnimatorSet reveal = new AnimatorSet();
 
         Rect stashedBounds = new Rect();
         mControllers.stashedHandleViewController.getStashedHandleBounds(stashedBounds);
 
-        int numChildren = mTaskbarView.getChildCount();
+        boolean isQsbInline = mActivity.getDeviceProfile().isQsbInline;
+        int numIcons = mTaskbarView.getChildCount() - (isQsbInline ? 1 : 0);
         // We do not actually modify the width of the icons, but we will use this width to position
         // the children to overlay the nav handle.
-        float virtualChildWidth = stashedBounds.width() / (float) numChildren;
+        float virtualChildWidth = stashedBounds.width() / (float) numIcons;
 
-        for (int i = numChildren - 1; i >= 0; i--) {
+        // All children move the same y-amount since they will be cropped to the same centerY.
+        float croppedTransY = mTaskbarView.getIconTouchSize() - stashedBounds.height();
+
+        boolean isRtl = Utilities.isRtl(mTaskbarView.getResources());
+        for (int i = mTaskbarView.getChildCount() - 1; i >= 0; i--) {
             View child = mTaskbarView.getChildAt(i);
-
-            if (child == mTaskbarView.getQsb()) {
-                continue;
-            }
+            boolean isQsb = child == mTaskbarView.getQsb();
 
             // Crop the icons to/from the nav handle shape.
-            as.play(createRevealAnimForView(child, isStashed));
+            reveal.play(createRevealAnimForView(child, isStashed).setDuration(duration));
 
             // Translate the icons to/from their locations as the "nav handle."
             // We look at 'left' and 'right' values to ensure that the children stay within the
             // bounds of the stashed handle.
-            float iconLeft = child.getLeft();
-            float newLeft = stashedBounds.left + (virtualChildWidth * i);
+
+            // All of the taskbar icons will overlap the entirety of the stashed handle
+            // And the QSB, if inline, will overlap part of stashed handle as well.
+            int positionInHandle = (isQsbInline && !isQsb)
+                    ? i + (isRtl ? 1 : -1)
+                    : i;
+            float currentPosition = isQsb ? child.getX() : child.getLeft();
+            float newPosition = stashedBounds.left + (virtualChildWidth * positionInHandle);
             final float croppedTransX;
-            if (iconLeft > newLeft) {
-                float newRight = stashedBounds.right - (virtualChildWidth * (numChildren - 1 - i));
-                croppedTransX = -(child.getLeft() + child.getWidth() - newRight);
+            if (currentPosition > newPosition) {
+                float newRight = stashedBounds.right - (virtualChildWidth
+                        * (numIcons - 1 - positionInHandle));
+                croppedTransX = -(currentPosition + child.getWidth() - newRight);
             } else {
-                croppedTransX = newLeft - iconLeft;
+                croppedTransX = newPosition - currentPosition;
             }
 
-            float croppedTransY = child.getHeight() - stashedBounds.height();
+            long transXDuration = (long) (duration * ICON_REVEAL_X_DURATION_MULTIPLIER);
+            float[] transX = isStashed
+                    ? new float[] {croppedTransX}
+                    : new float[] {croppedTransX, 0};
+            float[] transY = isStashed
+                    ? new float[] {croppedTransY}
+                    : new float[] {croppedTransY, 0};
+
             if (child instanceof Reorderable) {
                 MultiTranslateDelegate mtd = ((Reorderable) child).getTranslateDelegate();
 
-                as.play(ObjectAnimator.ofFloat(mtd.getTranslationX(INDEX_TASKBAR_REVEAL_ANIM),
-                        MULTI_PROPERTY_VALUE, isStashed
-                                ? new float[] {croppedTransX}
-                                : new float[] {croppedTransX, 0}));
-                as.play(ObjectAnimator.ofFloat(mtd.getTranslationY(INDEX_TASKBAR_REVEAL_ANIM),
-                        MULTI_PROPERTY_VALUE, isStashed
-                                ? new float[] {croppedTransY}
-                                : new float[] {croppedTransY, 0}));
+                reveal.play(ObjectAnimator.ofFloat(mtd.getTranslationX(INDEX_TASKBAR_REVEAL_ANIM),
+                        MULTI_PROPERTY_VALUE, transX)
+                        .setDuration(transXDuration));
+                reveal.play(ObjectAnimator.ofFloat(mtd.getTranslationY(INDEX_TASKBAR_REVEAL_ANIM),
+                        MULTI_PROPERTY_VALUE, transY));
                 as.addListener(forEndCallback(() ->
                         mtd.setTranslation(INDEX_TASKBAR_REVEAL_ANIM, 0, 0)));
             } else {
-                as.play(ObjectAnimator.ofFloat(child,
-                        VIEW_TRANSLATE_X, isStashed
-                                ? new float[] {croppedTransX}
-                                : new float[] {croppedTransX, 0}));
-                as.play(ObjectAnimator.ofFloat(child,
-                        VIEW_TRANSLATE_Y, isStashed
-                                ? new float[] {croppedTransY}
-                                : new float[] {croppedTransY, 0}));
+                reveal.play(ObjectAnimator.ofFloat(child, VIEW_TRANSLATE_X, transX)
+                        .setDuration(transXDuration));
+                reveal.play(ObjectAnimator.ofFloat(child, VIEW_TRANSLATE_Y, transY));
                 as.addListener(forEndCallback(() -> {
                     child.setTranslationX(0);
                     child.setTranslationY(0);
                 }));
             }
         }
-        return as;
+
+        reveal.setInterpolator(interpolator);
+        as.play(reveal);
     }
 
     /**
@@ -431,7 +454,6 @@
 
         for (int i = 0; i < mTaskbarView.getChildCount(); i++) {
             View child = mTaskbarView.getChildAt(i);
-            int positionInHotseat;
             boolean isAllAppsButton = child == mTaskbarView.getAllAppsButtonView();
             if (!mIsHotseatIconOnTopWhenAligned) {
                 // When going to home, the EMPHASIZED interpolator in TaskbarLauncherStateController
@@ -439,10 +461,17 @@
                 // to avoid icons disappearing rather than fading out visually.
                 setter.setViewAlpha(child, 0, Interpolators.clampToProgress(LINEAR, 0.8f, 1f));
             } else if ((isAllAppsButton && !FeatureFlags.ENABLE_ALL_APPS_BUTTON_IN_HOTSEAT.get())) {
-                setter.setViewAlpha(child, 0,
-                        isToHome
-                                ? Interpolators.clampToProgress(LINEAR, 0f, 0.17f)
-                                : Interpolators.clampToProgress(LINEAR, 0.72f, 0.84f));
+                if (!isToHome
+                        && mIsHotseatIconOnTopWhenAligned
+                        && mControllers.taskbarStashController.isStashed()) {
+                    // Prevent All Apps icon from appearing when going from hotseat to nav handle.
+                    setter.setViewAlpha(child, 0, Interpolators.clampToProgress(LINEAR, 0f, 0f));
+                } else {
+                    setter.setViewAlpha(child, 0,
+                            isToHome
+                                    ? Interpolators.clampToProgress(LINEAR, 0f, 0.17f)
+                                    : Interpolators.clampToProgress(LINEAR, 0.72f, 0.84f));
+                }
             }
 
             if (child == mTaskbarView.getQsb()) {
@@ -454,32 +483,36 @@
                 float childCenter = (child.getLeft() + child.getRight()) / 2f;
                 float halfQsbIconWidthDiff =
                         (launcherDp.hotseatQsbWidth - taskbarDp.iconSizePx) / 2f;
-                setter.addFloat(child, VIEW_TRANSLATE_X,
-                        isRtl ? -halfQsbIconWidthDiff : halfQsbIconWidthDiff,
-                        hotseatIconCenter - childCenter, interpolator);
-
                 float scale = ((float) taskbarDp.iconSizePx) / launcherDp.hotseatQsbVisualHeight;
                 setter.addFloat(child, SCALE_PROPERTY, scale, 1f, interpolator);
 
-                setter.setFloat(child, VIEW_TRANSLATE_Y, mTaskbarBottomMargin, interpolator);
+                float fromX = isRtl ? -halfQsbIconWidthDiff : halfQsbIconWidthDiff;
+                float toX = hotseatIconCenter - childCenter;
+                if (child instanceof Reorderable) {
+                    MultiTranslateDelegate mtd = ((Reorderable) child).getTranslateDelegate();
+
+                    setter.addFloat(mtd.getTranslationX(INDEX_TASKBAR_ALIGNMENT_ANIM),
+                            MULTI_PROPERTY_VALUE, fromX, toX, interpolator);
+                    setter.setFloat(mtd.getTranslationY(INDEX_TASKBAR_ALIGNMENT_ANIM),
+                            MULTI_PROPERTY_VALUE, mTaskbarBottomMargin, interpolator);
+                } else {
+                    setter.addFloat(child, VIEW_TRANSLATE_X, fromX, toX, interpolator);
+                    setter.setFloat(child, VIEW_TRANSLATE_Y, mTaskbarBottomMargin, interpolator);
+                }
 
                 if (mIsHotseatIconOnTopWhenAligned) {
                     setter.addFloat(child, VIEW_ALPHA, 0f, 1f,
                             isToHome
                                     ? Interpolators.clampToProgress(LINEAR, 0f, 0.35f)
-                                    : Interpolators.clampToProgress(LINEAR, 0.84f, 1f));
+                                    : mActivity.getDeviceProfile().isQsbInline
+                                            ? Interpolators.clampToProgress(LINEAR, 0f, 1f)
+                                            : Interpolators.clampToProgress(LINEAR, 0.84f, 1f));
                 }
                 setter.addOnFrameListener(animator -> AlphaUpdateListener.updateVisibility(child));
-
-                float qsbInsetFraction = halfQsbIconWidthDiff / launcherDp.hotseatQsbWidth;
-                if (child instanceof HorizontalInsettableView) {
-                    setter.addFloat((HorizontalInsettableView) child,
-                            HorizontalInsettableView.HORIZONTAL_INSETS, qsbInsetFraction, 0,
-                            interpolator);
-                }
                 continue;
             }
 
+            int positionInHotseat;
             if (isAllAppsButton) {
                 // Note that there is no All Apps button in the hotseat, this position is only used
                 // as its convenient for animation purposes.
@@ -496,18 +529,17 @@
             float hotseatIconCenter = hotseatPadding.left
                     + (hotseatCellSize + borderSpacing) * positionInHotseat
                     + hotseatCellSize / 2f;
-
             float childCenter = (child.getLeft() + child.getRight()) / 2f;
+            float toX = hotseatIconCenter - childCenter;
             if (child instanceof Reorderable) {
                 MultiTranslateDelegate mtd = ((Reorderable) child).getTranslateDelegate();
 
                 setter.setFloat(mtd.getTranslationX(INDEX_TASKBAR_ALIGNMENT_ANIM),
-                        MULTI_PROPERTY_VALUE, hotseatIconCenter - childCenter, interpolator);
+                        MULTI_PROPERTY_VALUE, toX, interpolator);
                 setter.setFloat(mtd.getTranslationY(INDEX_TASKBAR_ALIGNMENT_ANIM),
                         MULTI_PROPERTY_VALUE, mTaskbarBottomMargin, interpolator);
             } else {
-                setter.setFloat(child, VIEW_TRANSLATE_X,
-                        hotseatIconCenter - childCenter, interpolator);
+                setter.setFloat(child, VIEW_TRANSLATE_X, toX, interpolator);
                 setter.setFloat(child, VIEW_TRANSLATE_Y, mTaskbarBottomMargin, interpolator);
             }
             setter.setFloat(child, SCALE_PROPERTY, scaleUp, interpolator);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index a53f08a..2a46e08 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -20,11 +20,10 @@
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_OPTIMIZE_MEASURE;
 import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_FOCUSED;
 
-import static com.android.launcher3.LauncherSettings.Animation.DEFAULT_NO_ICON;
-import static com.android.launcher3.LauncherSettings.Animation.VIEW_BACKGROUND;
 import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT;
 import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
 import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
+import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_SEARCH_ACTION;
 import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
 import static com.android.launcher3.LauncherState.ALL_APPS;
 import static com.android.launcher3.LauncherState.NORMAL;
@@ -40,6 +39,9 @@
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP;
 import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
 import static com.android.launcher3.popup.QuickstepSystemShortcut.getSplitSelectShortcutByPosition;
+import static com.android.launcher3.popup.SystemShortcut.APP_INFO;
+import static com.android.launcher3.popup.SystemShortcut.INSTALL;
+import static com.android.launcher3.popup.SystemShortcut.WIDGETS;
 import static com.android.launcher3.taskbar.LauncherTaskbarUIController.ALL_APPS_PAGE_PROGRESS_INDEX;
 import static com.android.launcher3.taskbar.LauncherTaskbarUIController.MINUS_ONE_PAGE_PROGRESS_INDEX;
 import static com.android.launcher3.taskbar.LauncherTaskbarUIController.WIDGETS_PAGE_PROGRESS_INDEX;
@@ -80,7 +82,6 @@
 import android.view.HapticFeedbackConstants;
 import android.view.RemoteAnimationTarget;
 import android.view.View;
-import android.view.WindowManagerGlobal;
 import android.window.BackEvent;
 import android.window.OnBackAnimationCallback;
 import android.window.OnBackInvokedDispatcher;
@@ -171,6 +172,7 @@
 import com.android.quickstep.views.OverviewActionsView;
 import com.android.quickstep.views.RecentsView;
 import com.android.quickstep.views.TaskView;
+import com.android.systemui.shared.recents.model.Task;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.unfold.RemoteUnfoldSharedComponent;
 import com.android.systemui.unfold.UnfoldSharedComponent;
@@ -186,8 +188,11 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
+import java.util.function.Consumer;
 import java.util.function.Predicate;
 import java.util.stream.Stream;
 
@@ -385,22 +390,30 @@
 
     @Override
     public Stream<SystemShortcut.Factory> getSupportedShortcuts() {
-        Stream<SystemShortcut.Factory> base = Stream.of(WellbeingModel.SHORTCUT_FACTORY);
-        if (ENABLE_SPLIT_FROM_WORKSPACE.get() && mDeviceProfile.isTablet) {
-            RecentsView recentsView = getOverviewPanel();
-            // TODO(b/266482558): Pull it out of PagedOrentationHandler for split from workspace.
-            List<SplitPositionOption> positions =
-                    recentsView.getPagedOrientationHandler().getSplitPositionOptions(
-                            mDeviceProfile);
-            List<SystemShortcut.Factory<QuickstepLauncher>> splitShortcuts = new ArrayList<>();
-            for (SplitPositionOption position : positions) {
-                splitShortcuts.add(getSplitSelectShortcutByPosition(position));
-            }
-            base = Stream.concat(base, splitShortcuts.stream());
+        // Order matters as it affects order of appearance in popup container
+        List<SystemShortcut.Factory> shortcuts = new ArrayList(Arrays.asList(
+                APP_INFO, WellbeingModel.SHORTCUT_FACTORY, mHotseatPredictionController));
+        shortcuts.addAll(getSplitShortcuts());
+        shortcuts.add(WIDGETS);
+        shortcuts.add(INSTALL);
+        return shortcuts.stream();
+    }
+
+    private List<SystemShortcut.Factory<QuickstepLauncher>> getSplitShortcuts() {
+
+        if (!ENABLE_SPLIT_FROM_WORKSPACE.get() || !mDeviceProfile.isTablet) {
+            return Collections.emptyList();
         }
-        return Stream.concat(
-                Stream.of(mHotseatPredictionController),
-                Stream.concat(base, super.getSupportedShortcuts()));
+        RecentsView recentsView = getOverviewPanel();
+        // TODO(b/266482558): Pull it out of PagedOrentationHandler for split from workspace.
+        List<SplitPositionOption> positions =
+                recentsView.getPagedOrientationHandler().getSplitPositionOptions(
+                        mDeviceProfile);
+        List<SystemShortcut.Factory<QuickstepLauncher>> splitShortcuts = new ArrayList<>();
+        for (SplitPositionOption position : positions) {
+            splitShortcuts.add(getSplitSelectShortcutByPosition(position));
+        }
+        return splitShortcuts;
     }
 
     /**
@@ -408,15 +421,18 @@
      */
     private void onStateOrResumeChanging(boolean inTransition) {
         LauncherState state = getStateManager().getState();
-        if (!ENABLE_PIP_KEEP_CLEAR_ALGORITHM) {
-            boolean started = ((getActivityFlags() & ACTIVITY_STATE_STARTED)) != 0;
-            if (started) {
-                DeviceProfile profile = getDeviceProfile();
-                boolean willUserBeActive =
-                        (getActivityFlags() & ACTIVITY_STATE_USER_WILL_BE_ACTIVE) != 0;
-                boolean visible = (state == NORMAL || state == OVERVIEW)
-                        && (willUserBeActive || isUserActive())
-                        && !profile.isVerticalBarLayout();
+        boolean started = ((getActivityFlags() & ACTIVITY_STATE_STARTED)) != 0;
+        if (started) {
+            DeviceProfile profile = getDeviceProfile();
+            boolean willUserBeActive =
+                    (getActivityFlags() & ACTIVITY_STATE_USER_WILL_BE_ACTIVE) != 0;
+            boolean visible = (state == NORMAL || state == OVERVIEW)
+                    && (willUserBeActive || isUserActive())
+                    && !profile.isVerticalBarLayout();
+            if (ENABLE_PIP_KEEP_CLEAR_ALGORITHM)  {
+                SystemUiProxy.INSTANCE.get(this)
+                        .setLauncherKeepClearAreaHeight(visible, profile.hotseatBarSizePx);
+            } else {
                 SystemUiProxy.INSTANCE.get(this).setShelfHeight(visible, profile.hotseatBarSizePx);
             }
         }
@@ -1054,8 +1070,7 @@
             activityOptions.options.setSourceInfo(ActivityOptions.SourceInfo.TYPE_LAUNCHER,
                     mLastTouchUpTime);
         }
-        if (item != null && (item.animationType == DEFAULT_NO_ICON
-                || item.animationType == VIEW_BACKGROUND)) {
+        if (item != null && item.itemType == ITEM_TYPE_SEARCH_ACTION) {
             activityOptions.options.setSplashScreenStyle(
                     SplashScreen.SPLASH_SCREEN_STYLE_SOLID_COLOR);
         } else {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/DebugFlag.java b/quickstep/src/com/android/launcher3/uioverrides/flags/DebugFlag.java
index 177a399..d4944d0 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/flags/DebugFlag.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/flags/DebugFlag.java
@@ -24,8 +24,6 @@
 
     public final boolean defaultValue;
 
-    boolean mHasBeenChangedAtLeastOnce;
-
     public DebugFlag(String key, String description, boolean defaultValue, boolean currentValue) {
         super(currentValue);
         this.key = key;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagTogglerPrefUi.java b/quickstep/src/com/android/launcher3/uioverrides/flags/FlagTogglerPrefUi.java
index 4ca7e31..b7fb2ed 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagTogglerPrefUi.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/flags/FlagTogglerPrefUi.java
@@ -35,6 +35,9 @@
 import com.android.launcher3.R;
 import com.android.launcher3.config.FeatureFlags;
 
+import java.util.List;
+import java.util.Set;
+
 /**
  * Dev-build only UI allowing developers to toggle flag settings. See {@link FeatureFlags}.
  */
@@ -50,31 +53,15 @@
 
         @Override
         public void putBoolean(String key, boolean value) {
-            for (DebugFlag flag : FlagsFactory.getDebugFlags()) {
-                if (flag.key.equals(key)) {
-                    SharedPreferences prefs = mContext.getSharedPreferences(
-                            FLAGS_PREF_NAME, Context.MODE_PRIVATE);
-                    SharedPreferences.Editor editor = prefs.edit();
-                    // We keep the key in the prefs even if it has the default value, because it's a
-                    // signal that it has been changed at one point.
-                    if (!prefs.contains(key) && value == flag.defaultValue) {
-                        editor.remove(key).apply();
-                        flag.mHasBeenChangedAtLeastOnce = false;
-                    } else {
-                        editor.putBoolean(key, value).apply();
-                        flag.mHasBeenChangedAtLeastOnce = true;
-                    }
-                    updateMenu();
-                }
-            }
+            mSharedPreferences.edit().putBoolean(key, value).apply();
+            updateMenu();
         }
 
         @Override
         public boolean getBoolean(String key, boolean defaultValue) {
             for (DebugFlag flag : FlagsFactory.getDebugFlags()) {
                 if (flag.key.equals(key)) {
-                    return mContext.getSharedPreferences(FLAGS_PREF_NAME, Context.MODE_PRIVATE)
-                            .getBoolean(key, flag.defaultValue);
+                    return mSharedPreferences.getBoolean(key, flag.defaultValue);
                 }
             }
             return defaultValue;
@@ -89,11 +76,22 @@
     }
 
     public void applyTo(PreferenceGroup parent) {
+        Set<String> modifiedPrefs = mSharedPreferences.getAll().keySet();
+        List<DebugFlag> flags = FlagsFactory.getDebugFlags();
+        flags.sort((f1, f2) -> {
+            // Sort first by any prefs that the user has changed, then alphabetically.
+            int changeComparison = Boolean.compare(
+                    modifiedPrefs.contains(f2.key), modifiedPrefs.contains(f1.key));
+            return changeComparison != 0
+                    ? changeComparison
+                    : f1.key.compareToIgnoreCase(f2.key);
+        });
+
         // For flag overrides we only want to store when the engineer chose to override the
         // flag with a different value than the default. That way, when we flip flags in
         // future, engineers will pick up the new value immediately. To accomplish this, we use a
         // custom preference data store.
-        for (DebugFlag flag : FlagsFactory.getDebugFlags()) {
+        for (DebugFlag flag : flags) {
             SwitchPreference switchPreference = new SwitchPreference(mContext);
             switchPreference.setKey(flag.key);
             switchPreference.setDefaultValue(flag.defaultValue);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java b/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java
index 84b873d..888cc9d 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java
@@ -53,7 +53,6 @@
 
     private static final List<DebugFlag> sDebugFlags = new ArrayList<>();
 
-
     private final Set<String> mKeySet = new HashSet<>();
     private boolean mRestartRequested = false;
 
@@ -75,7 +74,6 @@
                     .getSharedPreferences(FLAGS_PREF_NAME, Context.MODE_PRIVATE);
             boolean currentValue = prefs.getBoolean(key, defaultValue);
             DebugFlag flag = new DebugFlag(key, description, defaultValue, currentValue);
-            flag.mHasBeenChangedAtLeastOnce = prefs.contains(key);
             sDebugFlags.add(flag);
             return flag;
         } else {
@@ -96,7 +94,6 @@
             boolean currentValue = prefs.getBoolean(key, defaultValue);
             DebugFlag flag = new DeviceFlag(key, description, defaultValue, currentValue,
                     defaultValueInCode);
-            flag.mHasBeenChangedAtLeastOnce = prefs.contains(key);
             sDebugFlags.add(flag);
             return flag;
         } else {
@@ -117,19 +114,9 @@
         if (!Utilities.IS_DEBUG_DEVICE) {
             return Collections.emptyList();
         }
-        List<DebugFlag> flags;
         synchronized (sDebugFlags) {
-            flags = new ArrayList<>(sDebugFlags);
+            return new ArrayList<>(sDebugFlags);
         }
-        flags.sort((f1, f2) -> {
-            // Sort first by any prefs that the user has changed, then alphabetically.
-            int changeComparison = Boolean.compare(
-                    f2.mHasBeenChangedAtLeastOnce, f1.mHasBeenChangedAtLeastOnce);
-            return changeComparison != 0
-                    ? changeComparison
-                    : f1.key.compareToIgnoreCase(f2.key);
-        });
-        return flags;
     }
 
     /**
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
index df95dc1..b7bafd8 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
@@ -191,7 +191,7 @@
             // need to manually set the duration to a reasonable value.
             animator.setDuration(HINT_STATE.getTransitionDuration(mLauncher, true /* isToState */));
         }
-        if (FeatureFlags.ENABLE_HAPTICS_ALL_APPS.get() &&
+        if (FeatureFlags.ENABLE_PREMIUM_HAPTICS_ALL_APPS.get() &&
                 ((mFromState == NORMAL && mToState == ALL_APPS)
                         || (mFromState == ALL_APPS && mToState == NORMAL)) && isFling) {
             mVibratorWrapper.vibrateForDragBump();
diff --git a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
index bb781c8..3151374 100644
--- a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
+++ b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
@@ -105,6 +105,9 @@
     private HomeAnimationFactory createIconHomeAnimationFactory(View workspaceView) {
         RectF iconLocation = new RectF();
         FloatingIconView floatingIconView = getFloatingIconView(mActivity, workspaceView,
+                mActivity.getTaskbarUIController() == null
+                        ? null
+                        : mActivity.getTaskbarUIController().findMatchingView(workspaceView),
                 true /* hideOriginal */, iconLocation, false /* isOpening */);
 
         // We want the window alpha to be 0 once this threshold is met, so that the
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index 86b02aa..7c09805 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -87,6 +87,7 @@
             new MainThreadInitializedObject<>(SystemUiProxy::new);
 
     private static final int MSG_SET_SHELF_HEIGHT = 1;
+    private static final int MSG_SET_LAUNCHER_KEEP_CLEAR_AREA_HEIGHT = 2;
 
     private ISystemUiProxy mSystemUiProxy;
     private IPip mPip;
@@ -121,6 +122,10 @@
     private int mLastShelfHeight;
     private boolean mLastShelfVisible;
 
+    // Used to dedupe calls to SystemUI
+    private int mLastLauncherKeepClearAreaHeight;
+    private boolean mLastLauncherKeepClearAreaHeightVisible;
+
     private final Context mContext;
     private final Handler mAsyncHandler;
 
@@ -454,6 +459,33 @@
     }
 
     /**
+     * Sets the height of the keep clear area that is going to be reported by
+     * the Launcher for the Hotseat.
+     */
+    public void setLauncherKeepClearAreaHeight(boolean visible, int height) {
+        Message.obtain(mAsyncHandler, MSG_SET_LAUNCHER_KEEP_CLEAR_AREA_HEIGHT,
+                visible ? 1 : 0 , height).sendToTarget();
+    }
+
+    @WorkerThread
+    private void setLauncherKeepClearAreaHeight(int visibleInt, int height) {
+        boolean visible = visibleInt != 0;
+        boolean changed = visible != mLastLauncherKeepClearAreaHeightVisible
+                || height != mLastLauncherKeepClearAreaHeight;
+        IPip pip = mPip;
+        if (pip != null && changed) {
+            mLastLauncherKeepClearAreaHeightVisible = visible;
+            mLastLauncherKeepClearAreaHeight = height;
+            try {
+                pip.setLauncherKeepClearAreaHeight(visible, height);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call setLauncherKeepClearAreaHeight visible: " + visible
+                        + " height: " + height, e);
+            }
+        }
+    }
+
+    /**
      * Sets listener to get pip animation callbacks.
      */
     public void setPipAnimationListener(IPipAnimationListener listener) {
@@ -945,6 +977,9 @@
             case MSG_SET_SHELF_HEIGHT:
                 setShelfHeightAsync(msg.arg1, msg.arg2);
                 return true;
+            case MSG_SET_LAUNCHER_KEEP_CLEAR_AREA_HEIGHT:
+                setLauncherKeepClearAreaHeight(msg.arg1, msg.arg2);
+                return true;
         }
 
         return false;
diff --git a/quickstep/src/com/android/quickstep/util/DesktopTask.java b/quickstep/src/com/android/quickstep/util/DesktopTask.java
index 433d23f..b3f5d82 100644
--- a/quickstep/src/com/android/quickstep/util/DesktopTask.java
+++ b/quickstep/src/com/android/quickstep/util/DesktopTask.java
@@ -16,6 +16,8 @@
 
 package com.android.quickstep.util;
 
+import androidx.annotation.NonNull;
+
 import com.android.quickstep.views.TaskView;
 import com.android.systemui.shared.recents.model.Task;
 
@@ -27,9 +29,10 @@
  */
 public class DesktopTask extends GroupTask {
 
-    public ArrayList<Task> tasks;
+    @NonNull
+    public final ArrayList<Task> tasks;
 
-    public DesktopTask(ArrayList<Task> tasks) {
+    public DesktopTask(@NonNull ArrayList<Task> tasks) {
         super(tasks.get(0), null, null, TaskView.Type.DESKTOP);
         this.tasks = tasks;
     }
diff --git a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
index 14898b1..5414068 100644
--- a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
@@ -92,7 +92,6 @@
     private final ArrayList<CancellableTask<?>> mPendingThumbnailRequests = new ArrayList<>();
 
     private View mBackgroundView;
-    private View mEmptyView;
 
     public DesktopTaskView(Context context) {
         this(context, null);
@@ -111,7 +110,6 @@
         super.onFinishInflate();
 
         mBackgroundView = findViewById(R.id.background);
-        mEmptyView = findViewById(R.id.empty_view);
 
         int topMarginPx =
                 mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx;
@@ -187,8 +185,6 @@
             mSnapshotViewMap.put(task.key.id, snapshotView);
         }
 
-        mEmptyView.setVisibility(mTasks.isEmpty() ? View.VISIBLE : View.GONE);
-
         updateTaskIdContainer();
         updateTaskIdAttributeContainer();
 
diff --git a/quickstep/src/com/android/quickstep/views/FloatingWidgetBackgroundView.java b/quickstep/src/com/android/quickstep/views/FloatingWidgetBackgroundView.java
index adea1a4..4ea7753 100644
--- a/quickstep/src/com/android/quickstep/views/FloatingWidgetBackgroundView.java
+++ b/quickstep/src/com/android/quickstep/views/FloatingWidgetBackgroundView.java
@@ -27,8 +27,10 @@
 import android.view.ViewOutlineProvider;
 import android.widget.RemoteViews.RemoteViewOutlineProvider;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import com.android.launcher3.R;
 import com.android.launcher3.widget.LauncherAppWidgetHostView;
 import com.android.launcher3.widget.RoundedCornerEnforcement;
 
@@ -65,14 +67,20 @@
         setClipToOutline(true);
     }
 
-    void init(LauncherAppWidgetHostView hostView, View backgroundView, float finalRadius,
-            int fallbackBackgroundColor) {
+    void init(LauncherAppWidgetHostView hostView, @NonNull View backgroundView,
+            float finalRadius, int fallbackBackgroundColor) {
         mFinalRadius = finalRadius;
         mSourceView = backgroundView;
         mInitialOutlineRadius = getOutlineRadius(hostView, backgroundView);
         mIsUsingFallback = false;
         if (isSupportedDrawable(backgroundView.getForeground())) {
-            mOriginalForeground = backgroundView.getForeground();
+            if (backgroundView.getTag(R.id.saved_floating_widget_foreground) == null) {
+                mOriginalForeground = backgroundView.getForeground();
+                backgroundView.setTag(R.id.saved_floating_widget_foreground, mOriginalForeground);
+            } else {
+                mOriginalForeground = (Drawable) backgroundView.getTag(
+                        R.id.saved_floating_widget_foreground);
+            }
             mForegroundProperties.init(
                     mOriginalForeground.getConstantState().newDrawable().mutate());
             setForeground(mForegroundProperties.mDrawable);
@@ -82,7 +90,13 @@
             mSourceView.setForeground(clipPlaceholder);
         }
         if (isSupportedDrawable(backgroundView.getBackground())) {
-            mOriginalBackground = backgroundView.getBackground();
+            if (backgroundView.getTag(R.id.saved_floating_widget_background) == null) {
+                mOriginalBackground = backgroundView.getBackground();
+                backgroundView.setTag(R.id.saved_floating_widget_background, mOriginalBackground);
+            } else {
+                mOriginalBackground = (Drawable) backgroundView.getTag(
+                        R.id.saved_floating_widget_background);
+            }
             mBackgroundProperties.init(
                     mOriginalBackground.getConstantState().newDrawable().mutate());
             setBackground(mBackgroundProperties.mDrawable);
@@ -115,6 +129,10 @@
     }
 
     void recycle() {
+        if (mSourceView != null) {
+            mSourceView.setTag(R.id.saved_floating_widget_foreground, null);
+            mSourceView.setTag(R.id.saved_floating_widget_background, null);
+        }
         mSourceView = null;
         mOriginalForeground = null;
         mOriginalBackground = null;
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index ac59403..717300e 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -147,8 +147,6 @@
 import com.android.launcher3.statehandlers.DepthController;
 import com.android.launcher3.statemanager.BaseState;
 import com.android.launcher3.statemanager.StatefulActivity;
-import com.android.launcher3.testing.TestLogging;
-import com.android.launcher3.testing.shared.TestProtocol;
 import com.android.launcher3.touch.OverScroll;
 import com.android.launcher3.touch.PagedOrientationHandler;
 import com.android.launcher3.util.DynamicResource;
@@ -1518,9 +1516,10 @@
         mMovingTaskView = null;
         runningTaskView.resetPersistentViewTransforms();
         int frontTaskIndex = 0;
-        if (DesktopTaskView.DESKTOP_IS_PROTO2_ENABLED && !runningTaskView.isDesktopTask()) {
-            // If desktop mode is enabled, desktop task view is pinned at first position.
-            // Move running task to position 1
+        if (DesktopTaskView.DESKTOP_IS_PROTO2_ENABLED && mDesktopTaskView != null
+                && !runningTaskView.isDesktopTask()) {
+            // If desktop mode is enabled, desktop task view is pinned at first position if present.
+            // Move running task to position 1.
             frontTaskIndex = 1;
         }
         addView(runningTaskView, frontTaskIndex);
@@ -1653,14 +1652,18 @@
 
         if (!taskGroups.isEmpty()) {
             addView(mClearAllButton);
-
-            if (DesktopTaskView.DESKTOP_IS_PROTO2_ENABLED
-                    && !getSplitSelectController().isSplitSelectActive()) {
-                mDesktopTaskView = (DesktopTaskView) getTaskViewFromPool(TaskView.Type.DESKTOP);
-                // Always add a desktop task to the first position. Even if it is empty
-                addView(mDesktopTaskView, 0);
-                ArrayList<Task> tasks = desktopTask != null ? desktopTask.tasks : new ArrayList<>();
-                mDesktopTaskView.bind(tasks, mOrientationState);
+            if (DesktopTaskView.DESKTOP_IS_PROTO2_ENABLED) {
+                // Check if we have apps on the desktop
+                if (desktopTask != null && !desktopTask.tasks.isEmpty()) {
+                    // If we are actively choosing apps for split, skip the desktop tile
+                    if (!getSplitSelectController().isSplitSelectActive()) {
+                        mDesktopTaskView = (DesktopTaskView) getTaskViewFromPool(
+                                TaskView.Type.DESKTOP);
+                        // Always add a desktop task to the first position
+                        addView(mDesktopTaskView, 0);
+                        mDesktopTaskView.bind(desktopTask.tasks, mOrientationState);
+                    }
+                }
             }
         }
 
@@ -4493,7 +4496,6 @@
      * Attempts to initiate split with an existing taskView, if one exists
      */
     public void initiateSplitSelect(SplitSelectSource splitSelectSource) {
-        TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "enterSplitSelect");
         mSplitSelectSource = splitSelectSource;
         mSplitHiddenTaskView = getTaskViewByTaskId(splitSelectSource.alreadyRunningTaskId);
         mSplitHiddenTaskViewIndex = indexOfChild(mSplitHiddenTaskView);
@@ -5201,7 +5203,7 @@
     }
 
     private int getFirstViewIndex() {
-        if (DesktopTaskView.DESKTOP_IS_PROTO2_ENABLED) {
+        if (DesktopTaskView.DESKTOP_IS_PROTO2_ENABLED && mDesktopTaskView != null) {
             // Desktop task is at position 0, that is the first view
             return 0;
         }
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java b/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
deleted file mode 100644
index f10b917..0000000
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2023 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.quickstep;
-
-import android.content.Intent;
-
-import com.android.launcher3.ui.TaplTestsLauncher3;
-import com.android.launcher3.util.rule.TestStabilityRule;
-import com.android.quickstep.TaskbarModeSwitchRule.TaskbarModeSwitch;
-
-import org.junit.After;
-import org.junit.Assume;
-import org.junit.Before;
-import org.junit.Test;
-
-public class TaplTestsSplitscreen extends AbstractQuickStepTest {
-    private static final String CALCULATOR_APP_NAME = "Calculator";
-    private static final String CALCULATOR_APP_PACKAGE =
-            resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR);
-
-    @Override
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-        TaplTestsLauncher3.initialize(this);
-
-        mLauncher.getWorkspace()
-                .deleteAppIcon(mLauncher.getWorkspace().getHotseatAppIcon(0))
-                .switchToAllApps()
-                .getAppIcon(CALCULATOR_APP_NAME)
-                .dragToHotseat(0);
-
-        startAppFast(CALCULATOR_APP_PACKAGE);
-        mLauncher.enableBlockTimeout(true);
-        mLauncher.showTaskbarIfHidden();
-    }
-
-    @After
-    public void tearDown() {
-        mLauncher.enableBlockTimeout(false);
-    }
-
-    @Test
-    // TODO (b/270201357): When this test is proven stable, remove this TestStabilityRule and
-    // introduce into presubmit as well.
-    @TestStabilityRule.Stability(
-            flavors = TestStabilityRule.LOCAL | TestStabilityRule.PLATFORM_POSTSUBMIT)
-    @PortraitLandscape
-    @TaskbarModeSwitch
-    public void testSplitAppFromHomeWithItself() throws Exception {
-        Assume.assumeTrue(mLauncher.isTablet());
-
-        mLauncher.goHome()
-                .switchToAllApps()
-                .getAppIcon(CALCULATOR_APP_NAME)
-                .openMenu()
-                .getSplitScreenMenuItem()
-                .click();
-
-        mLauncher.getLaunchedAppState()
-                .getTaskbar()
-                .getAppIcon(CALCULATOR_APP_NAME)
-                .launchIntoSplitScreen();
-    }
-}
diff --git a/res/drawable/ic_split_horizontal.xml b/res/drawable/ic_split_horizontal.xml
index ee710d0..2efd2b9 100644
--- a/res/drawable/ic_split_horizontal.xml
+++ b/res/drawable/ic_split_horizontal.xml
@@ -1,9 +1,9 @@
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="20dp"
-    android:height="16dp"
-    android:viewportWidth="20"
-    android:viewportHeight="16">
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
   <path
-      android:pathData="M18,14L13,14L13,2L18,2L18,14ZM20,14L20,2C20,0.9 19.1,-0 18,-0L13,-0C11.9,-0 11,0.9 11,2L11,14C11,15.1 11.9,16 13,16L18,16C19.1,16 20,15.1 20,14ZM7,14L2,14L2,2L7,2L7,14ZM9,14L9,2C9,0.9 8.1,-0 7,-0L2,-0C0.9,-0 -0,0.9 -0,2L-0,14C-0,15.1 0.9,16 2,16L7,16C8.1,16 9,15.1 9,14Z"
+      android:pathData="M4,6L9,6L9,18L4,18L4,6ZM2,6L2,18C2,19.1 2.9,20 4,20L9,20C10.1,20 11,19.1 11,18L11,6C11,4.9 10.1,4 9,4L4,4C2.9,4 2,4.9 2,6ZM15,6L20,6L20,18L15,18L15,6ZM13,6L13,18C13,19.1 13.9,20 15,20L20,20C21.1,20 22,19.1 22,18L22,6C22,4.9 21.1,4 20,4L15,4C13.9,4 13,4.9 13,6Z"
       android:fillColor="#000000"/>
 </vector>
diff --git a/res/layout/system_shortcut_icons_container.xml b/res/layout/system_shortcut_icons_container.xml
index ee104d9..dc4fdb3 100644
--- a/res/layout/system_shortcut_icons_container.xml
+++ b/res/layout/system_shortcut_icons_container.xml
@@ -22,11 +22,4 @@
     android:orientation="horizontal"
     android:gravity="end|center_vertical"
     android:background="@drawable/single_item_primary"
-    android:elevation="@dimen/deep_shortcuts_elevation"
-    android:clipToPadding="true">
-
-    <Space android:layout_width="0dp"
-        android:layout_height="match_parent"
-        android:layout_weight="1"
-        android:id="@+id/separator"/>
-</LinearLayout>
+    android:elevation="@dimen/deep_shortcuts_elevation"/>
diff --git a/res/layout/system_shortcut_icons_container_material_u.xml b/res/layout/system_shortcut_icons_container_material_u.xml
index afd11e6..70950ba 100644
--- a/res/layout/system_shortcut_icons_container_material_u.xml
+++ b/res/layout/system_shortcut_icons_container_material_u.xml
@@ -23,10 +23,4 @@
     android:orientation="horizontal"
     android:gravity="end|center_vertical"
     android:background="@drawable/popup_background_material_u"
-    android:elevation="@dimen/deep_shortcuts_elevation">
-
-    <Space android:layout_width="0dp"
-        android:layout_height="match_parent"
-        android:layout_weight="1"
-        android:id="@+id/separator"/>
-</LinearLayout>
+    android:elevation="@dimen/deep_shortcuts_elevation"/>
diff --git a/res/layout/system_shortcut_rows_container_material_u.xml b/res/layout/system_shortcut_rows_container.xml
similarity index 100%
rename from res/layout/system_shortcut_rows_container_material_u.xml
rename to res/layout/system_shortcut_rows_container.xml
diff --git a/res/layout/system_shortcut_spacer.xml b/res/layout/system_shortcut_spacer.xml
new file mode 100644
index 0000000..60ea9ec
--- /dev/null
+++ b/res/layout/system_shortcut_spacer.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<Space
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="0dp"
+    android:layout_height="match_parent"
+    android:layout_weight="1"
+    android:id="@+id/shortcut_spacer"/>
\ No newline at end of file
diff --git a/res/values/id.xml b/res/values/id.xml
index 375750f..dc81944 100644
--- a/res/values/id.xml
+++ b/res/values/id.xml
@@ -38,4 +38,7 @@
     <item type="id" name="cache_entry_tag_id" />
 
     <item type="id" name="saved_clip_children_tag_id" />
+
+    <item type="id" name="saved_floating_widget_foreground" />
+    <item type="id" name="saved_floating_widget_background" />
 </resources>
diff --git a/src/com/android/launcher3/LauncherSettings.java b/src/com/android/launcher3/LauncherSettings.java
index 76cae6a..66ea616 100644
--- a/src/com/android/launcher3/LauncherSettings.java
+++ b/src/com/android/launcher3/LauncherSettings.java
@@ -41,10 +41,6 @@
          * An animation using the view's background.
          */
         public static final int VIEW_BACKGROUND = 1;
-        /**
-         * The default animation for a given view/item info type, but without the splash icon.
-         */
-        public static final int DEFAULT_NO_ICON = 2;
     }
 
     /**
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index e3bce87..b5bc60d 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -16,8 +16,6 @@
 
 package com.android.launcher3;
 
-import static androidx.annotation.VisibleForTesting.PACKAGE_PRIVATE;
-
 import static com.android.launcher3.anim.Interpolators.SCROLL;
 import static com.android.launcher3.compat.AccessibilityManagerCompat.isAccessibilityEnabled;
 import static com.android.launcher3.compat.AccessibilityManagerCompat.isObservedEventType;
@@ -52,7 +50,6 @@
 import android.widget.ScrollView;
 
 import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
 
 import com.android.launcher3.compat.AccessibilityManagerCompat;
 import com.android.launcher3.config.FeatureFlags;
@@ -319,7 +316,6 @@
     /**
      * Returns an IntSet with the indices of the currently visible pages
      */
-    @VisibleForTesting(otherwise = PACKAGE_PRIVATE)
     public IntSet getVisiblePageIndices() {
         return getPageIndices(mCurrentPage);
     }
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 54bf6a8..85d7a05 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -355,7 +355,7 @@
             });
         }
 
-        if(FeatureFlags.ENABLE_HAPTICS_ALL_APPS.get() && config.userControlled
+        if(FeatureFlags.ENABLE_PREMIUM_HAPTICS_ALL_APPS.get() && config.userControlled
                 && Utilities.ATLEAST_S) {
             if (toState == ALL_APPS) {
                 builder.addOnFrameListener(
@@ -385,8 +385,9 @@
         builder.add(anim);
 
         setAlphas(toState, config, builder);
-
-        if (ALL_APPS.equals(toState) && mLauncher.isInState(NORMAL) && !(Utilities.ATLEAST_S)) {
+        // This controls both haptics for tapping on QSB and going to all apps.
+        if (ALL_APPS.equals(toState) && mLauncher.isInState(NORMAL) &&
+                !FeatureFlags.ENABLE_PREMIUM_HAPTICS_ALL_APPS.get()) {
             mLauncher.getAppsView().performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
                     HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
         }
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 98b61d1..6bb2a0f 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -352,8 +352,9 @@
             "Enable the ability to tap a staged app during split select to launch it in full screen"
     );
 
-    public static final BooleanFlag ENABLE_HAPTICS_ALL_APPS = getDebugFlag(270396358,
-            "ENABLE_HAPTICS_ALL_APPS", false, "Enables haptics opening/closing All apps");
+    public static final BooleanFlag ENABLE_PREMIUM_HAPTICS_ALL_APPS = getDebugFlag(270396358,
+            "ENABLE_PREMIUM_HAPTICS_ALL_APPS", false,
+            "Enables haptics opening/closing All apps");
 
     public static final BooleanFlag ENABLE_FORCED_MONO_ICON = getDebugFlag(270396209,
             "ENABLE_FORCED_MONO_ICON", false,
diff --git a/src/com/android/launcher3/graphics/SysUiScrim.java b/src/com/android/launcher3/graphics/SysUiScrim.java
index e983a30..be995bc 100644
--- a/src/com/android/launcher3/graphics/SysUiScrim.java
+++ b/src/com/android/launcher3/graphics/SysUiScrim.java
@@ -126,8 +126,14 @@
         mMaskHeight = ResourceUtils.pxFromDp(ALPHA_MASK_BITMAP_DP,
                 view.getResources().getDisplayMetrics());
         mTopScrim = Themes.getAttrDrawable(view.getContext(), R.attr.workspaceStatusBarScrim);
-        mBottomMask = mTopScrim == null ? null : createDitheredAlphaMask();
-        mHideSysUiScrim = mTopScrim == null;
+        if (mTopScrim != null) {
+            mTopScrim.setDither(true);
+            mBottomMask = createDitheredAlphaMask();
+            mHideSysUiScrim = false;
+        } else {
+            mBottomMask = null;
+            mHideSysUiScrim = true;
+        }
 
         mDrawWallpaperScrim = FeatureFlags.ENABLE_WALLPAPER_SCRIM.get()
                 && !Themes.getAttrBoolean(view.getContext(), R.attr.isMainColorDark)
diff --git a/src/com/android/launcher3/popup/ArrowPopup.java b/src/com/android/launcher3/popup/ArrowPopup.java
index a0f21dc..be3a09b 100644
--- a/src/com/android/launcher3/popup/ArrowPopup.java
+++ b/src/com/android/launcher3/popup/ArrowPopup.java
@@ -60,9 +60,7 @@
 import com.android.launcher3.views.ActivityContext;
 import com.android.launcher3.views.BaseDragLayer;
 
-import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 
 /**
  * A container for shortcuts to deep links and notifications associated with an app.
@@ -337,23 +335,6 @@
     }
 
     /**
-     * Shows the popup at the desired location, optionally reversing the children.
-     * @param viewsToFlip number of views from the top to to flip in case of reverse order
-     */
-    protected void reorderAndShow(int viewsToFlip) {
-        setupForDisplay();
-        boolean reverseOrder = !ENABLE_MATERIAL_U_POPUP.get() && mIsAboveIcon;
-        if (reverseOrder) {
-            reverseOrder(viewsToFlip);
-        }
-        assignMarginsAndBackgrounds(this);
-        if (shouldAddArrow()) {
-            addArrow();
-        }
-        animateOpen();
-    }
-
-    /**
      * Shows the popup at the desired location.
      */
     public void show() {
@@ -372,22 +353,6 @@
         orientAboutObject();
     }
 
-    private void reverseOrder(int viewsToFlip) {
-        int count = getChildCount();
-        ArrayList<View> allViews = new ArrayList<>(count);
-        for (int i = 0; i < count; i++) {
-            if (i == viewsToFlip) {
-                Collections.reverse(allViews);
-            }
-            allViews.add(getChildAt(i));
-        }
-        Collections.reverse(allViews);
-        removeAllViews();
-        for (int i = 0; i < count; i++) {
-            addView(allViews.get(i));
-        }
-    }
-
     private int getArrowLeft() {
         if (mIsLeftAligned) {
             return mArrowOffsetHorizontal;
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index 8fef5c6..c20ac17 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -227,17 +227,18 @@
         if (ENABLE_MATERIAL_U_POPUP.get()) {
             container = (PopupContainerWithArrow) launcher.getLayoutInflater().inflate(
                     R.layout.popup_container_material_u, launcher.getDragLayer(), false);
+            container.configureForLauncher(launcher);
             container.populateAndShowRowsMaterialU(icon, deepShortcutCount, systemShortcuts);
         } else {
             container = (PopupContainerWithArrow) launcher.getLayoutInflater().inflate(
                     R.layout.popup_container, launcher.getDragLayer(), false);
+            container.configureForLauncher(launcher);
             container.populateAndShow(
                     icon,
                     deepShortcutCount,
                     popupDataProvider.getNotificationKeysForItem(item),
                     systemShortcuts);
         }
-        container.configureForLauncher(launcher);
         launcher.refreshAndBindWidgetsForPackageUser(PackageUserKey.fromItemInfo(item));
         container.requestFocus();
         return container;
@@ -257,14 +258,19 @@
         }
         // If there is only 1 shortcut, add it to its own container so it can show text and icon
         if (shortcuts.size() == 1) {
-            initializeSystemShortcut(R.layout.system_shortcut, this, shortcuts.get(0));
+            mSystemShortcutContainer = inflateAndAdd(R.layout.system_shortcut_rows_container,
+                    this, 0);
+            initializeSystemShortcut(R.layout.system_shortcut, mSystemShortcutContainer,
+                    shortcuts.get(0), false);
             return;
         }
-        mSystemShortcutContainer = inflateAndAdd(R.layout.system_shortcut_icons_container, this);
-        for (SystemShortcut shortcut : shortcuts) {
+        mSystemShortcutContainer = inflateAndAdd(R.layout.system_shortcut_icons_container, this, 0);
+        for (int i = 0; i < shortcuts.size(); i++) {
             initializeSystemShortcut(
-                    R.layout.system_shortcut_icon_only, mSystemShortcutContainer,
-                    shortcut);
+                    R.layout.system_shortcut_icon_only,
+                    mSystemShortcutContainer,
+                    shortcuts.get(i),
+                    i < shortcuts.size() - 1);
         }
     }
 
@@ -289,7 +295,6 @@
             }
             updateNotificationHeader();
         }
-        int viewsToFlip = getChildCount();
         mSystemShortcutContainer = this;
         if (mDeepShortcutContainer == null) {
             mDeepShortcutContainer = findViewById(R.id.deep_shortcuts_container);
@@ -314,8 +319,7 @@
             Optional<SystemShortcut.Widgets> widgetShortcutOpt = getWidgetShortcut(shortcuts);
             if (widgetShortcutOpt.isPresent()) {
                 if (mWidgetContainer == null) {
-                    mWidgetContainer = inflateAndAdd(R.layout.widget_shortcut_container,
-                            this);
+                    mWidgetContainer = inflateAndAdd(R.layout.widget_shortcut_container, this, 0);
                 }
                 initializeWidgetShortcut(mWidgetContainer, widgetShortcutOpt.get());
             }
@@ -324,14 +328,17 @@
         } else {
             mDeepShortcutContainer.setVisibility(View.GONE);
             if (!shortcuts.isEmpty()) {
-                for (SystemShortcut shortcut : shortcuts) {
-                    initializeSystemShortcut(R.layout.system_shortcut, this, shortcut);
+                for (int i = 0; i < shortcuts.size(); i++) {
+                    initializeSystemShortcut(
+                            R.layout.system_shortcut,
+                            this,
+                            shortcuts.get(i),
+                            i < shortcuts.size() - 1);
                 }
             }
         }
-
-        reorderAndShow(viewsToFlip);
-        showPopupContainer((ItemInfo) originalIcon.getTag(), notificationKeys);
+        show();
+        loadAppShortcuts((ItemInfo) originalIcon.getTag(), notificationKeys);
     }
 
     /**
@@ -351,19 +358,17 @@
             addAllShortcutsMaterialU(deepShortcutCount, systemShortcuts);
         } else if (!systemShortcuts.isEmpty()) {
             addSystemShortcutsMaterialU(systemShortcuts,
-                    R.layout.system_shortcut_rows_container_material_u,
+                    R.layout.system_shortcut_rows_container,
                     R.layout.system_shortcut);
         }
-
-        // no reversing needed for U design
-        reorderAndShow(0);
-        showPopupContainer((ItemInfo) originalIcon.getTag(), /* notificationKeys= */ emptyList());
+        show();
+        loadAppShortcuts((ItemInfo) originalIcon.getTag(), /* notificationKeys= */ emptyList());
     }
 
     /**
      * Animates and loads shortcuts on background thread for this popup container
      */
-    private void showPopupContainer(ItemInfo originalItemInfo,
+    private void loadAppShortcuts(ItemInfo originalItemInfo,
             List<NotificationKeyData> notificationKeys) {
 
         if (ATLEAST_P) {
@@ -390,7 +395,7 @@
         if (deepShortcutCount + systemShortcuts.size() <= SHORTCUT_COLLAPSE_THRESHOLD) {
             // add all system shortcuts including widgets shortcut to same container
             addSystemShortcutsMaterialU(systemShortcuts,
-                    R.layout.system_shortcut_rows_container_material_u,
+                    R.layout.system_shortcut_rows_container,
                     R.layout.system_shortcut);
             addDeepShortcutsMaterialU(deepShortcutCount);
             return;
@@ -458,8 +463,12 @@
             return;
         }
         mSystemShortcutContainer = inflateAndAdd(systemShortcutContainerLayout, this);
-        for (SystemShortcut shortcut : systemShortcuts) {
-            initializeSystemShortcut(systemShortcutLayout, mSystemShortcutContainer, shortcut);
+        for (int i = 0; i < systemShortcuts.size(); i++) {
+            initializeSystemShortcut(
+                    systemShortcutLayout,
+                    mSystemShortcutContainer,
+                    systemShortcuts.get(i),
+                    i < systemShortcuts.size() - 1);
         }
     }
 
@@ -533,20 +542,31 @@
     }
 
     protected void initializeWidgetShortcut(ViewGroup container, SystemShortcut info) {
-        View view = initializeSystemShortcut(R.layout.system_shortcut, container, info);
+        View view = initializeSystemShortcut(R.layout.system_shortcut, container, info, false);
         view.getLayoutParams().width = mContainerWidth;
     }
 
-    protected View initializeSystemShortcut(int resId, ViewGroup container, SystemShortcut info) {
-        View view = inflateAndAdd(
-                resId, container, getInsertIndexForSystemShortcut(container, info));
+    /**
+     * Initializes and adds View for given SystemShortcut to a container.
+     * @param resId Resource id to use for SystemShortcut View.
+     * @param container ViewGroup to add the shortcut View to as a parent
+     * @param info The SystemShortcut instance to create a View for.
+     * @param shouldAddSpacer If True, will add a spacer after the shortcut, when showing the
+     *                        SystemShortcut as an icon only. Used to space the shortcut icons
+     *                        evenly.
+     * @return The view inflated for the SystemShortcut
+     */
+    protected View initializeSystemShortcut(int resId, ViewGroup container, SystemShortcut info,
+            boolean shouldAddSpacer) {
+        View view = inflateAndAdd(resId, container);
         if (view instanceof DeepShortcutView) {
-            // Expanded system shortcut, with both icon and text shown on white background.
+            // System shortcut takes entire row with icon and text
             final DeepShortcutView shortcutView = (DeepShortcutView) view;
             info.setIconAndLabelFor(shortcutView.getIconView(), shortcutView.getBubbleText());
         } else if (view instanceof ImageView) {
-            // Only the system shortcut icon shows on a gray background header.
+            // System shortcut is just an icon
             info.setIconAndContentDescriptionFor((ImageView) view);
+            if (shouldAddSpacer) inflateAndAdd(R.layout.system_shortcut_spacer, container);
             view.setTooltipText(view.getContentDescription());
         }
         view.setTag(info);
@@ -555,17 +575,6 @@
     }
 
     /**
-     * Returns an index for inserting a shortcut into a container.
-     */
-    private int getInsertIndexForSystemShortcut(ViewGroup container, SystemShortcut shortcut) {
-        final View separator = container.findViewById(R.id.separator);
-
-        return separator != null && shortcut.isLeftGroup() ?
-                container.indexOfChild(separator) :
-                container.getChildCount();
-    }
-
-    /**
      * Determines when the deferred drag should be started.
      *
      * Current behavior:
diff --git a/src/com/android/launcher3/util/MultiTranslateDelegate.java b/src/com/android/launcher3/util/MultiTranslateDelegate.java
index 0b5bc8d..1cb7a45 100644
--- a/src/com/android/launcher3/util/MultiTranslateDelegate.java
+++ b/src/com/android/launcher3/util/MultiTranslateDelegate.java
@@ -33,7 +33,7 @@
     public static final int INDEX_REORDER_PREVIEW_OFFSET = 1;
     public static final int INDEX_MOVE_FROM_CENTER_ANIM = 2;
 
-    // Specific for icons and folders
+    // Specific for items in taskbar (icons, folders, qsb)
     public static final int INDEX_TASKBAR_ALIGNMENT_ANIM = 3;
     public static final int INDEX_TASKBAR_REVEAL_ANIM = 4;
 
diff --git a/src/com/android/launcher3/views/ActivityContext.java b/src/com/android/launcher3/views/ActivityContext.java
index 10f40b7..b6f6223 100644
--- a/src/com/android/launcher3/views/ActivityContext.java
+++ b/src/com/android/launcher3/views/ActivityContext.java
@@ -45,7 +45,6 @@
 import android.view.WindowInsetsController;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.Toast;
-import android.window.SplashScreen;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -321,14 +320,7 @@
             return false;
         }
 
-        Bundle optsBundle = null;
-        if (v != null) {
-            optsBundle = getActivityLaunchOptions(v, item).toBundle();
-        } else if (item != null && item.animationType == LauncherSettings.Animation.DEFAULT_NO_ICON
-                && Utilities.ATLEAST_T) {
-            optsBundle = ActivityOptions.makeBasic()
-                    .setSplashScreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_SOLID_COLOR).toBundle();
-        }
+        Bundle optsBundle = (v != null) ? getActivityLaunchOptions(v, item).toBundle() : null;
         UserHandle user = item == null ? null : item.user;
 
         // Prepare intent
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index 55af622..e233e46 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -95,6 +95,9 @@
     private ClipIconView mClipIconView;
     private @Nullable Drawable mBadge;
 
+    // A view whose visibility should update in sync with mOriginalIcon.
+    private @Nullable View mMatchVisibilityView;
+
     private View mOriginalIcon;
     private RectF mPositionOut;
     private Runnable mOnTargetChangeRunnable;
@@ -386,7 +389,7 @@
      * Checks if the icon result is loaded. If true, we set the icon immediately. Else, we add a
      * callback to set the icon once the icon result is loaded.
      */
-    private void checkIconResult(View originalView) {
+    private void checkIconResult() {
         CancellationSignal cancellationSignal = new CancellationSignal();
 
         if (mIconLoadResult == null) {
@@ -399,7 +402,7 @@
                 setIcon(mIconLoadResult.drawable, mIconLoadResult.badge,
                         mIconLoadResult.btvDrawable, mIconLoadResult.iconOffset);
                 setVisibility(VISIBLE);
-                setIconAndDotVisible(originalView, false);
+                updateViewsVisibility(false  /* isVisible */);
             } else {
                 mIconLoadResult.onIconLoaded = () -> {
                     if (cancellationSignal.isCanceled()) {
@@ -410,7 +413,7 @@
                             mIconLoadResult.btvDrawable, mIconLoadResult.iconOffset);
 
                     setVisibility(VISIBLE);
-                    setIconAndDotVisible(originalView, false);
+                    updateViewsVisibility(false  /* isVisible */);
                 };
                 mLoadIconSignal = cancellationSignal;
             }
@@ -481,9 +484,9 @@
             // No need to wait for icon load since we can display the BubbleTextView drawable.
             setVisibility(View.VISIBLE);
         }
-        if (!mIsOpening && mOriginalIcon != null) {
+        if (!mIsOpening) {
             // When closing an app, we want the item on the workspace to be invisible immediately
-            setIconAndDotVisible(mOriginalIcon, false);
+            updateViewsVisibility(false  /* isVisible */);
         }
     }
 
@@ -562,13 +565,14 @@
     /**
      * Creates a floating icon view for {@param originalView}.
      * @param originalView The view to copy
+     * @param secondView A view whose visibility should update in sync with originalView.
      * @param hideOriginal If true, it will hide {@param originalView} while this view is visible.
      *                     Else, we will not draw anything in this view.
      * @param positionOut Rect that will hold the size and position of v.
      * @param isOpening True if this view replaces the icon for app open animation.
      */
     public static FloatingIconView getFloatingIconView(Launcher launcher, View originalView,
-            boolean hideOriginal, RectF positionOut, boolean isOpening) {
+            @Nullable View secondView, boolean hideOriginal, RectF positionOut, boolean isOpening) {
         final DragLayer dragLayer = launcher.getDragLayer();
         ViewGroup parent = (ViewGroup) dragLayer.getParent();
         FloatingIconView view = launcher.getViewCache().getView(R.layout.floating_icon_view,
@@ -578,6 +582,7 @@
         // Init properties before getting the drawable.
         view.mIsOpening = isOpening;
         view.mOriginalIcon = originalView;
+        view.mMatchVisibilityView = secondView;
         view.mPositionOut = positionOut;
 
         // Get the drawable on the background thread
@@ -597,7 +602,8 @@
         view.matchPositionOf(launcher, originalView, isOpening, positionOut);
 
         // We need to add it to the overlay, but keep it invisible until animation starts..
-        setIconAndDotVisible(view, false);
+        view.setVisibility(View.INVISIBLE);
+
         parent.addView(view);
         dragLayer.addView(view.mListenerView);
         view.mListenerView.setListener(view::fastFinish);
@@ -606,7 +612,7 @@
             view.mEndRunnable = null;
 
             if (hideOriginal) {
-                setIconAndDotVisible(originalView, true);
+                view.updateViewsVisibility(true /* isVisible */);
                 view.finish(dragLayer);
             } else {
                 view.finish(dragLayer);
@@ -617,12 +623,21 @@
         // Must be called after the fastFinish listener and end runnable is created so that
         // the icon is not left in a hidden state.
         if (shouldLoadIcon) {
-            view.checkIconResult(originalView);
+            view.checkIconResult();
         }
 
         return view;
     }
 
+    private void updateViewsVisibility(boolean isVisible) {
+        if (mOriginalIcon != null) {
+            setIconAndDotVisible(mOriginalIcon, isVisible);
+        }
+        if (mMatchVisibilityView != null) {
+            setIconAndDotVisible(mMatchVisibilityView, isVisible);
+        }
+    }
+
     private void finish(DragLayer dragLayer) {
         ((ViewGroup) dragLayer.getParent()).removeView(this);
         dragLayer.removeView(mListenerView);
diff --git a/src/com/android/launcher3/views/IconButtonView.java b/src/com/android/launcher3/views/IconButtonView.java
index 71f6756..0ac1919 100644
--- a/src/com/android/launcher3/views/IconButtonView.java
+++ b/src/com/android/launcher3/views/IconButtonView.java
@@ -29,6 +29,7 @@
 import android.graphics.drawable.Drawable;
 import android.os.Build;
 import android.util.AttributeSet;
+import android.view.accessibility.AccessibilityEvent;
 
 import androidx.annotation.ColorInt;
 import androidx.annotation.NonNull;
@@ -78,6 +79,12 @@
         }
     }
 
+    @Override
+    public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
+        super.onPopulateAccessibilityEvent(event);
+        event.getText().add(this.getContentDescription());
+    }
+
     /** Sets given Drawable as icon */
     public void setIconDrawable(@NonNull Drawable drawable) {
         ColorStateList tintList = getBackgroundTintList();
diff --git a/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java b/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java
index 667290f..82d9630 100644
--- a/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java
+++ b/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java
@@ -54,14 +54,5 @@
         return createMenuItem(menuItem);
     }
 
-    /**
-     * Returns a menu item that matches the text "Split screen". Fails if it doesn't exist.
-     */
-    public SplitScreenMenuItem getSplitScreenMenuItem() {
-        final UiObject2 menuItem = mLauncher.waitForObjectInContainer(mDeepShortcutsContainer,
-                AppIcon.getAppIconSelector("Split screen", mLauncher));
-        return new SplitScreenMenuItem(mLauncher, menuItem);
-    }
-
     protected abstract AppIconMenuItem createMenuItem(UiObject2 menuItem);
 }
diff --git a/tests/tapl/com/android/launcher3/tapl/Launchable.java b/tests/tapl/com/android/launcher3/tapl/Launchable.java
index 48e327f..3dcb437 100644
--- a/tests/tapl/com/android/launcher3/tapl/Launchable.java
+++ b/tests/tapl/com/android/launcher3/tapl/Launchable.java
@@ -76,27 +76,6 @@
         }
     }
 
-    /**
-     * Clicks a launcher object to initiate splitscreen, where the selected app will be one of two
-     * apps running on the screen. Should be called when Launcher is in a "split staging" state
-     * and is waiting for the user's selection of a second app. Expects a SPLIT_START_EVENT to be
-     * fired when the click is executed.
-     */
-    public LaunchedAppState launchIntoSplitScreen() {
-        try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
-                "want to launch split tasks from " + launchableType())) {
-            LauncherInstrumentation.log("Launchable.launch before click "
-                    + mObject.getVisibleCenter() + " in " + mLauncher.getVisibleBounds(mObject));
-
-            mLauncher.clickLauncherObject(mObject);
-
-            try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer("clicked")) {
-                mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, OverviewTask.SPLIT_START_EVENT);
-                return new LaunchedAppState(mLauncher);
-            }
-        }
-    }
-
     protected LaunchedAppState assertAppLaunched(BySelector selector) {
         mLauncher.assertTrue(
                 "App didn't start: (" + selector + ")",
diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
index 90f3d13..adc993d 100644
--- a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
+++ b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
@@ -37,9 +37,10 @@
 public final class OverviewTask {
     private static final String SYSTEMUI_PACKAGE = "com.android.systemui";
 
-    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");
+    static final Pattern TASK_START_EVENT =
+            Pattern.compile("startActivityFromRecentsAsync");
+    static final Pattern SPLIT_START_EVENT =
+            Pattern.compile("launchSplitTasks");
     private final LauncherInstrumentation mLauncher;
     private final UiObject2 mTask;
     private final BaseOverview mOverview;
diff --git a/tests/tapl/com/android/launcher3/tapl/SplitScreenMenuItem.java b/tests/tapl/com/android/launcher3/tapl/SplitScreenMenuItem.java
deleted file mode 100644
index 47cf20b..0000000
--- a/tests/tapl/com/android/launcher3/tapl/SplitScreenMenuItem.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2023 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.tapl;
-
-import androidx.test.uiautomator.UiObject2;
-
-import com.android.launcher3.testing.shared.TestProtocol;
-
-/**
- * A class representing the "Split screen" menu item in the app long-press menu. Used for TAPL
- * testing in a similar way as other menu items {@link AppIconMenuItem}, but unlike AppIconMenuItem,
- * the split screen command does not trigger an app launch. Instead, it causes Launcher to shift to
- * a different state (OverviewSplitSelect).
- */
-public final class SplitScreenMenuItem {
-    private final LauncherInstrumentation mLauncher;
-    private final UiObject2 mObject;
-
-    SplitScreenMenuItem(LauncherInstrumentation launcher, UiObject2 object) {
-        mLauncher = launcher;
-        mObject = object;
-    }
-
-    /**
-     * Executes a click command on this menu item. Expects a SPLIT_SELECT_EVENT to be fired.
-     */
-    public void click() {
-        try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
-                "want to enter split select from app long-press menu")) {
-            LauncherInstrumentation.log("clicking on split screen menu item "
-                    + mObject.getVisibleCenter() + " in " + mLauncher.getVisibleBounds(mObject));
-
-            mLauncher.clickLauncherObject(mObject);
-
-            try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer("clicked")) {
-                mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, OverviewTask.SPLIT_SELECT_EVENT);
-                mLauncher.waitForLauncherObject("split_placeholder");
-            }
-        }
-    }
-}