Merge "Make sure ReorderAlgorithm only work on the logic layer and not on the view layer" into main
diff --git a/quickstep/res/layout/icon_app_chip_view.xml b/quickstep/res/layout/icon_app_chip_view.xml
index 87519a0..37d5eb2 100644
--- a/quickstep/res/layout/icon_app_chip_view.xml
+++ b/quickstep/res/layout/icon_app_chip_view.xml
@@ -26,10 +26,22 @@
     android:elevation="@dimen/task_thumbnail_icon_menu_elevation" >
 
     <ImageView
+        android:id="@+id/icon_view_background_corners_start"
+        android:layout_width="@dimen/task_thumbnail_icon_menu_corner_width"
+        android:layout_height="@dimen/task_thumbnail_icon_menu_min_height"
+        android:src="@drawable/icon_menu_background_corners"
+        android:importantForAccessibility="no" />
+    <ImageView
         android:id="@+id/icon_view_background"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:background="@drawable/icon_menu_background"
+        android:layout_width="@dimen/task_thumbnail_icon_menu_background_min_width"
+        android:layout_height="@dimen/task_thumbnail_icon_menu_min_height"
+        android:src="@drawable/icon_menu_background"
+        android:importantForAccessibility="no" />
+    <ImageView
+        android:id="@+id/icon_view_background_corners_end"
+        android:layout_width="@dimen/task_thumbnail_icon_menu_corner_width"
+        android:layout_height="@dimen/task_thumbnail_icon_menu_min_height"
+        android:src="@drawable/icon_menu_background_corners"
         android:importantForAccessibility="no" />
 
     <com.android.quickstep.views.IconView
@@ -40,20 +52,33 @@
         android:importantForAccessibility="no" />
 
     <TextView
-        android:id="@+id/icon_text"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:gravity="center_vertical"
+        android:id="@+id/icon_text_collapsed"
+        android:layout_width="@dimen/task_thumbnail_icon_menu_text_width"
+        android:layout_height="@dimen/task_thumbnail_icon_menu_drawable_size"
+        android:gravity="start|center_vertical"
         android:maxLines="1"
+        android:ellipsize="end"
         android:textAlignment="viewStart"
         android:textColor="?androidprv:attr/materialColorOnSurface"
-        android:textSize="16sp"
+        android:textSize="@dimen/task_thumbnail_icon_menu_text_size"
+        android:importantForAccessibility="no" />
+
+    <TextView
+        android:id="@+id/icon_text_expanded"
+        android:layout_width="@dimen/task_thumbnail_icon_menu_text_max_width"
+        android:layout_height="@dimen/task_thumbnail_icon_menu_drawable_size"
+        android:gravity="start|center_vertical"
+        android:maxLines="1"
+        android:ellipsize="end"
+        android:textAlignment="viewStart"
+        android:textColor="?androidprv:attr/materialColorOnSurface"
+        android:textSize="@dimen/task_thumbnail_icon_menu_text_size"
         android:importantForAccessibility="no" />
 
     <ImageView
         android:id="@+id/icon_arrow"
         android:layout_width="@dimen/task_thumbnail_icon_menu_arrow_size"
-        android:layout_height="match_parent"
+        android:layout_height="@dimen/task_thumbnail_icon_menu_arrow_size"
         android:background="@drawable/icon_menu_arrow_background"
         android:src="@drawable/ic_chevron_down"
         android:importantForAccessibility="no" />
diff --git a/quickstep/res/layout/task_menu.xml b/quickstep/res/layout/task_menu.xml
index a5c9445..622edfe 100644
--- a/quickstep/res/layout/task_menu.xml
+++ b/quickstep/res/layout/task_menu.xml
@@ -31,8 +31,8 @@
         android:layout_height="match_parent"
         android:gravity="center"
         android:layout_marginBottom="2dp"
-        android:paddingTop="@dimen/task_menu_vertical_padding"
-        android:paddingBottom="@dimen/task_menu_vertical_padding"
+        android:paddingTop="@dimen/task_menu_edge_padding"
+        android:paddingBottom="@dimen/task_menu_edge_padding"
         android:textSize="16sp"/>
 
     <LinearLayout
diff --git a/quickstep/res/layout/task_view_menu_option.xml b/quickstep/res/layout/task_view_menu_option.xml
index c736c8c..30ab4b1 100644
--- a/quickstep/res/layout/task_view_menu_option.xml
+++ b/quickstep/res/layout/task_view_menu_option.xml
@@ -38,7 +38,7 @@
         android:id="@+id/text"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_marginStart="@dimen/task_menu_option_start_margin"
+        android:layout_marginStart="@dimen/task_menu_option_text_start_margin"
         android:textSize="14sp"
         android:textColor="?androidprv:attr/materialColorOnSurface"
         android:focusable="false" />
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 22f98fa..13a9fff 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -44,32 +44,50 @@
     <dimen name="overview_task_margin">16dp</dimen>
     <!--  The horizontal space between tasks  -->
     <dimen name="overview_page_spacing">16dp</dimen>
-    <!--  The width of the thumbnail icon menu  -->
-    <dimen name="task_thumbnail_icon_menu_min_width">132dp</dimen>
-    <!--  The width of the icon menu text  -->
-    <dimen name="task_thumbnail_icon_menu_text_width">62dp</dimen>
-    <!--  The max width of the icon menu text  -->
-    <dimen name="task_thumbnail_icon_menu_text_max_width">138dp</dimen>
+    <!--  The min width of the thumbnail icon menu for non-split tasks  -->
+    <dimen name="task_thumbnail_icon_menu_min_width">156dp</dimen>
     <!--  The max width of the thumbnail icon menu  -->
     <dimen name="task_thumbnail_icon_menu_max_width">216dp</dimen>
+    <!--  The width of the thumbnail icon menu background  -->
+    <dimen name="task_thumbnail_icon_menu_background_min_width">120dp</dimen>
+    <!--  The width of the icon menu text  -->
+    <dimen name="task_thumbnail_icon_menu_text_width">86dp</dimen>
+    <!--  The max width of the icon menu text  -->
+    <dimen name="task_thumbnail_icon_menu_text_max_width">118dp</dimen>
+    <!--  The size of the icon menu text  -->
+    <dimen name="task_thumbnail_icon_menu_text_size">16sp</dimen>
+    <!--  The max width of the thumbnail icon menu background  -->
+    <dimen name="task_thumbnail_icon_menu_background_max_width">164dp</dimen>
     <!--  The height of the thumbnail icon menu  -->
     <dimen name="task_thumbnail_icon_menu_min_height">36dp</dimen>
+    <!--  The corner radius of the thumbnail icon menu  -->
+    <dimen name="task_thumbnail_icon_menu_corner_radius">28dp</dimen>
+    <!--  The width of the thumbnail icon menu backgorund's corners when collapsed  -->
+    <dimen name="task_thumbnail_icon_menu_corner_width">36dp</dimen>
     <!--  The max height of the thumbnail icon menu  -->
     <dimen name="task_thumbnail_icon_menu_max_height">52dp</dimen>
     <!--  The size of the icon menu arrow  -->
-    <dimen name="task_thumbnail_icon_menu_arrow_size">32dp</dimen>
+    <dimen name="task_thumbnail_icon_menu_arrow_size">24dp</dimen>
     <!--  The size of the icon menu arrow drawable  -->
     <dimen name="task_thumbnail_icon_menu_arrow_drawable_size">16dp</dimen>
-    <!--  The margin around the task icon menu  -->
-    <dimen name="task_thumbnail_icon_menu_margin">12dp</dimen>
+    <!--  The margin at the start of the task icon menu  -->
+    <dimen name="task_thumbnail_icon_menu_start_margin">12dp</dimen>
+    <!--  The margin at the top of the task icon menu  -->
+    <dimen name="task_thumbnail_icon_menu_top_margin">6dp</dimen>
+    <!--  The margin at the top of the task icon menu when expanded  -->
+    <dimen name="task_thumbnail_icon_menu_top_margin_expanded">4dp</dimen>
+    <!--  The margin at the start of the task icon view in the icon menu  -->
+    <dimen name="task_thumbnail_icon_view_start_margin">6dp</dimen>
     <!--  The space around the task icon arrow within the icon menu  -->
-    <dimen name="task_thumbnail_icon_menu_arrow_margin">6dp</dimen>
+    <dimen name="task_thumbnail_icon_menu_arrow_margin">8dp</dimen>
     <!--  The max space around the task icon within the icon menu  -->
     <dimen name="task_thumbnail_icon_menu_touch_max_margin">8dp</dimen>
     <!--  The icon size for the icon menu  -->
     <dimen name="task_thumbnail_icon_menu_drawable_size">24dp</dimen>
+    <!--  The icon size for the icon menu  -->
+    <dimen name="task_thumbnail_icon_menu_drawable_max_size">32dp</dimen>
     <!--  The size of the icon menu's icon touch target  -->
-    <dimen name="task_thumbnail_icon_menu_drawable_touch_size">36dp</dimen>
+    <dimen name="task_thumbnail_icon_menu_drawable_touch_size">44dp</dimen>
     <dimen name="task_thumbnail_icon_menu_elevation">14dp</dimen>
 
     <dimen name="task_icon_cache_default_icon_size">72dp</dimen>
@@ -113,10 +131,11 @@
     <!-- Total space (start + end) between the task card and the edge of the screen
          in various configurations -->
     <dimen name="task_card_menu_option_vertical_padding">16dp</dimen>
-    <dimen name="task_menu_vertical_padding">8dp</dimen>
+    <dimen name="task_menu_edge_padding">8dp</dimen>
     <dimen name="task_card_margin">8dp</dimen>
     <dimen name="task_card_menu_shadow_height">3dp</dimen>
     <dimen name="task_menu_option_start_margin">16dp</dimen>
+    <dimen name="task_menu_option_text_start_margin">18dp</dimen>
     <!-- Copied from framework resource:
        docked_stack_divider_thickness - 2 * docked_stack_divider_insets -->
     <dimen name="multi_window_task_divider_size">10dp</dimen>
@@ -333,7 +352,7 @@
     <dimen name="taskbar_home_button_left_margin_kids">48dp</dimen>
     <dimen name="taskbar_icon_size_kids">32dp</dimen>
     <dimen name="taskbar_all_apps_button_translation_x_offset">6dp</dimen>
-    <dimen name="taskbar_all_apps_search_button_translation_x_offset">4.5dp</dimen>
+    <dimen name="taskbar_all_apps_search_button_translation_x_offset">6dp</dimen>
 
     <!-- Transient taskbar -->
     <dimen name="transient_taskbar_padding">12dp</dimen>
@@ -342,7 +361,7 @@
     <dimen name="transient_taskbar_shadow_blur">40dp</dimen>
     <dimen name="transient_taskbar_key_shadow_distance">10dp</dimen>
     <dimen name="transient_taskbar_stashed_height">32dp</dimen>
-    <dimen name="transient_taskbar_all_apps_button_translation_x_offset">4dp</dimen>
+    <dimen name="transient_taskbar_all_apps_button_translation_x_offset">8dp</dimen>
     <dimen name="transient_taskbar_stash_spring_velocity_dp_per_s">400dp</dimen>
     <dimen name="taskbar_tooltip_vertical_padding">8dp</dimen>
     <dimen name="taskbar_tooltip_horizontal_padding">16dp</dimen>
diff --git a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
index 2f84ac9..73b786f 100644
--- a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
@@ -174,7 +174,7 @@
             dismissTaskMenuView(mTarget);
             RecentsView rv = mTarget.getOverviewPanel();
             rv.switchToScreenshot(() -> {
-                rv.finishRecentsAnimation(true /* toHome */, () -> {
+                rv.finishRecentsAnimation(true /* toRecents */, false /* shouldPip */, () -> {
                     mTarget.returnToHomescreen();
                     rv.getHandler().post(this::startActivity);
                 });
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
index d38376c..8051e68 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
@@ -42,6 +42,7 @@
     private final Runnable mTriggerLongPress = this::triggerLongPress;
     private final float mTouchSlopSquared;
     private final int mLongPressTimeout;
+    private final boolean mDeepPressEnabled;
 
     private MotionEvent mCurrentDownEvent;
 
@@ -51,6 +52,7 @@
         mNavHandleWidth = context.getResources().getDimensionPixelSize(
                 R.dimen.navigation_home_handle_width);
         mScreenWidth = DisplayController.INSTANCE.get(context).getInfo().currentSize.x;
+        mDeepPressEnabled = FeatureFlags.ENABLE_LPNH_DEEP_PRESS.get();
         if (FeatureFlags.CUSTOM_LPNH_THRESHOLDS.get()) {
             mLongPressTimeout = LauncherPrefs.get(context).get(LONG_PRESS_NAV_HANDLE_TIMEOUT_MS);
         } else {
@@ -108,7 +110,7 @@
         }
 
         // If the gesture is deep press then trigger long press asap
-        if (MAIN_EXECUTOR.getHandler().hasCallbacks(mTriggerLongPress)
+        if (mDeepPressEnabled && MAIN_EXECUTOR.getHandler().hasCallbacks(mTriggerLongPress)
                 && ev.getClassification() == MotionEvent.CLASSIFICATION_DEEP_PRESS) {
             MAIN_EXECUTOR.getHandler().removeCallbacks(mTriggerLongPress);
             MAIN_EXECUTOR.getHandler().post(mTriggerLongPress);
diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
index 5b1d614..8559b37 100644
--- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
@@ -372,7 +372,20 @@
                                     mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx,
                             MeasureSpec.EXACTLY));
         }
-        updateIconPlacement();
+        if (!enableOverviewIconMenu()) {
+            updateIconPlacement();
+            return;
+        }
+
+        if (getRecentsView() == null) {
+            return;
+        }
+
+        int iconMargins = getResources().getDimensionPixelSize(
+                R.dimen.task_thumbnail_icon_menu_start_margin) * 2;
+        ((IconAppChipView) mIconView).setMaxWidth(mSnapshotView.getMeasuredWidth() - iconMargins);
+        ((IconAppChipView) mIconView2).setMaxWidth(mSnapshotView2.getMeasuredWidth() - iconMargins);
+        setOrientationState(getRecentsView().getPagedViewOrientedState());
     }
 
     @Override
diff --git a/quickstep/src/com/android/quickstep/views/IconAppChipView.java b/quickstep/src/com/android/quickstep/views/IconAppChipView.java
index 5a2e135..b14b917 100644
--- a/quickstep/src/com/android/quickstep/views/IconAppChipView.java
+++ b/quickstep/src/com/android/quickstep/views/IconAppChipView.java
@@ -16,13 +16,14 @@
 package com.android.quickstep.views;
 
 import static com.android.app.animation.Interpolators.EMPHASIZED;
-import static com.android.launcher3.Flags.enableOverviewIconMenu;
+import static com.android.app.animation.Interpolators.LINEAR;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.content.Context;
+import android.content.res.Resources;
 import android.graphics.drawable.AnimatedVectorDrawable;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
@@ -37,9 +38,8 @@
 
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.R;
-import com.android.launcher3.touch.LandscapePagedViewHandler;
+import com.android.launcher3.Utilities;
 import com.android.launcher3.touch.PagedOrientationHandler;
-import com.android.launcher3.touch.SeascapePagedViewHandler;
 import com.android.launcher3.views.ActivityContext;
 import com.android.quickstep.util.RecentsOrientedState;
 
@@ -52,20 +52,35 @@
     private static final int MENU_BACKGROUND_HIDE_DURATION = 333;
 
     private IconView mIconView;
-    private TextView mIconTextView;
+    // Two textview so we can ellipsize the collapsed view and crossfade on expand to the full name.
+    private TextView mIconTextCollapsedView;
+    private TextView mIconTextExpandedView;
     private ImageView mIconArrowView;
     private ImageView mIconViewBackground;
+    // Use separate views for the rounded corners so we can scale the background view without
+    // warping the corners.
+    private ImageView mIconViewBackgroundCornersStart;
+    private ImageView mIconViewBackgroundCornersEnd;
 
-    private int mMaxIconBackgroundWidth;
-    private int mMinIconBackgroundWidth;
-    private int mMaxIconBackgroundHeight;
-    private int mMinIconBackgroundHeight;
-    private int mIconTextMinWidth;
-    private int mIconTextMaxWidth;
-    private int mInnerMargin;
-    private int mIconArrowSize;
-    private int mIconMenuMarginStart;
-    private int mArrowMaxTranslationX;
+    private final int mMinimumMenuSize;
+    private final int mMaxMenuWidth;
+    private final int mIconMenuMarginTop;
+    private final int mIconMenuMarginStart;
+    private final int mIconViewMarginStart;
+    private final int mIconViewDrawableSize;
+    private final int mIconViewDrawableMaxSize;
+    private final int mIconTextMinWidth;
+    private final int mIconTextMaxWidth;
+    private final int mTextMaxTranslationX;
+    private final int mInnerMargin;
+    private final float mArrowMaxTranslationX;
+    private final int mMinIconBackgroundWidth;
+    private final int mMaxIconBackgroundHeight;
+    private final int mMinIconBackgroundHeight;
+    private final int mMaxIconBackgroundCornerRadius;
+    private final float mMinIconBackgroundCornerRadius;
+
+    private int mMaxWidth = Integer.MAX_VALUE;
 
     public IconAppChipView(Context context) {
         this(context, null);
@@ -82,40 +97,66 @@
     public IconAppChipView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
             int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
+        Resources res = getResources();
 
-        mMaxIconBackgroundWidth = getResources().getDimensionPixelSize(
-                R.dimen.task_thumbnail_icon_menu_max_width);
-        mMinIconBackgroundWidth = getResources().getDimensionPixelSize(
-                R.dimen.task_thumbnail_icon_menu_min_width);
-        mMaxIconBackgroundHeight = getResources().getDimensionPixelSize(
+        // Menu dimensions
+        mMaxMenuWidth = res.getDimensionPixelSize(R.dimen.task_thumbnail_icon_menu_max_width);
+        mIconMenuMarginTop = res.getDimensionPixelSize(R.dimen.task_thumbnail_icon_menu_top_margin);
+        mIconMenuMarginStart = res.getDimensionPixelSize(
+                R.dimen.task_thumbnail_icon_menu_start_margin);
+
+        // Background dimensions
+        mMinIconBackgroundWidth = res.getDimensionPixelSize(
+                R.dimen.task_thumbnail_icon_menu_background_min_width);
+        mMaxIconBackgroundHeight = res.getDimensionPixelSize(
                 R.dimen.task_thumbnail_icon_menu_max_height);
-        mMinIconBackgroundHeight = getResources().getDimensionPixelSize(
+        mMinIconBackgroundHeight = res.getDimensionPixelSize(
                 R.dimen.task_thumbnail_icon_menu_min_height);
-        mIconTextMaxWidth = getResources().getDimensionPixelSize(
+        mMaxIconBackgroundCornerRadius = res.getDimensionPixelSize(
+                R.dimen.task_thumbnail_icon_menu_corner_radius);
+
+        // TextView dimensions
+        mInnerMargin = (int) res.getDimension(R.dimen.task_thumbnail_icon_menu_arrow_margin);
+        mIconTextMinWidth = res.getDimensionPixelSize(R.dimen.task_thumbnail_icon_menu_text_width);
+        mIconTextMaxWidth = res.getDimensionPixelSize(
                 R.dimen.task_thumbnail_icon_menu_text_max_width);
-        mInnerMargin = (int) getResources().getDimension(
-                R.dimen.task_thumbnail_icon_menu_arrow_margin);
-        mIconTextMinWidth = getResources().getDimensionPixelSize(
-                R.dimen.task_thumbnail_icon_menu_text_width) + (2 * mInnerMargin);
-        int taskIconHeight = getResources().getDimensionPixelSize(
-                R.dimen.task_thumbnail_icon_menu_drawable_touch_size);
-        int arrowWidth = getResources().getDimensionPixelSize(
+
+        // IconView dimensions
+        mIconViewMarginStart = res.getDimensionPixelSize(
+                R.dimen.task_thumbnail_icon_view_start_margin);
+        mIconViewDrawableSize = res.getDimensionPixelSize(
+                R.dimen.task_thumbnail_icon_menu_drawable_size);
+        mIconViewDrawableMaxSize = res.getDimensionPixelSize(
+                R.dimen.task_thumbnail_icon_menu_drawable_max_size);
+        mTextMaxTranslationX =
+                (mIconViewDrawableMaxSize - mIconViewDrawableSize - mIconViewMarginStart)
+                        + (mInnerMargin / 2);
+
+        // ArrowView dimensions
+        int iconArrowViewWidth = res.getDimensionPixelSize(
                 R.dimen.task_thumbnail_icon_menu_arrow_size);
-        mIconArrowSize = getResources().getDimensionPixelSize(
-                R.dimen.task_thumbnail_icon_menu_arrow_drawable_size);
-        mIconMenuMarginStart = getResources().getDimensionPixelSize(
-                R.dimen.task_thumbnail_icon_menu_margin);
-        mArrowMaxTranslationX =
-                mMaxIconBackgroundWidth - taskIconHeight - mIconTextMaxWidth + arrowWidth;
+        mMinIconBackgroundCornerRadius = mMinIconBackgroundHeight / 2f;
+        float maxCornerSize = Math.min(mMaxIconBackgroundHeight / 2f,
+                mMaxIconBackgroundCornerRadius);
+        mArrowMaxTranslationX = (mMaxMenuWidth - maxCornerSize) - (Math.min(mMaxWidth,
+                mMinIconBackgroundWidth + (2 * mMinIconBackgroundCornerRadius)
+                        - mMinIconBackgroundCornerRadius)) - mInnerMargin;
+
+        // Menu dimensions
+        mMinimumMenuSize =
+                mIconViewMarginStart + mIconViewDrawableSize + mInnerMargin + iconArrowViewWidth;
     }
 
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
         mIconView = findViewById(R.id.icon_view);
-        mIconTextView = findViewById(R.id.icon_text);
+        mIconTextCollapsedView = findViewById(R.id.icon_text_collapsed);
+        mIconTextExpandedView = findViewById(R.id.icon_text_expanded);
         mIconArrowView = findViewById(R.id.icon_arrow);
         mIconViewBackground = findViewById(R.id.icon_view_background);
+        mIconViewBackgroundCornersStart = findViewById(R.id.icon_view_background_corners_start);
+        mIconViewBackgroundCornersEnd = findViewById(R.id.icon_view_background_corners_end);
     }
 
     protected IconView getIconView() {
@@ -124,8 +165,11 @@
 
     @Override
     public void setText(CharSequence text) {
-        if (mIconTextView != null) {
-            mIconTextView.setText(text);
+        if (mIconTextCollapsedView != null) {
+            mIconTextCollapsedView.setText(text);
+        }
+        if (mIconTextExpandedView != null) {
+            mIconTextExpandedView.setText(text);
         }
     }
 
@@ -148,83 +192,101 @@
         }
     }
 
+    /**
+     * Sets the maximum width of this Icon Menu.
+     */
+    public void setMaxWidth(int maxWidth) {
+        // Only the app icon and caret are visible at its minimum width.
+        mMaxWidth = Math.max(maxWidth, mMinimumMenuSize);
+    }
+
     @Override
     public void setIconOrientation(RecentsOrientedState orientationState, boolean isGridTask) {
-
         PagedOrientationHandler orientationHandler = orientationState.getOrientationHandler();
-        boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
+        boolean isRtl = isLayoutRtl();
         DeviceProfile deviceProfile =
                 ActivityContext.lookupContext(getContext()).getDeviceProfile();
 
-        int thumbnailTopMargin = deviceProfile.overviewTaskThumbnailTopMarginPx;
-        int taskIconSize = deviceProfile.overviewTaskIconSizePx;
-        int taskMargin = deviceProfile.overviewTaskMarginPx;
-
+        // Layout Params for the Menu View
+        int thumbnailTopMargin =
+                deviceProfile.overviewTaskThumbnailTopMarginPx + mIconMenuMarginTop;
         LayoutParams iconMenuParams = (LayoutParams) getLayoutParams();
-        orientationHandler.setTaskIconMenuParams(iconMenuParams, mIconMenuMarginStart,
+        orientationHandler.setIconAppChipMenuParams(this, iconMenuParams, mIconMenuMarginStart,
                 thumbnailTopMargin);
-        iconMenuParams.width = mMinIconBackgroundWidth;
-        iconMenuParams.height = taskIconSize;
-        if (orientationHandler instanceof SeascapePagedViewHandler) {
-            // Use half menu height to place the pivot within the X/Y center of icon in the menu.
-            setPivotX(getHeight() / 2f);
-            setPivotY(getHeight() / 2f - mIconMenuMarginStart);
-        } else if (orientationHandler instanceof LandscapePagedViewHandler) {
-            setPivotX(getWidth());
-            setPivotY(0);
-        }
-        // Pivot not updated for PortraitPagedViewHandler case, as it has 0 rotation.
+        iconMenuParams.width = Math.min(mMaxWidth,
+                mMinIconBackgroundWidth + (int) (2 * mMinIconBackgroundCornerRadius));
+        iconMenuParams.height = mMinIconBackgroundHeight;
+        setLayoutParams(iconMenuParams);
 
-        setTranslationY(0);
-        setRotation(orientationHandler.getDegreesRotated());
-
+        // Layout Params for the Icon View
         LayoutParams iconParams = (LayoutParams) mIconView.getLayoutParams();
-        orientationHandler.setTaskIconParams(iconParams, taskMargin, taskIconSize,
-                thumbnailTopMargin, isRtl);
-        iconParams.width = iconParams.height = taskIconSize;
-        iconParams.gravity = Gravity.START | Gravity.CENTER_VERTICAL;
+        orientationHandler.setTaskIconParams(iconParams, mIconViewMarginStart,
+                mIconViewDrawableSize, thumbnailTopMargin, isRtl);
+        iconParams.width = iconParams.height = mIconViewDrawableSize;
         mIconView.setLayoutParams(iconParams);
+        mIconView.setDrawableSize(mIconViewDrawableSize, mIconViewDrawableSize);
 
-        int iconDrawableSize = enableOverviewIconMenu()
-                ? deviceProfile.overviewTaskIconAppChipMenuDrawableSizePx
-                : isGridTask ? deviceProfile.overviewTaskIconDrawableSizeGridPx
-                        : deviceProfile.overviewTaskIconDrawableSizePx;
-        mIconView.setDrawableSize(iconDrawableSize, iconDrawableSize);
-
-        LayoutParams iconTextParams = (LayoutParams) mIconTextView.getLayoutParams();
-        orientationHandler.setTaskIconParams(iconTextParams, 0, taskIconSize,
+        // Layout Params for the collapsed Icon Text View
+        LayoutParams iconTextCollapsedParams =
+                (LayoutParams) mIconTextCollapsedView.getLayoutParams();
+        orientationHandler.setTaskIconParams(iconTextCollapsedParams, 0, mIconViewDrawableSize,
                 thumbnailTopMargin, isRtl);
-        iconTextParams.width = mIconTextMaxWidth;
-        iconTextParams.height = taskIconSize;
-        iconTextParams.setMarginStart(taskIconSize);
-        iconTextParams.topMargin = (getHeight() - mIconTextView.getHeight()) / 2;
-        iconTextParams.gravity = Gravity.CENTER_VERTICAL | Gravity.START;
-        mIconTextView.setLayoutParams(iconTextParams);
-        mIconTextView.setRevealClip(true, 0, taskIconSize / 2f, mIconTextMinWidth);
+        iconTextCollapsedParams.setMarginStart(
+                mIconViewDrawableSize + mIconViewMarginStart + mInnerMargin);
+        iconTextCollapsedParams.topMargin = (mMinIconBackgroundHeight - mIconViewDrawableSize) / 2;
+        iconTextCollapsedParams.gravity = Gravity.TOP | Gravity.START;
+        iconTextCollapsedParams.width = Math.min(
+                Math.max(mMaxWidth - mMinimumMenuSize - (2 * mInnerMargin), 0), mIconTextMinWidth);
+        mIconTextCollapsedView.setLayoutParams(iconTextCollapsedParams);
+        mIconTextCollapsedView.setAlpha(1f);
 
+        // Layout Params for the expanded Icon Text View
+        LayoutParams iconTextExpandedParams =
+                (LayoutParams) mIconTextExpandedView.getLayoutParams();
+        orientationHandler.setTaskIconParams(iconTextExpandedParams, 0, mIconViewDrawableSize,
+                thumbnailTopMargin, isRtl);
+        iconTextExpandedParams.setMarginStart(
+                mIconViewDrawableSize + mIconViewMarginStart + mInnerMargin);
+        iconTextExpandedParams.topMargin = (mMinIconBackgroundHeight - mIconViewDrawableSize) / 2;
+        iconTextExpandedParams.gravity = Gravity.TOP | Gravity.START;
+        mIconTextExpandedView.setLayoutParams(iconTextExpandedParams);
+        mIconTextExpandedView.setAlpha(0f);
+        mIconTextExpandedView.setRevealClip(true, 0, mIconViewDrawableSize / 2f, mIconTextMinWidth);
+
+        // Layout Params for the Icon Arrow View
         LayoutParams iconArrowParams = (LayoutParams) mIconArrowView.getLayoutParams();
         iconArrowParams.gravity = Gravity.CENTER_VERTICAL | Gravity.END;
-        iconArrowParams.setMarginStart(taskIconSize + mIconTextMinWidth);
         iconArrowParams.setMarginEnd(mInnerMargin);
         mIconArrowView.setLayoutParams(iconArrowParams);
-        mIconArrowView.getDrawable().setBounds(0, 0, mIconArrowSize, mIconArrowSize);
 
+        // Layout Params for the Icon View Background and its corners
+        int cornerlessBackgroundWidth = (int) Math.min(
+                mMaxWidth - (2 * mMinIconBackgroundCornerRadius), mMinIconBackgroundWidth);
+        LayoutParams backgroundCornerEndParams =
+                (LayoutParams) mIconViewBackgroundCornersEnd.getLayoutParams();
+        backgroundCornerEndParams.setMarginStart(cornerlessBackgroundWidth);
+        mIconViewBackgroundCornersEnd.setLayoutParams(backgroundCornerEndParams);
         LayoutParams backgroundParams = (LayoutParams) mIconViewBackground.getLayoutParams();
-        backgroundParams.width = mMinIconBackgroundWidth;
-        backgroundParams.height = taskIconSize;
-        mIconViewBackground.setPivotX(
-                isRtl ? mMinIconBackgroundWidth - (taskIconSize / 2f - mInnerMargin)
-                        : taskIconSize / 2f - mInnerMargin);
-        mIconViewBackground.setPivotY(taskIconSize / 2f);
+        backgroundParams.width = cornerlessBackgroundWidth;
+        backgroundParams.height = mMinIconBackgroundHeight;
+        backgroundParams.setMarginStart((int) mMinIconBackgroundCornerRadius);
+        mIconViewBackground.setLayoutParams(backgroundParams);
+        mIconViewBackground.setPivotX(isRtl ? cornerlessBackgroundWidth : 0);
+        mIconViewBackground.setPivotY(mMinIconBackgroundCornerRadius);
 
-        requestLayout();
+        // This method is called twice sometimes (like when rotating split tasks). It is called
+        // once before onMeasure and onLayout, and again after onMeasure but before onLayout with
+        // a new width. This happens because we update widths on rotation and on measure of
+        // grouped task views. Calling requestLayout() does not guarantee a call to onMeasure if
+        // it has just measured, so we explicitly call it here.
+        measure(MeasureSpec.makeMeasureSpec(getLayoutParams().width, MeasureSpec.EXACTLY),
+                MeasureSpec.makeMeasureSpec(getLayoutParams().height, MeasureSpec.EXACTLY));
     }
 
     @Override
     public void setIconColorTint(int color, float amount) {
-        if (mIconView != null) {
-            mIconView.setIconColorTint(color, amount);
-        }
+        // RecentsView's COLOR_TINT animates between 0 and 0.5f, we want to hide the app chip menu.
+        setAlpha(Utilities.mapToRange(amount, 0f, 0.5f, 1f, 0f, LINEAR));
     }
 
     @Override
@@ -239,37 +301,91 @@
 
     protected void revealAnim(boolean isRevealing) {
         if (isRevealing) {
+            boolean isRtl = isLayoutRtl();
+            bringToFront();
             ((AnimatedVectorDrawable) mIconArrowView.getDrawable()).start();
             AnimatorSet anim = new AnimatorSet();
+            float backgroundScaleY = mMaxIconBackgroundHeight / (float) mMinIconBackgroundHeight;
+            float maxCornerSize = Math.min(mMaxIconBackgroundHeight / 2f,
+                    mMaxIconBackgroundCornerRadius);
+            float backgroundScaleX = (mMaxMenuWidth - (2 * maxCornerSize)) / Math.min(
+                    mMaxWidth - (2 * mMinIconBackgroundCornerRadius), mMinIconBackgroundWidth);
+            float arrowTranslationX = mArrowMaxTranslationX + (mMinIconBackgroundWidth - Math.min(
+                    mMaxWidth - (2 * mMinIconBackgroundCornerRadius), mMinIconBackgroundWidth));
+            // Clip expanded text with reveal animation so it doesn't go beyond the edge of the menu
+            Animator expandedTextRevealAnim = ViewAnimationUtils.createCircularReveal(
+                    mIconTextExpandedView, 0, mIconTextExpandedView.getHeight() / 2, 0,
+                    mIconTextMaxWidth + maxCornerSize);
+            expandedTextRevealAnim.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    // createCircularReveal removes clip on finish, restore it here to clip text.
+                    mIconTextExpandedView.setRevealClip(true, 0,
+                            mIconTextExpandedView.getHeight() / 2f,
+                            mIconTextMaxWidth + maxCornerSize);
+                }
+            });
             anim.playTogether(
-                    ViewAnimationUtils.createCircularReveal(mIconTextView, 0,
-                            mIconTextView.getHeight() / 2, mIconTextMinWidth, mIconTextMaxWidth),
-                    ObjectAnimator.ofFloat(mIconViewBackground, SCALE_X,
-                            mMaxIconBackgroundWidth / (float) mMinIconBackgroundWidth),
-                    ObjectAnimator.ofFloat(mIconViewBackground, SCALE_Y,
-                            mMaxIconBackgroundHeight / (float) mMinIconBackgroundHeight),
+                    expandedTextRevealAnim,
+                    ObjectAnimator.ofFloat(mIconViewBackgroundCornersStart, SCALE_Y,
+                            backgroundScaleY),
+                    ObjectAnimator.ofFloat(mIconViewBackgroundCornersStart, SCALE_X,
+                            backgroundScaleY),
+                    ObjectAnimator.ofFloat(mIconViewBackgroundCornersEnd, SCALE_Y,
+                            backgroundScaleY),
+                    ObjectAnimator.ofFloat(mIconViewBackgroundCornersEnd, SCALE_X,
+                            backgroundScaleY),
+                    ObjectAnimator.ofFloat(mIconViewBackgroundCornersEnd, TRANSLATION_X,
+                            isRtl ? -arrowTranslationX : arrowTranslationX),
+                    ObjectAnimator.ofFloat(mIconViewBackground, SCALE_X, backgroundScaleX),
+                    ObjectAnimator.ofFloat(mIconViewBackground, SCALE_Y, backgroundScaleY),
+                    ObjectAnimator.ofFloat(mIconView, SCALE_X,
+                            mIconViewDrawableMaxSize / (float) mIconViewDrawableSize),
+                    ObjectAnimator.ofFloat(mIconView, SCALE_Y,
+                            mIconViewDrawableMaxSize / (float) mIconViewDrawableSize),
+                    ObjectAnimator.ofFloat(mIconTextCollapsedView, TRANSLATION_X,
+                            isLayoutRtl() ? -mTextMaxTranslationX : mTextMaxTranslationX),
+                    ObjectAnimator.ofFloat(mIconTextExpandedView, TRANSLATION_X,
+                            isLayoutRtl() ? -mTextMaxTranslationX : mTextMaxTranslationX),
+                    ObjectAnimator.ofFloat(mIconTextCollapsedView, ALPHA, 0),
+                    ObjectAnimator.ofFloat(mIconTextExpandedView, ALPHA, 1),
                     ObjectAnimator.ofFloat(mIconArrowView, TRANSLATION_X,
-                            isLayoutRtl() ? -mArrowMaxTranslationX : mArrowMaxTranslationX));
+                            isRtl ? -arrowTranslationX : arrowTranslationX));
             anim.setDuration(MENU_BACKGROUND_REVEAL_DURATION);
             anim.setInterpolator(EMPHASIZED);
             anim.start();
         } else {
             ((AnimatedVectorDrawable) mIconArrowView.getDrawable()).reverse();
-            AnimatorSet anim = new AnimatorSet();
-            Animator textRevealAnim = ViewAnimationUtils.createCircularReveal(mIconTextView, 0,
-                    mIconTextView.getHeight() / 2, mIconTextMaxWidth, mIconTextMinWidth);
-            textRevealAnim.addListener(new AnimatorListenerAdapter() {
+            float maxCornerSize = Math.min(mMaxIconBackgroundHeight / 2f,
+                    mMaxIconBackgroundCornerRadius);
+            // Clip expanded text with reveal animation so it doesn't go beyond the edge of the menu
+            Animator expandedTextClipAnim = ViewAnimationUtils.createCircularReveal(
+                    mIconTextExpandedView, 0, mIconTextExpandedView.getHeight() / 2,
+                    mIconTextMaxWidth + maxCornerSize, 0);
+            expandedTextClipAnim.addListener(new AnimatorListenerAdapter() {
                 @Override
                 public void onAnimationEnd(Animator animation) {
                     // createCircularReveal removes clip on finish, restore it here to clip text.
-                    mIconTextView.setRevealClip(true, 0, mIconTextView.getHeight() / 2f,
-                            mIconTextMinWidth);
+                    mIconTextExpandedView.setRevealClip(true, 0,
+                            mIconTextExpandedView.getHeight() / 2f, 0);
                 }
             });
+            AnimatorSet anim = new AnimatorSet();
             anim.playTogether(
-                    textRevealAnim,
+                    expandedTextClipAnim,
+                    ObjectAnimator.ofFloat(mIconViewBackgroundCornersStart, SCALE_X, 1),
+                    ObjectAnimator.ofFloat(mIconViewBackgroundCornersStart, SCALE_Y, 1),
+                    ObjectAnimator.ofFloat(mIconViewBackgroundCornersEnd, SCALE_X, 1),
+                    ObjectAnimator.ofFloat(mIconViewBackgroundCornersEnd, SCALE_Y, 1),
+                    ObjectAnimator.ofFloat(mIconViewBackgroundCornersEnd, TRANSLATION_X, 0),
                     ObjectAnimator.ofFloat(mIconViewBackground, SCALE_X, 1),
                     ObjectAnimator.ofFloat(mIconViewBackground, SCALE_Y, 1),
+                    ObjectAnimator.ofFloat(mIconView, SCALE_X, 1),
+                    ObjectAnimator.ofFloat(mIconView, SCALE_Y, 1),
+                    ObjectAnimator.ofFloat(mIconTextCollapsedView, TRANSLATION_X, 0),
+                    ObjectAnimator.ofFloat(mIconTextExpandedView, TRANSLATION_X, 0),
+                    ObjectAnimator.ofFloat(mIconTextCollapsedView, ALPHA, 1),
+                    ObjectAnimator.ofFloat(mIconTextExpandedView, ALPHA, 0),
                     ObjectAnimator.ofFloat(mIconArrowView, TRANSLATION_X, 0));
             anim.setDuration(MENU_BACKGROUND_HIDE_DURATION);
             anim.setInterpolator(EMPHASIZED);
@@ -277,6 +393,24 @@
         }
     }
 
+    protected void reset() {
+        mIconViewBackgroundCornersStart.setScaleX(1);
+        mIconViewBackgroundCornersStart.setScaleY(1);
+        mIconViewBackgroundCornersEnd.setScaleX(1);
+        mIconViewBackgroundCornersEnd.setScaleY(1);
+        mIconViewBackgroundCornersEnd.setTranslationX(0);
+        mIconViewBackground.setScaleX(1);
+        mIconViewBackground.setScaleY(1);
+        mIconView.setScaleX(1);
+        mIconView.setScaleY(1);
+        mIconTextCollapsedView.setTranslationX(0);
+        mIconTextExpandedView.setTranslationX(0);
+        mIconTextCollapsedView.setAlpha(1);
+        mIconTextExpandedView.setAlpha(0);
+        mIconArrowView.setTranslationX(0);
+        ((AnimatedVectorDrawable) mIconArrowView.getDrawable()).reset();
+    }
+
     @Override
     public View asView() {
         return this;
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 7972999..f55dce9 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -34,6 +34,7 @@
 import static com.android.launcher3.AbstractFloatingView.TYPE_TASK_MENU;
 import static com.android.launcher3.AbstractFloatingView.getTopOpenViewWithType;
 import static com.android.launcher3.BaseActivity.STATE_HANDLER_INVISIBILITY_FLAGS;
+import static com.android.launcher3.Flags.enableGridOnlyOverview;
 import static com.android.launcher3.LauncherAnimUtils.SUCCESS_TRANSITION_PROGRESS;
 import static com.android.launcher3.LauncherAnimUtils.VIEW_ALPHA;
 import static com.android.launcher3.LauncherState.BACKGROUND_APP;
@@ -42,7 +43,6 @@
 import static com.android.launcher3.Utilities.mapToRange;
 import static com.android.launcher3.Utilities.squaredHypot;
 import static com.android.launcher3.Utilities.squaredTouchSlop;
-import static com.android.launcher3.Flags.enableGridOnlyOverview;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_OVERVIEW_ACTIONS_SPLIT;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_CLEAR_ALL;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_DISMISS_SWIPE_UP;
@@ -2032,12 +2032,12 @@
         mActionsView.updateHiddenFlags(HIDDEN_NON_ZERO_ROTATION,
                 !mOrientationState.isRecentsActivityRotationAllowed() && isInLandscape);
 
-        // Update TaskView's DeviceProfile dependent layout.
-        updateChildTaskOrientations();
-
         // Recalculate DeviceProfile dependent layout.
         updateSizeAndPadding();
 
+        // Update TaskView's DeviceProfile dependent layout.
+        updateChildTaskOrientations();
+
         requestLayout();
         // Reapply the current page to update page scrolls.
         setCurrentPage(mCurrentPage);
diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuView.java b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
index 8f12909..0c816b8 100644
--- a/quickstep/src/com/android/quickstep/views/TaskMenuView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
@@ -18,6 +18,7 @@
 
 import static com.android.app.animation.Interpolators.EMPHASIZED;
 import static com.android.launcher3.Flags.enableOverviewIconMenu;
+import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
 import static com.android.quickstep.views.TaskThumbnailView.DIM_ALPHA;
 
 import android.animation.Animator;
@@ -73,7 +74,9 @@
     private TaskIdAttributeContainer mTaskContainer;
     private LinearLayout mOptionLayout;
     private float mMenuTranslationYBeforeOpen;
+    private float mMenuTranslationXBeforeOpen;
     private float mIconViewTranslationYBeforeOpen;
+    private float mIconViewTranslationXBeforeOpen;
 
     public TaskMenuView(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
@@ -112,6 +115,9 @@
             animateClose();
         } else {
             closeComplete();
+            if (enableOverviewIconMenu()) {
+                ((IconAppChipView) mTaskContainer.getIconView()).reset();
+            }
         }
     }
 
@@ -137,7 +143,7 @@
         }
         if (mIsOpen) {
             mOptionLayout.removeAllViews();
-            if (!populateAndLayoutMenu()) {
+            if (enableOverviewIconMenu() || !populateAndLayoutMenu()) {
                 close(false);
             }
         }
@@ -222,11 +228,8 @@
                         : taskContainer.getThumbnailView(), sTempRect);
         Rect insets = mActivity.getDragLayer().getInsets();
         BaseDragLayer.LayoutParams params = (BaseDragLayer.LayoutParams) getLayoutParams();
-        int padding = getResources()
-                .getDimensionPixelSize(R.dimen.task_menu_vertical_padding);
-        params.width = orientationHandler
-                .getTaskMenuWidth(taskContainer.getThumbnailView(),
-                        deviceProfile, taskContainer.getStagePosition()) - (2 * padding);
+        params.width = orientationHandler.getTaskMenuWidth(taskContainer.getThumbnailView(),
+                deviceProfile, taskContainer.getStagePosition());
         // Gravity set to Left instead of Start as sTempRect.left measures Left distance not Start
         params.gravity = Gravity.LEFT;
         setLayoutParams(params);
@@ -244,10 +247,13 @@
                 deviceProfile, mOptionLayout, dividerSpacing, divider);
         float thumbnailAlignedX = sTempRect.left - insets.left + (enableOverviewIconMenu()
                 ? -getResources().getDimensionPixelSize(
-                R.dimen.task_thumbnail_icon_menu_touch_max_margin) : 0);
+                        R.dimen.task_thumbnail_icon_menu_touch_max_margin)
+                        - getResources().getDimension(R.dimen.task_thumbnail_icon_menu_start_margin)
+                : 0);
         float thumbnailAlignedY = sTempRect.top - insets.top + (enableOverviewIconMenu()
                 ? getResources().getDimensionPixelSize(R.dimen.task_thumbnail_icon_menu_max_height)
-                - 2 * dividerSpacing : 0);
+                        - getResources().getDimensionPixelSize(
+                        R.dimen.task_thumbnail_icon_menu_top_margin) : 0);
         // Changing pivot to make computations easier
         // NOTE: Changing the pivots means the rotated view gets rotated about the new pivots set,
         // which would render the X and Y position set here incorrect
@@ -256,22 +262,26 @@
         setRotation(orientationHandler.getDegreesRotated());
 
         // Margin that insets the menuView inside the taskView
-        float taskInsetMargin =
-                enableOverviewIconMenu() ? getResources().getDimension(
-                        R.dimen.task_thumbnail_icon_menu_margin) : getResources().getDimension(
-                        R.dimen.task_card_margin);
+        float taskInsetMarginX = enableOverviewIconMenu() ? getResources().getDimension(
+                R.dimen.task_thumbnail_icon_menu_start_margin) : getResources().getDimension(
+                R.dimen.task_card_margin);
+        float taskInsetMarginY = enableOverviewIconMenu() ? getResources().getDimension(
+                R.dimen.task_thumbnail_icon_menu_start_margin) : getResources().getDimension(
+                R.dimen.task_card_margin);
         setTranslationX(orientationHandler.getTaskMenuX(thumbnailAlignedX,
-                mTaskContainer.getThumbnailView(), deviceProfile, taskInsetMargin,
+                mTaskContainer.getThumbnailView(), deviceProfile, taskInsetMarginX,
                 mTaskContainer.getIconView().asView()));
         setTranslationY(orientationHandler.getTaskMenuY(
                 thumbnailAlignedY, mTaskContainer.getThumbnailView(),
-                mTaskContainer.getStagePosition(), this, taskInsetMargin,
+                mTaskContainer.getStagePosition(), this, taskInsetMarginY,
                 mTaskContainer.getIconView().asView()));
     }
 
     private void animateOpen() {
         mMenuTranslationYBeforeOpen = getTranslationY();
+        mMenuTranslationXBeforeOpen = getTranslationX();
         mIconViewTranslationYBeforeOpen = mTaskContainer.getIconView().asView().getTranslationY();
+        mIconViewTranslationXBeforeOpen = mTaskContainer.getIconView().asView().getTranslationX();
         animateOpenOrClosed(false);
         mIsOpen = true;
     }
@@ -291,25 +301,55 @@
         revealAnimator.setInterpolator(enableOverviewIconMenu() ? Interpolators.EMPHASIZED
                 : Interpolators.DECELERATE);
 
-        if (enableOverviewIconMenu()
-                && ((RecentsView) mActivity.getOverviewPanel()).isOnGridBottomRow(mTaskView)) {
-            float taskBottom = mTaskView.getHeight() + mTaskView.getPersistentTranslationY();
-            float menuBottom = getHeight() + mMenuTranslationYBeforeOpen;
-            float additionalTranslationY = Math.max(menuBottom - taskBottom, 0);
-
+        if (enableOverviewIconMenu()) {
+            float additionalTranslationY = 0;
+            if (((RecentsView) mActivity.getOverviewPanel()).isOnGridBottomRow(mTaskView)) {
+                // Animate menu up for enough room to display full menu when task on bottom row.
+                float menuBottom = getHeight() + mMenuTranslationYBeforeOpen;
+                float taskBottom = mTaskView.getHeight() + mTaskView.getPersistentTranslationY();
+                float taskbarTop = mActivity.getDeviceProfile().heightPx
+                        - mActivity.getDeviceProfile().getOverviewActionsClaimedSpaceBelow();
+                float midpoint = (taskBottom + taskbarTop) / 2f;
+                additionalTranslationY = -Math.max(menuBottom - midpoint, 0);
+            } else {
+                // Animate the menu to leave a small margin at the top of the task.
+                additionalTranslationY = getResources().getDimensionPixelSize(
+                        R.dimen.task_thumbnail_icon_menu_top_margin_expanded);
+            }
             ObjectAnimator translationYAnim = ObjectAnimator.ofFloat(this, TRANSLATION_Y,
                     closing ? mMenuTranslationYBeforeOpen
-                            : mMenuTranslationYBeforeOpen - additionalTranslationY);
+                            : mMenuTranslationYBeforeOpen + additionalTranslationY);
             translationYAnim.setInterpolator(EMPHASIZED);
 
             ObjectAnimator menuTranslationYAnim = ObjectAnimator.ofFloat(
                     mTaskContainer.getIconView().asView(), TRANSLATION_Y,
                     closing ? mIconViewTranslationYBeforeOpen
-                            : mIconViewTranslationYBeforeOpen - additionalTranslationY);
+                            : mIconViewTranslationYBeforeOpen + additionalTranslationY);
             menuTranslationYAnim.setInterpolator(EMPHASIZED);
 
             mOpenCloseAnimator.playTogether(translationYAnim, menuTranslationYAnim);
         }
+        // Animate menu and icon when split task would display off the side of the screen.
+        if (enableOverviewIconMenu() && mActivity.getDeviceProfile().isLandscape
+                && mTaskContainer.getStagePosition() == STAGE_POSITION_BOTTOM_OR_RIGHT) {
+            float additionalTranslationX = Math.max(
+                    getTranslationX() + getWidth() - (mActivity.getDeviceProfile().widthPx
+                            - getResources().getDimensionPixelSize(
+                            R.dimen.task_menu_edge_padding) * 2), 0);
+
+            ObjectAnimator translationXAnim = ObjectAnimator.ofFloat(this, TRANSLATION_X,
+                    closing ? mMenuTranslationXBeforeOpen
+                            : mMenuTranslationXBeforeOpen - additionalTranslationX);
+            translationXAnim.setInterpolator(EMPHASIZED);
+
+            ObjectAnimator menuTranslationXAnim = ObjectAnimator.ofFloat(
+                    mTaskContainer.getIconView().asView(), TRANSLATION_X,
+                    closing ? mIconViewTranslationXBeforeOpen
+                            : mIconViewTranslationXBeforeOpen - additionalTranslationX);
+            menuTranslationXAnim.setInterpolator(EMPHASIZED);
+
+            mOpenCloseAnimator.playTogether(translationXAnim, menuTranslationXAnim);
+        }
 
         mOpenCloseAnimator.playTogether(revealAnimator,
                 ObjectAnimator.ofFloat(
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
index ff8537b..7c43bfb 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
@@ -294,7 +294,6 @@
     }
 
     @Test
-    @ScreenRecord // b/242163205
     @TaskbarModeSwitch(mode = PERSISTENT)
     public void testQuickSwitchToPreviousAppForTablet() throws Exception {
         assumeTrue(mLauncher.isTablet());
@@ -352,6 +351,7 @@
     @TaskbarModeSwitch(mode = PERSISTENT)
     @PlatinumTest(focusArea = "launcher")
     @TestStabilityRule.Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT) // b/309820115
+    @ScreenRecord // b/309820115
     public void testOverviewForTablet() throws Exception {
         assumeTrue(mLauncher.isTablet());
 
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java b/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java
index 0e382a4..28473cd 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java
@@ -22,7 +22,6 @@
 import androidx.test.filters.LargeTest;
 
 import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
-import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -90,7 +89,6 @@
     }
 
     @Test
-    @ScreenRecord // b/231615831
     @PortraitLandscape
     public void testLaunchAppInSplitscreen() {
         getTaskbar().getAppIcon(TEST_APP_NAME).dragToSplitscreen(
@@ -104,7 +102,6 @@
     }
 
     @Test
-    @ScreenRecord // b/231615831
     @PortraitLandscape
     public void testLaunchShortcutInSplitscreen() {
         getTaskbar().getAppIcon(TEST_APP_NAME)
@@ -133,7 +130,6 @@
     }
 
     @Test
-    @ScreenRecord // b/231615831
     @PortraitLandscape
     public void testLaunchAppInSplitscreen_fromTaskbarAllApps() {
         getTaskbar().openAllApps()
@@ -142,7 +138,6 @@
     }
 
     @Test
-    @ScreenRecord // b/231615831
     @PortraitLandscape
     public void testLaunchShortcutInSplitscreen_fromTaskbarAllApps() {
         getTaskbar().openAllApps()
diff --git a/res/drawable-sw720dp/ic_transient_taskbar_all_apps_search_button.xml b/res/drawable-sw720dp/ic_transient_taskbar_all_apps_search_button.xml
index 654f0b3..eb5b41e 100644
--- a/res/drawable-sw720dp/ic_transient_taskbar_all_apps_search_button.xml
+++ b/res/drawable-sw720dp/ic_transient_taskbar_all_apps_search_button.xml
@@ -16,23 +16,21 @@
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:width="52dp"
     android:height="52dp"
-    android:viewportWidth="52"
-    android:viewportHeight="52">
-  <path
-      android:pathData="M39.4,17.5c0,3.1 -2.5,5.5 -5.5,5.5c-3.1,0 -5.5,-2.5 -5.5,-5.5s2.5,-5.5 5.5,-5.5C36.9,12 39.4,14.5 39.4,17.5z"
-      android:fillColor="#FF000000"/>
-  <path
-      android:pathData="M23.1,17.5c0,3.1 -2.5,5.5 -5.5,5.5S12,20.6 12,17.5s2.5,-5.5 5.5,-5.5S23.1,14.5 23.1,17.5z"
-      android:fillColor="#FF000000"/>
-  <path
-      android:pathData="M17.5,33.9m-5.5,0a5.5,5.5 0,1 1,11 0a5.5,5.5 0,1 1,-11 0"
-      android:fillColor="#FF000000"/>
+    android:autoMirrored="true"
+    android:viewportHeight="52"
+    android:viewportWidth="52">
+
   <path
       android:fillColor="#FF000000"
-      android:pathData="M33.9,30c2.1,0 3.9,1.7 3.9,3.9s-1.7,3.9 -3.9,3.9S30,36.1 30,33.9S31.8,30 33.9,30M33.9,28.3c-3.1,0 -5.6,2.5 -5.6,5.6c0,3.1 2.5,5.6 5.6,5.6c3.1,0 5.6,-2.5 5.6,-5.6C39.5,30.8 37,28.3 33.9,28.3L33.9,28.3z"/>
+      android:pathData="M18.25,17.75m-6,0a6,6 0,1 1,12 0a6,6 0,1 1,-12 0" />
   <path
-      android:pathData="M36.9,37L43.2,43.3"
-      android:strokeWidth="1.7"
-      android:fillColor="#00000000"
-      android:strokeColor="#000000"/>
-</vector>
+      android:fillColor="#FF000000"
+      android:pathData="M18.25,34.25m-6,0a6,6 0,1 1,12 0a6,6 0,1 1,-12 0" />
+  <path
+      android:fillColor="#FF000000"
+      android:pathData="M34.75,17.75m-6,0a6,6 0,1 1,12 0a6,6 0,1 1,-12 0" />
+  <path
+      android:fillColor="#FF000000"
+      android:fillType="evenOdd"
+      android:pathData="M37.75,34.25C37.75,32.6 36.4,31.25 34.75,31.25C33.1,31.25 31.75,32.6 31.75,34.25C31.75,35.9 33.1,37.25 34.75,37.25C36.4,37.25 37.75,35.9 37.75,34.25ZM28.75,34.25C28.75,30.935 31.435,28.25 34.75,28.25C38.065,28.25 40.75,30.935 40.75,34.25C40.75,35.361 40.449,36.401 39.923,37.292L44.5,41.884L42.386,43.999L37.795,39.422C36.902,39.948 35.862,40.25 34.75,40.25C31.435,40.25 28.75,37.565 28.75,34.25Z" />
+</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_taskbar_all_apps_search_button.xml b/res/drawable/ic_taskbar_all_apps_search_button.xml
index 8fbe539..5b4b01b 100644
--- a/res/drawable/ic_taskbar_all_apps_search_button.xml
+++ b/res/drawable/ic_taskbar_all_apps_search_button.xml
@@ -16,23 +16,20 @@
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:width="44dp"
     android:height="44dp"
-    android:viewportWidth="44"
-    android:viewportHeight="44">
+    android:autoMirrored="true"
+    android:viewportHeight="44"
+    android:viewportWidth="44">
   <path
       android:fillColor="#FF000000"
-      android:pathData="M34.1,14.9c0,2.7 -2.2,4.9 -4.9,4.9s-4.9,-2.2 -4.9,-4.9s2.2,-4.9 4.9,-4.9S34.1,12.2 34.1,14.9z"/>
+      android:pathData="M14.333,14.333m-5.333,0a5.333,5.333 0,1 1,10.667 0a5.333,5.333 0,1 1,-10.667 0" />
   <path
       android:fillColor="#FF000000"
-      android:pathData="M19.7,14.9c0,2.7 -2.2,4.9 -4.9,4.9S10,17.6 10,14.9s2.2,-4.9 4.9,-4.9S19.7,12.2 19.7,14.9z"/>
+      android:pathData="M14.333,28.997m-5.333,0a5.333,5.333 0,1 1,10.667 0a5.333,5.333 0,1 1,-10.667 0" />
   <path
       android:fillColor="#FF000000"
-      android:pathData="M14.9,29.2m-4.9,0a4.9,4.9 0,1 1,9.8 0a4.9,4.9 0,1 1,-9.8 0"/>
+      android:pathData="M28.999,14.333m-5.333,0a5.333,5.333 0,1 1,10.667 0a5.333,5.333 0,1 1,-10.667 0" />
   <path
       android:fillColor="#FF000000"
-      android:pathData="M29.3,25.9c1.9,0 3.4,1.5 3.4,3.4c0,1.9 -1.5,3.4 -3.4,3.4s-3.4,-1.5 -3.4,-3.4C25.9,27.4 27.4,25.9 29.3,25.9M29.3,24.4c-2.7,0 -4.9,2.2 -4.9,4.9s2.2,4.9 4.9,4.9c2.7,0 4.9,-2.2 4.9,-4.9S32,24.4 29.3,24.4L29.3,24.4z"/>
-  <path
-      android:pathData="M31.9,32L37.4,37.5"
-      android:strokeWidth="1.5"
-      android:fillColor="#00000000"
-      android:strokeColor="#000000"/>
+      android:fillType="evenOdd"
+      android:pathData="M31.668,29.005C31.668,27.538 30.468,26.338 29.001,26.338C27.535,26.338 26.335,27.538 26.335,29.005C26.335,30.472 27.535,31.672 29.001,31.672C30.468,31.672 31.668,30.472 31.668,29.005ZM23.668,29.005C23.668,26.059 26.055,23.672 29.001,23.672C31.948,23.672 34.335,26.059 34.335,29.005C34.335,29.992 34.067,30.917 33.6,31.709L37.669,35.791L35.789,37.671L31.708,33.602C30.915,34.07 29.989,34.339 29.001,34.339C26.055,34.339 23.668,31.952 23.668,29.005Z" />
 </vector>
diff --git a/res/drawable/ic_transient_taskbar_all_apps_search_button.xml b/res/drawable/ic_transient_taskbar_all_apps_search_button.xml
index 59a666b..85a17f5 100644
--- a/res/drawable/ic_transient_taskbar_all_apps_search_button.xml
+++ b/res/drawable/ic_transient_taskbar_all_apps_search_button.xml
@@ -16,23 +16,20 @@
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:width="48dp"
     android:height="48dp"
-    android:viewportWidth="48"
-    android:viewportHeight="48">
+    android:autoMirrored="true"
+    android:viewportHeight="48"
+    android:viewportWidth="48">
   <path
       android:fillColor="#FF000000"
-      android:pathData="M37.4,15.5c0,3.1 -2.5,5.5 -5.5,5.5c-3.1,0 -5.5,-2.5 -5.5,-5.5s2.5,-5.5 5.5,-5.5C34.9,10 37.4,12.5 37.4,15.5z"/>
+      android:pathData="M16.833,16.333m-5.333,0a5.333,5.333 0,1 1,10.667 0a5.333,5.333 0,1 1,-10.667 0" />
   <path
       android:fillColor="#FF000000"
-      android:pathData="M21.1,15.5c0,3.1 -2.5,5.5 -5.5,5.5S10,18.6 10,15.5s2.5,-5.5 5.5,-5.5S21.1,12.5 21.1,15.5z"/>
+      android:pathData="M16.833,30.997m-5.333,0a5.333,5.333 0,1 1,10.667 0a5.333,5.333 0,1 1,-10.667 0" />
   <path
       android:fillColor="#FF000000"
-      android:pathData="M15.5,31.9m-5.5,0a5.5,5.5 0,1 1,11 0a5.5,5.5 0,1 1,-11 0"/>
+      android:pathData="M31.499,16.333m-5.333,0a5.333,5.333 0,1 1,10.667 0a5.333,5.333 0,1 1,-10.667 0" />
   <path
       android:fillColor="#FF000000"
-      android:pathData="M31.9,28c2.1,0 3.9,1.7 3.9,3.9s-1.7,3.9 -3.9,3.9c-2.1,0 -3.9,-1.7 -3.9,-3.9S29.8,28 31.9,28M31.9,26.3c-3.1,0 -5.6,2.5 -5.6,5.6c0,3.1 2.5,5.6 5.6,5.6c3.1,0 5.6,-2.5 5.6,-5.6C37.5,28.8 35,26.3 31.9,26.3L31.9,26.3z"/>
-  <path
-      android:pathData="M34.9,35L41.2,41.3"
-      android:strokeWidth="1.7"
-      android:fillColor="#00000000"
-      android:strokeColor="#000000"/>
+      android:fillType="evenOdd"
+      android:pathData="M34.168,31.005C34.168,29.538 32.968,28.338 31.501,28.338C30.035,28.338 28.835,29.538 28.835,31.005C28.835,32.472 30.035,33.672 31.501,33.672C32.968,33.672 34.168,32.472 34.168,31.005ZM26.168,31.005C26.168,28.059 28.555,25.672 31.501,25.672C34.448,25.672 36.835,28.059 36.835,31.005C36.835,31.992 36.567,32.917 36.1,33.709L40.169,37.791L38.289,39.671L34.208,35.602C33.415,36.07 32.489,36.339 31.501,36.339C28.555,36.339 26.168,33.952 26.168,31.005Z" />
 </vector>
diff --git a/res/drawable/icon_menu_arrow_background.xml b/res/drawable/icon_menu_arrow_background.xml
index f24022e..2eb1dfc 100644
--- a/res/drawable/icon_menu_arrow_background.xml
+++ b/res/drawable/icon_menu_arrow_background.xml
@@ -22,7 +22,7 @@
         android:angle="0"
         android:startColor="#00000000"
         android:centerX="0.25"
-        android:centerColor="?androidprv:attr/materialColorSurfaceContainer"
-        android:endColor="?androidprv:attr/materialColorSurfaceContainer" />
+        android:centerColor="?androidprv:attr/materialColorSurfaceBright"
+        android:endColor="?androidprv:attr/materialColorSurfaceBright" />
     <corners android:radius="@dimen/dialogCornerRadius" />
 </shape>
\ No newline at end of file
diff --git a/res/drawable/icon_menu_background.xml b/res/drawable/icon_menu_background.xml
index ec5f011..8a95c3e 100644
--- a/res/drawable/icon_menu_background.xml
+++ b/res/drawable/icon_menu_background.xml
@@ -17,6 +17,5 @@
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:shape="rectangle">
-    <solid android:color="?androidprv:attr/materialColorSurfaceContainer" />
-    <corners android:radius="@dimen/dialogCornerRadius" />
+    <solid android:color="?androidprv:attr/materialColorSurfaceBright" />
 </shape>
\ No newline at end of file
diff --git a/res/drawable/icon_menu_background_corners.xml b/res/drawable/icon_menu_background_corners.xml
new file mode 100644
index 0000000..16e3fe2
--- /dev/null
+++ b/res/drawable/icon_menu_background_corners.xml
@@ -0,0 +1,22 @@
+<?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.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+    android:shape="rectangle">
+    <solid android:color="?androidprv:attr/materialColorSurfaceBright" />
+    <corners android:radius="@dimen/task_thumbnail_icon_menu_corner_radius" />
+</shape>
\ No newline at end of file
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index ac701d6..6c9a238 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -402,9 +402,12 @@
     <dimen name="task_thumbnail_icon_drawable_size">0dp</dimen>
     <dimen name="task_thumbnail_icon_drawable_size_grid">0dp</dimen>
     <dimen name="task_thumbnail_icon_menu_max_width">0dp</dimen>
+    <dimen name="task_thumbnail_icon_menu_start_margin">0dp</dimen>
+    <dimen name="task_thumbnail_icon_menu_background_max_width">0dp</dimen>
+    <dimen name="task_thumbnail_icon_menu_corner_radius">0dp</dimen>
     <dimen name="task_thumbnail_icon_menu_drawable_size">0dp</dimen>
     <dimen name="task_thumbnail_icon_menu_drawable_touch_size">0dp</dimen>
-    <dimen name="task_menu_vertical_padding">0dp</dimen>
+    <dimen name="task_menu_edge_padding">0dp</dimen>
     <dimen name="overview_task_margin">0dp</dimen>
     <dimen name="overview_actions_height">0dp</dimen>
     <dimen name="overview_actions_button_spacing">0dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 31579cd..6a4a9a4 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -447,10 +447,6 @@
     <!-- A hint shown in launcher settings develop options filter box -->
     <string name="developer_options_filter_hint">Filter</string>
 
-    <!-- Title for preference screen show in Home Settings related to smart search preferences. [CHAR LIMIT=50]-->
-    <string name="search_pref_screen_title">Search your phone</string>
-    <!-- Title for preference screen show in Home Settings related to smart search preferences. [CHAR LIMIT=50]-->
-    <string name="search_pref_screen_title_tablet">Search your tablet</string>
     <!-- Failed action error message: e.g. Failed: Pause -->
     <string name="remote_action_failed">Failed: <xliff:g id="what" example="Pause">%1$s</xliff:g></string>
 
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 7d9f709..26751ee 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -302,6 +302,10 @@
             getIntFlag(309972570, "FLAG_LPNH_HAPTIC_HINT_ITERATIONS", 50,
             "Haptic hint number of iterations.");
 
+    public static final BooleanFlag ENABLE_LPNH_DEEP_PRESS =
+            getReleaseFlag(310952290, "ENABLE_LPNH_DEEP_PRESS", ENABLED,
+                    "Long press of nav handle is instantly triggered if deep press is detected.");
+
     // TODO(Block 17): Clean up flags
     // Aconfig migration complete for ENABLE_TASKBAR_PINNING.
     private static final BooleanFlag ENABLE_TASKBAR_PINNING = getDebugFlag(270396583,
diff --git a/src/com/android/launcher3/settings/SettingsActivity.java b/src/com/android/launcher3/settings/SettingsActivity.java
index 650fbcc..8cb15a5 100644
--- a/src/com/android/launcher3/settings/SettingsActivity.java
+++ b/src/com/android/launcher3/settings/SettingsActivity.java
@@ -50,8 +50,6 @@
 import androidx.recyclerview.widget.RecyclerView;
 
 import com.android.launcher3.BuildConfig;
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.LauncherFiles;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
@@ -206,15 +204,6 @@
             }
 
             if (getActivity() != null && !TextUtils.isEmpty(getPreferenceScreen().getTitle())) {
-                if (getPreferenceScreen().getTitle().equals(
-                        getResources().getString(R.string.search_pref_screen_title))){
-                    DeviceProfile mDeviceProfile = InvariantDeviceProfile.INSTANCE.get(
-                            getContext()).getDeviceProfile(getContext());
-                    getPreferenceScreen().setTitle(mDeviceProfile.isMultiDisplay
-                            || mDeviceProfile.isPhone ?
-                            R.string.search_pref_screen_title :
-                            R.string.search_pref_screen_title_tablet);
-                }
                 getActivity().setTitle(getPreferenceScreen().getTitle());
             }
         }
diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
index c80f243..51c047c 100644
--- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
@@ -22,12 +22,13 @@
 import static android.view.Gravity.LEFT;
 import static android.view.Gravity.START;
 import static android.view.Gravity.TOP;
+import static android.view.View.LAYOUT_DIRECTION_RTL;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
 
+import static com.android.launcher3.Flags.enableOverviewIconMenu;
 import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
 import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
-import static com.android.launcher3.Flags.enableOverviewIconMenu;
 import static com.android.launcher3.touch.SingleAxisSwipeDetector.HORIZONTAL;
 import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
 import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
@@ -41,6 +42,7 @@
 import android.graphics.drawable.ShapeDrawable;
 import android.util.FloatProperty;
 import android.util.Pair;
+import android.view.Gravity;
 import android.view.MotionEvent;
 import android.view.Surface;
 import android.view.VelocityTracker;
@@ -270,7 +272,7 @@
     public float getTaskMenuX(float x, View thumbnailView,
             DeviceProfile deviceProfile, float taskInsetMargin, View taskViewIcon) {
         if (enableOverviewIconMenu()) {
-            return x - (taskInsetMargin / 2f);
+            return x + (taskInsetMargin / 2f);
         }
         return thumbnailView.getMeasuredWidth() + x - taskInsetMargin;
     }
@@ -279,7 +281,10 @@
     public float getTaskMenuY(float y, View thumbnailView, int stagePosition,
             View taskMenuView, float taskInsetMargin, View taskViewIcon) {
         if (enableOverviewIconMenu()) {
-            return y - taskMenuView.getMeasuredHeight() - taskInsetMargin;
+            return y - (thumbnailView.getLayoutDirection() == LAYOUT_DIRECTION_RTL
+                    ? taskMenuView.getMeasuredHeight() * 2 - (taskInsetMargin / 2f)
+                    : taskMenuView.getMeasuredHeight());
+
         }
         BaseDragLayer.LayoutParams lp = (BaseDragLayer.LayoutParams) taskMenuView.getLayoutParams();
         int taskMenuWidth = lp.width;
@@ -294,6 +299,10 @@
     @Override
     public int getTaskMenuWidth(View thumbnailView, DeviceProfile deviceProfile,
             @StagePosition int stagePosition) {
+        if (enableOverviewIconMenu()) {
+            return thumbnailView.getResources().getDimensionPixelSize(
+                    R.dimen.task_thumbnail_icon_menu_max_width);
+        }
         if (stagePosition == SplitConfigurationOptions.STAGE_POSITION_UNDEFINED) {
             return thumbnailView.getMeasuredWidth();
         } else {
@@ -323,7 +332,7 @@
     public Pair<Float, Float> getDwbLayoutTranslations(int taskViewWidth,
             int taskViewHeight, SplitBounds splitBounds, DeviceProfile deviceProfile,
             View[] thumbnailViews, int desiredTaskId, View banner) {
-        boolean isRtl = banner.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
+        boolean isRtl = banner.getLayoutDirection() == LAYOUT_DIRECTION_RTL;
         float translationX = 0;
         float translationY = 0;
         FrameLayout.LayoutParams bannerParams = (FrameLayout.LayoutParams) banner.getLayoutParams();
@@ -504,8 +513,19 @@
 
     @Override
     public void measureGroupedTaskViewThumbnailBounds(View primarySnapshot, View secondarySnapshot,
-            int parentWidth, int parentHeight, SplitBounds splitBoundsConfig,
-            DeviceProfile dp, boolean isRtl) {
+            int parentWidth, int parentHeight, SplitBounds splitBoundsConfig, DeviceProfile dp,
+            boolean isRtl) {
+        FrameLayout.LayoutParams primaryParams =
+                (FrameLayout.LayoutParams) primarySnapshot.getLayoutParams();
+        FrameLayout.LayoutParams secondaryParams =
+                (FrameLayout.LayoutParams) secondarySnapshot.getLayoutParams();
+
+        // Swap the margins that are set in TaskView#setRecentsOrientedState()
+        secondaryParams.topMargin = dp.overviewTaskThumbnailTopMarginPx;
+        primaryParams.topMargin = 0;
+
+        // Measure and layout the thumbnails bottom up, since the primary is on the visual left
+        // (portrait bottom) and secondary is on the right (portrait top)
         int spaceAboveSnapshot = dp.overviewTaskThumbnailTopMarginPx;
         int totalThumbnailHeight = parentHeight - spaceAboveSnapshot;
         int dividerBar = Math.round(totalThumbnailHeight * (splitBoundsConfig.appsStackedVertically
@@ -519,11 +539,12 @@
         float taskPercent = splitBoundsConfig.appsStackedVertically ?
                 splitBoundsConfig.topTaskPercent : splitBoundsConfig.leftTaskPercent;
         primarySnapshotWidth = parentWidth;
-        primarySnapshotHeight = (int) (totalThumbnailHeight * taskPercent);
+        primarySnapshotHeight = (int) (totalThumbnailHeight * (taskPercent));
 
         secondarySnapshotWidth = parentWidth;
         secondarySnapshotHeight = totalThumbnailHeight - primarySnapshotHeight - dividerBar;
-        secondarySnapshot.setTranslationY(primarySnapshotHeight + spaceAboveSnapshot + dividerBar);
+        secondarySnapshot.setTranslationY(0);
+        primarySnapshot.setTranslationY(secondarySnapshotHeight + spaceAboveSnapshot + dividerBar);
         primarySnapshot.measure(
                 View.MeasureSpec.makeMeasureSpec(primarySnapshotWidth, View.MeasureSpec.EXACTLY),
                 View.MeasureSpec.makeMeasureSpec(primarySnapshotHeight, View.MeasureSpec.EXACTLY));
@@ -536,6 +557,11 @@
     @Override
     public void setTaskIconParams(FrameLayout.LayoutParams iconParams, int taskIconMargin,
             int taskIconHeight, int thumbnailTopMargin, boolean isRtl) {
+        if (enableOverviewIconMenu()) {
+            iconParams.gravity = Gravity.START | Gravity.CENTER_VERTICAL;
+            iconParams.topMargin = 0;
+            return;
+        }
         iconParams.gravity = (isRtl ? START : END) | CENTER_VERTICAL;
         iconParams.rightMargin = -taskIconHeight - taskIconMargin / 2;
         iconParams.leftMargin = 0;
@@ -544,13 +570,21 @@
     }
 
     @Override
-    public void setTaskIconMenuParams(FrameLayout.LayoutParams iconMenuParams, int iconMenuMargin,
-            int thumbnailTopMargin) {
-        iconMenuParams.gravity = END | TOP;
-        iconMenuParams.setMarginStart(0);
-        iconMenuParams.topMargin = iconMenuParams.width + iconMenuMargin;
-        iconMenuParams.bottomMargin = 0;
+    public void setIconAppChipMenuParams(View iconAppChipMenuView,
+            FrameLayout.LayoutParams iconMenuParams, int iconMenuMargin, int thumbnailTopMargin) {
+        boolean isRtl = iconAppChipMenuView.getLayoutDirection() == LAYOUT_DIRECTION_RTL;
+        iconMenuParams.gravity = (isRtl ? START : END) | (isRtl ? BOTTOM : TOP);
+        iconMenuParams.setMarginStart(isRtl ? iconMenuMargin : 0);
+        iconMenuParams.topMargin = iconMenuMargin;
+        iconMenuParams.bottomMargin = isRtl ? iconMenuMargin : 0;
         iconMenuParams.setMarginEnd(iconMenuMargin);
+
+        iconAppChipMenuView.setPivotX(isRtl ? iconMenuParams.width - (iconMenuParams.height / 2f)
+                : iconMenuParams.width / 2f);
+        iconAppChipMenuView.setPivotY(
+                isRtl ? (iconMenuParams.height / 2f) : iconMenuParams.width / 2f);
+        iconAppChipMenuView.setTranslationY(0);
+        iconAppChipMenuView.setRotation(getDegreesRotated());
     }
 
     @Override
@@ -578,16 +612,23 @@
         int bottomToMidpointOffset = (int) (overviewThumbnailAreaThickness * midpointFromBottomPct);
         int insetOffset = (int) (overviewThumbnailAreaThickness * insetPct);
 
-        primaryIconParams.gravity = enableOverviewIconMenu() ? TOP | (isRtl ? START : END)
-                : BOTTOM | (isRtl ? START : END);
-        secondaryIconParams.gravity = enableOverviewIconMenu() ? TOP | (isRtl ? START : END)
-                : BOTTOM | (isRtl ? START : END);
+        if (enableOverviewIconMenu()) {
+            primaryIconParams.gravity = isRtl ? BOTTOM | START : TOP | END;
+            secondaryIconParams.gravity = isRtl ? BOTTOM | START : TOP | END;
+        } else {
+            primaryIconParams.gravity = BOTTOM | (isRtl ? START : END);
+            secondaryIconParams.gravity = BOTTOM | (isRtl ? START : END);
+        }
         primaryIconView.setTranslationX(0);
         secondaryIconView.setTranslationX(0);
         if (enableOverviewIconMenu()) {
-            int dividerThickness = Math.min(splitConfig.visualDividerBounds.width(),
-                    splitConfig.visualDividerBounds.height());
-            secondaryIconView.setTranslationY(primarySnapshotHeight + dividerThickness);
+            if (primaryIconView.getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
+                secondaryIconView.setTranslationY(-primarySnapshotHeight);
+                primaryIconView.setTranslationY(0);
+            } else {
+                int secondarySnapshotHeight = groupedTaskViewHeight - primarySnapshotHeight;
+                primaryIconView.setTranslationY(secondarySnapshotHeight);
+            }
         } else if (splitConfig.initiatedFromSeascape) {
             // if the split was initiated from seascape,
             // the task on the right (secondary) is slightly larger
diff --git a/src/com/android/launcher3/touch/PagedOrientationHandler.java b/src/com/android/launcher3/touch/PagedOrientationHandler.java
index 0069d9b..74d88ba 100644
--- a/src/com/android/launcher3/touch/PagedOrientationHandler.java
+++ b/src/com/android/launcher3/touch/PagedOrientationHandler.java
@@ -173,8 +173,8 @@
     // Overview TaskMenuView methods
     void setTaskIconParams(FrameLayout.LayoutParams iconParams,
             int taskIconMargin, int taskIconHeight, int thumbnailTopMargin, boolean isRtl);
-    void setTaskIconMenuParams(FrameLayout.LayoutParams iconMenuParams, int iconMenuMargin,
-            int thumbnailTopMargin);
+    void setIconAppChipMenuParams(View iconAppChipMenuView, FrameLayout.LayoutParams iconMenuParams,
+            int iconMenuMargin, int thumbnailTopMargin);
     void setSplitIconParams(View primaryIconView, View secondaryIconView,
             int taskIconHeight, int primarySnapshotWidth, int primarySnapshotHeight,
             int groupedTaskViewHeight, int groupedTaskViewWidth, boolean isRtl,
diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
index 62ef229..158747c 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -25,9 +25,9 @@
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
 
+import static com.android.launcher3.Flags.enableOverviewIconMenu;
 import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
 import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
-import static com.android.launcher3.Flags.enableOverviewIconMenu;
 import static com.android.launcher3.touch.SingleAxisSwipeDetector.VERTICAL;
 import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
 import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
@@ -41,6 +41,7 @@
 import android.graphics.drawable.ShapeDrawable;
 import android.util.FloatProperty;
 import android.util.Pair;
+import android.view.Gravity;
 import android.view.MotionEvent;
 import android.view.Surface;
 import android.view.VelocityTracker;
@@ -268,8 +269,10 @@
     public float getTaskMenuX(float x, View thumbnailView,
             DeviceProfile deviceProfile, float taskInsetMargin, View taskViewIcon) {
         if (enableOverviewIconMenu()) {
-            return x + (thumbnailView.getLayoutDirection() == LAYOUT_DIRECTION_RTL
-                    ? -(taskViewIcon.getWidth() / 2f) : 0);
+            if (thumbnailView.getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
+                return x + taskInsetMargin - taskViewIcon.getHeight() - (taskInsetMargin / 2f);
+            }
+            return x + taskInsetMargin;
         } else if (deviceProfile.isLandscape) {
             return x + taskInsetMargin
                     + (thumbnailView.getMeasuredWidth() - thumbnailView.getMeasuredHeight()) / 2f;
@@ -291,14 +294,14 @@
     public int getTaskMenuWidth(View thumbnailView, DeviceProfile deviceProfile,
             @StagePosition int stagePosition) {
         if (enableOverviewIconMenu()) {
-            int padding = thumbnailView.getResources().getDimensionPixelSize(
-                    R.dimen.task_menu_vertical_padding);
             return thumbnailView.getResources().getDimensionPixelSize(
-                    R.dimen.task_thumbnail_icon_menu_max_width) + (2 * padding);
+                    R.dimen.task_thumbnail_icon_menu_max_width);
         }
-        return deviceProfile.isLandscape && !deviceProfile.isTablet
+        int padding = thumbnailView.getResources()
+                .getDimensionPixelSize(R.dimen.task_menu_edge_padding);
+        return (deviceProfile.isLandscape && !deviceProfile.isTablet
                 ? thumbnailView.getMeasuredHeight()
-                : thumbnailView.getMeasuredWidth();
+                : thumbnailView.getMeasuredWidth()) - (2 * padding);
     }
 
     @Override
@@ -696,6 +699,12 @@
     @Override
     public void setTaskIconParams(FrameLayout.LayoutParams iconParams, int taskIconMargin,
             int taskIconHeight, int thumbnailTopMargin, boolean isRtl) {
+        if (enableOverviewIconMenu()) {
+            iconParams.setMarginStart(taskIconMargin);
+            iconParams.gravity = Gravity.START | Gravity.CENTER_VERTICAL;
+            iconParams.topMargin = 0;
+            return;
+        }
         iconParams.gravity = TOP | CENTER_HORIZONTAL;
         // Reset margins, since they may have been set on rotation
         iconParams.leftMargin = iconParams.rightMargin = 0;
@@ -703,13 +712,18 @@
     }
 
     @Override
-    public void setTaskIconMenuParams(FrameLayout.LayoutParams iconMenuParams, int iconMenuMargin,
-            int thumbnailTopMargin) {
+    public void setIconAppChipMenuParams(View iconAppChipMenuView,
+            FrameLayout.LayoutParams iconMenuParams, int iconMenuMargin, int thumbnailTopMargin) {
         iconMenuParams.gravity = TOP | START;
         iconMenuParams.setMarginStart(iconMenuMargin);
-        iconMenuParams.topMargin = iconMenuMargin;
+        iconMenuParams.topMargin = thumbnailTopMargin;
         iconMenuParams.bottomMargin = 0;
         iconMenuParams.setMarginEnd(0);
+
+        iconAppChipMenuView.setPivotX(0);
+        iconAppChipMenuView.setPivotY(0);
+        iconAppChipMenuView.setTranslationY(0);
+        iconAppChipMenuView.setRotation(getDegreesRotated());
     }
 
     @Override
@@ -729,20 +743,13 @@
             secondaryIconParams.topMargin = primaryIconParams.topMargin;
             secondaryIconParams.setMarginStart(primaryIconParams.getMarginStart());
             if (deviceProfile.isLandscape) {
-                int fullscreenInsetThickness = deviceProfile.isSeascape()
-                        ? deviceProfile.getInsets().right
-                        : deviceProfile.getInsets().left;
-                int fullscreenMidpointFromBottom = ((deviceProfile.widthPx
-                        - fullscreenInsetThickness) / 2);
-                float midpointFromEndPct = (float) fullscreenMidpointFromBottom
-                        / deviceProfile.widthPx;
-                int bottomToMidpointOffset = (int) (groupedTaskViewWidth * midpointFromEndPct);
                 if (isRtl) {
-                    primaryIconView.setTranslationX(-bottomToMidpointOffset);
+                    primaryIconView.setTranslationX(-primarySnapshotWidth);
                 } else {
-                    secondaryIconView.setTranslationX(bottomToMidpointOffset);
+                    secondaryIconView.setTranslationX(primarySnapshotWidth);
                 }
             } else {
+                primaryIconView.setTranslationX(0);
                 secondaryIconView.setTranslationX(0);
                 int dividerThickness = Math.min(splitConfig.visualDividerBounds.width(),
                         splitConfig.visualDividerBounds.height());
diff --git a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
index 4409572..06526a8 100644
--- a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
@@ -21,6 +21,8 @@
 import static android.view.Gravity.END;
 import static android.view.Gravity.RIGHT;
 import static android.view.Gravity.START;
+import static android.view.Gravity.TOP;
+import static android.view.View.LAYOUT_DIRECTION_RTL;
 
 import static com.android.launcher3.Flags.enableOverviewIconMenu;
 import static com.android.launcher3.touch.SingleAxisSwipeDetector.HORIZONTAL;
@@ -32,6 +34,7 @@
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.util.Pair;
+import android.view.Gravity;
 import android.view.Surface;
 import android.view.View;
 import android.widget.FrameLayout;
@@ -89,7 +92,7 @@
     public float getTaskMenuX(float x, View thumbnailView,
             DeviceProfile deviceProfile, float taskInsetMargin, View taskViewIcon) {
         if (enableOverviewIconMenu()) {
-            return x + taskViewIcon.getHeight() + taskInsetMargin * 2;
+            return x + (taskViewIcon.getHeight() * 2);
         }
         return x + taskInsetMargin;
     }
@@ -98,7 +101,9 @@
     public float getTaskMenuY(float y, View thumbnailView, int stagePosition,
             View taskMenuView, float taskInsetMargin, View taskViewIcon) {
         if (enableOverviewIconMenu()) {
-            return y + taskViewIcon.getWidth() - taskViewIcon.getHeight();
+            return y + taskViewIcon.getWidth() + (
+                    thumbnailView.getLayoutDirection() == LAYOUT_DIRECTION_RTL ? taskInsetMargin
+                            / 2f : -taskViewIcon.getHeight());
         }
         BaseDragLayer.LayoutParams lp = (BaseDragLayer.LayoutParams) taskMenuView.getLayoutParams();
         int taskMenuWidth = lp.width;
@@ -134,7 +139,7 @@
     public Pair<Float, Float> getDwbLayoutTranslations(int taskViewWidth,
             int taskViewHeight, SplitBounds splitBounds, DeviceProfile deviceProfile,
             View[] thumbnailViews, int desiredTaskId, View banner) {
-        boolean isRtl = banner.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
+        boolean isRtl = banner.getLayoutDirection() == LAYOUT_DIRECTION_RTL;
         float translationX = 0;
         float translationY = 0;
         FrameLayout.LayoutParams bannerParams = (FrameLayout.LayoutParams) banner.getLayoutParams();
@@ -214,22 +219,37 @@
     @Override
     public void setTaskIconParams(FrameLayout.LayoutParams iconParams,
             int taskIconMargin, int taskIconHeight, int thumbnailTopMargin, boolean isRtl) {
-        iconParams.gravity = (isRtl ? END : START) | CENTER_VERTICAL;
-        iconParams.leftMargin =
-                enableOverviewIconMenu() ? 0 : -taskIconHeight - taskIconMargin / 2;
         iconParams.rightMargin = 0;
-        iconParams.topMargin = enableOverviewIconMenu() ? 0 : thumbnailTopMargin / 2;
         iconParams.bottomMargin = 0;
+        if (enableOverviewIconMenu()) {
+            iconParams.setMarginStart(taskIconMargin);
+            iconParams.gravity = Gravity.START | Gravity.CENTER_VERTICAL;
+            iconParams.leftMargin = 0;
+            iconParams.topMargin = 0;
+        } else {
+            iconParams.gravity = (isRtl ? END : START) | CENTER_VERTICAL;
+            iconParams.leftMargin = -taskIconHeight - taskIconMargin / 2;
+            iconParams.topMargin = thumbnailTopMargin / 2;
+        }
     }
 
     @Override
-    public void setTaskIconMenuParams(FrameLayout.LayoutParams iconMenuParams, int iconMenuMargin,
-            int thumbnailTopMargin) {
-        iconMenuParams.gravity = BOTTOM | START;
+    public void setIconAppChipMenuParams(View iconAppChipMenuView,
+            FrameLayout.LayoutParams iconMenuParams, int iconMenuMargin, int thumbnailTopMargin) {
+        boolean isRtl = iconAppChipMenuView.getLayoutDirection() == LAYOUT_DIRECTION_RTL;
+        iconMenuParams.gravity = (isRtl ? TOP : BOTTOM) | (isRtl ? END : START);
         iconMenuParams.setMarginStart(0);
-        iconMenuParams.topMargin = 0;
+        iconMenuParams.topMargin = isRtl ? iconMenuMargin : 0;
         iconMenuParams.bottomMargin = 0;
-        iconMenuParams.setMarginEnd(0);
+        iconMenuParams.setMarginEnd(isRtl ? thumbnailTopMargin : 0);
+
+        // Use half menu height to place the pivot within the X/Y center of icon in the menu.
+        float iconCenter = iconAppChipMenuView.getHeight() / 2f;
+        iconAppChipMenuView.setPivotX(isRtl ? iconMenuParams.width / 2f : iconCenter);
+        iconAppChipMenuView.setPivotY(
+                isRtl ? iconMenuParams.width / 2f : iconCenter - iconMenuMargin);
+        iconAppChipMenuView.setTranslationY(0);
+        iconAppChipMenuView.setRotation(getDegreesRotated());
     }
 
     @Override
@@ -259,14 +279,19 @@
         int bottomToMidpointOffset = (int) (overviewThumbnailAreaThickness * midpointFromBottomPct);
         int insetOffset = (int) (overviewThumbnailAreaThickness * insetPct);
 
-        primaryIconParams.gravity = BOTTOM | (isRtl ? END : START);
-        secondaryIconParams.gravity = BOTTOM | (isRtl ? END : START);
+        int gravity = (isRtl ? TOP : BOTTOM) | (isRtl ? END : START);
+        primaryIconParams.gravity = gravity;
+        secondaryIconParams.gravity = gravity;
         primaryIconView.setTranslationX(0);
         secondaryIconView.setTranslationX(0);
         if (enableOverviewIconMenu()) {
-            int dividerThickness = Math.min(splitConfig.visualDividerBounds.width(),
-                    splitConfig.visualDividerBounds.height());
-            secondaryIconView.setTranslationY(-primarySnapshotHeight - dividerThickness);
+            if (primaryIconView.getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
+                primaryIconView.setTranslationY(groupedTaskViewHeight - primarySnapshotHeight);
+                secondaryIconView.setTranslationY(0);
+            } else {
+                secondaryIconView.setTranslationY(-primarySnapshotHeight);
+                primaryIconView.setTranslationY(0);
+            }
         } else if (splitConfig.initiatedFromSeascape) {
             // if the split was initiated from seascape,
             // the task on the right (secondary) is slightly larger
diff --git a/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java b/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
index 3e80e6b..e1b06a8 100644
--- a/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
+++ b/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
@@ -158,6 +158,7 @@
     public static final String PERMANENT_DIAG_TAG = "TaplTarget";
     public static final String TWO_TASKBAR_LONG_CLICKS = "b/262282528";
     public static final String ICON_MISSING = "b/282963545";
+    public static final String WORKSPACE_LONG_PRESS = "b/311099513";
 
     public static final String REQUEST_EMULATE_DISPLAY = "emulate-display";
     public static final String REQUEST_STOP_EMULATE_DISPLAY = "stop-emulate-display";
diff --git a/tests/src/com/android/launcher3/allapps/TaplKeyboardFocusTest.java b/tests/src/com/android/launcher3/allapps/TaplKeyboardFocusTest.java
index fe9464a..d71bf84 100644
--- a/tests/src/com/android/launcher3/allapps/TaplKeyboardFocusTest.java
+++ b/tests/src/com/android/launcher3/allapps/TaplKeyboardFocusTest.java
@@ -16,6 +16,8 @@
 package com.android.launcher3.allapps;
 
 import static com.android.launcher3.ui.TaplTestsLauncher3.initialize;
+import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL;
+import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT;
 
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
@@ -30,6 +32,7 @@
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.tapl.HomeAllApps;
 import com.android.launcher3.ui.AbstractLauncherUiTest;
+import com.android.launcher3.util.rule.TestStabilityRule;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -80,6 +83,7 @@
     }
 
     @Test
+    @TestStabilityRule.Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT) // b/311410127
     public void testAllAppsExitSearchAndFocusSearchResults() {
         final HomeAllApps allApps = mLauncher.goHome().switchToAllApps();
         assertTrue("Launcher internal state is not All Apps",
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 406de35..720c8e5 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -28,6 +28,8 @@
 import static com.android.launcher3.tapl.TestHelpers.getOverviewPackageName;
 import static com.android.launcher3.testing.shared.TestProtocol.NORMAL_STATE_ORDINAL;
 import static com.android.launcher3.testing.shared.TestProtocol.REQUEST_NUM_ALL_APPS_COLUMNS;
+import static com.android.launcher3.testing.shared.TestProtocol.WORKSPACE_LONG_PRESS;
+import static com.android.launcher3.testing.shared.TestProtocol.testLogD;
 
 import android.app.ActivityManager;
 import android.app.Instrumentation;
@@ -1705,6 +1707,7 @@
         final Point start = new Point(startX, startY);
         final Point end = new Point(endX, endY);
         sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, start, gestureScope);
+        testLogD(WORKSPACE_LONG_PRESS, "Sent ACTION_DOWN");
         if (mTrackpadGestureType != TrackpadGestureType.NONE) {
             sendPointer(downTime, downTime, getPointerAction(MotionEvent.ACTION_POINTER_DOWN, 1),
                     start, gestureScope);
@@ -1909,6 +1912,10 @@
         long steps = duration / GESTURE_STEP_MS;
 
         long currentTime = startTime;
+        testLogD(WORKSPACE_LONG_PRESS, "movingPointer" +
+                " downTime: " + downTime + " startTime: " + startTime +
+                " duration: " + duration + " isDecel? " + isDecelerating +
+                " gestureScope: " + gestureScope);
 
         if (isDecelerating) {
             // formula: V = V0 - D*T, assuming V = 0 when T = duration