Merge "Revert "Revert "Add TaskbarModeSwitchRule to test both transient/persistent taskbar.""" into tm-qpr-dev
diff --git a/quickstep/res/layout-sw600dp-land/allset_navigation_and_hint.xml b/quickstep/res/layout-sw600dp-land/allset_navigation_and_hint.xml
deleted file mode 100644
index 3bfa6da..0000000
--- a/quickstep/res/layout-sw600dp-land/allset_navigation_and_hint.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2022 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.
--->
-<merge xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto">
-
-    <TextView
-        android:id="@+id/navigation_settings"
-        style="@style/TextAppearance.GestureTutorial.LinkText"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="32dp"
-        android:background="?android:attr/selectableItemBackground"
-        android:minHeight="48dp"
-        android:text="@string/allset_navigation_settings"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toBottomOf="@id/subtitle" />
-
-    <TextView
-        android:id="@+id/hint"
-        style="@style/TextAppearance.GestureTutorial.Feedback.Subtitle"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginBottom="@dimen/allset_page_margin_bottom"
-        android:text="@string/allset_hint"
-        android:textSize="@dimen/allset_page_swipe_up_text_size"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="parent" />
-
-</merge>
\ No newline at end of file
diff --git a/quickstep/res/layout-sw600dp/allset_navigation_and_hint.xml b/quickstep/res/layout-sw600dp/allset_navigation_and_hint.xml
index 9559072..44b3ecb 100644
--- a/quickstep/res/layout-sw600dp/allset_navigation_and_hint.xml
+++ b/quickstep/res/layout-sw600dp/allset_navigation_and_hint.xml
@@ -21,12 +21,11 @@
         style="@style/TextAppearance.GestureTutorial.LinkText"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_marginBottom="96dp"
+        android:layout_marginTop="24dp"
         android:background="?android:attr/selectableItemBackground"
         android:minHeight="48dp"
         android:text="@string/allset_navigation_settings"
-        app:layout_constraintBottom_toTopOf="@id/hint"
-        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/subtitle"
         app:layout_constraintStart_toStartOf="parent" />
 
     <TextView
@@ -34,7 +33,7 @@
         style="@style/TextAppearance.GestureTutorial.Feedback.Subtitle"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_marginBottom="@dimen/allset_page_margin_bottom"
+        android:layout_marginBottom="24dp"
         android:text="@string/allset_hint"
         android:textSize="@dimen/allset_page_swipe_up_text_size"
         app:layout_constraintBottom_toBottomOf="parent"
diff --git a/quickstep/res/values-sw600dp-land/dimens.xml b/quickstep/res/values-sw600dp-land/dimens.xml
index 5507fcf..dc10c24 100644
--- a/quickstep/res/values-sw600dp-land/dimens.xml
+++ b/quickstep/res/values-sw600dp-land/dimens.xml
@@ -20,6 +20,5 @@
 
     <!-- All Set page -->
     <dimen name="allset_page_margin_horizontal">48dp</dimen>
-    <dimen name="allset_page_margin_bottom">24dp</dimen>
 
 </resources>
diff --git a/quickstep/res/values-sw600dp/dimens.xml b/quickstep/res/values-sw600dp/dimens.xml
index c96ad11..5899814 100644
--- a/quickstep/res/values-sw600dp/dimens.xml
+++ b/quickstep/res/values-sw600dp/dimens.xml
@@ -36,7 +36,6 @@
 
     <!-- All Set page -->
     <dimen name="allset_page_margin_horizontal">120dp</dimen>
-    <dimen name="allset_page_margin_bottom">24dp</dimen>
     <dimen name="allset_page_allset_text_size">38sp</dimen>
     <dimen name="allset_page_swipe_up_text_size">15sp</dimen>
 
diff --git a/quickstep/res/values-sw720dp-land/dimens.xml b/quickstep/res/values-sw720dp-land/dimens.xml
index 4bc8bf3..02d1189 100644
--- a/quickstep/res/values-sw720dp-land/dimens.xml
+++ b/quickstep/res/values-sw720dp-land/dimens.xml
@@ -17,7 +17,4 @@
 <resources>
     <!--  Overview actions  -->
     <dimen name="overview_actions_top_margin">20dp</dimen>
-
-    <!-- All Set page-->
-    <dimen name="allset_page_margin_bottom">24dp</dimen>
 </resources>
diff --git a/quickstep/res/values-sw720dp/dimens.xml b/quickstep/res/values-sw720dp/dimens.xml
index a84b939..585f01e 100644
--- a/quickstep/res/values-sw720dp/dimens.xml
+++ b/quickstep/res/values-sw720dp/dimens.xml
@@ -35,7 +35,6 @@
     <dimen name="overview_grid_side_margin">64dp</dimen>
 
     <!-- All Set page-->
-    <dimen name="allset_page_margin_bottom">0dp</dimen>
     <dimen name="allset_page_allset_text_size">42sp</dimen>
     <dimen name="allset_page_swipe_up_text_size">16sp</dimen>
 </resources>
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 6e3fd32..cd60879 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -202,7 +202,6 @@
 
     <!-- All Set page -->
     <dimen name="allset_page_margin_horizontal">40dp</dimen>
-    <dimen name="allset_page_margin_bottom">0dp</dimen>
     <dimen name="allset_page_allset_text_size">36sp</dimen>
     <dimen name="allset_page_swipe_up_text_size">14sp</dimen>
 
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index c0d52a4..1a801b5 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -187,6 +187,8 @@
     <string name="allset_title">All set!</string>
     <!-- Hint string at the bottom of "All Set" page [CHAR LIMIT=NONE] -->
     <string name="allset_hint">Swipe up to go Home</string>
+    <!-- Hint string at the bottom of "All Set" page for button navigation [CHAR LIMIT=NONE] -->
+    <string name="allset_button_hint">Tap the home button to go to your home screen</string>
     <!-- Description of "All Set" page on phones [CHAR LIMIT=NONE] -->
     <string name="allset_description">You\u2019re ready to start using your phone</string>
     <!-- Description of "All Set" page on tablets [CHAR LIMIT=NONE] -->
@@ -204,7 +206,7 @@
     <!-- Label for toast with instructions for split screen selection mode. [CHAR_LIMIT=50] -->
     <string name="toast_split_select_app">Tap another app to use splitscreen</string>
     <!-- Label for toast when app selected for split isn't supported. [CHAR_LIMIT=50] -->
-    <string name="toast_split_app_unsupported">App does not support split-screen.</string>
+    <string name="toast_split_app_unsupported">Choose another app to use split screen</string>
     <!-- Message shown when an action is blocked by a policy enforced by the app or the organization managing the device. [CHAR_LIMIT=NONE] -->
     <string name="blocked_by_policy">This action isn\'t allowed by the app or your organization</string>
 
diff --git a/quickstep/res/values/styles.xml b/quickstep/res/values/styles.xml
index 868d38b..4f0fdf1 100644
--- a/quickstep/res/values/styles.xml
+++ b/quickstep/res/values/styles.xml
@@ -152,6 +152,8 @@
         <item name="android:background">@drawable/bg_overview_clear_all_button</item>
         <item name="android:minWidth">96dp</item>
         <item name="android:minHeight">48dp</item>
+        <item name="android:paddingStart">12dp</item>
+        <item name="android:paddingEnd">12dp</item>
         <item name="android:stateListAnimator">@null</item>
     </style>
 
diff --git a/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java
index 08ed60d..df867cb 100644
--- a/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java
@@ -41,8 +41,7 @@
                     animateToRecentsState(toState);
 
                     // Handle tapping on live tile.
-                    RecentsView recentsView = mRecentsActivity.getOverviewPanel();
-                    recentsView.setTaskLaunchListener(toState == RecentsState.DEFAULT
+                    getRecentsView().setTaskLaunchListener(toState == RecentsState.DEFAULT
                             ? (() -> animateToRecentsState(RecentsState.BACKGROUND_APP)) : null);
                 }
             };
@@ -88,4 +87,9 @@
             anim.start();
         }
     }
+
+    @Override
+    public RecentsView getRecentsView() {
+        return mRecentsActivity.getOverviewPanel();
+    }
 }
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index 174f97f..beab56c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -47,6 +47,7 @@
 import com.android.launcher3.util.OnboardingPrefs;
 import com.android.quickstep.AnimatedFloat;
 import com.android.quickstep.RecentsAnimationCallbacks;
+import com.android.quickstep.views.RecentsView;
 
 import java.io.PrintWriter;
 import java.util.Arrays;
@@ -391,4 +392,9 @@
 
         mTaskbarLauncherStateController.dumpLogs(prefix + "\t", pw);
     }
+
+    @Override
+    public RecentsView getRecentsView() {
+        return mLauncher.getOverviewPanel();
+    }
 }
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 4882842..27159d3 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -92,6 +92,7 @@
 import com.android.launcher3.util.TraceHelper;
 import com.android.launcher3.util.ViewCache;
 import com.android.launcher3.views.ActivityContext;
+import com.android.quickstep.views.RecentsView;
 import com.android.systemui.shared.recents.model.Task;
 import com.android.systemui.shared.rotation.RotationButtonController;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -134,6 +135,7 @@
     private final boolean mIsUserSetupComplete;
     private final boolean mIsNavBarForceVisible;
     private final boolean mIsNavBarKidsMode;
+
     private boolean mIsDestroyed = false;
     // The flag to know if the window is excluded from magnification region computation.
     private boolean mIsExcludeFromMagnificationRegion = false;
@@ -759,42 +761,63 @@
             if (info.isDisabled()) {
                 ItemClickHandler.handleDisabledItemClicked(info, this);
             } else {
-                Intent intent = new Intent(info.getIntent())
-                        .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                try {
-                    if (mIsSafeModeEnabled && !PackageManagerHelper.isSystemApp(this, intent)) {
-                        Toast.makeText(this, R.string.safemode_shortcut_error,
-                                Toast.LENGTH_SHORT).show();
-                    } else  if (info.isPromise()) {
-                        TestLogging.recordEvent(
-                                TestProtocol.SEQUENCE_MAIN, "start: taskbarPromiseIcon");
-                        intent = new PackageManagerHelper(this)
-                                .getMarketIntent(info.getTargetPackage())
-                                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                        startActivity(intent);
+                TaskbarUIController taskbarUIController = mControllers.uiController;
+                RecentsView recents = taskbarUIController.getRecentsView();
+                if (recents != null
+                        && taskbarUIController.getRecentsView().isSplitSelectionActive()) {
+                    // If we are selecting a second app for split, launch the split tasks
+                    taskbarUIController.triggerSecondAppForSplit(info, info.intent, view);
+                } else {
+                    // Else launch the selected task
+                    Intent intent = new Intent(info.getIntent())
+                            .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                    try {
+                        if (mIsSafeModeEnabled && !PackageManagerHelper.isSystemApp(this, intent)) {
+                            Toast.makeText(this, R.string.safemode_shortcut_error,
+                                    Toast.LENGTH_SHORT).show();
+                        } else if (info.isPromise()) {
+                            TestLogging.recordEvent(
+                                    TestProtocol.SEQUENCE_MAIN, "start: taskbarPromiseIcon");
+                            intent = new PackageManagerHelper(this)
+                                    .getMarketIntent(info.getTargetPackage())
+                                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                            startActivity(intent);
 
-                    } else if (info.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
-                        TestLogging.recordEvent(
-                                TestProtocol.SEQUENCE_MAIN, "start: taskbarDeepShortcut");
-                        String id = info.getDeepShortcutId();
-                        String packageName = intent.getPackage();
-                        getSystemService(LauncherApps.class)
-                                .startShortcut(packageName, id, null, null, info.user);
-                    } else {
-                        startItemInfoActivity(info);
+                        } else if (info.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
+                            TestLogging.recordEvent(
+                                    TestProtocol.SEQUENCE_MAIN, "start: taskbarDeepShortcut");
+                            String id = info.getDeepShortcutId();
+                            String packageName = intent.getPackage();
+                            getSystemService(LauncherApps.class)
+                                    .startShortcut(packageName, id, null, null, info.user);
+                        } else {
+                            startItemInfoActivity(info);
+                        }
+
+                        mControllers.uiController.onTaskbarIconLaunched(info);
+                    } catch (NullPointerException
+                            | ActivityNotFoundException
+                            | SecurityException e) {
+                        Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT)
+                                .show();
+                        Log.e(TAG, "Unable to launch. tag=" + info + " intent=" + intent, e);
                     }
-
-                    mControllers.uiController.onTaskbarIconLaunched(info);
-                    mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true);
-                } catch (NullPointerException | ActivityNotFoundException | SecurityException e) {
-                    Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT)
-                            .show();
-                    Log.e(TAG, "Unable to launch. tag=" + info + " intent=" + intent, e);
                 }
+                mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true);
             }
         } else if (tag instanceof AppInfo) {
-            startItemInfoActivity((AppInfo) tag);
-            mControllers.uiController.onTaskbarIconLaunched((AppInfo) tag);
+            AppInfo info = (AppInfo) tag;
+            TaskbarUIController taskbarUIController = mControllers.uiController;
+            RecentsView recents = taskbarUIController.getRecentsView();
+            if (recents != null
+                    && taskbarUIController.getRecentsView().isSplitSelectionActive()) {
+                // If we are selecting a second app for split, launch the split tasks
+                taskbarUIController.triggerSecondAppForSplit(info, info.intent, view);
+            } else {
+                // Else launch the selected task
+                startItemInfoActivity((AppInfo) tag);
+                mControllers.uiController.onTaskbarIconLaunched((AppInfo) tag);
+            }
             mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true);
         } else {
             Log.e(TAG, "Unknown type clicked: " + tag);
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
index d7bb16e..3045eca 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
@@ -15,6 +15,7 @@
  */
 package com.android.launcher3.taskbar;
 
+import static com.android.launcher3.AbstractFloatingView.TYPE_TASKBAR_ALL_APPS;
 import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_ALL_APPS;
 import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_PREDICTION;
 import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
@@ -301,7 +302,12 @@
     protected void callOnDragStart() {
         super.callOnDragStart();
         // Pre-drag has ended, start the global system drag.
-        AbstractFloatingView.closeAllOpenViews(mActivity);
+        if (mDisallowGlobalDrag) {
+            AbstractFloatingView.closeAllOpenViewsExcept(mActivity, TYPE_TASKBAR_ALL_APPS);
+        } else {
+            AbstractFloatingView.closeAllOpenViews(mActivity);
+        }
+
         startSystemDrag((BubbleTextView) mDragObject.originalView);
     }
 
@@ -536,10 +542,15 @@
 
     private View findTaskbarTargetForIconView(@NonNull View iconView) {
         Object tag = iconView.getTag();
+        TaskbarViewController taskbarViewController = mControllers.taskbarViewController;
+
         if (tag instanceof ItemInfo) {
             ItemInfo item = (ItemInfo) tag;
-            TaskbarViewController taskbarViewController = mControllers.taskbarViewController;
             if (item.container == CONTAINER_ALL_APPS || item.container == CONTAINER_PREDICTION) {
+                if (mDisallowGlobalDrag) {
+                    // We're dragging in taskbarAllApps, we don't have folders or shortcuts
+                    return iconView;
+                }
                 // Since all apps closes when the drag starts, target the all apps button instead.
                 return taskbarViewController.getAllAppsButtonView();
             } else if (item.container >= 0) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
index fc26f5f..ea5df87 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
@@ -119,10 +119,13 @@
                     mLauncherState = finalState;
                     updateStateForFlag(FLAG_TRANSITION_STATE_RUNNING, false);
                     applyState();
-                    mControllers.taskbarDragController.setDisallowGlobalDrag(
-                            (finalState instanceof OverviewState));
-                    mControllers.taskbarDragController.setDisallowLongClick(
-                            finalState == LauncherState.OVERVIEW_SPLIT_SELECT);
+                    boolean disallowGlobalDrag = finalState instanceof OverviewState;
+                    boolean disallowLongClick = finalState == LauncherState.OVERVIEW_SPLIT_SELECT;
+                    mControllers.taskbarDragController.setDisallowGlobalDrag(disallowGlobalDrag);
+                    mControllers.taskbarDragController.setDisallowLongClick(disallowLongClick);
+                    mControllers.taskbarAllAppsController.setDisallowGlobalDrag(disallowGlobalDrag);
+                    mControllers.taskbarAllAppsController.setDisallowLongClick(disallowLongClick);
+                    mControllers.taskbarPopupController.setHideSplitOptions(disallowGlobalDrag);
                 }
             };
 
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
index da6dab1..9b27c9d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
@@ -75,6 +75,7 @@
 
     // Initialized in init.
     private TaskbarControllers mControllers;
+    private boolean mHideSplitOptions;
 
     public TaskbarPopupController(TaskbarActivityContext context) {
         mContext = context;
@@ -100,6 +101,10 @@
         mPopupDataProvider.setDeepShortcutMap(deepShortcutMapCopy);
     }
 
+    public void setHideSplitOptions(boolean hideSplitOptions) {
+        mHideSplitOptions = hideSplitOptions;
+    }
+
     private void updateNotificationDots(Predicate<PackageUserKey> updatedDots) {
         final PackageUserKey packageUserKey = new PackageUserKey(null, null);
         Predicate<ItemInfo> matcher = info -> !packageUserKey.updateFromItemInfo(info)
@@ -186,11 +191,16 @@
     // TODO(b/227800345): Add "Split bottom" option when tablet is in portrait mode.
     private Stream<SystemShortcut.Factory> getSystemShortcuts() {
         // concat a Stream of split options with a Stream of APP_INFO
+        Stream<SystemShortcut.Factory> appInfo = Stream.of(APP_INFO);
+        if (mHideSplitOptions) {
+            return appInfo;
+        }
+
         return Stream.concat(
                 Utilities.getSplitPositionOptions(mContext.getDeviceProfile())
                         .stream()
                         .map(this::createSplitShortcutFactory),
-                Stream.of(APP_INFO)
+                appInfo
         );
     }
 
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
index 1014cb6..4ec9b41 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
@@ -15,13 +15,18 @@
  */
 package com.android.launcher3.taskbar;
 
+import android.content.Intent;
+import android.graphics.drawable.BitmapDrawable;
 import android.view.MotionEvent;
 import android.view.View;
 
 import androidx.annotation.CallSuper;
+import androidx.annotation.Nullable;
 
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.ItemInfoWithIcon;
+import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.TaskView;
 
 import java.io.PrintWriter;
 import java.util.stream.Stream;
@@ -135,4 +140,38 @@
                 prefix,
                 getClass().getSimpleName()));
     }
+
+    /**
+     * Returns RecentsView. Overwritten in LauncherTaskbarUIController and
+     * FallbackTaskbarUIController with Launcher-specific implementations. Returns null for other
+     * UI controllers (like DesktopTaskbarUIController) that don't have a RecentsView.
+     */
+    public @Nullable RecentsView getRecentsView() {
+        return null;
+    }
+
+    /**
+     * Uses the clicked Taskbar icon to launch a second app for splitscreen.
+     */
+    public void triggerSecondAppForSplit(ItemInfoWithIcon info, Intent intent, View startingView) {
+        RecentsView recents = getRecentsView();
+        TaskView foundTaskView = recents.getTaskViewByComponentName(info.getTargetComponent());
+        if (foundTaskView != null) {
+            recents.confirmSplitSelect(
+                    foundTaskView,
+                    foundTaskView.getTask(),
+                    foundTaskView.getIconView().getDrawable(),
+                    foundTaskView.getThumbnail(),
+                    foundTaskView.getThumbnail().getThumbnail(),
+                    /* intent */ null);
+        } else {
+            recents.confirmSplitSelect(
+                    /* containerTaskView */ null,
+                    /* task */ null,
+                    new BitmapDrawable(info.bitmap.icon),
+                    startingView,
+                    /* thumbnail */ null,
+                    intent);
+        }
+    }
 }
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
index 85c6318..4dc8d47 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
@@ -48,6 +48,8 @@
     private AppInfo[] mApps;
     private int mAppsModelFlags;
     private List<ItemInfo> mPredictedApps;
+    private boolean mDisallowGlobalDrag;
+    private boolean mDisallowLongClick;
 
     /** Initialize the controller. */
     public void init(TaskbarControllers controllers, boolean allAppsVisible) {
@@ -78,6 +80,14 @@
         }
     }
 
+    public void setDisallowGlobalDrag(boolean disableDragForOverviewState) {
+        mDisallowGlobalDrag = disableDragForOverviewState;
+    }
+
+    public void setDisallowLongClick(boolean disallowLongClick) {
+        mDisallowLongClick = disallowLongClick;
+    }
+
     /** Updates the current predictions. */
     public void setPredictedApps(List<ItemInfo> predictedApps) {
         if (!FeatureFlags.ENABLE_ALL_APPS_IN_TASKBAR.get()) {
@@ -123,6 +133,12 @@
         mAppsView.getFloatingHeaderView()
                 .findFixedRowByType(PredictionRowView.class)
                 .setPredictedApps(mPredictedApps);
+        // 1 alternative that would be more work:
+        // Create a shared drag layer between taskbar and taskbarAllApps so that when dragging
+        // starts and taskbarAllApps can close, but the drag layer that the view is being dragged in
+        // doesn't also close
+        overlayContext.getDragController().setDisallowGlobalDrag(mDisallowGlobalDrag);
+        overlayContext.getDragController().setDisallowLongClick(mDisallowLongClick);
     }
 
 
diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
index 875b72c..5a09e02 100644
--- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
+++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
@@ -116,7 +116,7 @@
      */
     @BinderThread
     public void addCommand(int type) {
-        if (mPendingCommands.size() > MAX_QUEUE_SIZE) {
+        if (mPendingCommands.size() >= MAX_QUEUE_SIZE) {
             return;
         }
         CommandInfo cmd = new CommandInfo(type);
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index acf597b..ef7c6dc 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -548,15 +548,13 @@
         }
     }
 
-    public void startIntentAndTask(PendingIntent pendingIntent, Intent fillInIntent,
-            Bundle options1, int taskId, Bundle options2,
-            @SplitConfigurationOptions.StagePosition int splitPosition, float splitRatio,
-            RemoteTransition remoteTransition, InstanceId instanceId) {
+    public void startIntentAndTask(PendingIntent pendingIntent, Bundle options1, int taskId,
+            Bundle options2, @SplitConfigurationOptions.StagePosition int splitPosition,
+            float splitRatio, RemoteTransition remoteTransition, InstanceId instanceId) {
         if (mSystemUiProxy != null) {
             try {
-                mSplitScreen.startIntentAndTask(pendingIntent, fillInIntent, options1,
-                        taskId, options2, splitPosition, splitRatio,
-                        remoteTransition, instanceId);
+                mSplitScreen.startIntentAndTask(pendingIntent, options1, taskId, options2,
+                        splitPosition, splitRatio, remoteTransition, instanceId);
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed call startIntentAndTask");
             }
@@ -593,13 +591,13 @@
     }
 
     public void startIntentAndTaskWithLegacyTransition(PendingIntent pendingIntent,
-            Intent fillInIntent, Bundle options1, int taskId, Bundle options2,
+            Bundle options1, int taskId, Bundle options2,
             @SplitConfigurationOptions.StagePosition int splitPosition, float splitRatio,
             RemoteAnimationAdapter adapter, InstanceId instanceId) {
         if (mSystemUiProxy != null) {
             try {
-                mSplitScreen.startIntentAndTaskWithLegacyTransition(pendingIntent, fillInIntent,
-                        options1, taskId, options2, splitPosition, splitRatio, adapter, instanceId);
+                mSplitScreen.startIntentAndTaskWithLegacyTransition(pendingIntent, options1, taskId,
+                        options2, splitPosition, splitRatio, adapter, instanceId);
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed call startIntentAndTaskWithLegacyTransition");
             }
diff --git a/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java
index 8986c05..897b559 100644
--- a/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java
+++ b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java
@@ -53,6 +53,7 @@
 import androidx.annotation.Nullable;
 import androidx.core.graphics.ColorUtils;
 
+import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
@@ -120,10 +121,9 @@
         mContentView = findViewById(R.id.content_view);
         mSwipeUpShift = getResources().getDimension(R.dimen.allset_swipe_up_shift);
 
-        boolean isTablet = InvariantDeviceProfile.INSTANCE.get(getApplicationContext())
-                .getDeviceProfile(this).isTablet;
+        DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(this).getDeviceProfile(this);
         TextView subtitle = findViewById(R.id.subtitle);
-        subtitle.setText(isTablet
+        subtitle.setText(dp.isTablet
                 ? R.string.allset_description_tablet : R.string.allset_description);
 
         TextView tv = findViewById(R.id.navigation_settings);
@@ -137,7 +137,11 @@
             }
         });
 
-        findViewById(R.id.hint).setAccessibilityDelegate(new SkipButtonAccessibilityDelegate());
+        TextView hintTextView = findViewById(R.id.hint);
+        if (!dp.isGestureMode) {
+            hintTextView.setText(R.string.allset_button_hint);
+        }
+        hintTextView.setAccessibilityDelegate(new SkipButtonAccessibilityDelegate());
         mTISBindHelper = new TISBindHelper(this, this::onTISConnected);
 
         mVibrator = getSystemService(Vibrator.class);
diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
index 08f9fa6..4a74ac6 100644
--- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
@@ -37,7 +37,6 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.UserHandle;
-import android.text.TextUtils;
 import android.util.Log;
 import android.util.Pair;
 import android.view.RemoteAnimationAdapter;
@@ -88,10 +87,8 @@
     private ItemInfo mItemInfo;
     private Intent mInitialTaskIntent;
     private int mInitialTaskId = INVALID_TASK_ID;
-    private String mInitialTaskPackageName;
     private Intent mSecondTaskIntent;
     private int mSecondTaskId = INVALID_TASK_ID;
-    private String mSecondTaskPackageName;
     private boolean mRecentsAnimationRunning;
     @Nullable
     private UserHandle mUser;
@@ -119,7 +116,6 @@
     public void setInitialTaskSelect(Task task, @StagePosition int stagePosition,
             StatsLogManager.EventEnum splitEvent, ItemInfo itemInfo) {
         mInitialTaskId = task.key.id;
-        mInitialTaskPackageName = task.getTopComponent().getPackageName();
         setInitialData(stagePosition, splitEvent, itemInfo);
     }
 
@@ -131,7 +127,6 @@
         mInitialTaskIntent = intent;
         mUser = itemInfo.user;
         mItemInfo = itemInfo;
-        mInitialTaskPackageName = intent.getComponent().getPackageName();
         setInitialData(stagePosition, splitEvent, itemInfo);
     }
 
@@ -143,7 +138,6 @@
             @StagePosition int stagePosition, @NonNull ItemInfo itemInfo,
             StatsLogManager.EventEnum splitEvent) {
         mInitialTaskId = info.taskId;
-        mInitialTaskPackageName = info.topActivity.getPackageName();
         setInitialData(stagePosition, splitEvent, itemInfo);
     }
 
@@ -161,9 +155,9 @@
     public void launchSplitTasks(Consumer<Boolean> callback) {
         Pair<InstanceId, com.android.launcher3.logging.InstanceId> instanceIds =
                 LogUtils.getShellShareableInstanceId();
-        launchTasks(mInitialTaskId, mInitialTaskIntent, mInitialTaskPackageName, mSecondTaskId,
-                mSecondTaskIntent, mSecondTaskPackageName, mStagePosition, callback,
-                false /* freezeTaskList */, DEFAULT_SPLIT_RATIO, instanceIds.first);
+        launchTasks(mInitialTaskId, mInitialTaskIntent, mSecondTaskId, mSecondTaskIntent,
+                mStagePosition, callback, false /* freezeTaskList */, DEFAULT_SPLIT_RATIO,
+                instanceIds.first);
 
         mStatsLogManager.logger()
                 .withItemInfo(mItemInfo)
@@ -177,12 +171,10 @@
      */
     public void setSecondTask(Task task) {
         mSecondTaskId = task.key.id;
-        mSecondTaskPackageName = task.getTopComponent().getPackageName();
     }
 
     public void setSecondTask(Intent intent) {
         mSecondTaskIntent = intent;
-        mSecondTaskPackageName = intent.getComponent().getPackageName();
     }
 
     /**
@@ -205,9 +197,8 @@
      */
     public void launchTasks(int taskId1, int taskId2, @StagePosition int stagePosition,
             Consumer<Boolean> callback, boolean freezeTaskList, float splitRatio) {
-        launchTasks(taskId1, null /* intent1 */, null /* packageName1 */, taskId2,
-                null /* intent2 */, null /* packageName2 */, stagePosition, callback,
-                freezeTaskList, splitRatio, null);
+        launchTasks(taskId1, null /* intent1 */, taskId2, null /* intent2 */, stagePosition,
+                callback, freezeTaskList, splitRatio, null);
     }
 
     /**
@@ -220,8 +211,8 @@
      *                   a split instance, null for cases that bring existing instaces to the
      *                   foreground (quickswitch, launching previous pairs from overview)
      */
-    public void launchTasks(int taskId1, @Nullable Intent intent1, String packageName1, int taskId2,
-            @Nullable Intent intent2, String packageName2, @StagePosition int stagePosition,
+    public void launchTasks(int taskId1, @Nullable Intent intent1, int taskId2,
+            @Nullable Intent intent2, @StagePosition int stagePosition,
             Consumer<Boolean> callback, boolean freezeTaskList, float splitRatio,
             @Nullable InstanceId shellInstanceId) {
         TestLogging.recordEvent(
@@ -240,10 +231,10 @@
                         null /* options2 */, stagePosition, splitRatio, remoteTransition,
                         shellInstanceId);
             } else if (intent2 == null) {
-                launchIntentOrShortcut(intent1, packageName2, options1, taskId2, stagePosition,
-                        splitRatio, remoteTransition, shellInstanceId);
+                launchIntentOrShortcut(intent1, options1, taskId2, stagePosition, splitRatio,
+                        remoteTransition, shellInstanceId);
             } else if (intent1 == null) {
-                launchIntentOrShortcut(intent2, packageName1, options1, taskId1,
+                launchIntentOrShortcut(intent2, options1, taskId1,
                         getOppositeStagePosition(stagePosition), splitRatio, remoteTransition,
                         shellInstanceId);
             } else {
@@ -261,10 +252,10 @@
                         taskId2, null /* options2 */, stagePosition, splitRatio, adapter,
                         shellInstanceId);
             } else if (intent2 == null) {
-                launchIntentOrShortcutLegacy(intent1, packageName2, options1, taskId2,
-                        stagePosition, splitRatio, adapter, shellInstanceId);
+                launchIntentOrShortcutLegacy(intent1, options1, taskId2, stagePosition, splitRatio,
+                        adapter, shellInstanceId);
             } else if (intent1 == null) {
-                launchIntentOrShortcutLegacy(intent2, packageName1, options1, taskId1,
+                launchIntentOrShortcutLegacy(intent2, options1, taskId1,
                         getOppositeStagePosition(stagePosition), splitRatio, adapter,
                         shellInstanceId);
             } else {
@@ -273,9 +264,8 @@
         }
     }
 
-    private void launchIntentOrShortcut(Intent intent, String otherTaskPackageName,
-            ActivityOptions options1, int taskId, @StagePosition int stagePosition,
-            float splitRatio, RemoteTransition remoteTransition,
+    private void launchIntentOrShortcut(Intent intent, ActivityOptions options1, int taskId,
+            @StagePosition int stagePosition, float splitRatio, RemoteTransition remoteTransition,
             @Nullable InstanceId shellInstanceId) {
         PendingIntent pendingIntent = getPendingIntent(intent);
         final ShortcutInfo shortcutInfo = getShortcutInfo(intent,
@@ -285,16 +275,14 @@
                     options1.toBundle(), taskId, null /* options2 */, stagePosition,
                     splitRatio, remoteTransition, shellInstanceId);
         } else {
-            mSystemUiProxy.startIntentAndTask(pendingIntent,
-                    getFillInIntent(intent, otherTaskPackageName), options1.toBundle(), taskId,
+            mSystemUiProxy.startIntentAndTask(pendingIntent, options1.toBundle(), taskId,
                     null /* options2 */, stagePosition, splitRatio, remoteTransition,
                     shellInstanceId);
         }
     }
 
-    private void launchIntentOrShortcutLegacy(Intent intent, String otherTaskPackageName,
-            ActivityOptions options1, int taskId, @StagePosition int stagePosition,
-            float splitRatio, RemoteAnimationAdapter adapter,
+    private void launchIntentOrShortcutLegacy(Intent intent, ActivityOptions options1, int taskId,
+            @StagePosition int stagePosition, float splitRatio, RemoteAnimationAdapter adapter,
             @Nullable InstanceId shellInstanceId) {
         PendingIntent pendingIntent = getPendingIntent(intent);
         final ShortcutInfo shortcutInfo = getShortcutInfo(intent,
@@ -305,9 +293,8 @@
                     splitRatio, adapter, shellInstanceId);
         } else {
             mSystemUiProxy.startIntentAndTaskWithLegacyTransition(pendingIntent,
-                    getFillInIntent(intent, otherTaskPackageName), options1.toBundle(), taskId,
-                    null /* options2 */, stagePosition, splitRatio, adapter,
-                    shellInstanceId);
+                    options1.toBundle(), taskId, null /* options2 */, stagePosition, splitRatio,
+                    adapter, shellInstanceId);
         }
     }
 
@@ -318,18 +305,6 @@
                 : PendingIntent.getActivity(mContext, 0, intent, FLAG_MUTABLE));
     }
 
-    private Intent getFillInIntent(Intent intent, String otherTaskPackageName) {
-        if (intent == null) {
-            return null;
-        }
-
-        Intent fillInIntent = new Intent();
-        if (TextUtils.equals(intent.getComponent().getPackageName(), otherTaskPackageName)) {
-            fillInIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
-        }
-        return fillInIntent;
-    }
-
 
     public @StagePosition int getActiveSplitStagePosition() {
         return mStagePosition;
@@ -464,10 +439,8 @@
     public void resetState() {
         mInitialTaskId = INVALID_TASK_ID;
         mInitialTaskIntent = null;
-        mInitialTaskPackageName = null;
         mSecondTaskId = INVALID_TASK_ID;
         mSecondTaskIntent = null;
-        mSecondTaskPackageName = null;
         mStagePosition = SplitConfigurationOptions.STAGE_POSITION_UNDEFINED;
         mRecentsAnimationRunning = false;
         mLaunchingTaskView = null;
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
index 5c37da1..b476c12 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -322,7 +322,7 @@
             boolean isRtlEnabled = !mIsRecentsRtl;
             mPositionHelper.updateThumbnailMatrix(
                     mThumbnailPosition, mThumbnailData, mTaskRect.width(), mTaskRect.height(),
-                    mDp.widthPx, mDp.taskbarSize, mDp.isTablet,
+                    mDp.widthPx, mDp.heightPx, mDp.taskbarSize, mDp.isTablet,
                     mOrientationState.getRecentsActivityRotation(), isRtlEnabled);
             mPositionHelper.getMatrix().invert(mInversePositionMatrix);
             if (DEBUG) {
diff --git a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
index 2abd715..8c43fd1 100644
--- a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
@@ -288,7 +288,7 @@
     public RunnableList launchTasks() {
         SystemUiProxy.INSTANCE.get(getContext()).showDesktopApps();
         getRecentsView().startHome();
-        return new RunnableList();
+        return null;
     }
 
     @Nullable
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 47374e0..ff0c984 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -74,9 +74,12 @@
 import android.annotation.SuppressLint;
 import android.annotation.TargetApi;
 import android.app.WindowConfiguration;
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
 import android.content.LocusId;
 import android.content.res.Configuration;
+import android.graphics.Bitmap;
 import android.graphics.BlendMode;
 import android.graphics.Canvas;
 import android.graphics.Color;
@@ -662,8 +665,6 @@
     private TaskView mSecondSplitHiddenView;
     @Nullable
     private SplitBounds mSplitBoundsConfig;
-    private final Toast mSplitToast = Toast.makeText(getContext(),
-            R.string.toast_split_select_app, Toast.LENGTH_SHORT);
     private final Toast mSplitUnsupportedToast = Toast.makeText(getContext(),
             R.string.toast_split_app_unsupported, Toast.LENGTH_SHORT);
 
@@ -1213,6 +1214,21 @@
         return null;
     }
 
+    /**
+     * Returns a {@link TaskView} that has ComponentName matching {@code componentName} or null if
+     * no match.
+     */
+    @Nullable
+    public TaskView getTaskViewByComponentName(ComponentName componentName) {
+        for (int i = 0; i < getTaskViewCount(); i++) {
+            TaskView taskView = requireTaskViewAt(i);
+            if (taskView.getTask().key.sourceComponent.equals(componentName)) {
+                return taskView;
+            }
+        }
+        return null;
+    }
+
     public void setOverviewStateEnabled(boolean enabled) {
         mOverviewStateEnabled = enabled;
         updateTaskStackListenerState();
@@ -3528,7 +3544,8 @@
         mActionsView.updateHiddenFlags(HIDDEN_SPLIT_SELECT_ACTIVE, isSplitSelectionActive());
         mActionsView.updateSplitButtonHiddenFlags(FLAG_IS_NOT_TABLET,
                 !mActivity.getDeviceProfile().isTablet);
-        mActionsView.updateSplitButtonDisabledFlags(FLAG_SINGLE_TASK, getTaskViewCount() <= 1);
+        mActionsView.updateSplitButtonDisabledFlags(FLAG_SINGLE_TASK,
+                !FeatureFlags.ENABLE_TASKBAR_IN_OVERVIEW.get() && getTaskViewCount() <= 1);
     }
 
     /**
@@ -4237,24 +4254,39 @@
      * Confirms the selection of the next split task. The extra data is passed through because the
      * user may be selecting a subtask in a group.
      *
+     * @param containerTaskView If our second selected app is currently running in Recents, this is
+     *                          the "container" TaskView from Recents. If we are starting a fresh
+     *                          instance of the app from an Intent, this will be null.
+     * @param task The Task corresponding to our second selected app. If we are starting a fresh
+     *             instance of the app from an Intent, this will be null.
+     * @param drawable The Drawable corresponding to our second selected app's icon.
+     * @param secondView The View representing the current space on the screen where the second app
+     *                   is (either the ThumbnailView or the tapped icon).
+     * @param intent If we are launching a fresh instance of the app, this is the Intent for it. If
+     *               the second app is already running in Recents, this will be null.
      * @return true if waiting for confirmation of second app or if split animations are running,
      *          false otherwise
      */
-    public boolean confirmSplitSelect(TaskView containerTaskView, Task task, IconView iconView,
-            TaskThumbnailView thumbnailView) {
+    public boolean confirmSplitSelect(TaskView containerTaskView, Task task, Drawable drawable,
+            View secondView, @Nullable Bitmap thumbnail, Intent intent) {
         if (canLaunchFullscreenTask()) {
             return false;
         }
         if (mSplitSelectStateController.isBothSplitAppsConfirmed()) {
             return true;
         }
-        mSplitToast.cancel();
-        if (!task.isDockable) {
-            // Task not split screen supported
-            mSplitUnsupportedToast.show();
-            return true;
+        // Second task is selected either as an already-running Task or an Intent
+        if (task != null) {
+            if (!task.isDockable) {
+                // Task does not support split screen
+                mSplitUnsupportedToast.show();
+                return true;
+            }
+            mSplitSelectStateController.setSecondTask(task);
+        } else {
+            mSplitSelectStateController.setSecondTask(intent);
         }
-        mSplitSelectStateController.setSecondTask(task);
+
         RectF secondTaskStartingBounds = new RectF();
         Rect secondTaskEndingBounds = new Rect();
         // TODO(194414938) starting bounds seem slightly off, investigate
@@ -4281,9 +4313,9 @@
                 false /* fadeWithThumbnail */, true /* isStagedTask */);
 
         safeRemoveDragLayerView(mSecondFloatingTaskView);
-        mSecondFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
-                thumbnailView, thumbnailView.getThumbnail(),
-                iconView.getDrawable(), secondTaskStartingBounds);
+
+        mSecondFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity, secondView,
+                thumbnail, drawable, secondTaskStartingBounds);
         mSecondFloatingTaskView.setAlpha(1);
         mSecondFloatingTaskView.addConfirmAnimation(pendingAnimation, secondTaskStartingBounds,
                 secondTaskEndingBounds, true /* fadeWithThumbnail */, false /* isStagedTask */);
@@ -4299,7 +4331,9 @@
         });
 
         mSecondSplitHiddenView = containerTaskView;
-        mSecondSplitHiddenView.setThumbnailVisibility(INVISIBLE);
+        if (mSecondSplitHiddenView != null) {
+            mSecondSplitHiddenView.setThumbnailVisibility(INVISIBLE);
+        }
 
         InteractionJankMonitorWrapper.begin(this,
                 InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER, "Second tile selected");
diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
index 6792dc5..904c944 100644
--- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -473,8 +473,8 @@
             boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
             DeviceProfile dp = mActivity.getDeviceProfile();
             mPreviewPositionHelper.updateThumbnailMatrix(mPreviewRect, mThumbnailData,
-                    getMeasuredWidth(), getMeasuredHeight(), dp.widthPx, dp.taskbarSize,
-                    dp.isTablet, currentRotation, isRtl);
+                    getMeasuredWidth(), getMeasuredHeight(), dp.widthPx, dp.heightPx,
+                    dp.taskbarSize, dp.isTablet, currentRotation, isRtl);
 
             mBitmapShader.setLocalMatrix(mPreviewPositionHelper.getMatrix());
             mPaint.setShader(mBitmapShader);
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 527a0d1..c428c64 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -621,7 +621,8 @@
         TaskIdAttributeContainer container = mTaskIdAttributeContainer[index];
         if (container != null) {
             return getRecentsView().confirmSplitSelect(this, container.getTask(),
-                    container.getIconView(), container.getThumbnailView());
+                    container.getIconView().getDrawable(), container.getThumbnailView(),
+                    container.getThumbnailView().getThumbnail(), /* intent */ null);
         }
         return false;
     }
@@ -725,13 +726,14 @@
     /**
      * Launch of the current task (both live and inactive tasks) with an animation.
      */
+    @Nullable
     public RunnableList launchTasks() {
         RecentsView recentsView = getRecentsView();
         RemoteTargetHandle[] remoteTargetHandles = recentsView.mRemoteTargetHandles;
-        RunnableList runnableList = new RunnableList();
         if (isRunningTask() && remoteTargetHandles != null) {
             if (!mIsClickableAsLiveTile) {
-                return runnableList;
+                Log.e(TAG, "TaskView is not clickable as a live tile; returning to home.");
+                return null;
             }
 
             mIsClickableAsLiveTile = false;
@@ -756,11 +758,16 @@
             if (targets == null) {
                 // If the recents animation is cancelled somehow between the parent if block and
                 // here, try to launch the task as a non live tile task.
-                launchTaskAnimated();
+                RunnableList runnableList = launchTaskAnimated();
+                if (runnableList == null) {
+                    Log.e(TAG, "Recents animation cancelled and cannot launch task as non-live tile"
+                            + "; returning to home");
+                }
                 mIsClickableAsLiveTile = true;
                 return runnableList;
             }
 
+            RunnableList runnableList = new RunnableList();
             AnimatorSet anim = new AnimatorSet();
             TaskViewUtils.composeRecentsLaunchAnimator(
                     anim, this, targets.apps,
@@ -797,10 +804,10 @@
             });
             anim.start();
             recentsView.onTaskLaunchedInLiveTileMode();
+            return runnableList;
         } else {
             return launchTaskAnimated();
         }
-        return runnableList;
     }
 
     /**
diff --git a/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt b/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt
index 4785350..963da27 100644
--- a/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt
+++ b/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt
@@ -57,7 +57,7 @@
         val isRtl = false
 
         mPreviewPositionHelper.updateThumbnailMatrix(previewRect, mThumbnailData, canvasWidth,
-                canvasHeight, dp.widthPx, dp.taskbarSize, dp.isTablet, currentRotation,
+                canvasHeight, dp.widthPx, dp.heightPx, dp.taskbarSize, dp.isTablet, currentRotation,
                 isRtl)
         params.setProgress(/* fullscreenProgress= */ 1.0f, /* parentScale= */ 1.0f,
                 /* taskViewScale= */ 1.0f,  /* previewWidth= */ 0, dp, mPreviewPositionHelper)
@@ -78,7 +78,7 @@
         val isRtl = false
 
         mPreviewPositionHelper.updateThumbnailMatrix(previewRect, mThumbnailData, canvasWidth,
-                canvasHeight, dp.widthPx, dp.taskbarSize, dp.isTablet, currentRotation,
+                canvasHeight, dp.widthPx, dp.heightPx, dp.taskbarSize, dp.isTablet, currentRotation,
                 isRtl)
         params.setProgress(/* fullscreenProgress= */ 1.0f, /* parentScale= */ 1.0f,
                 /* taskViewScale= */ 1.0f,  /* previewWidth= */ 0, dp, mPreviewPositionHelper)
diff --git a/res/color-night-v31/transient_taskbar_background.xml b/res/color-night-v31/transient_taskbar_background.xml
new file mode 100644
index 0000000..40f6494
--- /dev/null
+++ b/res/color-night-v31/transient_taskbar_background.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2022 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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+  <item android:color="@android:color/system_neutral1_500" android:lStar="15" />
+</selector>
+
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 033346a..3b92ac4 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -333,7 +333,7 @@
 
     <!-- Snackbar -->
     <dimen name="snackbar_height">48dp</dimen>
-    <dimen name="snackbar_content_height">32dp</dimen>
+    <dimen name="snackbar_content_height">48dp</dimen>
     <dimen name="snackbar_padding">8dp</dimen>
     <dimen name="snackbar_min_margin_left_right">6dp</dimen>
     <dimen name="snackbar_max_margin_left_right">72dp</dimen>
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 0c6f340..ca92aa4 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -324,6 +324,11 @@
         return displayOption.grid.name;
     }
 
+    @VisibleForTesting
+    public static String getDefaultGridName(Context context) {
+        return new InvariantDeviceProfile().initGrid(context, null);
+    }
+
     private void initGrid(Context context, Info displayInfo, DisplayOption displayOption,
             @DeviceType int deviceType) {
         DisplayMetrics metrics = context.getResources().getDisplayMetrics();
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index f70511a..a507532 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -521,6 +521,11 @@
         return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
     }
 
+    /** Converts a dp value to pixels for a certain density. */
+    public static int dpToPx(float dp, int densityDpi) {
+        float densityRatio = (float) densityDpi / DisplayMetrics.DENSITY_DEFAULT;
+        return (int) (dp * densityRatio);
+    }
 
     public static int pxFromSp(float size, DisplayMetrics metrics) {
         return pxFromSp(size, metrics, 1f);
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 27e1ba1..a8def69 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -2350,7 +2350,7 @@
             }
 
             mTargetCell = findNearestArea((int) mDragViewVisualCenter[0],
-                    (int) mDragViewVisualCenter[1], minSpanX, minSpanY,
+                    (int) mDragViewVisualCenter[1], item.spanX, item.spanY,
                     mDragTargetLayout, mTargetCell);
             int reorderX = mTargetCell[0];
             int reorderY = mTargetCell[1];
@@ -2366,7 +2366,8 @@
                     mDragViewVisualCenter[0], (int) mDragViewVisualCenter[1], item.spanX,
                     item.spanY, child, mTargetCell);
 
-            manageReorderOnDragOver(d, targetCellDistance, nearestDropOccupied, minSpanX, minSpanY);
+            manageReorderOnDragOver(d, targetCellDistance, nearestDropOccupied, minSpanX, minSpanY,
+                    reorderX, reorderY);
 
             if (mDragMode == DRAG_MODE_CREATE_FOLDER || mDragMode == DRAG_MODE_ADD_TO_FOLDER ||
                     !nearestDropOccupied) {
@@ -2378,26 +2379,23 @@
     }
 
     protected void manageReorderOnDragOver(DragObject d, float targetCellDistance,
-            boolean nearestDropOccupied, int minSpanX, int minSpanY) {
+            boolean nearestDropOccupied, int minSpanX, int minSpanY, int reorderX, int reorderY) {
 
         ItemInfo item = d.dragInfo;
         final View child = (mDragInfo == null) ? null : mDragInfo.cell;
-        int reorderX = mTargetCell[0];
-        int reorderY = mTargetCell[1];
-        if ((mDragMode == DRAG_MODE_NONE || mDragMode == DRAG_MODE_REORDER)
-                && (mLastReorderX != reorderX || mLastReorderY != reorderY)
-                && targetCellDistance < mDragTargetLayout.getReorderRadius(mTargetCell, item.spanX,
-                item.spanY)) {
-            mDragTargetLayout.performReorder((int) mDragViewVisualCenter[0],
-                    (int) mDragViewVisualCenter[1], minSpanX, minSpanY, item.spanX, item.spanY,
-                    child, mTargetCell, new int[2], CellLayout.MODE_SHOW_REORDER_HINT);
-        }
-
         if (!nearestDropOccupied) {
             mDragTargetLayout.visualizeDropLocation(mTargetCell[0], mTargetCell[1],
                     item.spanX, item.spanY, d);
         } else if ((mDragMode == DRAG_MODE_NONE || mDragMode == DRAG_MODE_REORDER)
-                && !mReorderAlarm.alarmPending()) {
+                && !mReorderAlarm.alarmPending()
+                && (mLastReorderX != reorderX || mLastReorderY != reorderY)
+                && targetCellDistance < mDragTargetLayout.getReorderRadius(mTargetCell, item.spanX,
+                item.spanY)) {
+            mLastReorderX = reorderX;
+            mLastReorderY = reorderY;
+            mDragTargetLayout.performReorder((int) mDragViewVisualCenter[0],
+                    (int) mDragViewVisualCenter[1], minSpanX, minSpanY, item.spanX, item.spanY,
+                    child, mTargetCell, new int[2], CellLayout.MODE_SHOW_REORDER_HINT);
             // Otherwise, if we aren't adding to or creating a folder and there's no pending
             // reorder, then we schedule a reorder
             ReorderAlarmListener listener = new ReorderAlarmListener(mDragViewVisualCenter,
@@ -2602,8 +2600,6 @@
             mTargetCell = findNearestArea((int) mDragViewVisualCenter[0],
                     (int) mDragViewVisualCenter[1], minSpanX, minSpanY, mDragTargetLayout,
                     mTargetCell);
-            mLastReorderX = mTargetCell[0];
-            mLastReorderY = mTargetCell[1];
 
             mTargetCell = mDragTargetLayout.performReorder((int) mDragViewVisualCenter[0],
                 (int) mDragViewVisualCenter[1], minSpanX, minSpanY, spanX, spanY,
diff --git a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
index dd47592..063b82e 100644
--- a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
@@ -1,5 +1,7 @@
 package com.android.launcher3.accessibility;
 
+import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_FOCUSED;
+import static android.view.accessibility.AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS;
 import static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK;
 
 import static com.android.launcher3.LauncherState.NORMAL;
@@ -172,7 +174,11 @@
             mContext.getDragLayer().getDescendantRectRelativeToSelf(host, pos);
             ArrowPopup popup = OptionsPopupView.show(mContext, new RectF(pos), actions, false);
             popup.requestFocus();
-            popup.setOnCloseCallback(host::requestFocus);
+            popup.setOnCloseCallback(() -> {
+                host.requestFocus();
+                host.sendAccessibilityEvent(TYPE_VIEW_FOCUSED);
+                host.performAccessibilityAction(ACTION_ACCESSIBILITY_FOCUS, null);
+            });
             return true;
         } else if (action == DEEP_SHORTCUTS || action == SHORTCUTS_AND_NOTIFICATIONS) {
             BubbleTextView btv = host instanceof BubbleTextView ? (BubbleTextView) host
diff --git a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
index 08b42cd..c86f08d 100644
--- a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
@@ -102,6 +102,16 @@
         }
     }
 
+    /**
+     * Sets results list for search.
+     *
+     * @param searchResultCode indicates if the result is final or intermediate for a given query
+     *                         since we can get search results from multiple sources.
+     */
+    public void setSearchResults(ArrayList<AdapterItem> results, int searchResultCode) {
+        setSearchResults(results);
+    }
+
     private void animateToSearchState(boolean goingToSearch) {
         animateToSearchState(goingToSearch, DEFAULT_SEARCH_TRANSITION_DURATION_MS);
     }
@@ -311,7 +321,7 @@
         layoutParams.topMargin =
                 includeTabsMargin
                         ? getContext().getResources().getDimensionPixelSize(
-                                R.dimen.all_apps_header_pill_height)
+                        R.dimen.all_apps_header_pill_height)
                         : 0;
     }
 
diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
index 368a373..e34d4c8 100644
--- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
+++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
@@ -31,6 +31,7 @@
 import com.android.launcher3.util.ScrollableLayoutManager;
 import com.android.launcher3.views.ActivityContext;
 
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -43,6 +44,31 @@
 
     public static final String TAG = "AppsGridAdapter";
     private final AppsGridLayoutManager mGridLayoutMgr;
+    private final List<OnLayoutCompletedListener> mOnLayoutCompletedListeners = new ArrayList<>();
+
+    /**
+     * Listener for {@link RecyclerView.LayoutManager#onLayoutCompleted(RecyclerView.State)}
+     */
+    public interface OnLayoutCompletedListener {
+        void onLayoutCompleted();
+    }
+
+    /**
+     * Adds a {@link OnLayoutCompletedListener} to receive a callback when {@link
+     * RecyclerView.LayoutManager#onLayoutCompleted(RecyclerView.State)} is called
+     */
+    public void addOnLayoutCompletedListener(OnLayoutCompletedListener listener) {
+        mOnLayoutCompletedListeners.add(listener);
+    }
+
+    /**
+     * Removes a {@link OnLayoutCompletedListener} to not receive a callback when {@link
+     * RecyclerView.LayoutManager#onLayoutCompleted(RecyclerView.State)} is called
+     */
+    public void removeOnLayoutCompletedListener(OnLayoutCompletedListener listener) {
+        mOnLayoutCompletedListeners.remove(listener);
+    }
+
 
     public AllAppsGridAdapter(T activityContext, LayoutInflater inflater,
             AlphabeticalAppsList apps, BaseAdapterProvider[] adapterProviders) {
@@ -133,6 +159,14 @@
         }
 
         @Override
+        public void onLayoutCompleted(RecyclerView.State state) {
+            super.onLayoutCompleted(state);
+            for (OnLayoutCompletedListener listener : mOnLayoutCompletedListeners) {
+                listener.onLayoutCompleted();
+            }
+        }
+
+        @Override
         protected int incrementTotalHeight(Adapter adapter, int position, int heightUntilLastPos) {
             AllAppsGridAdapter.AdapterItem item = mApps.getAdapterItems().get(position);
             // only account for the first icon in the row since they are the same size within a row
diff --git a/src/com/android/launcher3/allapps/SearchTransitionController.java b/src/com/android/launcher3/allapps/SearchTransitionController.java
index 9c3dab4..495f5c3 100644
--- a/src/com/android/launcher3/allapps/SearchTransitionController.java
+++ b/src/com/android/launcher3/allapps/SearchTransitionController.java
@@ -32,6 +32,7 @@
 import android.util.FloatProperty;
 import android.util.Log;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.animation.Interpolator;
 
 import com.android.launcher3.BubbleTextView;
@@ -39,6 +40,7 @@
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
+import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.model.data.ItemInfo;
 
 /** Coordinates the transition between Search and A-Z in All Apps. */
@@ -225,16 +227,35 @@
 
                 numSearchResultsAnimated++;
             }
-            searchResultView.setAlpha(contentAlpha);
-            // Apply background alpha to decorator if possible.
-            if (adapterPosition != NO_POSITION) {
-                searchRecyclerView.getApps().getAdapterItems()
-                        .get(adapterPosition).setDecorationFillAlpha((int) (255 * backgroundAlpha));
-            }
-            // Apply background alpha to view's background (e.g. for Search Edu card).
+
             Drawable background = searchResultView.getBackground();
-            if (background != null) {
+            if (background != null
+                    && searchResultView instanceof ViewGroup
+                    && FeatureFlags.ENABLE_SEARCH_RESULT_BACKGROUND_DRAWABLES.get()) {
+                searchResultView.setAlpha(1f);
+
+                // Apply content alpha to each child, since the view needs to be fully opaque for
+                // the background to show properly.
+                ViewGroup searchResultViewGroup = (ViewGroup) searchResultView;
+                for (int j = 0; j < searchResultViewGroup.getChildCount(); j++) {
+                    searchResultViewGroup.getChildAt(j).setAlpha(contentAlpha);
+                }
+
+                // Apply background alpha to the background drawable directly.
                 background.setAlpha((int) (255 * backgroundAlpha));
+            } else {
+                searchResultView.setAlpha(contentAlpha);
+
+                // Apply background alpha to decorator if possible.
+                if (adapterPosition != NO_POSITION) {
+                    searchRecyclerView.getApps().getAdapterItems().get(adapterPosition)
+                            .setDecorationFillAlpha((int) (255 * backgroundAlpha));
+                }
+
+                // Apply background alpha to view's background (e.g. for Search Edu card).
+                if (background != null) {
+                    background.setAlpha((int) (255 * backgroundAlpha));
+                }
             }
 
             float scaleY = 1;
@@ -304,6 +325,13 @@
                 getSearchRecyclerView().getApps().getAdapterItems().get(adapterPosition)
                         .setDecorationFillAlpha(255);
             }
+            if (child instanceof ViewGroup
+                    && FeatureFlags.ENABLE_SEARCH_RESULT_BACKGROUND_DRAWABLES.get()) {
+                ViewGroup childGroup = (ViewGroup) child;
+                for (int i = 0; i < childGroup.getChildCount(); i++) {
+                    childGroup.getChildAt(i).setAlpha(1f);
+                }
+            }
             if (child.getBackground() != null) {
                 child.getBackground().setAlpha(255);
             }
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 4287779..9484fff 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -264,6 +264,10 @@
     public static final BooleanFlag ENABLE_ONE_SEARCH_MOTION = new DeviceFlag(
             "ENABLE_ONE_SEARCH_MOTION", true, "Enables animations in OneSearch.");
 
+    public static final BooleanFlag ENABLE_SEARCH_RESULT_BACKGROUND_DRAWABLES = new DeviceFlag(
+            "ENABLE_SEARCH_RESULT_BACKGROUND_DRAWABLES", false,
+            "Enable option to replace decorator-based search result backgrounds with drawables");
+
     public static final BooleanFlag ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS = new DeviceFlag(
             "ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS", true,
             "Enable option to show keyboard when going to all-apps");
@@ -323,6 +327,17 @@
     public static final BooleanFlag SHOW_DOT_PAGINATION = getDebugFlag(
             "SHOW_DOT_PAGINATION", false, "Enable showing dot pagination in workspace");
 
+    public static final BooleanFlag LARGE_SCREEN_WIDGET_PICKER = getDebugFlag(
+            "LARGE_SCREEN_WIDGET_PICKER", false, "Enable new widget picker that takes "
+                    + "advantage of large screen format");
+
+    public static final BooleanFlag ENABLE_NEW_GESTURE_NAV_TUTORIAL = getDebugFlag(
+            "ENABLE_NEW_GESTURE_NAV_TUTORIAL", false,
+            "Enable the redesigned gesture navigation tutorial");
+
+    public static final BooleanFlag ENABLE_TOAST_IMPRESSION_LOGGING = getDebugFlag(
+            "ENABLE_TOAST_IMPRESSION_LOGGING", false, "Enable toast impression logging");
+
     public static void initialize(Context context) {
         synchronized (sDebugFlags) {
             for (DebugFlag flag : sDebugFlags) {
diff --git a/src/com/android/launcher3/search/SearchCallback.java b/src/com/android/launcher3/search/SearchCallback.java
index 495a303..cf7ab10 100644
--- a/src/com/android/launcher3/search/SearchCallback.java
+++ b/src/com/android/launcher3/search/SearchCallback.java
@@ -24,6 +24,11 @@
  */
 public interface SearchCallback<T> {
 
+    // Search Result Codes
+    int UNKNOWN = 0;
+    int INTERMEDIATE = 1;
+    int FINAL = 2;
+
     /**
      * Called when the search from primary source is complete.
      *
@@ -32,6 +37,17 @@
     void onSearchResult(String query, ArrayList<T> items);
 
     /**
+     * Called when the search from primary source is complete.
+     *
+     * @param items            list of search results
+     * @param searchResultCode indicates if the result is final or intermediate for a given query
+     *                         since we can get search results from multiple sources.
+     */
+    default void onSearchResult(String query, ArrayList<T> items, int searchResultCode) {
+        onSearchResult(query, items);
+    }
+
+    /**
      * Called when the search results should be cleared.
      */
     void clearSearchResult();
diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
index af689dc..78e17d8 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -585,7 +585,6 @@
     @Override
     public void setSplitTaskSwipeRect(DeviceProfile dp, Rect outRect,
             SplitBounds splitInfo, int desiredStagePosition) {
-        boolean isLandscape = dp.isLandscape;
         float topLeftTaskPercent = splitInfo.appsStackedVertically
                 ? splitInfo.topTaskPercent
                 : splitInfo.leftTaskPercent;
@@ -593,18 +592,24 @@
                 ? splitInfo.dividerHeightPercent
                 : splitInfo.dividerWidthPercent;
 
+        int deviceHeightWithoutTaskbar = dp.availableHeightPx - dp.taskbarSize;
+        float scale = (float) outRect.height() / deviceHeightWithoutTaskbar;
+        float topTaskHeight = dp.availableHeightPx * topLeftTaskPercent;
+        float scaledTopTaskHeight = topTaskHeight * scale;
+        float dividerHeight = dp.availableHeightPx * dividerBarPercent;
+        float scaledDividerHeight = dividerHeight * scale;
+
         if (desiredStagePosition == SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT) {
-            if (isLandscape) {
-                outRect.right = outRect.left + Math.round(outRect.width() * topLeftTaskPercent);
+            if (splitInfo.appsStackedVertically) {
+                outRect.bottom = Math.round(outRect.top + scaledTopTaskHeight);
             } else {
-                outRect.bottom = outRect.top + Math.round(outRect.height() * topLeftTaskPercent);
+                outRect.right = outRect.left + Math.round(outRect.width() * topLeftTaskPercent);
             }
         } else {
-            if (isLandscape) {
-                outRect.left += Math.round(outRect.width()
-                        * (topLeftTaskPercent + dividerBarPercent));
+            if (splitInfo.appsStackedVertically) {
+                outRect.top += Math.round(scaledTopTaskHeight + scaledDividerHeight);
             } else {
-                outRect.top += Math.round(outRect.height()
+                outRect.left += Math.round(outRect.width()
                         * (topLeftTaskPercent + dividerBarPercent));
             }
         }
@@ -617,7 +622,7 @@
         int spaceAboveSnapshot = dp.overviewTaskThumbnailTopMarginPx;
         int totalThumbnailHeight = parentHeight - spaceAboveSnapshot;
         int dividerBar = Math.round(splitBoundsConfig.appsStackedVertically
-                ? splitBoundsConfig.dividerHeightPercent * totalThumbnailHeight
+                ? splitBoundsConfig.dividerHeightPercent * dp.availableHeightPx
                 : splitBoundsConfig.dividerWidthPercent * parentWidth);
         int primarySnapshotHeight;
         int primarySnapshotWidth;
@@ -641,12 +646,18 @@
             }
             secondarySnapshot.setTranslationY(spaceAboveSnapshot);
         } else {
+            int deviceHeightWithoutTaskbar = dp.availableHeightPx - dp.taskbarSize;
+            float scale = (float) totalThumbnailHeight / deviceHeightWithoutTaskbar;
+            float topTaskHeight = dp.availableHeightPx * taskPercent;
+            float finalDividerHeight = dividerBar * scale;
+            float scaledTopTaskHeight = topTaskHeight * scale;
             primarySnapshotWidth = parentWidth;
-            primarySnapshotHeight = Math.round(totalThumbnailHeight * taskPercent);
+            primarySnapshotHeight = Math.round(scaledTopTaskHeight);
 
             secondarySnapshotWidth = parentWidth;
-            secondarySnapshotHeight = totalThumbnailHeight - primarySnapshotHeight - dividerBar;
-            int translationY = primarySnapshotHeight + spaceAboveSnapshot + dividerBar;
+            secondarySnapshotHeight = Math.round(totalThumbnailHeight - primarySnapshotHeight
+                    - finalDividerHeight);
+            float translationY = primarySnapshotHeight + spaceAboveSnapshot + finalDividerHeight;
             secondarySnapshot.setTranslationY(translationY);
 
             FrameLayout.LayoutParams primaryParams =