Merge "Don't avoid blurring overview" into sc-v2-dev
diff --git a/quickstep/res/drawable/bg_overview_clear_all_button.xml b/quickstep/res/drawable/bg_overview_clear_all_button.xml
new file mode 100644
index 0000000..47cbd9f
--- /dev/null
+++ b/quickstep/res/drawable/bg_overview_clear_all_button.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2021 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.
+-->
+<ripple android:color="?android:attr/colorControlHighlight"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
+    <item>
+        <shape android:shape="rectangle"
+            android:tint="?colorButtonNormal">
+            <corners android:radius="18dp" />
+            <solid android:color="?androidprv:attr/colorSurface"/>
+        </shape>
+    </item>
+</ripple>
\ No newline at end of file
diff --git a/quickstep/res/drawable/taskbar_edu_splitscreen.png b/quickstep/res/drawable/taskbar_edu_splitscreen.png
new file mode 100644
index 0000000..f9d2a63
--- /dev/null
+++ b/quickstep/res/drawable/taskbar_edu_splitscreen.png
Binary files differ
diff --git a/quickstep/res/drawable/taskbar_edu_splitscreen.webp b/quickstep/res/drawable/taskbar_edu_splitscreen.webp
deleted file mode 100644
index 2f4402f..0000000
--- a/quickstep/res/drawable/taskbar_edu_splitscreen.webp
+++ /dev/null
Binary files differ
diff --git a/quickstep/res/drawable/taskbar_edu_stashing.png b/quickstep/res/drawable/taskbar_edu_stashing.png
new file mode 100644
index 0000000..f9d2a63
--- /dev/null
+++ b/quickstep/res/drawable/taskbar_edu_stashing.png
Binary files differ
diff --git a/quickstep/res/drawable/taskbar_edu_switch_apps.png b/quickstep/res/drawable/taskbar_edu_switch_apps.png
new file mode 100644
index 0000000..f9d2a63
--- /dev/null
+++ b/quickstep/res/drawable/taskbar_edu_switch_apps.png
Binary files differ
diff --git a/quickstep/res/layout/overview_actions_container.xml b/quickstep/res/layout/overview_actions_container.xml
index 0c2a28c..acbb5b9 100644
--- a/quickstep/res/layout/overview_actions_container.xml
+++ b/quickstep/res/layout/overview_actions_container.xml
@@ -47,6 +47,23 @@
             android:layout_weight="1" />
 
         <Button
+            android:id="@+id/action_split"
+            style="@style/OverviewActionButton"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:drawableStart="@drawable/ic_split_screen"
+            android:text="@string/action_split"
+            android:theme="@style/ThemeControlHighlightWorkspaceColor"
+            android:visibility="gone" />
+
+        <Space
+            android:id="@+id/action_split_space"
+            android:layout_width="0dp"
+            android:layout_height="1dp"
+            android:layout_weight="1"
+            android:visibility="gone" />
+
+        <Button
             android:id="@+id/action_share"
             style="@style/OverviewActionButton"
             android:layout_width="wrap_content"
diff --git a/quickstep/res/layout/overview_clear_all_button.xml b/quickstep/res/layout/overview_clear_all_button.xml
index 1ee726e..1dea57e 100644
--- a/quickstep/res/layout/overview_clear_all_button.xml
+++ b/quickstep/res/layout/overview_clear_all_button.xml
@@ -16,7 +16,7 @@
 -->
 <com.android.quickstep.views.ClearAllButton
     xmlns:android="http://schemas.android.com/apk/res/android"
-    style="@android:style/Widget.DeviceDefault.Button.Borderless"
+    style="@style/OverviewClearAllButton"
     android:id="@+id/clear_all"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
diff --git a/quickstep/res/layout/taskbar_edu.xml b/quickstep/res/layout/taskbar_edu.xml
index ef57a53..3796ff9 100644
--- a/quickstep/res/layout/taskbar_edu.xml
+++ b/quickstep/res/layout/taskbar_edu.xml
@@ -43,6 +43,26 @@
             launcher:pageIndicator="@+id/content_page_indicator">
 
             <LinearLayout
+                android:id="@+id/page_switch_apps"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                android:gravity="center_horizontal">
+
+                <TextView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    style="@style/TextAppearance.TaskbarEdu.Title"
+                    android:text="@string/taskbar_edu_switch_apps"/>
+
+                <ImageView
+                    android:layout_width="322dp"
+                    android:layout_height="282dp"
+                    android:layout_marginTop="16dp"
+                    android:src="@drawable/taskbar_edu_switch_apps"/>
+            </LinearLayout>
+
+            <LinearLayout
                 android:id="@+id/page_splitscreen"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
@@ -52,14 +72,8 @@
                 <TextView
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
-                    android:layout_marginHorizontal="16dp"
-                    android:gravity="center_horizontal"
-                    style="@style/TextHeadline"
-                    android:text="@string/taskbar_edu_splitscreen"
-                    android:fontFamily="google-sans"
-                    android:textColor="?android:attr/textColorPrimary"
-                    android:textSize="24sp"
-                    android:maxLines="2"/>
+                    style="@style/TextAppearance.TaskbarEdu.Title"
+                    android:text="@string/taskbar_edu_splitscreen"/>
 
                 <ImageView
                     android:layout_width="322dp"
@@ -69,7 +83,7 @@
             </LinearLayout>
 
             <LinearLayout
-                android:id="@+id/page_customize"
+                android:id="@+id/page_stashing"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:orientation="vertical"
@@ -78,46 +92,14 @@
                 <TextView
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
-                    android:layout_marginHorizontal="16dp"
-                    android:gravity="center_horizontal"
-                    style="@style/TextHeadline"
-                    android:text="@string/taskbar_edu_customize"
-                    android:fontFamily="google-sans"
-                    android:textColor="?android:attr/textColorPrimary"
-                    android:textSize="24sp"
-                    android:maxLines="2"/>
+                    style="@style/TextAppearance.TaskbarEdu.Title"
+                    android:text="@string/taskbar_edu_stashing"/>
 
                 <ImageView
                     android:layout_width="322dp"
                     android:layout_height="282dp"
                     android:layout_marginTop="16dp"
-                    android:src="@drawable/taskbar_edu_splitscreen"/>
-            </LinearLayout>
-
-            <LinearLayout
-                android:id="@+id/page_dock"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:orientation="vertical"
-                android:gravity="center_horizontal">
-
-                <TextView
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:layout_marginHorizontal="16dp"
-                    android:gravity="center_horizontal"
-                    style="@style/TextHeadline"
-                    android:text="@string/taskbar_edu_dock"
-                    android:fontFamily="google-sans"
-                    android:textColor="?android:attr/textColorPrimary"
-                    android:textSize="24sp"
-                    android:maxLines="2"/>
-
-                <ImageView
-                    android:layout_width="322dp"
-                    android:layout_height="282dp"
-                    android:layout_marginTop="16dp"
-                    android:src="@drawable/taskbar_edu_splitscreen"/>
+                    android:src="@drawable/taskbar_edu_stashing"/>
             </LinearLayout>
         </com.android.launcher3.taskbar.TaskbarEduPagedView>
 
@@ -126,6 +108,7 @@
             android:layout_width="wrap_content"
             android:layout_height="36dp"
             android:layout_marginBottom="92dp"
+            android:layout_marginTop="32dp"
             app:layout_constraintTop_toBottomOf="@id/content"
             app:layout_constraintBottom_toBottomOf="parent"
             app:layout_constraintStart_toStartOf="parent"
@@ -146,10 +129,9 @@
         <Button
             android:id="@+id/edu_end_button"
             android:layout_width="wrap_content"
-            android:layout_height="36dp"
-            android:layout_marginBottom="92dp"
-            app:layout_constraintTop_toBottomOf="@id/content"
-            app:layout_constraintBottom_toBottomOf="parent"
+            android:layout_height="0dp"
+            app:layout_constraintTop_toTopOf="@id/edu_start_button"
+            app:layout_constraintBottom_toBottomOf="@id/edu_start_button"
             app:layout_constraintEnd_toEndOf="parent"
             android:text="@string/taskbar_edu_next"
             style="@style/TaskbarEdu.Button.Next"
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index f1f23c4..1ec5bb8 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -166,5 +166,6 @@
     <dimen name="taskbar_stashed_size">24dp</dimen>
     <dimen name="taskbar_stashed_handle_width">220dp</dimen>
     <dimen name="taskbar_stashed_handle_height">6dp</dimen>
-    <dimen name="taskbar_edu_bg_corner_radius">28dp</dimen>
+    <dimen name="taskbar_edu_wave_anim_trans_y">25dp</dimen>
+    <dimen name="taskbar_edu_wave_anim_trans_y_return_overshoot">4dp</dimen>
 </resources>
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index 2916121..7158287 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -191,6 +191,8 @@
     <string name="action_share">Share</string>
     <!-- Label for a button that causes a screen shot of the current app to be taken. [CHAR_LIMIT=40] -->
     <string name="action_screenshot">Screenshot</string>
+    <!-- Label for a button that enters split screen selection mode. [CHAR_LIMIT=20] -->
+    <string name="action_split">Split</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>
 
@@ -209,15 +211,15 @@
     <string name="taskbar_edu_opened">Taskbar education appeared</string>
     <!-- Accessibility text spoken when the taskbar education panel disappears [CHAR_LIMIT=NONE] -->
     <string name="taskbar_edu_closed">Taskbar education closed</string>
-    <!-- Text in dialog that lets a user know how they can use the taskbar to use multiple apps on their device.
+    <!-- Text in dialog that lets a user know how they can use the taskbar to switch apps on their device.
          [CHAR_LIMIT=60] -->
-    <string name="taskbar_edu_splitscreen" translatable="false">Use 2 apps at once and switch apps with the taskbar</string>
-    <!-- Text in dialog that lets a user know how they can customize the taskbar on their device.
+    <string name="taskbar_edu_switch_apps" translatable="false">Use the taskbar to switch apps</string>
+    <!-- Text in dialog that lets a user know how they can use the taskbar to use multiple apps at once on their device.
          [CHAR_LIMIT=60] -->
-    <string name="taskbar_edu_customize" translatable="false">Add your favorite apps and get automatic suggestions</string>
+    <string name="taskbar_edu_splitscreen" translatable="false">Drag to the side to use two apps at once</string>
     <!-- Text in dialog that lets a user know how they can hide the taskbar on their device.
          [CHAR_LIMIT=60] -->
-    <string name="taskbar_edu_dock">Touch &amp; hold to hide the taskbar anytime</string>
+    <string name="taskbar_edu_stashing">Touch &amp; hold to hide the taskbar</string>
     <!-- Text on button to go to the next screen of a tutorial [CHAR_LIMIT=16] -->
     <string name="taskbar_edu_next">Next</string>
     <!-- Text on button to go to the previous screen of a tutorial [CHAR_LIMIT=16] -->
diff --git a/quickstep/res/values/styles.xml b/quickstep/res/values/styles.xml
index ac70279..b5444b5 100644
--- a/quickstep/res/values/styles.xml
+++ b/quickstep/res/values/styles.xml
@@ -135,6 +135,13 @@
         <item name="android:textAllCaps">false</item>
     </style>
 
+    <style name="OverviewClearAllButton" parent="@android:style/Widget.DeviceDefault.Button">
+        <item name="android:background">@drawable/bg_overview_clear_all_button</item>
+        <item name="android:minWidth">85dp</item>
+        <item name="android:minHeight">36dp</item>
+        <item name="android:stateListAnimator">@null</item>
+    </style>
+
     <!-- Icon displayed on the taskbar -->
     <style name="BaseIcon.Workspace.Taskbar" >
         <item name="iconDisplay">taskbar</item>
@@ -153,4 +160,14 @@
         <item name="android:textSize">16sp</item>
         <item name="android:padding">4dp</item>
     </style>
+
+    <style name="TextAppearance.TaskbarEdu.Title"
+        parent="@android:style/TextAppearance.DeviceDefault.DialogWindowTitle" >
+        <item name="android:layout_marginHorizontal">16dp</item>
+        <item name="android:gravity">center_horizontal</item>
+        <item name="android:fontFamily">google-sans</item>
+        <item name="android:textColor">?android:attr/textColorPrimary</item>
+        <item name="android:textSize">24sp</item>
+        <item name="android:lines">2</item>
+    </style>
 </resources>
\ No newline at end of file
diff --git a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
index b40a1d5..13baf56 100644
--- a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
+++ b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
@@ -200,6 +200,7 @@
         }
 
         int predictionIndex = 0;
+        int numViewsAnimated = 0;
         ArrayList<WorkspaceItemInfo> newItems = new ArrayList<>();
         // make sure predicted icon removal and filling predictions don't step on each other
         if (mIconRemoveAnimators != null && mIconRemoveAnimators.isRunning()) {
@@ -233,7 +234,11 @@
                     (WorkspaceItemInfo) mPredictedItems.get(predictionIndex++);
             if (isPredictedIcon(child) && child.isEnabled()) {
                 PredictedAppIcon icon = (PredictedAppIcon) child;
-                icon.applyFromWorkspaceItem(predictedItem);
+                boolean animateIconChange = icon.shouldAnimateIconChange(predictedItem);
+                icon.applyFromWorkspaceItem(predictedItem, animateIconChange, numViewsAnimated);
+                if (animateIconChange) {
+                    numViewsAnimated++;
+                }
                 icon.finishBinding(mPredictionLongClickListener);
             } else {
                 newItems.add(predictedItem);
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index da10bfb..acabb0d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -34,6 +34,7 @@
 import com.android.launcher3.R;
 import com.android.launcher3.anim.AnimatorListeners;
 import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.model.data.ItemInfoWithIcon;
 import com.android.launcher3.util.MultiValueAlpha;
 import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
 import com.android.launcher3.util.OnboardingPrefs;
@@ -45,6 +46,9 @@
 import com.android.quickstep.views.RecentsView;
 import com.android.systemui.shared.recents.model.ThumbnailData;
 
+import java.util.Arrays;
+import java.util.stream.Stream;
+
 /**
  * A data source which integrates with a Launcher instance
  */
@@ -268,6 +272,11 @@
         mTaskbarOverrideBackgroundAlpha.updateValue(forceHide ? 0 : 1);
     }
 
+    @Override
+    public Stream<ItemInfoWithIcon> getAppIconsForEdu() {
+        return Arrays.stream(mLauncher.getAppsView().getAppsStore().getApps());
+    }
+
     /**
      * Starts the taskbar education flow, if the user hasn't seen it yet.
      */
diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
index e871c25..be9368f 100644
--- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
@@ -261,6 +261,13 @@
     }
 
     /**
+     * Returns true if the recents (overview) button is disabled
+     */
+    public boolean isRecentsDisabled() {
+        return (mState & FLAG_DISABLE_RECENTS) != 0;
+    }
+
+    /**
      * Adds the bounds corresponding to all visible buttons to provided region
      */
     public void addVisibleButtonsRegion(TaskbarDragLayer parent, Region outRegion) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 8d7a6dc..8c12567 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -236,6 +236,8 @@
                 systemUiStateFlags, forceUpdate);
         mControllers.taskbarViewController.setImeIsVisible(
                 mControllers.navbarButtonsViewController.isImeVisible());
+        mControllers.taskbarViewController.setRecentsButtonDisabled(
+                mControllers.navbarButtonsViewController.isRecentsDisabled());
         mControllers.taskbarKeyguardController.updateStateForSysuiFlags(systemUiStateFlags);
     }
 
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
index b32a41e..1197543 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
@@ -78,6 +78,7 @@
         taskbarKeyguardController.init(navbarButtonsViewController);
         stashedHandleViewController.init(this);
         taskbarStashController.init(this);
+        taskbarEduController.init(this);
     }
 
     /**
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java
index ae9592d..fd5c2ea 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java
@@ -15,16 +15,72 @@
  */
 package com.android.launcher3.taskbar;
 
+import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
+import static com.android.launcher3.anim.Interpolators.ACCEL_2;
+import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
+import static com.android.launcher3.anim.Interpolators.DEACCEL;
+import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.Keyframe;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.animation.TimeInterpolator;
+import android.content.res.Resources;
+import android.text.TextUtils;
+import android.view.View;
+
 import com.android.launcher3.R;
+import com.android.launcher3.icons.BitmapInfo;
+import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.uioverrides.PredictedAppIcon;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
 
 /** Handles the Taskbar Education flow. */
 public class TaskbarEduController {
 
+    private static final long WAVE_ANIM_DELAY = 250;
+    private static final long WAVE_ANIM_STAGGER = 50;
+    private static final long WAVE_ANIM_EACH_ICON_DURATION = 633;
+    private static final long WAVE_ANIM_SLOT_MACHINE_DURATION = 1085;
+    // The fraction of each icon's animation at which we reach the top point of the wave.
+    private static final float WAVE_ANIM_FRACTION_TOP = 0.4f;
+    // The fraction of each icon's animation at which we reach the bottom, before overshooting.
+    private static final float WAVE_ANIM_FRACTION_BOTTOM = 0.9f;
+    private static final TimeInterpolator WAVE_ANIM_TO_TOP_INTERPOLATOR = FAST_OUT_SLOW_IN;
+    private static final TimeInterpolator WAVE_ANIM_TO_BOTTOM_INTERPOLATOR = ACCEL_2;
+    private static final TimeInterpolator WAVE_ANIM_OVERSHOOT_INTERPOLATOR = DEACCEL;
+    private static final TimeInterpolator WAVE_ANIM_OVERSHOOT_RETURN_INTERPOLATOR = ACCEL_DEACCEL;
+    private static final float WAVE_ANIM_ICON_SCALE = 1.2f;
+    // How many icons to cycle through in the slot machine (+ the original icon at each end).
+    private static final int WAVE_ANIM_SLOT_MACHINE_NUM_ICONS = 3;
+
     private final TaskbarActivityContext mActivity;
+    private final float mWaveAnimTranslationY;
+    private final float mWaveAnimTranslationYReturnOvershoot;
+
+    // Initialized in init.
+    TaskbarControllers mControllers;
+
     private TaskbarEduView mTaskbarEduView;
+    private Animator mAnim;
 
     public TaskbarEduController(TaskbarActivityContext activity) {
         mActivity = activity;
+
+        final Resources resources = activity.getResources();
+        mWaveAnimTranslationY = resources.getDimension(R.dimen.taskbar_edu_wave_anim_trans_y);
+        mWaveAnimTranslationYReturnOvershoot = resources.getDimension(
+                R.dimen.taskbar_edu_wave_anim_trans_y_return_overshoot);
+    }
+
+    public void init(TaskbarControllers controllers) {
+        mControllers = controllers;
     }
 
     void showEdu() {
@@ -35,6 +91,7 @@
             mTaskbarEduView.init(new TaskbarEduCallbacks());
             mTaskbarEduView.addOnCloseListener(() -> mTaskbarEduView = null);
             mTaskbarEduView.show();
+            startAnim(createWaveAnim());
         });
     }
 
@@ -44,6 +101,90 @@
         }
     }
 
+    /**
+     * Starts the given animation, ending the previous animation first if it's still playing.
+     */
+    private void startAnim(Animator anim) {
+        if (mAnim != null) {
+            mAnim.end();
+        }
+        mAnim = anim;
+        mAnim.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mAnim = null;
+            }
+        });
+        mAnim.start();
+    }
+
+    /**
+     * Creates a staggered "wave" animation where each icon translates and scales up in succession.
+     */
+    private Animator createWaveAnim() {
+        AnimatorSet waveAnim = new AnimatorSet();
+        View[] icons = mControllers.taskbarViewController.getIconViews();
+        for (int i = 0; i < icons.length; i++) {
+            View icon = icons[i];
+            AnimatorSet iconAnim = new AnimatorSet();
+
+            Keyframe[] scaleKeyframes = new Keyframe[] {
+                    Keyframe.ofFloat(0, 1f),
+                    Keyframe.ofFloat(WAVE_ANIM_FRACTION_TOP, WAVE_ANIM_ICON_SCALE),
+                    Keyframe.ofFloat(WAVE_ANIM_FRACTION_BOTTOM, 1f),
+                    Keyframe.ofFloat(1f, 1f)
+            };
+            scaleKeyframes[1].setInterpolator(WAVE_ANIM_TO_TOP_INTERPOLATOR);
+            scaleKeyframes[2].setInterpolator(WAVE_ANIM_TO_BOTTOM_INTERPOLATOR);
+
+            Keyframe[] translationYKeyframes = new Keyframe[] {
+                    Keyframe.ofFloat(0, 0f),
+                    Keyframe.ofFloat(WAVE_ANIM_FRACTION_TOP, -mWaveAnimTranslationY),
+                    Keyframe.ofFloat(WAVE_ANIM_FRACTION_BOTTOM, 0f),
+                    // Half of the remaining fraction overshoots, then the other half returns to 0.
+                    Keyframe.ofFloat(
+                            WAVE_ANIM_FRACTION_BOTTOM + (1 - WAVE_ANIM_FRACTION_BOTTOM) / 2f,
+                            mWaveAnimTranslationYReturnOvershoot),
+                    Keyframe.ofFloat(1f, 0f)
+            };
+            translationYKeyframes[1].setInterpolator(WAVE_ANIM_TO_TOP_INTERPOLATOR);
+            translationYKeyframes[2].setInterpolator(WAVE_ANIM_TO_BOTTOM_INTERPOLATOR);
+            translationYKeyframes[3].setInterpolator(WAVE_ANIM_OVERSHOOT_INTERPOLATOR);
+            translationYKeyframes[4].setInterpolator(WAVE_ANIM_OVERSHOOT_RETURN_INTERPOLATOR);
+
+            iconAnim.play(ObjectAnimator.ofPropertyValuesHolder(icon,
+                    PropertyValuesHolder.ofKeyframe(SCALE_PROPERTY, scaleKeyframes))
+                    .setDuration(WAVE_ANIM_EACH_ICON_DURATION));
+            iconAnim.play(ObjectAnimator.ofPropertyValuesHolder(icon,
+                    PropertyValuesHolder.ofKeyframe(View.TRANSLATION_Y, translationYKeyframes))
+                    .setDuration(WAVE_ANIM_EACH_ICON_DURATION));
+
+            if (icon instanceof PredictedAppIcon) {
+                // Play slot machine animation through random icons from AllAppsList.
+                PredictedAppIcon predictedAppIcon = (PredictedAppIcon) icon;
+                ItemInfo itemInfo = (ItemInfo) icon.getTag();
+                List<BitmapInfo> iconsToAnimate = mControllers.uiController.getAppIconsForEdu()
+                        .filter(appInfo -> !TextUtils.equals(appInfo.title, itemInfo.title))
+                        .map(appInfo -> appInfo.bitmap)
+                        .filter(bitmap -> !bitmap.isNullOrLowRes())
+                        .collect(Collectors.toList());
+                // Pick n icons at random.
+                Collections.shuffle(iconsToAnimate);
+                if (iconsToAnimate.size() > WAVE_ANIM_SLOT_MACHINE_NUM_ICONS) {
+                    iconsToAnimate = iconsToAnimate.subList(0, WAVE_ANIM_SLOT_MACHINE_NUM_ICONS);
+                }
+                Animator slotMachineAnim = predictedAppIcon.createSlotMachineAnim(iconsToAnimate);
+                if (slotMachineAnim != null) {
+                    iconAnim.play(slotMachineAnim.setDuration(WAVE_ANIM_SLOT_MACHINE_DURATION));
+                }
+            }
+
+            iconAnim.setStartDelay(WAVE_ANIM_STAGGER * i);
+            waveAnim.play(iconAnim);
+        }
+        waveAnim.setStartDelay(WAVE_ANIM_DELAY);
+        return waveAnim;
+    }
 
     /**
      * Callbacks for {@link TaskbarEduView} to interact with its controller.
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduView.java
index 9c4e844..8525427 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduView.java
@@ -15,7 +15,7 @@
  */
 package com.android.launcher3.taskbar;
 
-import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
+import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE;
 
 import android.animation.PropertyValuesHolder;
 import android.content.Context;
@@ -33,6 +33,7 @@
 public class TaskbarEduView extends AbstractSlideInView<TaskbarActivityContext>
         implements Insettable {
 
+    private static final int DEFAULT_OPEN_DURATION = 500;
     private static final int DEFAULT_CLOSE_DURATION = 200;
 
     private final Rect mInsets = new Rect();
@@ -129,8 +130,8 @@
         mIsOpen = true;
         mOpenCloseAnimator.setValues(
                 PropertyValuesHolder.ofFloat(TRANSLATION_SHIFT, TRANSLATION_SHIFT_OPENED));
-        mOpenCloseAnimator.setInterpolator(FAST_OUT_SLOW_IN);
-        mOpenCloseAnimator.start();
+        mOpenCloseAnimator.setInterpolator(AGGRESSIVE_EASE);
+        mOpenCloseAnimator.setDuration(DEFAULT_OPEN_DURATION).start();
     }
 
     void snapToPage(int page) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
index df88e02..c0312a0 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
@@ -17,6 +17,10 @@
 
 import android.graphics.Rect;
 
+import com.android.launcher3.model.data.ItemInfoWithIcon;
+
+import java.util.stream.Stream;
+
 /**
  * Base class for providing different taskbar UI
  */
@@ -35,4 +39,8 @@
     protected void updateContentInsets(Rect outContentInsets) { }
 
     protected void onStashedInAppChanged() { }
+
+    public Stream<ItemInfoWithIcon> getAppIconsForEdu() {
+        return Stream.empty();
+    }
 }
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
index a4a92f7..5144d9a 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
@@ -90,6 +90,9 @@
         // We layout the icons to be of mIconTouchSize in width and height
         mItemMarginLeftRight = actualMargin - (mIconTouchSize - actualIconSize) / 2;
         mItemPadding = (mIconTouchSize - actualIconSize) / 2;
+
+        // Needed to draw folder leave-behind when opening one.
+        setWillNotDraw(false);
     }
 
     protected void init(TaskbarViewController.TaskbarViewCallbacks callbacks) {
@@ -115,6 +118,7 @@
      */
     protected void updateHotseatItems(ItemInfo[] hotseatItemInfos) {
         int nextViewIndex = 0;
+        int numViewsAnimated = 0;
 
         for (int i = 0; i < hotseatItemInfos.length; i++) {
             ItemInfo hotseatItemInfo = hotseatItemInfos[i];
@@ -170,8 +174,14 @@
             // Apply the Hotseat ItemInfos, or hide the view if there is none for a given index.
             if (hotseatView instanceof BubbleTextView
                     && hotseatItemInfo instanceof WorkspaceItemInfo) {
-                ((BubbleTextView) hotseatView).applyFromWorkspaceItem(
-                        (WorkspaceItemInfo) hotseatItemInfo);
+                BubbleTextView btv = (BubbleTextView) hotseatView;
+                WorkspaceItemInfo workspaceInfo = (WorkspaceItemInfo) hotseatItemInfo;
+
+                boolean animate = btv.shouldAnimateIconChange((WorkspaceItemInfo) hotseatItemInfo);
+                btv.applyFromWorkspaceItem(workspaceInfo, animate, numViewsAnimated);
+                if (animate) {
+                    numViewsAnimated++;
+                }
             }
             setClickAndLongClickListenersForIcon(hotseatView);
             nextViewIndex++;
@@ -256,6 +266,18 @@
         return mIconLayoutBounds;
     }
 
+    /**
+     * Returns the app icons currently shown in the taskbar.
+     */
+    public View[] getIconViews() {
+        final int count = getChildCount();
+        View[] icons = new View[count];
+        for (int i = 0; i < count; i++) {
+            icons[i] = getChildAt(i);
+        }
+        return icons;
+    }
+
     // FolderIconParent implemented methods.
 
     @Override
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
index 1882762..40b0e18 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
@@ -44,6 +44,8 @@
     public static final int ALPHA_INDEX_IME = 1;
     public static final int ALPHA_INDEX_KEYGUARD = 2;
     public static final int ALPHA_INDEX_STASH = 3;
+    public static final int ALPHA_INDEX_RECENTS_DISABLED = 4;
+    private static final int NUM_ALPHA_CHANNELS = 5;
 
     private final TaskbarActivityContext mActivity;
     private final TaskbarView mTaskbarView;
@@ -67,7 +69,7 @@
     public TaskbarViewController(TaskbarActivityContext activity, TaskbarView taskbarView) {
         mActivity = activity;
         mTaskbarView = taskbarView;
-        mTaskbarIconAlpha = new MultiValueAlpha(mTaskbarView, 4);
+        mTaskbarIconAlpha = new MultiValueAlpha(mTaskbarView, NUM_ALPHA_CHANNELS);
         mTaskbarIconAlpha.setUpdateVisibility(true);
         mModelCallbacks = new TaskbarModelCallbacks(activity, mTaskbarView);
     }
@@ -101,6 +103,14 @@
     }
 
     /**
+     * Should be called when the recents button is disabled, so we can hide taskbar icons as well.
+     */
+    public void setRecentsButtonDisabled(boolean isDisabled) {
+        // TODO: check TaskbarStashController#supportsStashing(), to stash instead of setting alpha.
+        mTaskbarIconAlpha.getProperty(ALPHA_INDEX_RECENTS_DISABLED).setValue(isDisabled ? 0 : 1);
+    }
+
+    /**
      * Sets OnClickListener and OnLongClickListener for the given view.
      */
     public void setClickAndLongClickListenersForIcon(View icon) {
@@ -111,6 +121,10 @@
         return mTaskbarView.getIconLayoutBounds();
     }
 
+    public View[] getIconViews() {
+        return mTaskbarView.getIconViews();
+    }
+
     public AnimatedFloat getTaskbarIconScaleForStash() {
         return mTaskbarIconScaleForStash;
     }
diff --git a/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java b/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
index d839a36..ee6e8ce 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
@@ -15,6 +15,16 @@
  */
 package com.android.launcher3.uioverrides;
 
+import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
+
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.animation.ArgbEvaluator;
+import android.animation.Keyframe;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.animation.ValueAnimator;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.graphics.BlurMaskFilter;
 import android.graphics.Canvas;
@@ -23,8 +33,10 @@
 import android.graphics.Paint;
 import android.graphics.Path;
 import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
 import android.os.Process;
 import android.util.AttributeSet;
+import android.util.FloatProperty;
 import android.view.LayoutInflater;
 import android.view.ViewGroup;
 
@@ -35,6 +47,8 @@
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.R;
+import com.android.launcher3.anim.AnimatorListeners;
+import com.android.launcher3.icons.BitmapInfo;
 import com.android.launcher3.icons.GraphicsUtils;
 import com.android.launcher3.icons.IconNormalizer;
 import com.android.launcher3.icons.LauncherIcons;
@@ -45,6 +59,10 @@
 import com.android.launcher3.views.ActivityContext;
 import com.android.launcher3.views.DoubleShadowBubbleTextView;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
 /**
  * A BubbleTextView with a ring around it's drawable
  */
@@ -53,6 +71,9 @@
     private static final int RING_SHADOW_COLOR = 0x99000000;
     private static final float RING_EFFECT_RATIO = 0.095f;
 
+    private static final long ICON_CHANGE_ANIM_DURATION = 360;
+    private static final long ICON_CHANGE_ANIM_STAGGER = 50;
+
     boolean mIsDrawingDot = false;
     private final DeviceProfile mDeviceProfile;
     private final Paint mIconRingPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@@ -67,6 +88,25 @@
     private int mPlateColor;
     boolean mDrawForDrag = false;
 
+    // Used for the "slot-machine" education animation.
+    private List<Drawable> mSlotMachineIcons;
+    private Animator mSlotMachineAnim;
+    private float mSlotMachineIconTranslationY;
+
+    private static final FloatProperty<PredictedAppIcon> SLOT_MACHINE_TRANSLATION_Y =
+            new FloatProperty<PredictedAppIcon>("slotMachineTranslationY") {
+        @Override
+        public void setValue(PredictedAppIcon predictedAppIcon, float transY) {
+            predictedAppIcon.mSlotMachineIconTranslationY = transY;
+            predictedAppIcon.invalidate();
+        }
+
+        @Override
+        public Float get(PredictedAppIcon predictedAppIcon) {
+            return predictedAppIcon.mSlotMachineIconTranslationY;
+        }
+    };
+
     public PredictedAppIcon(Context context) {
         this(context, null, 0);
     }
@@ -88,15 +128,38 @@
     @Override
     public void onDraw(Canvas canvas) {
         int count = canvas.save();
+        boolean isSlotMachineAnimRunning = mSlotMachineAnim != null;
         if (!mIsPinned) {
             drawEffect(canvas);
+            if (isSlotMachineAnimRunning) {
+                // Clip to to outside of the ring during the slot machine animation.
+                canvas.clipPath(mRingPath);
+            }
             canvas.translate(getWidth() * RING_EFFECT_RATIO, getHeight() * RING_EFFECT_RATIO);
             canvas.scale(1 - 2 * RING_EFFECT_RATIO, 1 - 2 * RING_EFFECT_RATIO);
         }
-        super.onDraw(canvas);
+        if (isSlotMachineAnimRunning) {
+            drawSlotMachineIcons(canvas);
+        } else {
+            super.onDraw(canvas);
+        }
         canvas.restoreToCount(count);
     }
 
+    private void drawSlotMachineIcons(Canvas canvas) {
+        canvas.translate((getWidth() - getIconSize()) / 2f,
+                (getHeight() - getIconSize()) / 2f + mSlotMachineIconTranslationY);
+        for (Drawable icon : mSlotMachineIcons) {
+            icon.setBounds(0, 0, getIconSize(), getIconSize());
+            icon.draw(canvas);
+            canvas.translate(0, getSlotMachineIconPlusSpacingSize());
+        }
+    }
+
+    private float getSlotMachineIconPlusSpacingSize() {
+        return getIconSize() + getOutlineOffsetY();
+    }
+
     @Override
     protected void drawDotIfNecessary(Canvas canvas) {
         mIsDrawingDot = true;
@@ -109,9 +172,17 @@
     }
 
     @Override
-    public void applyFromWorkspaceItem(WorkspaceItemInfo info) {
-        super.applyFromWorkspaceItem(info);
-        mPlateColor = ColorUtils.setAlphaComponent(mDotParams.color, 200);
+    public void applyFromWorkspaceItem(WorkspaceItemInfo info, boolean animate, int staggerIndex) {
+        // Create the slot machine animation first, since it uses the current icon to start.
+        Animator slotMachineAnim = animate
+                ? createSlotMachineAnim(Collections.singletonList(info.bitmap), false)
+                : null;
+        super.applyFromWorkspaceItem(info, animate, staggerIndex);
+        int oldPlateColor = mPlateColor;
+        int newPlateColor = ColorUtils.setAlphaComponent(mDotParams.color, 200);
+        if (!animate) {
+            mPlateColor = newPlateColor;
+        }
         if (mIsPinned) {
             setContentDescription(info.contentDescription);
         } else {
@@ -119,6 +190,76 @@
                     getContext().getString(R.string.hotseat_prediction_content_description,
                             info.contentDescription));
         }
+
+        if (animate) {
+            ValueAnimator plateColorAnim = ValueAnimator.ofObject(new ArgbEvaluator(),
+                    oldPlateColor, newPlateColor);
+            plateColorAnim.addUpdateListener(valueAnimator -> {
+                mPlateColor = (int) valueAnimator.getAnimatedValue();
+                invalidate();
+            });
+            AnimatorSet changeIconAnim = new AnimatorSet();
+            if (slotMachineAnim != null) {
+                changeIconAnim.play(slotMachineAnim);
+            }
+            changeIconAnim.play(plateColorAnim);
+            changeIconAnim.setStartDelay(staggerIndex * ICON_CHANGE_ANIM_STAGGER);
+            changeIconAnim.setDuration(ICON_CHANGE_ANIM_DURATION).start();
+        }
+    }
+
+    /**
+     * Returns an Animator that translates the given icons in a "slot-machine" fashion, beginning
+     * and ending with the original icon.
+     */
+    public @Nullable Animator createSlotMachineAnim(List<BitmapInfo> iconsToAnimate) {
+        return createSlotMachineAnim(iconsToAnimate, true);
+    }
+
+    /**
+     * Returns an Animator that translates the given icons in a "slot-machine" fashion, beginning
+     * with the original icon, then cycling through the given icons, optionally ending back with
+     * the original icon.
+     * @param endWithOriginalIcon Whether we should land back on the icon we started with, rather
+     *                            than the last item in iconsToAnimate.
+     */
+    public @Nullable Animator createSlotMachineAnim(List<BitmapInfo> iconsToAnimate,
+            boolean endWithOriginalIcon) {
+        if (mIsPinned || iconsToAnimate == null || iconsToAnimate.isEmpty()) {
+            return null;
+        }
+        if (mSlotMachineAnim != null) {
+            mSlotMachineAnim.end();
+        }
+
+        // Bookend the other animating icons with the original icon on both ends.
+        mSlotMachineIcons = new ArrayList<>(iconsToAnimate.size() + 2);
+        mSlotMachineIcons.add(getIcon());
+        iconsToAnimate.stream()
+                .map(iconInfo -> iconInfo.newThemedIcon(mContext))
+                .forEach(mSlotMachineIcons::add);
+        if (endWithOriginalIcon) {
+            mSlotMachineIcons.add(getIcon());
+        }
+
+        float finalTrans = -getSlotMachineIconPlusSpacingSize() * (mSlotMachineIcons.size() - 1);
+        Keyframe[] keyframes = new Keyframe[] {
+                Keyframe.ofFloat(0f, 0f),
+                Keyframe.ofFloat(0.82f, finalTrans - getOutlineOffsetY() / 2f), // Overshoot
+                Keyframe.ofFloat(1f, finalTrans) // Ease back into the final position
+        };
+        keyframes[1].setInterpolator(ACCEL_DEACCEL);
+        keyframes[2].setInterpolator(ACCEL_DEACCEL);
+
+        mSlotMachineAnim = ObjectAnimator.ofPropertyValuesHolder(this,
+                PropertyValuesHolder.ofKeyframe(SLOT_MACHINE_TRANSLATION_Y, keyframes));
+        mSlotMachineAnim.addListener(AnimatorListeners.forEndCallback(() -> {
+            mSlotMachineIcons = null;
+            mSlotMachineAnim = null;
+            mSlotMachineIconTranslationY = 0;
+            invalidate();
+        }));
+        return mSlotMachineAnim;
     }
 
     /**
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/SplitScreenSelectState.java b/quickstep/src/com/android/launcher3/uioverrides/states/SplitScreenSelectState.java
index cbb4081..9fc0450 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/SplitScreenSelectState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/SplitScreenSelectState.java
@@ -43,8 +43,12 @@
     @Override
     public float getSplitSelectTranslation(Launcher launcher) {
         RecentsView recentsView = launcher.getOverviewPanel();
-        int splitPosition = recentsView.getSplitPlaceholder()
-                .getActiveSplitPositionOption().stagePosition;
+//<<<<<<< HEAD
+//        int splitPosition = recentsView.getSplitPlaceholder()
+//                .getActiveSplitPositionOption().stagePosition;
+//=======
+        int splitPosition = recentsView.getSplitPlaceholder().getActiveSplitStagePosition();
+//>>>>>>> f6769c8532 (Add Split button in OverviewActions)
         if (!recentsView.shouldShiftThumbnailsForSplitSelect(splitPosition)) {
             return 0f;
         }
diff --git a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
index f49c9b0..eb5c43f 100644
--- a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
@@ -218,6 +218,11 @@
             }
         }
 
+        private void enterSplitSelect() {
+            RecentsView overviewPanel = mThumbnailView.getTaskView().getRecentsView();
+            overviewPanel.initiateSplitSelect(mThumbnailView.getTaskView());
+        }
+
         /**
          * Called when the overlay is no longer used.
          */
@@ -323,6 +328,10 @@
             public void onScreenshot() {
                 endLiveTileMode(() -> saveScreenshot(mTask));
             }
+
+            public void onSplit() {
+                endLiveTileMode(TaskOverlay.this::enterSplitSelect);
+            }
         }
     }
 
@@ -336,5 +345,8 @@
 
         /** User has indicated they want to screenshot the current task. */
         void onScreenshot();
+
+        /** User wants to start split screen with current app. */
+        void onSplit();
     }
 }
diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
index 6dff857..eb77ac0 100644
--- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
@@ -32,12 +32,11 @@
 import android.view.SurfaceControl;
 import android.window.TransitionInfo;
 
-import androidx.annotation.Nullable;
-
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.InsettableFrameLayout;
 import com.android.launcher3.R;
-import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
+import com.android.launcher3.util.SplitConfigurationOptions;
+import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
 import com.android.quickstep.SystemUiProxy;
 import com.android.quickstep.TaskAnimationManager;
 import com.android.quickstep.TaskViewUtils;
@@ -57,7 +56,7 @@
     private final SystemUiProxy mSystemUiProxy;
     private TaskView mInitialTaskView;
     private TaskView mSecondTaskView;
-    private SplitPositionOption mInitialPosition;
+    private @StagePosition int mStagePosition;
     private Rect mInitialBounds;
     private final Handler mHandler;
 
@@ -69,10 +68,10 @@
     /**
      * To be called after first task selected
      */
-    public void setInitialTaskSelect(TaskView taskView, SplitPositionOption positionOption,
+    public void setInitialTaskSelect(TaskView taskView, @StagePosition int stagePosition,
             Rect initialBounds) {
         mInitialTaskView = taskView;
-        mInitialPosition = positionOption;
+        mStagePosition = stagePosition;
         mInitialBounds = initialBounds;
     }
 
@@ -83,7 +82,11 @@
         mSecondTaskView = taskView;
         // Assume initial task is for top/left part of screen
 
-        final int[] taskIds = mInitialPosition.stagePosition == STAGE_POSITION_TOP_OR_LEFT
+//<<<<<<< HEAD
+//        final int[] taskIds = mInitialPosition.stagePosition == STAGE_POSITION_TOP_OR_LEFT
+//=======
+        final int[] taskIds = mStagePosition == STAGE_POSITION_TOP_OR_LEFT
+//>>>>>>> f6769c8532 (Add Split button in OverviewActions)
                 ? new int[]{mInitialTaskView.getTask().key.id, taskView.getTask().key.id}
                 : new int[]{taskView.getTask().key.id, mInitialTaskView.getTask().key.id};
         if (TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) {
@@ -113,7 +116,11 @@
             DeviceProfile deviceProfile) {
         InsettableFrameLayout.LayoutParams params =
                 new InsettableFrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT);
-        boolean topLeftPosition = mInitialPosition.stagePosition == STAGE_POSITION_TOP_OR_LEFT;
+//<<<<<<< HEAD
+//        boolean topLeftPosition = mInitialPosition.stagePosition == STAGE_POSITION_TOP_OR_LEFT;
+//=======
+        boolean topLeftPosition = mStagePosition == STAGE_POSITION_TOP_OR_LEFT;
+//>>>>>>> f6769c8532 (Add Split button in OverviewActions)
         if (deviceProfile.isLandscape) {
             params.width = (int) resources.getDimension(R.dimen.split_placeholder_size);
             params.gravity = topLeftPosition ? Gravity.START : Gravity.END;
@@ -125,9 +132,8 @@
         return params;
     }
 
-    @Nullable
-    public SplitPositionOption getActiveSplitPositionOption() {
-        return mInitialPosition;
+    public @StagePosition int getActiveSplitStagePosition() {
+        return mStagePosition;
     }
 
     /**
@@ -189,7 +195,7 @@
     public void resetState() {
         mInitialTaskView = null;
         mSecondTaskView = null;
-        mInitialPosition = null;
+        mStagePosition = SplitConfigurationOptions.STAGE_POSITION_UNDEFINED;
         mInitialBounds = null;
     }
 
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index 6b2d19c..ddb1fca 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -245,8 +245,8 @@
 
     @Override
     public void initiateSplitSelect(TaskView taskView,
-            SplitConfigurationOptions.SplitPositionOption splitPositionOption) {
-        super.initiateSplitSelect(taskView, splitPositionOption);
+            @SplitConfigurationOptions.StagePosition int stagePosition) {
+        super.initiateSplitSelect(taskView, stagePosition);
         mActivity.getStateManager().goToState(LauncherState.OVERVIEW_SPLIT_SELECT);
     }
 
diff --git a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
index a2d2179..5d1c202 100644
--- a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
+++ b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
@@ -79,6 +79,7 @@
     private static final int INDEX_SCROLL_ALPHA = 4;
 
     private final MultiValueAlpha mMultiValueAlpha;
+    private View mSplitButton;
 
     @ActionsHiddenFlags
     private int mHiddenFlags;
@@ -110,6 +111,8 @@
         View share = findViewById(R.id.action_share);
         share.setOnClickListener(this);
         findViewById(R.id.action_screenshot).setOnClickListener(this);
+        mSplitButton = findViewById(R.id.action_split);
+        mSplitButton.setOnClickListener(this);
         if (ENABLE_OVERVIEW_SHARE.get()) {
             share.setVisibility(VISIBLE);
             findViewById(R.id.oav_three_button_space).setVisibility(VISIBLE);
@@ -135,6 +138,8 @@
             mCallbacks.onShare();
         } else if (id == R.id.action_screenshot) {
             mCallbacks.onScreenshot();
+        } else if (id == R.id.action_split) {
+            mCallbacks.onSplit();
         }
     }
 
@@ -218,6 +223,16 @@
         mDp = dp;
         updateVerticalMargin(SysUINavigationMode.getMode(getContext()));
         requestLayout();
+        setSplitButtonVisible(mDp.isTablet);
+    }
+
+    public void setSplitButtonVisible(boolean visible) {
+        if (mSplitButton == null) {
+            return;
+        }
+
+        mSplitButton.setVisibility(visible ? VISIBLE : GONE);
+        findViewById(R.id.action_split_space).setVisibility(visible ? VISIBLE : GONE);
     }
 
     /** Get the top margin associated with the action buttons in Overview. */
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 5974677..646312e 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -133,7 +133,7 @@
 import com.android.launcher3.util.ResourceBasedOverride.Overrides;
 import com.android.launcher3.util.RunnableList;
 import com.android.launcher3.util.SplitConfigurationOptions;
-import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
+import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
 import com.android.launcher3.util.Themes;
 import com.android.launcher3.util.TranslateEdgeEffect;
 import com.android.launcher3.util.ViewPool;
@@ -2572,8 +2572,8 @@
     private void createInitialSplitSelectAnimation(PendingAnimation anim) {
         float placeholderHeight = getResources().getDimension(R.dimen.split_placeholder_size);
         mOrientationHandler.getInitialSplitPlaceholderBounds((int) placeholderHeight,
-                        mActivity.getDeviceProfile(),
-                mSplitSelectStateController.getActiveSplitPositionOption(), mTempRect);
+                mActivity.getDeviceProfile(),
+                mSplitSelectStateController.getActiveSplitStagePosition(), mTempRect);
 
         RectF startingTaskRect = new RectF();
         mSplitHiddenTaskView.setVisibility(INVISIBLE);
@@ -2582,6 +2582,7 @@
         mFirstFloatingTaskView.setAlpha(1);
         mFirstFloatingTaskView.addAnimation(anim, startingTaskRect,
                 mTempRect, mSplitHiddenTaskView, true /*fadeWithThumbnail*/);
+        anim.addEndListener(aBoolean -> mActionsView.setSplitButtonVisible(false));
     }
 
     /**
@@ -3014,8 +3015,7 @@
      * @return {@code true} if one of the task thumbnails would intersect/overlap with the
      *         {@link #mFirstFloatingTaskView}
      */
-    public boolean shouldShiftThumbnailsForSplitSelect(@SplitConfigurationOptions.StagePosition
-            int stagePosition) {
+    public boolean shouldShiftThumbnailsForSplitSelect(@StagePosition int stagePosition) {
         if (!mActivity.getDeviceProfile().isTablet) {
             // Never enough space on phones
             return true;
@@ -3547,12 +3547,17 @@
         }
     }
 
-    public void initiateSplitSelect(TaskView taskView, SplitPositionOption splitPositionOption) {
+    public void initiateSplitSelect(TaskView taskView) {
+        int defaultSplitPosition = mOrientationHandler
+                .getDefaultSplitPosition(mActivity.getDeviceProfile());
+        initiateSplitSelect(taskView, defaultSplitPosition);
+    }
+
+    public void initiateSplitSelect(TaskView taskView, @StagePosition int stagePosition) {
         mSplitHiddenTaskView = taskView;
         Rect initialBounds = new Rect(taskView.getLeft(), taskView.getTop(), taskView.getRight(),
                 taskView.getBottom());
-        mSplitSelectStateController.setInitialTaskSelect(taskView,
-                splitPositionOption, initialBounds);
+        mSplitSelectStateController.setInitialTaskSelect(taskView, stagePosition, initialBounds);
         mSplitHiddenTaskViewIndex = indexOfChild(taskView);
         if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
             finishRecentsAnimation(true, null);
@@ -3578,7 +3583,7 @@
                 .getDimensionPixelSize(R.dimen.multi_window_task_divider_size) / 2;
         mOrientationHandler.getFinalSplitPlaceholderBounds(halfDividerSize,
                 mActivity.getDeviceProfile(),
-                mSplitSelectStateController.getActiveSplitPositionOption(), firstTaskEndingBounds,
+                mSplitSelectStateController.getActiveSplitStagePosition(), firstTaskEndingBounds,
                 secondTaskEndingBounds);
 
         mFirstFloatingTaskView.getBoundsOnScreen(firstTaskStartingBounds);
@@ -3603,7 +3608,7 @@
 
     public PendingAnimation cancelSplitSelect(boolean animate) {
         SplitSelectStateController splitController = mSplitSelectStateController;
-        SplitPositionOption splitOption = splitController.getActiveSplitPositionOption();
+        @StagePosition int stagePosition = splitController.getActiveSplitStagePosition();
         Rect initialBounds = splitController.getInitialBounds();
         splitController.resetState();
         int duration = mActivity.getStateManager().getState().getTransitionDuration(getContext());
@@ -3629,7 +3634,7 @@
             if (child == mSplitHiddenTaskView) {
                 TaskView taskView = (TaskView) child;
 
-                int dir = mOrientationHandler.getSplitTaskViewDismissDirection(splitOption,
+                int dir = mOrientationHandler.getSplitTaskViewDismissDirection(stagePosition,
                         mActivity.getDeviceProfile());
                 FloatProperty<TaskView> dismissingTaskViewTranslate;
                 Rect hiddenBounds = new Rect(taskView.getLeft(), taskView.getTop(),
@@ -3701,10 +3706,10 @@
         return pendingAnim;
     }
 
+    /** TODO(b/181707736) More gracefully handle exiting split selection state */
     private void resetFromSplitSelectionState() {
         mSplitHiddenTaskView.setTranslationY(0);
         if (!showAsGrid()) {
-            // TODO(b/186800707)
             int pageToSnapTo = mCurrentPage;
             if (mSplitHiddenTaskViewIndex <= pageToSnapTo) {
                 pageToSnapTo += 1;
@@ -3728,6 +3733,7 @@
             mSecondSplitHiddenTaskView.setVisibility(VISIBLE);
             mSecondSplitHiddenTaskView = null;
         }
+        mActionsView.setSplitButtonVisible(true);
     }
 
     private void updateDeadZoneRects() {
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 5986649..bfe6ca4 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -1514,7 +1514,7 @@
 
     public void initiateSplitSelect(SplitPositionOption splitPositionOption) {
         AbstractFloatingView.closeOpenViews(mActivity, false, TYPE_TASK_MENU);
-        getRecentsView().initiateSplitSelect(this, splitPositionOption);
+        getRecentsView().initiateSplitSelect(this, splitPositionOption.stagePosition);
     }
 
     /**
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 353e52b..02ec5e8 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -256,9 +256,27 @@
 
     @UiThread
     public void applyFromWorkspaceItem(WorkspaceItemInfo info) {
+        applyFromWorkspaceItem(info, /* animate = */ false, /* staggerIndex = */ 0);
+    }
+
+    @UiThread
+    public void applyFromWorkspaceItem(WorkspaceItemInfo info, boolean animate, int staggerIndex) {
         applyFromWorkspaceItem(info, false);
     }
 
+    /**
+     * Returns whether the newInfo differs from the current getTag().
+     */
+    public boolean shouldAnimateIconChange(WorkspaceItemInfo newInfo) {
+        WorkspaceItemInfo oldInfo = getTag() instanceof WorkspaceItemInfo
+                ? (WorkspaceItemInfo) getTag()
+                : null;
+        boolean changedIcons = oldInfo != null && oldInfo.getTargetComponent() != null
+                && newInfo.getTargetComponent() != null
+                && !oldInfo.getTargetComponent().equals(newInfo.getTargetComponent());
+        return changedIcons && isShown();
+    }
+
     @Override
     public void setAccessibilityDelegate(AccessibilityDelegate delegate) {
         if (delegate instanceof LauncherAccessibilityDelegate) {
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index d2c71b2..f420ec2 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -499,8 +499,10 @@
 
     private void replaceRVContainer(boolean showTabs) {
         for (int i = 0; i < mAH.length; i++) {
-            if (mAH[i].recyclerView != null) {
-                mAH[i].recyclerView.setLayoutManager(null);
+            AllAppsRecyclerView rv = mAH[i].recyclerView;
+            if (rv != null) {
+                rv.setLayoutManager(null);
+                rv.setAdapter(null);
             }
         }
         View oldView = getRecyclerViewContainer();
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index 2c84a3d..bddbbd0 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -63,6 +63,13 @@
     private final SparseIntArray mCachedScrollPositions = new SparseIntArray();
     private final AllAppsFastScrollHelper mFastScrollHelper;
 
+
+    private final AdapterDataObserver mObserver = new RecyclerView.AdapterDataObserver() {
+        public void onChanged() {
+            mCachedScrollPositions.clear();
+        }
+    };
+
     // The empty-search result background
     private AllAppsBackgroundDrawable mEmptySearchBackground;
     private int mEmptySearchBackgroundTopOffset;
@@ -247,12 +254,13 @@
 
     @Override
     public void setAdapter(Adapter adapter) {
+        if (getAdapter() != null) {
+            getAdapter().unregisterAdapterDataObserver(mObserver);
+        }
         super.setAdapter(adapter);
-        adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
-            public void onChanged() {
-                mCachedScrollPositions.clear();
-            }
-        });
+        if (adapter != null) {
+            adapter.registerAdapterDataObserver(mObserver);
+        }
     }
 
     @Override
diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
index 29e5446..17a00e2 100644
--- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
@@ -45,6 +45,7 @@
 import com.android.launcher3.Utilities;
 import com.android.launcher3.util.SplitConfigurationOptions;
 import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
+import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
 import com.android.launcher3.views.BaseDragLayer;
 
 import java.util.Collections;
@@ -165,16 +166,24 @@
     }
 
     @Override
-    public int getSplitTaskViewDismissDirection(SplitPositionOption splitPosition,
+    public int getSplitTaskViewDismissDirection(@StagePosition int stagePosition,
             DeviceProfile dp) {
         // Don't use device profile here because we know we're in fake landscape, only split option
         // available is top/left
-        if (splitPosition.stagePosition == STAGE_POSITION_TOP_OR_LEFT) {
+//<<<<<<< HEAD
+//        if (splitPosition.stagePosition == STAGE_POSITION_TOP_OR_LEFT) {
+//            // Top (visually left) side
+//            return SPLIT_TRANSLATE_PRIMARY_NEGATIVE;
+//        }
+//        throw new IllegalStateException("Invalid split stage position: " +
+//                splitPosition.stagePosition);
+//=======
+        if (stagePosition == STAGE_POSITION_TOP_OR_LEFT) {
             // Top (visually left) side
             return SPLIT_TRANSLATE_PRIMARY_NEGATIVE;
         }
-        throw new IllegalStateException("Invalid split stage position: " +
-                splitPosition.stagePosition);
+        throw new IllegalStateException("Invalid split stage position: " + stagePosition);
+//>>>>>>> f6769c8532 (Add Split button in OverviewActions)
     }
 
     @Override
@@ -367,7 +376,7 @@
 
     @Override
     public void getInitialSplitPlaceholderBounds(int placeholderHeight, DeviceProfile dp,
-            SplitPositionOption splitPositionOption, Rect out) {
+            @StagePosition int stagePosition, Rect out) {
         // In fake land/seascape, the placeholder always needs to go to the "top" of the device,
         // which is the same bounds as 0 rotation.
         int width = dp.widthPx;
@@ -376,7 +385,7 @@
 
     @Override
     public void getFinalSplitPlaceholderBounds(int splitDividerSize, DeviceProfile dp,
-            SplitPositionOption initialSplitOption, Rect out1, Rect out2) {
+            @StagePosition int stagePosition, Rect out1, Rect out2) {
         // In fake land/seascape, the window bounds are always top and bottom half
         int screenHeight = dp.heightPx;
         int screenWidth = dp.widthPx;
@@ -385,6 +394,7 @@
     }
 
     @Override
+//<<<<<<< HEAD
     public void setSplitTaskSwipeRect(DeviceProfile dp, Rect outRect,
             SplitConfigurationOptions.StagedSplitBounds splitInfo, int desiredStagePosition) {
         float diff;
@@ -418,13 +428,20 @@
         ViewGroup.LayoutParams secondaryLp = mSnapshotView2.getLayoutParams();
 
         primaryLp.width = totalThumbnailWidth;
-        primaryLp.height = (int)(totalThumbnailHeight * splitBoundsConfig.leftTaskPercent);
+        primaryLp.height = (int) (totalThumbnailHeight * splitBoundsConfig.leftTaskPercent);
 
         secondaryLp.width = totalThumbnailWidth;
         secondaryLp.height = totalThumbnailHeight - primaryLp.height - dividerBar;
         mSnapshotView2.setTranslationY(primaryLp.height + spaceAboveSnapshot + dividerBar);
     }
 
+//=======
+    @Override
+    public int getDefaultSplitPosition(DeviceProfile deviceProfile) {
+        throw new IllegalStateException("Default position not available in fake landscape");
+//>>>>>>> f6769c8532 (Add Split button in OverviewActions)
+    }
+
     @Override
     public FloatProperty getSplitSelectTaskOffset(FloatProperty primary, FloatProperty secondary,
             DeviceProfile deviceProfile) {
diff --git a/src/com/android/launcher3/touch/PagedOrientationHandler.java b/src/com/android/launcher3/touch/PagedOrientationHandler.java
index 5ef6950..b34a81e 100644
--- a/src/com/android/launcher3/touch/PagedOrientationHandler.java
+++ b/src/com/android/launcher3/touch/PagedOrientationHandler.java
@@ -80,11 +80,11 @@
     FloatProperty<View> getSecondaryViewTranslate();
 
     /**
-     * @param splitPosition The position where the view to be split will go
+     * @param stagePosition The position where the view to be split will go
      * @return {@link #SPLIT_TRANSLATE_*} constants to indicate which direction the
      * dismissal should happen
      */
-    int getSplitTaskViewDismissDirection(SplitPositionOption splitPosition, DeviceProfile dp);
+    int getSplitTaskViewDismissDirection(@StagePosition int stagePosition, DeviceProfile dp);
     int getPrimaryScroll(View view);
     float getPrimaryScale(View view);
     int getChildStart(View view);
@@ -122,18 +122,20 @@
      * @param splitholderSize height of placeholder view in portrait, width in landscape
      */
     void getInitialSplitPlaceholderBounds(int splitholderSize, DeviceProfile dp,
-            SplitPositionOption splitPositionOption, Rect out);
+            @StagePosition int stagePosition, Rect out);
 
     /**
      * @param splitDividerSize height of split screen drag handle in portrait, width in landscape
-     * @param initialSplitOption the split position option (top/left, bottom/right) of the first
+     * @param stagePosition the split position option (top/left, bottom/right) of the first
      *                           task selected for entering split
      * @param out1 the bounds for where the first selected app will be
      * @param out2 the bounds for where the second selected app will be, complimentary to
      *             {@param out1} based on {@param initialSplitOption}
      */
     void getFinalSplitPlaceholderBounds(int splitDividerSize, DeviceProfile dp,
-            SplitPositionOption initialSplitOption, Rect out1, Rect out2);
+            @StagePosition int stagePosition, Rect out1, Rect out2);
+
+    int getDefaultSplitPosition(DeviceProfile deviceProfile);
 
     /**
      * @param outRect This is expected to be the rect that has the dimensions for a non-split,
diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
index 737162f..640e6cc 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -44,6 +44,7 @@
 import com.android.launcher3.Utilities;
 import com.android.launcher3.util.SplitConfigurationOptions;
 import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
+import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
 import com.android.launcher3.views.BaseDragLayer;
 
 import java.util.ArrayList;
@@ -165,9 +166,13 @@
     }
 
     @Override
-    public int getSplitTaskViewDismissDirection(SplitPositionOption splitPosition,
+    public int getSplitTaskViewDismissDirection(@StagePosition int stagePosition,
             DeviceProfile dp) {
-        if (splitPosition.stagePosition == STAGE_POSITION_TOP_OR_LEFT) {
+//<<<<<<< HEAD
+//        if (splitPosition.stagePosition == STAGE_POSITION_TOP_OR_LEFT) {
+//=======
+        if (stagePosition == STAGE_POSITION_TOP_OR_LEFT) {
+//>>>>>>> f6769c8532 (Add Split button in OverviewActions)
             if (dp.isLandscape) {
                 // Left side
                 return SPLIT_TRANSLATE_PRIMARY_NEGATIVE;
@@ -175,12 +180,20 @@
                 // Top side
                 return SPLIT_TRANSLATE_SECONDARY_NEGATIVE;
             }
-        } else if (splitPosition.stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) {
+//<<<<<<< HEAD
+//        } else if (splitPosition.stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) {
+             // We don't have a bottom option, so should be right
+//            return SPLIT_TRANSLATE_PRIMARY_POSITIVE;
+//        }
+//        throw new IllegalStateException("Invalid split stage position: " +
+//                splitPosition.stagePosition);
+//=======
+        } else if (stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) {
             // We don't have a bottom option, so should be right
             return SPLIT_TRANSLATE_PRIMARY_POSITIVE;
         }
-        throw new IllegalStateException("Invalid split stage position: " +
-                splitPosition.stagePosition);
+        throw new IllegalStateException("Invalid split stage position: " + stagePosition);
+//>>>>>>> f6769c8532 (Add Split button in OverviewActions)
     }
 
     @Override
@@ -416,7 +429,7 @@
 
     @Override
     public void getInitialSplitPlaceholderBounds(int placeholderHeight, DeviceProfile dp,
-            SplitPositionOption splitPositionOption, Rect out) {
+            @StagePosition int stagePosition, Rect out) {
         int width = dp.widthPx;
         out.set(0, 0, width, placeholderHeight);
         if (!dp.isLandscape) {
@@ -425,7 +438,11 @@
         }
 
         // Now we rotate the portrait rect depending on what side we want pinned
-        boolean pinToRight = splitPositionOption.stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT;
+//<<<<<<< HEAD
+//        boolean pinToRight = splitPositionOption.stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT;
+//=======
+        boolean pinToRight = stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT;
+//>>>>>>> f6769c8532 (Add Split button in OverviewActions)
 
         int screenHeight = dp.heightPx;
         float postRotateScale = (float) screenHeight / width;
@@ -442,7 +459,7 @@
 
     @Override
     public void getFinalSplitPlaceholderBounds(int splitDividerSize, DeviceProfile dp,
-            SplitPositionOption initialSplitOption, Rect out1, Rect out2) {
+            @StagePosition int stagePosition, Rect out1, Rect out2) {
         int screenHeight = dp.heightPx;
         int screenWidth = dp.widthPx;
         out1.set(0, 0, screenWidth, screenHeight / 2 - splitDividerSize);
@@ -453,7 +470,11 @@
         }
 
         // Now we rotate the portrait rect depending on what side we want pinned
-        boolean pinToRight = initialSplitOption.stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT;
+//<<<<<<< HEAD
+//        boolean pinToRight = initialSplitOption.stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT;
+//=======
+        boolean pinToRight = stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT;
+//>>>>>>> f6769c8532 (Add Split button in OverviewActions)
         float postRotateScale = (float) screenHeight / screenWidth;
 
         mTmpMatrix.reset();
@@ -471,6 +492,7 @@
     }
 
     @Override
+//<<<<<<< HEAD
     public void setSplitTaskSwipeRect(DeviceProfile dp, Rect outRect,
             SplitConfigurationOptions.StagedSplitBounds splitInfo, int desiredStagePosition) {
         boolean isLandscape = dp.isLandscape;
@@ -524,7 +546,7 @@
 
         if (dp.isLandscape) {
             primaryLp.height = totalThumbnailHeight;
-            primaryLp.width = (int)(totalThumbnailWidth * splitBoundsConfig.leftTaskPercent);
+            primaryLp.width = (int) (totalThumbnailWidth * splitBoundsConfig.leftTaskPercent);
 
             secondaryLp.height = totalThumbnailHeight;
             secondaryLp.width = totalThumbnailWidth - primaryLp.width - dividerBar;
@@ -532,7 +554,7 @@
             mSnapshotView2.setTranslationY(spaceAboveSnapshot);
         } else {
             primaryLp.width = totalThumbnailWidth;
-            primaryLp.height = (int)(totalThumbnailHeight * splitBoundsConfig.topTaskPercent);
+            primaryLp.height = (int) (totalThumbnailHeight * splitBoundsConfig.topTaskPercent);
 
             secondaryLp.width = totalThumbnailWidth;
             secondaryLp.height = totalThumbnailHeight - primaryLp.height - dividerBar;
@@ -541,6 +563,20 @@
         }
     }
 
+//=======
+    @Override
+    public int getDefaultSplitPosition(DeviceProfile deviceProfile) {
+        if (!deviceProfile.isTablet) {
+            throw new IllegalStateException("Default position available only for large screens");
+        }
+        if (deviceProfile.isLandscape) {
+            return STAGE_POSITION_BOTTOM_OR_RIGHT;
+        } else {
+            return STAGE_POSITION_TOP_OR_LEFT;
+//>>>>>>> f6769c8532 (Add Split button in OverviewActions)
+        }
+    }
+
     @Override
     public FloatProperty getSplitSelectTaskOffset(FloatProperty primary, FloatProperty secondary,
             DeviceProfile dp) {