Merge "Animate depth from the right value on Taskbar All Apps launches." into udc-qpr-dev
diff --git a/quickstep/res/drawable/ic_screenshot.xml b/quickstep/res/drawable/ic_screenshot.xml
index ea10661..9ee6c44 100644
--- a/quickstep/res/drawable/ic_screenshot.xml
+++ b/quickstep/res/drawable/ic_screenshot.xml
@@ -1,10 +1,32 @@
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
+    android:width="20dp"
+    android:height="20dp"
+    android:viewportWidth="20"
+    android:viewportHeight="20">
   <path
-      android:pathData="M5,4C5,2.343 6.343,1 8,1L16,1C17.657,1 19,2.343 19,4L19,20C19,21.657 17.657,23 16,23L8,23C6.343,23 5,21.657 5,20L5,4ZM8,3C7.448,3 7,3.448 7,4L7,20C7,20.552 7.448,21 8,21L16,21C16.552,21 17,20.552 17,20L17,4C17,3.448 16.552,3 16,3L8,3ZM8,4L8,8L9.5,8L9.5,5.5L12,5.5L12,4L8,4ZM16,16L16,20L12,20L12,18.5L14.5,18.5L14.5,16L16,16Z"
-      android:fillColor="@color/overview_button"
-      android:fillType="evenOdd"/>
-</vector>
+      android:pathData="M5.8334,1.666H8.3334V3.3327H5.8334V6.666H4.1667V3.3327C4.1667,2.4122 4.9129,1.666 5.8334,1.666Z"
+      android:fillColor="#000000"/>
+  <path
+      android:pathData="M4.1667,13.3327V16.666C4.1667,17.5865 4.9129,18.3327 5.8334,18.3327H8.3334V16.666H5.8334V13.3327H4.1667Z"
+      android:fillColor="#000000"/>
+  <path
+      android:pathData="M14.1667,13.3327V16.666H11.6667V18.3327H14.1667C15.0872,18.3327 15.8334,17.5865 15.8334,16.666V13.3327H14.1667Z"
+      android:fillColor="#000000"/>
+  <path
+      android:pathData="M15.8334,6.666V3.3327C15.8334,2.4122 15.0872,1.666 14.1667,1.666H11.6667V3.3327H14.1667V6.666H15.8334Z"
+      android:fillColor="#000000"/>
+</vector>
\ No newline at end of file
diff --git a/quickstep/res/layout/fallback_recents_activity.xml b/quickstep/res/layout/fallback_recents_activity.xml
index f0ea09c..bfeb82d 100644
--- a/quickstep/res/layout/fallback_recents_activity.xml
+++ b/quickstep/res/layout/fallback_recents_activity.xml
@@ -15,7 +15,6 @@
 -->
 <com.android.launcher3.LauncherRootView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/launcher"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:fitsSystemWindows="true">
diff --git a/quickstep/res/layout/gesture_tutorial_activity.xml b/quickstep/res/layout/gesture_tutorial_activity.xml
index 0e763ec..82caedf 100644
--- a/quickstep/res/layout/gesture_tutorial_activity.xml
+++ b/quickstep/res/layout/gesture_tutorial_activity.xml
@@ -13,80 +13,8 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 -->
-<androidx.constraintlayout.widget.ConstraintLayout
+<FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/gesture_tutorial_fragment_container"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
-
-    <FrameLayout
-        android:id="@+id/gesture_tutorial_fragment_container"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent" />
-
-    <RelativeLayout
-        android:id="@+id/rotation_prompt"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:background="?attr/surfaceHome"
-        android:visibility="gone"
-
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent">
-
-        <androidx.constraintlayout.widget.ConstraintLayout
-            android:id="@+id/background"
-            android:layout_width="300dp"
-            android:layout_height="wrap_content"
-            android:layout_centerHorizontal="true"
-            android:layout_centerVertical="true"
-            android:background="@drawable/rotate_prompt_bg"
-            android:padding="24dp">
-
-            <ImageView
-                android:id="@+id/icon"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:src="@drawable/rotate_tutorial_warning"
-
-                app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintTop_toTopOf="parent"
-                app:layout_constraintEnd_toEndOf="parent" />
-
-            <TextView
-                android:id="@+id/rotate_title"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="20dp"
-                android:lineSpacingExtra="2sp"
-                android:text="@string/gesture_tutorial_rotation_prompt_title"
-                android:textAppearance="@style/rotate_prompt_title"
-
-                app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintTop_toBottomOf="@id/icon"
-                app:layout_constraintEnd_toEndOf="parent" />
-
-            <TextView
-                android:id="@+id/rotate_screen_subtitle"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="16dp"
-                android:gravity="center"
-                android:text="@string/gesture_tutorial_rotation_prompt"
-                android:textAppearance="@style/rotate_prompt_subtitle"
-
-                app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintTop_toBottomOf="@id/rotate_title"
-                app:layout_constraintEnd_toEndOf="parent" />
-
-        </androidx.constraintlayout.widget.ConstraintLayout>
-    </RelativeLayout>
-
-</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
+    android:layout_height="match_parent"/>
\ No newline at end of file
diff --git a/quickstep/res/layout/gesture_tutorial_rotation_prompt.xml b/quickstep/res/layout/gesture_tutorial_rotation_prompt.xml
new file mode 100644
index 0000000..b41a96d
--- /dev/null
+++ b/quickstep/res/layout/gesture_tutorial_rotation_prompt.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="?attr/surfaceHome">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/background"
+        android:layout_width="300dp"
+        android:layout_height="wrap_content"
+        android:layout_centerHorizontal="true"
+        android:layout_centerVertical="true"
+        android:background="@drawable/rotate_prompt_bg"
+        android:padding="24dp"
+
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent">
+
+        <ImageView
+            android:id="@+id/icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/rotate_tutorial_warning"
+
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintEnd_toEndOf="parent" />
+
+        <TextView
+            android:id="@+id/rotate_title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="20dp"
+            android:lineSpacingExtra="2sp"
+            android:text="@string/gesture_tutorial_rotation_prompt_title"
+            android:textAppearance="@style/rotate_prompt_title"
+
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/icon"
+            app:layout_constraintEnd_toEndOf="parent" />
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="16dp"
+            android:gravity="center"
+            android:text="@string/gesture_tutorial_rotation_prompt"
+            android:textAppearance="@style/rotate_prompt_subtitle"
+
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/rotate_title"
+            app:layout_constraintEnd_toEndOf="parent" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/quickstep/res/layout/overview_actions_container.xml b/quickstep/res/layout/overview_actions_container.xml
index 2192a64..0fda0bf 100644
--- a/quickstep/res/layout/overview_actions_container.xml
+++ b/quickstep/res/layout/overview_actions_container.xml
@@ -22,7 +22,7 @@
     <LinearLayout
         android:id="@+id/action_buttons"
         android:layout_width="match_parent"
-        android:layout_height="@dimen/overview_actions_size"
+        android:layout_height="@dimen/overview_actions_height"
         android:layout_gravity="bottom|center_horizontal"
         android:orientation="horizontal">
 
@@ -31,14 +31,13 @@
             android:layout_height="1dp"
             android:layout_weight="1" />
 
-        <ImageButton
+        <Button
             android:id="@+id/action_screenshot"
             style="@style/OverviewActionButton"
-            android:layout_width="@dimen/overview_actions_size"
-            android:layout_height="@dimen/overview_actions_size"
-            android:gravity="center"
-            android:src="@drawable/ic_screenshot"
-            android:contentDescription="@string/action_screenshot"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:drawableStart="@drawable/ic_screenshot"
+            android:text="@string/action_screenshot"
             android:theme="@style/ThemeControlHighlightWorkspaceColor" />
 
         <Space
@@ -47,14 +46,12 @@
             android:layout_height="1dp"
             android:visibility="gone" />
 
-        <ImageButton
+        <Button
             android:id="@+id/action_split"
             style="@style/OverviewActionButton"
-            android:layout_width="@dimen/overview_actions_size"
-            android:layout_height="@dimen/overview_actions_size"
-            android:gravity="center"
-            android:src="@drawable/ic_split_vertical"
-            android:contentDescription="@string/action_split"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/action_split"
             android:theme="@style/ThemeControlHighlightWorkspaceColor"
             android:visibility="gone" />
 
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 88f1478..b0e91a1 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -50,10 +50,8 @@
 
     <!-- Overrideable in overlay that provides the Overview Actions. -->
     <dimen name="overview_actions_top_margin">24dp</dimen>
-    <dimen name="overview_actions_size">60dp</dimen>
+    <dimen name="overview_actions_height">48dp</dimen>
     <dimen name="overview_actions_button_spacing">36dp</dimen>
-    <!-- 12dp + 156dp floating search pill width (note this is in addition to normal 36dp) -->
-    <dimen name="overview_actions_additional_floating_search_spacing">168dp</dimen>
 
     <!-- These speeds are in dp/s -->
     <dimen name="max_task_dismiss_drag_velocity">2.25dp</dimen>
diff --git a/quickstep/res/values/styles.xml b/quickstep/res/values/styles.xml
index 0c4e782..fc03704 100644
--- a/quickstep/res/values/styles.xml
+++ b/quickstep/res/values/styles.xml
@@ -221,10 +221,15 @@
         <item name="android:colorControlHighlight">?attr/workspaceTextColor</item>
     </style>
 
-    <style name="OverviewActionButton" parent="@android:style/Widget.DeviceDefault.ImageButton">
-        <item name="android:background">@drawable/circle_btn_bg</item>
-        <item name="android:backgroundTint">?androidprv:attr/materialColorSurfaceBright</item>
+    <style name="OverviewActionButton"
+        parent="@android:style/Widget.DeviceDefault.Button.Borderless">
+        <item name="android:paddingTop">4dp</item>
+        <item name="android:paddingBottom">4dp</item>
+        <item name="android:textColor">@color/overview_button</item>
         <item name="android:drawableTint">@color/overview_button</item>
+        <item name="android:tint">?android:attr/textColorPrimary</item>
+        <item name="android:drawablePadding">8dp</item>
+        <item name="android:textAllCaps">false</item>
     </style>
 
     <style name="OverviewClearAllButton" parent="@android:style/Widget.DeviceDefault.Button">
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
index 296e0db..90f7bea 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
@@ -204,7 +204,7 @@
                     updateStateForFlag(FLAG_LAUNCHER_IN_STATE_TRANSITION, false);
                     // TODO(b/279514548) Cleans up bad state that can occur when user interacts with
                     // taskbar on top of transparent activity.
-                    if (finalState == LauncherState.NORMAL && mLauncher.isResumed()) {
+                    if (finalState == LauncherState.NORMAL && mLauncher.hasBeenResumed()) {
                         updateStateForFlag(FLAG_RESUMED, true);
                     }
                     applyState();
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
index fecdd79..396d0ab 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
@@ -125,33 +125,8 @@
 
     @Override
     public int getFloatingSearchBarRestingMarginBottom(Launcher launcher) {
-        if (!areElementsVisible(launcher, FLOATING_SEARCH_BAR)) {
-            return super.getFloatingSearchBarRestingMarginBottom(launcher);
-        }
-        RecentsView recentsView = launcher.getOverviewPanel();
-        DeviceProfile dp = launcher.getDeviceProfile();
-        int activeTaskMarginBottom = LayoutUtils.getShelfTrackingDistance(launcher, dp,
-                recentsView.getPagedOrientationHandler());
-        // Center between task bottom and bottom of the screen.
-        return (activeTaskMarginBottom - dp.overviewActionsHeight) / 2
-                - launcher.getResources().getDimensionPixelSize(R.dimen.qsb_shadow_height);
-    }
-
-    @Override
-    public int getFloatingSearchBarRestingMarginStart(Launcher launcher) {
-        return getFloatingSearchBarRestingMarginHorizontal(launcher);
-    }
-
-    @Override
-    public int getFloatingSearchBarRestingMarginEnd(Launcher launcher) {
-        return getFloatingSearchBarRestingMarginHorizontal(launcher);
-    }
-
-    private static int getFloatingSearchBarRestingMarginHorizontal(Launcher launcher) {
-        // Width if the search bar were to be expanded (focused).
-        int expandedWidth = launcher.getResources().getDimensionPixelSize(
-                R.dimen.overview_floating_search_width);
-        return (launcher.getDeviceProfile().widthPx - expandedWidth) / 2;
+        return areElementsVisible(launcher, FLOATING_SEARCH_BAR) ? 0
+                : super.getFloatingSearchBarRestingMarginBottom(launcher);
     }
 
     @Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
index d3ef589..6f421eb 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
@@ -16,7 +16,6 @@
 package com.android.launcher3.uioverrides.touchcontrollers;
 
 import static android.view.MotionEvent.ACTION_DOWN;
-import static android.view.MotionEvent.ACTION_MOVE;
 
 import static com.android.app.animation.Interpolators.ACCELERATE_0_75;
 import static com.android.app.animation.Interpolators.DECELERATE_3;
@@ -87,6 +86,7 @@
 import com.android.quickstep.views.DesktopTaskView;
 import com.android.quickstep.views.LauncherRecentsView;
 import com.android.quickstep.views.RecentsView;
+import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
 
 /**
  * Handles quick switching to a recent task from the home screen. To give as much flexibility to
@@ -191,6 +191,9 @@
     public void onDragStart(boolean start) {
         mMotionPauseDetector.clear();
         if (start) {
+            InteractionJankMonitorWrapper.begin(mRecentsView,
+                    InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH);
+
             mStartState = mLauncher.getStateManager().getState();
 
             mMotionPauseDetector.setOnMotionPauseListener(this::onMotionPauseDetected);
@@ -325,6 +328,7 @@
         if (mMotionPauseDetector.isPaused() && noFling) {
             // Going to Overview.
             cancelAnimations();
+            InteractionJankMonitorWrapper.cancel(InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH);
 
             StateAnimationConfig config = new StateAnimationConfig();
             config.duration = ATOMIC_DURATION_FROM_PAUSED_TO_OVERVIEW;
@@ -441,6 +445,8 @@
                     RecentsView.SCROLL_VIBRATION_PRIMITIVE,
                     RecentsView.SCROLL_VIBRATION_PRIMITIVE_SCALE,
                     RecentsView.SCROLL_VIBRATION_FALLBACK);
+        } else {
+            InteractionJankMonitorWrapper.cancel(InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH);
         }
 
         nonOverviewAnim.setDuration(Math.max(xDuration, yDuration));
@@ -462,6 +468,11 @@
                                 : targetState.ordinal > mStartState.ordinal
                                         ? LAUNCHER_UNKNOWN_SWIPEUP
                                         : LAUNCHER_UNKNOWN_SWIPEDOWN));
+
+        if (targetState == QUICK_SWITCH_FROM_HOME) {
+            InteractionJankMonitorWrapper.end(InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH);
+        }
+
         mLauncher.getStateManager().goToState(targetState, false, forEndCallback(this::clearState));
     }
 
diff --git a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
index ab37493..c5a88bc 100644
--- a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
@@ -139,6 +139,7 @@
         mTmpMatrix.setScale(scale, scale,
                 app.localBounds.exactCenterX(), app.localBounds.exactCenterY());
         builder.setMatrix(mTmpMatrix).setAlpha(alpha);
+        builder.setShow();
     }
 
     @Override
diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
index c0684d7..6dbb5bf 100644
--- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java
+++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
@@ -19,6 +19,7 @@
 
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
 import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+import static com.android.launcher3.util.NavigationMode.NO_BUTTON;
 import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS;
 import static com.android.quickstep.GestureState.STATE_RECENTS_ANIMATION_INITIALIZED;
 import static com.android.quickstep.GestureState.STATE_RECENTS_ANIMATION_STARTED;
@@ -37,6 +38,7 @@
 
 import com.android.launcher3.Utilities;
 import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.util.DisplayController;
 import com.android.quickstep.TopTaskTracker.CachedTaskInfo;
 import com.android.quickstep.util.ActiveGestureLog;
 import com.android.quickstep.views.DesktopTaskView;
@@ -169,10 +171,16 @@
 
                 for (RemoteAnimationTarget compat : appearedTaskTargets) {
                     if (compat.windowConfiguration.getActivityType() == ACTIVITY_TYPE_HOME
-                            && activityInterface.getCreatedActivity() instanceof RecentsActivity) {
-                        // When receive opening home activity while recents is running, enter home
-                        // and dismiss recents.
-                        ((RecentsActivity) activityInterface.getCreatedActivity()).startHome();
+                            && activityInterface.getCreatedActivity() instanceof RecentsActivity
+                            && DisplayController.getNavigationMode(mCtx) != NO_BUTTON) {
+                        // The only time we get onTasksAppeared() in button navigation with a
+                        // 3p launcher is if the user goes to overview first, and in this case we
+                        // can immediately finish the transition
+                        RecentsView recentsView =
+                                activityInterface.getCreatedActivity().getOverviewPanel();
+                        if (recentsView != null) {
+                            recentsView.finishRecentsAnimation(true, null);
+                        }
                         return;
                     }
                 }
diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
index 135cb72..631cff7 100644
--- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
@@ -154,7 +154,7 @@
 
     @Override
     public void onBackGestureAttempted(BackGestureResult result) {
-        if (skipGestureAttempt()) {
+        if (isGestureCompleted()) {
             return;
         }
         switch (mTutorialType) {
@@ -172,7 +172,7 @@
 
     @Override
     public void onBackGestureProgress(float diffx, float diffy, boolean isLeftGesture) {
-        if (skipGestureAttempt()) {
+        if (isGestureCompleted()) {
             return;
         }
 
@@ -241,7 +241,7 @@
 
     @Override
     public void onNavBarGestureAttempted(NavBarGestureResult result, PointF finalVelocity) {
-        if (skipGestureAttempt()) {
+        if (isGestureCompleted()) {
             return;
         }
         if (mTutorialType == BACK_NAVIGATION_COMPLETE) {
diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
index a16b239..b379baa 100644
--- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
@@ -42,6 +42,12 @@
         super(fromTutorialMenu);
     }
 
+    @NonNull
+    @Override
+    TutorialType getDefaultTutorialType() {
+        return TutorialType.BACK_NAVIGATION;
+    }
+
     @Nullable
     @Override
     Integer getEdgeAnimationResId() {
diff --git a/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
index 2189a24..d102502 100644
--- a/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
+++ b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
@@ -53,16 +53,14 @@
     static final String KEY_USE_TUTORIAL_MENU = "use_tutorial_menu";
 
     @Nullable private TutorialType[] mTutorialSteps;
-    private GestureSandboxFragment mFragment;
+    private GestureSandboxFragment mCurrentFragment;
+    private GestureSandboxFragment mPendingFragment;
 
     private int mCurrentStep;
     private int mNumSteps;
-    private boolean mShowRotationPrompt;
 
     private SharedPreferences mSharedPrefs;
     private StatsLogManager mStatsLogManager;
-
-    private View mRotationPrompt;
     private TISBindHelper mTISBindHelper;
 
     @Override
@@ -82,7 +80,7 @@
                 && args.getBoolean(KEY_USE_TUTORIAL_MENU, false)) {
             mTutorialSteps = null;
             TutorialType tutorialTypeOverride = (TutorialType) args.get(KEY_TUTORIAL_TYPE);
-            mFragment = tutorialTypeOverride == null
+            mCurrentFragment = tutorialTypeOverride == null
                     ? new MenuFragment()
                     : makeTutorialFragment(
                             tutorialTypeOverride,
@@ -90,16 +88,15 @@
                             /* fromMenu= */ true);
         } else {
             mTutorialSteps = getTutorialSteps(args);
-            mFragment = makeTutorialFragment(
+            mCurrentFragment = makeTutorialFragment(
                     mTutorialSteps[mCurrentStep - 1],
                     gestureComplete,
                     /* fromMenu= */ false);
         }
         getSupportFragmentManager().beginTransaction()
-                .add(R.id.gesture_tutorial_fragment_container, mFragment)
+                .add(R.id.gesture_tutorial_fragment_container, mCurrentFragment)
                 .commit();
 
-        mRotationPrompt = findViewById(R.id.rotation_prompt);
         if (FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
             correctUserOrientation();
         }
@@ -127,34 +124,45 @@
         DeviceProfile deviceProfile = InvariantDeviceProfile.INSTANCE.get(
                 getApplicationContext()).getDeviceProfile(this);
         if (deviceProfile.isTablet) {
-            mShowRotationPrompt = getResources().getConfiguration().orientation
+            boolean showRotationPrompt = getResources().getConfiguration().orientation
                     == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
-            updateVisibility(mRotationPrompt, mShowRotationPrompt ? View.VISIBLE : View.GONE);
+
+            GestureSandboxFragment recreatedFragment =
+                    showRotationPrompt || mPendingFragment == null
+                            ? null : mPendingFragment.recreateFragment();
+            showFragment(showRotationPrompt
+                    ? new RotationPromptFragment()
+                    : recreatedFragment == null
+                            ? mCurrentFragment : recreatedFragment);
         } else {
             setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
         }
     }
 
-    void updateVisibility(View view, int visibility) {
-        if (view == null || view.getVisibility() == visibility) {
-            return;
+    private void showFragment(@NonNull GestureSandboxFragment fragment) {
+        if (mCurrentFragment.recreateFragment() != null) {
+            mPendingFragment = mCurrentFragment;
         }
-        view.setVisibility(visibility);
+        mCurrentFragment = fragment;
+        getSupportFragmentManager().beginTransaction()
+                .replace(R.id.gesture_tutorial_fragment_container, mCurrentFragment)
+                .runOnCommit(() -> mCurrentFragment.onAttachedToWindow())
+                .commit();
     }
 
     @Override
     public void onAttachedToWindow() {
         super.onAttachedToWindow();
-        if (mFragment.shouldDisableSystemGestures()) {
+        if (mCurrentFragment.shouldDisableSystemGestures()) {
             disableSystemGestures();
         }
-        mFragment.onAttachedToWindow();
+        mCurrentFragment.onAttachedToWindow();
     }
 
     @Override
     public void onDetachedFromWindow() {
         super.onDetachedFromWindow();
-        mFragment.onDetachedFromWindow();
+        mCurrentFragment.onDetachedFromWindow();
     }
 
     @Override
@@ -169,14 +177,10 @@
     protected void onSaveInstanceState(@NonNull Bundle savedInstanceState) {
         savedInstanceState.putStringArray(KEY_TUTORIAL_STEPS, getTutorialStepNames());
         savedInstanceState.putInt(KEY_CURRENT_STEP, mCurrentStep);
-        mFragment.onSaveInstanceState(savedInstanceState);
+        mCurrentFragment.onSaveInstanceState(savedInstanceState);
         super.onSaveInstanceState(savedInstanceState);
     }
 
-    protected boolean isRotationPromptShowing() {
-        return mShowRotationPrompt;
-    }
-
     protected SharedPreferences getSharedPrefs() {
         return mSharedPrefs;
     }
@@ -205,7 +209,7 @@
      */
     public void continueTutorial() {
         if (isTutorialComplete() || mTutorialSteps == null) {
-            mFragment.close();
+            mCurrentFragment.close();
             return;
         }
         launchTutorialStep(mTutorialSteps[mCurrentStep], false);
@@ -224,20 +228,12 @@
      * the menu when complete.
      */
     public void launchTutorialStep(@NonNull TutorialType tutorialType, boolean fromMenu) {
-        mFragment = makeTutorialFragment(tutorialType, false, fromMenu);
-        getSupportFragmentManager().beginTransaction()
-                .replace(R.id.gesture_tutorial_fragment_container, mFragment)
-                .runOnCommit(() -> mFragment.onAttachedToWindow())
-                .commit();
+        showFragment(makeTutorialFragment(tutorialType, false, fromMenu));
     }
 
     /** Launches the gesture nav tutorial menu page */
     public void launchTutorialMenu() {
-        mFragment = new MenuFragment();
-        getSupportFragmentManager().beginTransaction()
-                .replace(R.id.gesture_tutorial_fragment_container, mFragment)
-                .runOnCommit(() -> mFragment.onAttachedToWindow())
-                .commit();
+        showFragment(new MenuFragment());
     }
 
     private String[] getTutorialStepNames() {
diff --git a/quickstep/src/com/android/quickstep/interaction/GestureSandboxFragment.java b/quickstep/src/com/android/quickstep/interaction/GestureSandboxFragment.java
index d52f19a..08f2989 100644
--- a/quickstep/src/com/android/quickstep/interaction/GestureSandboxFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/GestureSandboxFragment.java
@@ -17,6 +17,7 @@
 
 import android.app.Activity;
 
+import androidx.annotation.Nullable;
 import androidx.fragment.app.Fragment;
 import androidx.fragment.app.FragmentActivity;
 
@@ -27,6 +28,11 @@
 
     void onDetachedFromWindow() {}
 
+    @Nullable
+    GestureSandboxFragment recreateFragment() {
+        return null;
+    }
+
     boolean shouldDisableSystemGestures() {
         return true;
     }
diff --git a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
index 0aa80d3..daac99b 100644
--- a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
@@ -147,7 +147,7 @@
 
     @Override
     public void onBackGestureAttempted(BackGestureResult result) {
-        if (skipGestureAttempt()) {
+        if (isGestureCompleted()) {
             return;
         }
         switch (mTutorialType) {
@@ -174,7 +174,7 @@
 
     @Override
     public void onNavBarGestureAttempted(NavBarGestureResult result, PointF finalVelocity) {
-        if (skipGestureAttempt()) {
+        if (isGestureCompleted()) {
             return;
         }
         switch (mTutorialType) {
diff --git a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java
index bced8c4..3e924d7 100644
--- a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java
@@ -41,6 +41,12 @@
         super(fromTutorialMenu);
     }
 
+    @NonNull
+    @Override
+    TutorialType getDefaultTutorialType() {
+        return TutorialType.HOME_NAVIGATION;
+    }
+
     @Nullable
     @Override
     Integer getEdgeAnimationResId() {
diff --git a/quickstep/src/com/android/quickstep/interaction/MenuFragment.java b/quickstep/src/com/android/quickstep/interaction/MenuFragment.java
index c19d44a..dbf141b 100644
--- a/quickstep/src/com/android/quickstep/interaction/MenuFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/MenuFragment.java
@@ -32,6 +32,12 @@
 /** Displays the gesture nav tutorial menu. */
 public final class MenuFragment extends GestureSandboxFragment {
 
+    @NonNull
+    @Override
+    GestureSandboxFragment recreateFragment() {
+        return new MenuFragment();
+    }
+
     @Override
     public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
             @Nullable Bundle savedInstanceState) {
diff --git a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
index 75b80b3..afdc1e5 100644
--- a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
@@ -179,7 +179,7 @@
 
     @Override
     public void onBackGestureAttempted(BackGestureResult result) {
-        if (skipGestureAttempt()) {
+        if (isGestureCompleted()) {
             return;
         }
         switch (mTutorialType) {
@@ -206,7 +206,7 @@
 
     @Override
     public void onNavBarGestureAttempted(NavBarGestureResult result, PointF finalVelocity) {
-        if (skipGestureAttempt()) {
+        if (isGestureCompleted()) {
             return;
         }
         switch (mTutorialType) {
diff --git a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java
index 01074dd..ee1c460 100644
--- a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java
@@ -41,6 +41,12 @@
         super(fromTutorialMenu);
     }
 
+    @NonNull
+    @Override
+    TutorialType getDefaultTutorialType() {
+        return TutorialType.OVERVIEW_NAVIGATION;
+    }
+
     @Nullable
     @Override
     Integer getEdgeAnimationResId() {
diff --git a/quickstep/src/com/android/quickstep/interaction/RotationPromptFragment.java b/quickstep/src/com/android/quickstep/interaction/RotationPromptFragment.java
new file mode 100644
index 0000000..89af647
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/interaction/RotationPromptFragment.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.interaction;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.R;
+
+/** Displays the prompt requesting that the user rotates their device. */
+public class RotationPromptFragment extends GestureSandboxFragment {
+
+    @Nullable
+    @Override
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
+            @Nullable Bundle savedInstanceState) {
+        return inflater.inflate(R.layout.gesture_tutorial_rotation_prompt, container, false);
+    }
+}
diff --git a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
index d0d7534..87defc5 100644
--- a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
@@ -282,7 +282,7 @@
 
     @Override
     public void setNavBarGestureProgress(@Nullable Float displacement) {
-        if (skipGestureAttempt()) {
+        if (isGestureCompleted()) {
             return;
         }
         if (mTutorialType == HOME_NAVIGATION_COMPLETE
@@ -303,7 +303,7 @@
 
     @Override
     public void onMotionPaused(boolean unused) {
-        if (skipGestureAttempt()) {
+        if (isGestureCompleted()) {
             return;
         }
         if (mShowTasks) {
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialController.java b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
index 4a1fec3..ed2d18a 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
@@ -489,10 +489,6 @@
         return mGestureCompleted;
     }
 
-    public boolean skipGestureAttempt() {
-        return isGestureCompleted() || mTutorialFragment.isRotationPromptShowing();
-    }
-
     void hideFeedback() {
         if (mFeedbackView.getVisibility() != View.VISIBLE) {
             return;
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
index 84326f5..a28cf58 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
@@ -100,6 +100,19 @@
         return fragment;
     }
 
+    @Nullable
+    @Override
+    GestureSandboxFragment recreateFragment() {
+        TutorialType tutorialType = mTutorialController == null
+                ? (mTutorialType == null
+                        ? getDefaultTutorialType() : mTutorialType)
+                : mTutorialController.mTutorialType;
+        return newInstance(tutorialType, isGestureComplete(), mFromTutorialMenu);
+    }
+
+    @NonNull
+    abstract TutorialType getDefaultTutorialType();
+
     TutorialFragment(boolean fromTutorialMenu) {
         mFromTutorialMenu = fromTutorialMenu;
     }
@@ -498,11 +511,6 @@
         return activity != null ? activity.getStatsLogManager() : null;
     }
 
-    protected boolean isRotationPromptShowing() {
-        GestureSandboxActivity activity = getGestureSandboxActivity();
-        return activity != null && activity.isRotationPromptShowing();
-    }
-
     @Nullable
     private SharedPreferences getSharedPreferences() {
         GestureSandboxActivity activity = getGestureSandboxActivity();
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index 5e488cc..80e5a54 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -20,7 +20,6 @@
 import static com.android.launcher3.LauncherState.ALL_APPS;
 import static com.android.launcher3.LauncherState.CLEAR_ALL_BUTTON;
 import static com.android.launcher3.LauncherState.EDIT_MODE;
-import static com.android.launcher3.LauncherState.FLOATING_SEARCH_BAR;
 import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.LauncherState.OVERVIEW;
 import static com.android.launcher3.LauncherState.OVERVIEW_MODAL_TASK;
@@ -100,12 +99,6 @@
     }
 
     @Override
-    public boolean isFloatingSearchVisible() {
-        return FeatureFlags.ENABLE_FLOATING_SEARCH_BAR.get()
-                && OVERVIEW.areElementsVisible(mActivity, FLOATING_SEARCH_BAR);
-    }
-
-    @Override
     protected void onTaskLaunchAnimationEnd(boolean success) {
         if (success) {
             mActivity.getStateManager().moveToRestState();
diff --git a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
index 754d1ff..e47c089 100644
--- a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
+++ b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
@@ -22,14 +22,12 @@
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.View.OnClickListener;
+import android.widget.Button;
 import android.widget.FrameLayout;
-import android.widget.ImageButton;
 
 import androidx.annotation.IntDef;
 import androidx.annotation.Nullable;
 
-import com.android.launcher3.BaseActivity;
-import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Insettable;
 import com.android.launcher3.R;
@@ -51,7 +49,6 @@
         implements OnClickListener, Insettable {
 
     private final Rect mInsets = new Rect();
-    private BaseDraggingActivity mActivity;
 
     @IntDef(flag = true, value = {
             HIDDEN_NON_ZERO_ROTATION,
@@ -99,7 +96,7 @@
     public static final int FLAG_SINGLE_TASK = 1 << 0;
 
     private MultiValueAlpha mMultiValueAlpha;
-    private ImageButton mSplitButton;
+    private Button mSplitButton;
 
     @ActionsHiddenFlags
     private int mHiddenFlags;
@@ -135,8 +132,6 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        mActivity = BaseActivity.fromContext(getContext());
-
         mMultiValueAlpha = new MultiValueAlpha(findViewById(R.id.action_buttons), NUM_ALPHAS);
         mMultiValueAlpha.setUpdateVisibility(true);
 
@@ -278,7 +273,7 @@
         LayoutParams actionParams = (LayoutParams) findViewById(
                 R.id.action_buttons).getLayoutParams();
         actionParams.setMargins(
-                actionParams.leftMargin, 0,
+                actionParams.leftMargin, mDp.overviewActionsTopMarginPx,
                 actionParams.rightMargin, getBottomMargin());
     }
 
@@ -291,11 +286,6 @@
             return mDp.stashedTaskbarHeight;
         }
 
-        if (isFloatingSearchVisible()) {
-            // Center between task and bottom of the screen.
-            return (mDp.heightPx - mTaskSize.bottom - mDp.overviewActionsHeight) / 2;
-        }
-
         // Align to bottom of task Rect.
         return mDp.heightPx - mTaskSize.bottom - mDp.overviewActionsTopMarginPx
                 - mDp.overviewActionsHeight;
@@ -311,12 +301,9 @@
 
         requestLayout();
 
-        mSplitButton.setImageResource(
-                dp.isLandscape ? R.drawable.ic_split_horizontal : R.drawable.ic_split_vertical);
-    }
-
-    protected boolean isFloatingSearchVisible() {
-        return ((RecentsView) mActivity.getOverviewPanel()).isFloatingSearchVisible();
+        mSplitButton.setCompoundDrawablesRelativeWithIntrinsicBounds(
+                (dp.isLandscape ? R.drawable.ic_split_horizontal : R.drawable.ic_split_vertical),
+                0, 0, 0);
     }
 
     /**
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 0071927..a21bbe1 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -5220,11 +5220,6 @@
         });
     }
 
-    /** @return {@code true} if floating search bar is visible in Recents. */
-    public boolean isFloatingSearchVisible() {
-        return false;
-    }
-
     public RemoteTargetHandle[] getRemoteTargetHandles() {
         return mRemoteTargetHandles;
     }
diff --git a/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java b/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java
index 59f9d5f..3a5fb04 100644
--- a/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java
+++ b/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java
@@ -16,11 +16,17 @@
 
 package com.android.quickstep;
 
+import static com.android.launcher3.ui.TaplTestsLauncher3.getAppPackageName;
+
 import static org.junit.Assert.assertTrue;
 
 import android.os.SystemProperties;
 
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.Until;
+
 import com.android.launcher3.Launcher;
+import com.android.launcher3.tapl.LaunchedAppState;
 import com.android.launcher3.tapl.LauncherInstrumentation;
 import com.android.launcher3.tapl.LauncherInstrumentation.ContainerType;
 import com.android.launcher3.ui.AbstractLauncherUiTest;
@@ -76,6 +82,21 @@
         }
     }
 
+    protected void assertTestActivityIsRunning(int activityNumber, String message) {
+        assertTrue(message, mDevice.wait(
+                Until.hasObject(By.pkg(getAppPackageName()).text("TestActivity" + activityNumber)),
+                DEFAULT_UI_TIMEOUT));
+    }
+
+    protected LaunchedAppState getAndAssertLaunchedApp() {
+        final LaunchedAppState launchedAppState = mLauncher.getLaunchedAppState();
+        executeOnLauncher(launcher -> assertTrue(
+                "Launcher activity is the top activity; expecting another activity to be the top "
+                        + "one",
+                isInLaunchedApp(launcher)));
+        return launchedAppState;
+    }
+
     private boolean isInLiveTileMode(Launcher launcher,
             LauncherInstrumentation.ContainerType expectedContainerType) {
         if (expectedContainerType != LauncherInstrumentation.ContainerType.OVERVIEW) {
diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
index bc90db0..a67d787 100644
--- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
+++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
@@ -116,7 +116,8 @@
             Utilities.enableRunningInTestHarnessForTests();
         }
 
-        final ViewCaptureRule viewCaptureRule = new ViewCaptureRule();
+        final ViewCaptureRule viewCaptureRule = new ViewCaptureRule(
+                RecentsActivity.ACTIVITY_TRACKER::getCreatedActivity);
         mOrderSensitiveRules = RuleChain
                 .outerRule(new SamplerRule())
                 .around(new NavigationModeSwitchRule(mLauncher))
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
index bb246c2..06ce0e5 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
@@ -241,16 +241,6 @@
                 isInState(() -> LauncherState.OVERVIEW));
     }
 
-    private LaunchedAppState getAndAssertLaunchedApp() {
-        final LaunchedAppState launchedAppState = mLauncher.getLaunchedAppState();
-        assertNotNull("Launcher.getLaunchedApp() returned null", launchedAppState);
-        executeOnLauncher(launcher -> assertTrue(
-                "Launcher activity is the top activity; expecting another activity to be the top "
-                        + "one",
-                isInLaunchedApp(launcher)));
-        return launchedAppState;
-    }
-
     private void quickSwitchToPreviousAppAndAssert(boolean toRight) {
         final LaunchedAppState launchedAppState = getAndAssertLaunchedApp();
         if (toRight) {
@@ -292,22 +282,22 @@
         startTestActivity(4);
 
         quickSwitchToPreviousAppAndAssert(true /* toRight */);
-        assertTrue("The first app we should have quick switched to is not running",
-                isTestActivityRunning(3));
+        assertTestActivityIsRunning(3,
+                "The first app we should have quick switched to is not running");
 
         quickSwitchToPreviousAppAndAssert(true /* toRight */);
         if (mLauncher.getNavigationModel() == NavigationModel.THREE_BUTTON) {
             // 3-button mode toggles between 2 apps, rather than going back further.
-            assertTrue("Second quick switch should have returned to the first app.",
-                    isTestActivityRunning(4));
+            assertTestActivityIsRunning(4,
+                    "Second quick switch should have returned to the first app.");
         } else {
-            assertTrue("The second app we should have quick switched to is not running",
-                    isTestActivityRunning(2));
+            assertTestActivityIsRunning(2,
+                    "The second app we should have quick switched to is not running");
         }
 
         quickSwitchToPreviousAppAndAssert(false /* toRight */);
-        assertTrue("The 2nd app we should have quick switched to is not running",
-                isTestActivityRunning(3));
+        assertTestActivityIsRunning(3,
+                "The 2nd app we should have quick switched to is not running");
 
         final LaunchedAppState launchedAppState = getAndAssertLaunchedApp();
         launchedAppState.switchToOverview();
@@ -331,9 +321,9 @@
         // Quick-switch to the test app with swiping to right.
         quickSwitchToPreviousAppAndAssert(true /* toRight */);
 
-        assertTrue("The first app we should have quick switched to is not running",
-                isTestActivityRunning(2));
-
+        assertTestActivityIsRunning(2,
+                "The first app we should have quick switched to is not running");
+        // Expect task bar visible when the launched app was the test activity.
         launchedAppState = getAndAssertLaunchedApp();
 
         Log.e(FLAKY_QUICK_SWITCH_TO_PREVIOUS_APP,
@@ -347,12 +337,6 @@
         }
     }
 
-    private boolean isTestActivityRunning(int activityNumber) {
-        return mDevice.wait(Until.hasObject(By.pkg(getAppPackageName())
-                        .text("TestActivity" + activityNumber)),
-                DEFAULT_UI_TIMEOUT);
-    }
-
     @Test
     @NavigationModeSwitch
     @PortraitLandscape
@@ -360,8 +344,8 @@
     public void testQuickSwitchFromHome() throws Exception {
         startTestActivity(2);
         mLauncher.goHome().quickSwitchToPreviousApp();
-        assertTrue("The most recent task is not running after quick switching from home",
-                isTestActivityRunning(2));
+        assertTestActivityIsRunning(2,
+                "The most recent task is not running after quick switching from home");
         getAndAssertLaunchedApp();
     }
 
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsTrackpad.java b/quickstep/tests/src/com/android/quickstep/TaplTestsTrackpad.java
index 7ae3f29..907dbcc 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsTrackpad.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsTrackpad.java
@@ -19,6 +19,7 @@
 import static com.android.quickstep.NavigationModeSwitchRule.Mode.ZERO_BUTTON;
 
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assume.assumeFalse;
 import static org.junit.Assume.assumeTrue;
 
@@ -30,6 +31,7 @@
 
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.tapl.LauncherInstrumentation.TrackpadGestureType;
+import com.android.launcher3.tapl.Workspace;
 import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
 import com.android.launcher3.ui.TaplTestsLauncher3;
 import com.android.quickstep.NavigationModeSwitchRule.NavigationModeSwitch;
@@ -112,4 +114,19 @@
         assertNotNull("switchToAllApps() returned null",
                 mLauncher.getWorkspace().switchToAllApps());
     }
+
+    @Test
+    @NavigationModeSwitch
+    @PortraitLandscape
+    public void testQuickSwitchFromHome() throws Exception {
+        assumeTrue(mLauncher.isTablet());
+
+        startTestActivity(2);
+        Workspace workspace = mLauncher.goHome();
+        mLauncher.setTrackpadGestureType(TrackpadGestureType.FOUR_FINGER);
+        workspace.quickSwitchToPreviousApp();
+        assertTestActivityIsRunning(2,
+                "The most recent task is not running after quick switching from home");
+        getAndAssertLaunchedApp();
+    }
 }
diff --git a/res/color/overview_button.xml b/res/color/overview_button.xml
index ccc042a..1dd8da6 100644
--- a/res/color/overview_button.xml
+++ b/res/color/overview_button.xml
@@ -3,10 +3,10 @@
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
     <item
         android:alpha="1"
-        android:color="?androidprv:attr/materialColorOnSurfaceVariant"
+        android:color="?androidprv:attr/materialColorOnSurface"
         android:state_enabled="true" />
     <item
         android:alpha="?android:disabledAlpha"
-        android:color="?androidprv:attr/materialColorOnSurfaceVariant"
+        android:color="?androidprv:attr/materialColorOnSurface"
         android:state_enabled="false" />
 </selector>
\ No newline at end of file
diff --git a/res/drawable/circle_btn_bg.xml b/res/drawable/circle_btn_bg.xml
deleted file mode 100644
index ad59ea5..0000000
--- a/res/drawable/circle_btn_bg.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<ripple xmlns:android="http://schemas.android.com/apk/res/android"
-    android:color="@color/accent_ripple_color">
-    <item android:id="@android:id/mask">
-        <shape android:shape="oval">
-            <solid android:color="@android:color/white" />
-        </shape>
-    </item>
-    <item>
-        <shape android:shape="oval">
-            <solid android:color="@android:color/white" />
-        </shape>
-    </item>
-</ripple>
diff --git a/res/drawable/ic_split_horizontal.xml b/res/drawable/ic_split_horizontal.xml
index 875b1be..2efd2b9 100644
--- a/res/drawable/ic_split_horizontal.xml
+++ b/res/drawable/ic_split_horizontal.xml
@@ -5,5 +5,5 @@
     android:viewportHeight="24">
   <path
       android:pathData="M4,6L9,6L9,18L4,18L4,6ZM2,6L2,18C2,19.1 2.9,20 4,20L9,20C10.1,20 11,19.1 11,18L11,6C11,4.9 10.1,4 9,4L4,4C2.9,4 2,4.9 2,6ZM15,6L20,6L20,18L15,18L15,6ZM13,6L13,18C13,19.1 13.9,20 15,20L20,20C21.1,20 22,19.1 22,18L22,6C22,4.9 21.1,4 20,4L15,4C13.9,4 13,4.9 13,6Z"
-      android:fillColor="@color/overview_button"/>
+      android:fillColor="#000000"/>
 </vector>
diff --git a/res/drawable/ic_split_vertical.xml b/res/drawable/ic_split_vertical.xml
index e73a1b2..9bc9785 100644
--- a/res/drawable/ic_split_vertical.xml
+++ b/res/drawable/ic_split_vertical.xml
@@ -5,5 +5,5 @@
     android:viewportHeight="24">
   <path
       android:pathData="M18,4V9H6V4H18ZM18,2H6C4.9,2 4,2.9 4,4V9C4,10.1 4.9,11 6,11H18C19.1,11 20,10.1 20,9V4C20,2.9 19.1,2 18,2ZM18,15V20H6V15H18ZM18,13H6C4.9,13 4,13.9 4,15V20C4,21.1 4.9,22 6,22H18C19.1,22 20,21.1 20,20V15C20,13.9 19.1,13 18,13Z"
-      android:fillColor="@color/overview_button"/>
+      android:fillColor="#000000"/>
 </vector>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index bea86fa..1079e00 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -396,12 +396,10 @@
     <dimen name="task_thumbnail_icon_drawable_size">0dp</dimen>
     <dimen name="task_thumbnail_icon_drawable_size_grid">0dp</dimen>
     <dimen name="overview_task_margin">0dp</dimen>
-    <dimen name="overview_actions_size">0dp</dimen>
+    <dimen name="overview_actions_height">0dp</dimen>
     <dimen name="overview_actions_button_spacing">0dp</dimen>
     <dimen name="overview_actions_margin_gesture">0dp</dimen>
     <dimen name="overview_actions_top_margin">0dp</dimen>
-    <!-- Width if the search bar were to be full-size in Overview. Note pill is 192dp smaller. -->
-    <dimen name="overview_floating_search_width">348dp</dimen>
     <dimen name="overview_grid_side_margin">0dp</dimen>
     <dimen name="overview_grid_row_spacing">0dp</dimen>
     <dimen name="overview_page_spacing">0dp</dimen>
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 64ac841..4674401 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -2735,11 +2735,13 @@
     }
 
     public boolean isOccupied(int x, int y) {
-        if (x < mCountX && y < mCountY) {
+        if (x >= 0 && x < mCountX && y >= 0 && y < mCountY) {
             return mOccupied.cells[x][y];
-        } else {
+        }
+        if (BuildConfig.IS_STUDIO_BUILD) {
             throw new RuntimeException("Position exceeds the bound of this CellLayout");
         }
+        return true;
     }
 
     @Override
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 28e0cf2..42372f1 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -584,11 +584,13 @@
         overviewTaskIconDrawableSizeGridPx =
                 res.getDimensionPixelSize(R.dimen.task_thumbnail_icon_drawable_size_grid);
         overviewTaskThumbnailTopMarginPx = overviewTaskIconSizePx + overviewTaskMarginPx;
-        overviewActionsTopMarginPx = res.getDimensionPixelSize(R.dimen.overview_actions_top_margin);
+        // Don't add margin with floating search bar to minimize risk of overlapping.
+        overviewActionsTopMarginPx = FeatureFlags.ENABLE_FLOATING_SEARCH_BAR.get() ? 0
+                : res.getDimensionPixelSize(R.dimen.overview_actions_top_margin);
         overviewPageSpacing = res.getDimensionPixelSize(R.dimen.overview_page_spacing);
         overviewActionsButtonSpacing = res.getDimensionPixelSize(
                 R.dimen.overview_actions_button_spacing);
-        overviewActionsHeight = res.getDimensionPixelSize(R.dimen.overview_actions_size);
+        overviewActionsHeight = res.getDimensionPixelSize(R.dimen.overview_actions_height);
         overviewRowSpacing = res.getDimensionPixelSize(R.dimen.overview_grid_row_spacing);
         overviewGridSideMargin = res.getDimensionPixelSize(R.dimen.overview_grid_side_margin);
 
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index bfbd660..6df9aab 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -1663,7 +1663,8 @@
         if (isActionMain) {
             if (!internalStateHandled) {
                 // In all these cases, only animate if we're already on home
-                closeOpenViews(isStarted());
+                AbstractFloatingView.closeAllOpenViewsExcept(
+                        this, isStarted(), AbstractFloatingView.TYPE_LISTENER);
 
                 if (!isInState(NORMAL)) {
                     // Only change state, if not already the same. This prevents cancelling any
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index e3e1400..d2f37fb 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -129,7 +129,7 @@
 
     // TODO(Block 5): Clean up flags
     public static final BooleanFlag ENABLE_TWOLINE_DEVICESEARCH = getDebugFlag(201388851,
-            "ENABLE_TWOLINE_DEVICESEARCH", TEAMFOOD,
+            "ENABLE_TWOLINE_DEVICESEARCH", ENABLED,
             "Enable two line label for icons with labels on device search.");
 
     public static final BooleanFlag ENABLE_ICON_IN_TEXT_HEADER = getDebugFlag(270395143,
@@ -227,7 +227,7 @@
             "COLLECT_SEARCH_HISTORY", DISABLED, "Allow launcher to collect search history for log");
 
     public static final BooleanFlag ENABLE_TWOLINE_ALLAPPS = getDebugFlag(270390937,
-            "ENABLE_TWOLINE_ALLAPPS", TEAMFOOD, "Enables two line label inside all apps.");
+            "ENABLE_TWOLINE_ALLAPPS", ENABLED, "Enables two line label inside all apps.");
 
     public static final BooleanFlag IME_STICKY_SNACKBAR_EDU = getDebugFlag(270391693,
             "IME_STICKY_SNACKBAR_EDU", ENABLED, "Show sticky IME edu in AllApps");
@@ -363,7 +363,7 @@
                     "Enable splitting from fullscreen app with keyboard shortcuts");
 
     public static final BooleanFlag ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE = getDebugFlag(
-            270393453, "ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE", DISABLED,
+            270393453, "ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE", TEAMFOOD,
             "Enable initiating split screen from workspace to workspace.");
 
     public static final BooleanFlag ENABLE_TRACKPAD_GESTURE = getDebugFlag(271010401,
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index b1b3baa..5240e6a 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -201,7 +201,8 @@
     }
 
     protected TestRule getRulesInsideActivityMonitor() {
-        final ViewCaptureRule viewCaptureRule = new ViewCaptureRule();
+        final ViewCaptureRule viewCaptureRule = new ViewCaptureRule(
+                Launcher.ACTIVITY_TRACKER::getCreatedActivity);
         final RuleChain inner = RuleChain
                 .outerRule(new PortraitLandscapeRunner(this))
                 .around(new FailureWatcher(mLauncher, viewCaptureRule::getViewCaptureData))
diff --git a/tests/src/com/android/launcher3/util/rule/ViewCaptureRule.kt b/tests/src/com/android/launcher3/util/rule/ViewCaptureRule.kt
index 1ca4434..b4ad1f3 100644
--- a/tests/src/com/android/launcher3/util/rule/ViewCaptureRule.kt
+++ b/tests/src/com/android/launcher3/util/rule/ViewCaptureRule.kt
@@ -23,8 +23,11 @@
 import com.android.app.viewcapture.SimpleViewCapture
 import com.android.app.viewcapture.ViewCapture.MAIN_EXECUTOR
 import com.android.app.viewcapture.data.ExportedData
+import com.android.launcher3.tapl.TestHelpers
 import com.android.launcher3.util.ActivityLifecycleCallbacksAdapter
 import com.android.launcher3.util.viewcapture_analysis.ViewCaptureAnalyzer
+import org.junit.Assert.assertTrue
+import java.util.function.Supplier
 import org.junit.rules.TestRule
 import org.junit.runner.Description
 import org.junit.runners.model.Statement
@@ -35,7 +38,7 @@
  *
  * This rule will not work in OOP tests that don't have access to the activity under test.
  */
-class ViewCaptureRule : TestRule {
+class ViewCaptureRule(var alreadyOpenActivitySupplier: Supplier<Activity?>) : TestRule {
     private val viewCapture = SimpleViewCapture("test-view-capture")
     var viewCaptureData: ExportedData? = null
         private set
@@ -46,6 +49,8 @@
                 viewCaptureData = null
                 val windowListenerCloseables = mutableListOf<SafeCloseable>()
 
+                startCapturingExistingActivity(windowListenerCloseables)
+
                 val lifecycleCallbacks =
                     object : ActivityLifecycleCallbacksAdapter {
                         override fun onActivityCreated(activity: Activity, bundle: Bundle?) {
@@ -76,7 +81,16 @@
                     MAIN_EXECUTOR.execute { windowListenerCloseables.onEach(SafeCloseable::close) }
                 }
 
-                ViewCaptureAnalyzer.assertNoAnomalies(viewCaptureData)
+                analyzeViewCapture()
+            }
+
+            private fun startCapturingExistingActivity(
+                windowListenerCloseables: MutableCollection<SafeCloseable>
+            ) {
+                val alreadyOpenActivity = alreadyOpenActivitySupplier.get()
+                if (alreadyOpenActivity != null) {
+                    startCapture(windowListenerCloseables, alreadyOpenActivity)
+                }
             }
 
             private fun startCapture(
@@ -92,4 +106,17 @@
             }
         }
     }
+
+    private fun analyzeViewCapture() {
+        // OOP tests don't produce ViewCapture data
+        if (!TestHelpers.isInLauncherProcess()) return
+
+        ViewCaptureAnalyzer.assertNoAnomalies(viewCaptureData)
+
+        var frameCount = 0
+        for (i in 0 until viewCaptureData!!.windowDataCount) {
+            frameCount += viewCaptureData!!.getWindowData(i).frameDataCount
+        }
+        assertTrue("Empty ViewCapture data", frameCount > 0)
+    }
 }
diff --git a/tests/src/com/android/launcher3/util/viewcapture_analysis/AlphaJumpDetector.java b/tests/src/com/android/launcher3/util/viewcapture_analysis/AlphaJumpDetector.java
index 54ac655..d3d9de0 100644
--- a/tests/src/com/android/launcher3/util/viewcapture_analysis/AlphaJumpDetector.java
+++ b/tests/src/com/android/launcher3/util/viewcapture_analysis/AlphaJumpDetector.java
@@ -32,8 +32,6 @@
     private static final String CONTENT = "DecorView|LinearLayout|FrameLayout:id/content|";
     private static final String DRAG_LAYER =
             CONTENT + "LauncherRootView:id/launcher|DragLayer:id/drag_layer|";
-    private static final String RECENTS_DRAG_LAYER =
-            CONTENT + "LauncherRootView:id/launcher|RecentsDragLayer:id/drag_layer|";
 
     // Paths of nodes that are excluded from analysis.
     private static final Collection<String> PATHS_TO_IGNORE = Set.of(
@@ -114,26 +112,19 @@
             DRAG_LAYER + "WidgetsFullSheet|SpringRelativeLayout:id/container",
             DRAG_LAYER + "WidgetsTwoPaneSheet|SpringRelativeLayout:id/container",
             CONTENT + "LauncherRootView:id/launcher|FloatingIconView",
-            DRAG_LAYER + "FallbackRecentsView:id/overview_panel",
-            RECENTS_DRAG_LAYER + "FallbackRecentsView:id/overview_panel",
-            DRAG_LAYER
-                    + "NexusOverviewActionsView:id/overview_actions_view"
-                    + "|LinearLayout:id/action_buttons|ImageButton:id/action_screenshot",
-            RECENTS_DRAG_LAYER
-                    + "NexusOverviewActionsView:id/overview_actions_view"
-                    + "|LinearLayout:id/action_buttons|ImageButton:id/action_screenshot",
-            DRAG_LAYER
-                    + "NexusOverviewActionsView:id/overview_actions_view"
-                    + "|LinearLayout:id/action_buttons|ImageButton:id/action_select",
-            RECENTS_DRAG_LAYER
-                    + "NexusOverviewActionsView:id/overview_actions_view"
-                    + "|LinearLayout:id/action_buttons|ImageButton:id/action_select",
-            DRAG_LAYER
-                    + "NexusOverviewActionsView:id/overview_actions_view"
-                    + "|LinearLayout:id/action_buttons|ImageButton:id/action_split",
-            RECENTS_DRAG_LAYER
-                    + "NexusOverviewActionsView:id/overview_actions_view"
-                    + "|LinearLayout:id/action_buttons|ImageButton:id/action_split"
+            CONTENT
+                    + "LauncherRootView|RecentsDragLayer:id/drag_layer|ArrowTipView|View:id/arrow",
+            CONTENT
+                    + "LauncherRootView|RecentsDragLayer:id/drag_layer|FallbackRecentsView:id"
+                    + "/overview_panel",
+            CONTENT
+                    + "LauncherRootView|RecentsDragLayer:id/drag_layer|NexusOverviewActionsView"
+                    + ":id/overview_actions_view|LinearLayout:id/action_buttons|Button:id"
+                    + "/action_screenshot",
+            CONTENT
+                    + "LauncherRootView|RecentsDragLayer:id/drag_layer|NexusOverviewActionsView"
+                    + ":id/overview_actions_view|LinearLayout:id/action_buttons|Button:id"
+                    + "/action_select"
     );
     // Minimal increase or decrease of view's alpha between frames that triggers the error.
     private static final float ALPHA_JUMP_THRESHOLD = 1f;
diff --git a/tests/tapl/com/android/launcher3/tapl/Background.java b/tests/tapl/com/android/launcher3/tapl/Background.java
index 3dab9a8..7dd5827 100644
--- a/tests/tapl/com/android/launcher3/tapl/Background.java
+++ b/tests/tapl/com/android/launcher3/tapl/Background.java
@@ -240,76 +240,71 @@
                      "want to quick switch to the previous app")) {
             verifyActiveContainer();
             final boolean launcherWasVisible = mLauncher.isLauncherVisible();
-            switch (mLauncher.getNavigationModel()) {
-                case ZERO_BUTTON: {
-                    final int startX;
-                    final int startY;
-                    final int endX;
-                    final int endY;
-                    final int cornerRadius = (int) Math.ceil(mLauncher.getWindowCornerRadius());
-                    if (toRight) {
-                        // Swipe from the bottom left to the bottom right of the screen.
-                        startX = cornerRadius;
-                        startY = getSwipeStartY();
-                        endX = mLauncher.getDevice().getDisplayWidth() - cornerRadius;
-                        endY = startY;
-                    } else {
-                        // Swipe from the bottom right to the bottom left of the screen.
-                        startX = mLauncher.getDevice().getDisplayWidth() - cornerRadius;
-                        startY = getSwipeStartY();
-                        endX = cornerRadius;
-                        endY = startY;
-                    }
-
-                    LauncherInstrumentation.GestureScope gestureScope =
-                            launcherWasVisible
-                                    ? LauncherInstrumentation.GestureScope.INSIDE_TO_OUTSIDE
-                                    : LauncherInstrumentation.GestureScope.OUTSIDE_WITH_PILFER;
-                    mLauncher.executeAndWaitForEvent(
-                            () -> mLauncher.linearGesture(
-                                    startX, startY, endX, endY, 20, false, gestureScope),
-                            event -> event.getEventType() == TYPE_WINDOW_STATE_CHANGED,
-                            () -> "Quick switch gesture didn't change window state", "swiping");
-                    break;
+            if (mLauncher.getNavigationModel() == NavigationModel.ZERO_BUTTON
+                    || mLauncher.getTrackpadGestureType() == TrackpadGestureType.FOUR_FINGER) {
+                final int startX;
+                final int startY;
+                final int endX;
+                final int endY;
+                final int cornerRadius = (int) Math.ceil(mLauncher.getWindowCornerRadius());
+                if (toRight) {
+                    // Swipe from the bottom left to the bottom right of the screen.
+                    startX = cornerRadius;
+                    startY = getSwipeStartY();
+                    endX = mLauncher.getDevice().getDisplayWidth() - cornerRadius;
+                    endY = startY;
+                } else {
+                    // Swipe from the bottom right to the bottom left of the screen.
+                    startX = mLauncher.getDevice().getDisplayWidth() - cornerRadius;
+                    startY = getSwipeStartY();
+                    endX = cornerRadius;
+                    endY = startY;
                 }
 
-                case THREE_BUTTON:
-                    // Double press the recents button.
-                    UiObject2 recentsButton = mLauncher.waitForNavigationUiObject("recent_apps");
-                    if (mLauncher.isTablet()) {
-                        mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN,
-                                LauncherInstrumentation.EVENT_TOUCH_DOWN);
-                        mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN,
-                                LauncherInstrumentation.EVENT_TOUCH_UP);
-                    }
-                    if (mLauncher.isTrackpadGestureEnabled()) {
-                        mLauncher.expectEvent(TestProtocol.SEQUENCE_TIS, EVENT_TOUCH_DOWN_TIS);
-                        mLauncher.expectEvent(TestProtocol.SEQUENCE_TIS, EVENT_TOUCH_UP_TIS);
-                    }
-                    mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, SQUARE_BUTTON_EVENT);
-                    mLauncher.runToState(() -> recentsButton.click(), OVERVIEW_STATE_ORDINAL,
-                            "clicking Recents button for the first time");
-                    mLauncher.getOverview();
-                    if (mLauncher.isTablet()) {
-                        mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN,
-                                LauncherInstrumentation.EVENT_TOUCH_DOWN);
-                        mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN,
-                                LauncherInstrumentation.EVENT_TOUCH_UP);
-                    }
-                    if (mLauncher.isTrackpadGestureEnabled()) {
-                        mLauncher.expectEvent(TestProtocol.SEQUENCE_TIS, EVENT_TOUCH_DOWN_TIS);
-                        mLauncher.expectEvent(TestProtocol.SEQUENCE_TIS, EVENT_TOUCH_UP_TIS);
-                    }
-                    mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, SQUARE_BUTTON_EVENT);
-                    mLauncher.executeAndWaitForEvent(
-                            () -> recentsButton.click(),
-                            event -> event.getEventType() == TYPE_WINDOW_STATE_CHANGED,
-                            () -> "Pressing recents button didn't change window state",
-                            "clicking Recents button for the second time");
-                    break;
+                LauncherInstrumentation.GestureScope gestureScope =
+                        launcherWasVisible
+                                ? LauncherInstrumentation.GestureScope.INSIDE_TO_OUTSIDE
+                                : LauncherInstrumentation.GestureScope.OUTSIDE_WITH_PILFER;
+                mLauncher.executeAndWaitForEvent(
+                        () -> mLauncher.linearGesture(
+                                startX, startY, endX, endY, 20, false, gestureScope),
+                        event -> event.getEventType() == TYPE_WINDOW_STATE_CHANGED,
+                        () -> "Quick switch gesture didn't change window state", "swiping");
+            } else {
+                // Double press the recents button.
+                UiObject2 recentsButton = mLauncher.waitForNavigationUiObject("recent_apps");
+                if (mLauncher.isTablet()) {
+                    mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN,
+                            LauncherInstrumentation.EVENT_TOUCH_DOWN);
+                    mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN,
+                            LauncherInstrumentation.EVENT_TOUCH_UP);
+                }
+                if (mLauncher.isTrackpadGestureEnabled()) {
+                    mLauncher.expectEvent(TestProtocol.SEQUENCE_TIS, EVENT_TOUCH_DOWN_TIS);
+                    mLauncher.expectEvent(TestProtocol.SEQUENCE_TIS, EVENT_TOUCH_UP_TIS);
+                }
+                mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, SQUARE_BUTTON_EVENT);
+                mLauncher.runToState(() -> recentsButton.click(), OVERVIEW_STATE_ORDINAL,
+                        "clicking Recents button for the first time");
+                mLauncher.getOverview();
+                if (mLauncher.isTablet()) {
+                    mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN,
+                            LauncherInstrumentation.EVENT_TOUCH_DOWN);
+                    mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN,
+                            LauncherInstrumentation.EVENT_TOUCH_UP);
+                }
+                if (mLauncher.isTrackpadGestureEnabled()) {
+                    mLauncher.expectEvent(TestProtocol.SEQUENCE_TIS, EVENT_TOUCH_DOWN_TIS);
+                    mLauncher.expectEvent(TestProtocol.SEQUENCE_TIS, EVENT_TOUCH_UP_TIS);
+                }
+                mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, SQUARE_BUTTON_EVENT);
+                mLauncher.executeAndWaitForEvent(
+                        () -> recentsButton.click(),
+                        event -> event.getEventType() == TYPE_WINDOW_STATE_CHANGED,
+                        () -> "Pressing recents button didn't change window state",
+                        "clicking Recents button for the second time");
             }
             mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, TASK_START_EVENT);
-            return;
         }
     }