Merge "Prevent double touch inputs in the BaseDragLayer" into tm-qpr-dev
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
index 7b2b7ec..079e8a1 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
@@ -44,7 +44,7 @@
     /** The bottom insets taskbar provides to the IME when IME is visible. */
     val taskbarHeightForIme: Int = context.resources.getDimensionPixelSize(
         KtR.dimen.taskbar_ime_size)
-    private val contentRegion: Region = Region()
+    private val touchableRegion: Region = Region()
     private val deviceProfileChangeListener = { _: DeviceProfile ->
         onTaskbarWindowHeightOrInsetsChanged()
     }
@@ -77,10 +77,11 @@
     }
 
     fun onTaskbarWindowHeightOrInsetsChanged() {
-        var contentHeight = controllers.taskbarStashController.contentHeightToReportToApps
-        contentRegion.set(0, windowLayoutParams.height - contentHeight,
+        val touchableHeight = controllers.taskbarStashController.touchableHeight
+        touchableRegion.set(0, windowLayoutParams.height - touchableHeight,
             context.deviceProfile.widthPx, windowLayoutParams.height)
-        var tappableHeight = controllers.taskbarStashController.tappableHeightToReportToApps
+        val contentHeight = controllers.taskbarStashController.contentHeightToReportToApps
+        val tappableHeight = controllers.taskbarStashController.tappableHeightToReportToApps
         for (provider in windowLayoutParams.providedInsets) {
             if (provider.type == ITYPE_EXTRA_NAVIGATION_BAR) {
                 provider.insetsSize = Insets.of(0, 0, 0, contentHeight)
@@ -154,7 +155,7 @@
                 if (context.isTaskbarWindowFullscreen) {
                     TOUCHABLE_INSETS_FRAME
                 } else {
-                    insetsInfo.touchableRegion.set(contentRegion)
+                    insetsInfo.touchableRegion.set(touchableRegion)
                     TOUCHABLE_INSETS_REGION
                 }
             )
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index 4b0adb1..b9bcf1b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -67,7 +67,7 @@
     public static final int FLAG_STASHED_IN_APP_SETUP = 1 << 4; // setup wizard and AllSetActivity
     public static final int FLAG_STASHED_IN_APP_IME = 1 << 5; // IME is visible
     public static final int FLAG_IN_STASHED_LAUNCHER_STATE = 1 << 6;
-    public static final int FLAG_STASHED_IN_APP_ALL_APPS = 1 << 7; // All apps is visible.
+    public static final int FLAG_STASHED_IN_TASKBAR_ALL_APPS = 1 << 7; // All apps is visible.
     public static final int FLAG_IN_SETUP = 1 << 8; // In the Setup Wizard
     public static final int FLAG_STASHED_SMALL_SCREEN = 1 << 9; // phone screen gesture nav, stashed
 
@@ -77,8 +77,8 @@
     // If we're in an app and any of these flags are enabled, taskbar should be stashed.
     private static final int FLAGS_STASHED_IN_APP = FLAG_STASHED_IN_APP_MANUAL
             | FLAG_STASHED_IN_APP_PINNED | FLAG_STASHED_IN_APP_EMPTY | FLAG_STASHED_IN_APP_SETUP
-            | FLAG_STASHED_IN_APP_IME | FLAG_STASHED_IN_APP_ALL_APPS |
-            FLAG_STASHED_SMALL_SCREEN;
+            | FLAG_STASHED_IN_APP_IME | FLAG_STASHED_IN_TASKBAR_ALL_APPS
+            | FLAG_STASHED_SMALL_SCREEN;
 
     private static final int FLAGS_STASHED_IN_APP_IGNORING_IME =
             FLAGS_STASHED_IN_APP & ~FLAG_STASHED_IN_APP_IME;
@@ -88,7 +88,7 @@
     // Currently any flag that causes us to stash in an app is included, except for IME or All Apps
     // since those cover the underlying app anyway and thus the app shouldn't change insets.
     private static final int FLAGS_REPORT_STASHED_INSETS_TO_APP = FLAGS_STASHED_IN_APP
-            & ~FLAG_STASHED_IN_APP_IME & ~FLAG_STASHED_IN_APP_ALL_APPS;
+            & ~FLAG_STASHED_IN_APP_IME & ~FLAG_STASHED_IN_TASKBAR_ALL_APPS;
 
     /**
      * How long to stash/unstash when manually invoked via long press.
@@ -168,9 +168,11 @@
                 boolean inApp = hasAnyFlag(flags, FLAGS_IN_APP);
                 boolean stashedInApp = hasAnyFlag(flags, FLAGS_STASHED_IN_APP);
                 boolean stashedLauncherState = hasAnyFlag(flags, FLAG_IN_STASHED_LAUNCHER_STATE);
+                boolean stashedInTaskbarAllApps =
+                        hasAnyFlag(flags, FLAG_STASHED_IN_TASKBAR_ALL_APPS);
                 boolean stashedForSmallScreen = hasAnyFlag(flags, FLAG_STASHED_SMALL_SCREEN);
                 return (inApp && stashedInApp) || (!inApp && stashedLauncherState)
-                        || stashedForSmallScreen;
+                        || stashedInTaskbarAllApps || stashedForSmallScreen;
             });
 
     public TaskbarStashController(TaskbarActivityContext activity) {
@@ -317,6 +319,13 @@
     }
 
     /**
+     * Returns the height that taskbar will be touchable.
+     */
+    public int getTouchableHeight() {
+        return mIsStashed ? mStashedHeight : mUnstashedHeight;
+    }
+
+    /**
      * Returns the height that taskbar will inset when inside apps.
      * @see WindowInsets.Type#navigationBars()
      * @see WindowInsets.Type#systemBars()
@@ -659,7 +668,7 @@
             return;
         }
 
-        updateStateForFlag(FLAG_STASHED_IN_APP_ALL_APPS, false);
+        updateStateForFlag(FLAG_STASHED_IN_TASKBAR_ALL_APPS, false);
         if (applyState) {
             applyState(ALL_APPS.getTransitionDuration(
                     mControllers.taskbarActivityContext, false /* isToState */));
@@ -779,7 +788,7 @@
         appendFlag(str, flags, FLAG_STASHED_IN_APP_SETUP, "FLAG_STASHED_IN_APP_SETUP");
         appendFlag(str, flags, FLAG_STASHED_IN_APP_IME, "FLAG_STASHED_IN_APP_IME");
         appendFlag(str, flags, FLAG_IN_STASHED_LAUNCHER_STATE, "FLAG_IN_STASHED_LAUNCHER_STATE");
-        appendFlag(str, flags, FLAG_STASHED_IN_APP_ALL_APPS, "FLAG_STASHED_IN_APP_ALL_APPS");
+        appendFlag(str, flags, FLAG_STASHED_IN_TASKBAR_ALL_APPS, "FLAG_STASHED_IN_APP_ALL_APPS");
         appendFlag(str, flags, FLAG_IN_SETUP, "FLAG_IN_SETUP");
         return str.toString();
     }
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
index b0d3528..128fa5e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
@@ -16,7 +16,7 @@
 package com.android.launcher3.taskbar.allapps;
 
 import static com.android.launcher3.LauncherState.ALL_APPS;
-import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_STASHED_IN_APP_ALL_APPS;
+import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_STASHED_IN_TASKBAR_ALL_APPS;
 import static com.android.launcher3.util.OnboardingPrefs.ALL_APPS_VISITED_COUNT;
 
 import com.android.launcher3.AbstractFloatingView;
@@ -84,7 +84,7 @@
     }
 
     private void setUpTaskbarStashing() {
-        mTaskbarStashController.updateStateForFlag(FLAG_STASHED_IN_APP_ALL_APPS, true);
+        mTaskbarStashController.updateStateForFlag(FLAG_STASHED_IN_TASKBAR_ALL_APPS, true);
         mTaskbarStashController.applyState(
                 ALL_APPS.getTransitionDuration(mContext, true /* isToState */));
         mNavbarButtonsViewController.setSlideInViewVisible(true);
diff --git a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
index abace7c..514d5b9 100644
--- a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
+++ b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
@@ -31,6 +31,7 @@
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Insettable;
 import com.android.launcher3.R;
+import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.util.DisplayController;
 import com.android.launcher3.util.MultiValueAlpha;
 import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
@@ -258,7 +259,9 @@
         // If in 3-button mode, shift action buttons to accommodate 3-button layout.
         // (Special exception for landscape tablets, where there is enough room and we don't need to
         // shift the action buttons.)
-        if (mDp.areNavButtonsInline && !largeScreenLandscape) {
+        if (mDp.areNavButtonsInline && !largeScreenLandscape
+                // If taskbar is in overview, overview action has dedicated space above nav buttons
+                && !FeatureFlags.ENABLE_TASKBAR_IN_OVERVIEW.get()) {
             // Add extra horizontal spacing
             int additionalPadding = mDp.hotseatBarEndOffset;
             if (isLayoutRtl()) {
@@ -288,7 +291,8 @@
             return 0;
         }
 
-        if (!mDp.isGestureMode && mDp.isTaskbarPresent) {
+        if (!mDp.isGestureMode && mDp.isTaskbarPresent
+                && !FeatureFlags.ENABLE_TASKBAR_IN_OVERVIEW.get()) {
             return mDp.getOverviewActionsClaimedSpaceBelow();
         }
 
diff --git a/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java b/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java
index 27ec01a..fae96dc 100644
--- a/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java
+++ b/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java
@@ -29,6 +29,7 @@
 
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.R;
+import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.statemanager.StatefulActivity;
 import com.android.launcher3.util.DisplayController;
 
@@ -114,7 +115,9 @@
     int getThreeButtonNavShift() {
         DeviceProfile dp = mLauncher.getDeviceProfile();
         if ((DisplayController.getNavigationMode(getContext()) == THREE_BUTTONS)
-                && ((dp.isTwoPanels) || (dp.isTablet && !dp.isLandscape))) {
+                && ((dp.isTwoPanels) || (dp.isTablet && !dp.isLandscape))
+                // If taskbar is in overview, overview action has dedicated space above nav buttons
+                && !FeatureFlags.ENABLE_TASKBAR_IN_OVERVIEW.get()) {
             int navButtonWidth = getResources().getDimensionPixelSize(
                     R.dimen.taskbar_nav_buttons_size);
             int extraMargin = getResources().getDimensionPixelSize(
diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml
index eee5ae2..0a4943e 100644
--- a/res/values-as/strings.xml
+++ b/res/values-as/strings.xml
@@ -109,7 +109,7 @@
     <string name="notification_dots_title" msgid="9062440428204120317">"জাননী বিন্দু"</string>
     <string name="notification_dots_desc_on" msgid="1679848116452218908">"অন আছে"</string>
     <string name="notification_dots_desc_off" msgid="1760796511504341095">"অফ আছে"</string>
-    <string name="title_missing_notification_access" msgid="7503287056163941064">"জাননী চাবলৈ অনুমতিৰ প্ৰয়োজন"</string>
+    <string name="title_missing_notification_access" msgid="7503287056163941064">"জাননীৰ এক্সেছৰ প্ৰয়োজন"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"জাননী সম্পৰ্কীয় বিন্দুবোৰ দেখুৱাবলৈ <xliff:g id="NAME">%1$s</xliff:g>ৰ বাবে এপৰ জাননীসমূহ অন কৰক"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"ছেটিং সলনি কৰক"</string>
     <string name="notification_dots_service_title" msgid="4284221181793592871">"জাননী বিন্দু দেখুৱাওক"</string>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
index e70466f..605278f 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -58,7 +58,7 @@
     <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"విడ్జెట్ సెట్టింగ్‌లను మార్చండి"</string>
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"యాప్‌ల కోసం సెర్చ్ చేయండి"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"అప్లికేషన్‌లను లోడ్ చేస్తోంది…"</string>
-    <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\"కి సరిపోలే అప్లికేషన్‌లేవీ కనుగొనబడలేదు"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\"కి మ్యాచ్ అయ్యే అప్లికేషన్‌లేవీ కనుగొనబడలేదు"</string>
     <string name="label_application" msgid="8531721983832654978">"యాప్"</string>
     <string name="all_apps_label" msgid="5015784846527570951">"అన్ని యాప్‌లు"</string>
     <string name="notifications_header" msgid="1404149926117359025">"నోటిఫికేషన్‌లు"</string>
@@ -146,12 +146,12 @@
     <string name="create_folder_with" msgid="4050141361160214248">"ఈ పేరుతో ఫోల్డర్‌ను క్రియేట్ చేయండి: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="folder_created" msgid="6409794597405184510">"ఫోల్డర్ క్రియేట్ చేయబడింది"</string>
     <string name="action_move_to_workspace" msgid="39528912300293768">"మొదటి స్క్రీన్‌కు తరలించండి"</string>
-    <string name="action_resize" msgid="1802976324781771067">"పరిమాణం మార్చు"</string>
+    <string name="action_resize" msgid="1802976324781771067">"సైజ్‌ మార్చు"</string>
     <string name="action_increase_width" msgid="8773715375078513326">"వెడల్పును పెంచు"</string>
     <string name="action_increase_height" msgid="459390020612501122">"ఎత్తును పెంచు"</string>
     <string name="action_decrease_width" msgid="1374549771083094654">"వెడల్పును తగ్గించు"</string>
     <string name="action_decrease_height" msgid="282377193880900022">"ఎత్తును తగ్గించు"</string>
-    <string name="widget_resized" msgid="9130327887929620">"విడ్జెట్ పరిమాణం వెడల్పు <xliff:g id="NUMBER_0">%1$s</xliff:g>కి, ఎత్తు <xliff:g id="NUMBER_1">%2$s</xliff:g>కి మార్చబడింది"</string>
+    <string name="widget_resized" msgid="9130327887929620">"విడ్జెట్ సైజ్‌ వెడల్పు <xliff:g id="NUMBER_0">%1$s</xliff:g>కి, ఎత్తు <xliff:g id="NUMBER_1">%2$s</xliff:g>కి మార్చబడింది"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"షార్ట్‌కట్స్"</string>
     <string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"షార్ట్‌కట్‌లు మరియు నోటిఫికేషన్‌లు"</string>
     <string name="action_dismiss_notification" msgid="5909461085055959187">"తీసివేయండి"</string>
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 9a1bba9..7881a26 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -1272,7 +1272,9 @@
      * Returns the number of pixels required below OverviewActions excluding insets.
      */
     public int getOverviewActionsClaimedSpaceBelow() {
-        if (isTaskbarPresent && !isGestureMode) {
+        if (isTaskbarPresent && !isGestureMode
+                // If taskbar is in overview, overview action has dedicated space above nav buttons
+                && !FeatureFlags.ENABLE_TASKBAR_IN_OVERVIEW.get()) {
             // Align vertically to where nav buttons are.
             return ((taskbarSize - overviewActionsHeight) / 2) + getTaskbarOffsetY();
         }
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index a6831aa..447745e 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -1579,6 +1579,14 @@
         return mOldConfig.orientation;
     }
 
+    /**
+     * Whether keyboard sync is enabled for transitions between Home and All Apps.
+     * TODO(b/251387263): move this method inside an All Apps specific config class.
+     */
+    public boolean isKeyboardSyncEnabled() {
+        return false;
+    }
+
     @Override
     protected void onNewIntent(Intent intent) {
         if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
@@ -2742,6 +2750,8 @@
         getViewCache().setCacheSize(R.layout.folder_page, 2);
 
         TraceHelper.INSTANCE.endSection(traceToken);
+
+        mWorkspace.removeExtraEmptyScreen(true);
     }
 
     private boolean canAnimatePageChange() {
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 872c4fd..001b494 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -39,7 +39,6 @@
 import com.android.launcher3.anim.AnimatorListeners;
 import com.android.launcher3.anim.PendingAnimation;
 import com.android.launcher3.anim.PropertySetter;
-import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.statemanager.StateManager.StateHandler;
 import com.android.launcher3.states.StateAnimationConfig;
 import com.android.launcher3.util.MultiPropertyFactory;
@@ -229,7 +228,7 @@
             StateAnimationConfig config, PendingAnimation builder) {
         if (mLauncher.isInState(ALL_APPS) && !ALL_APPS.equals(toState)) {
             // For atomic animations, we close the keyboard immediately.
-            if (!config.userControlled && !FeatureFlags.ENABLE_KEYBOARD_TRANSITION_SYNC.get()) {
+            if (!config.userControlled && !mLauncher.isKeyboardSyncEnabled()) {
                 mLauncher.getAppsView().getSearchUiManager().getEditText().hideKeyboard();
             }
 
diff --git a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
index c717310..7f6247e 100644
--- a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
@@ -799,6 +799,17 @@
         return mActivityContext.getDeviceProfile().isTablet ? mBottomSheetBackground : this;
     }
 
+    /**
+     * Sets whether the view or its children should react to the window inset.
+     * Used for when exiting all apps -> workspace and determines if window inset
+     * should be applied.. ex) the work mode switch.
+     */
+    public void setApplyWindowInset(boolean shouldApplyWindowInset) {
+        if (mWorkManager.getWorkModeSwitch() != null) {
+            mWorkManager.getWorkModeSwitch().setApplyWindowInset(shouldApplyWindowInset);
+        }
+    }
+
     /** Holds a {@link BaseAllAppsAdapter} and related fields. */
     public class AdapterHolder {
         public static final int MAIN = 0;
diff --git a/src/com/android/launcher3/allapps/WorkModeSwitch.java b/src/com/android/launcher3/allapps/WorkModeSwitch.java
index 15fb77c..0a938b2 100644
--- a/src/com/android/launcher3/allapps/WorkModeSwitch.java
+++ b/src/com/android/launcher3/allapps/WorkModeSwitch.java
@@ -52,6 +52,7 @@
     private int mFlags;
     private boolean mWorkEnabled;
     private boolean mOnWorkTab;
+    private boolean mApplyWindowInset;
 
     public WorkModeSwitch(Context context) {
         this(context, null, 0);
@@ -168,7 +169,7 @@
 
     @Override
     public WindowInsets onApplyWindowInsets(WindowInsets insets) {
-        if (!Utilities.ATLEAST_R) {
+        if (!Utilities.ATLEAST_R || !mApplyWindowInset) {
             return insets;
         }
         if (insets.isVisible(WindowInsets.Type.ime())) {
@@ -197,4 +198,8 @@
     private void removeFlag(int flag) {
         mFlags &= ~flag;
     }
+
+    public void setApplyWindowInset(boolean applyWindowInset){
+        mApplyWindowInset = applyWindowInset;
+    }
 }
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 882d6a6..3a530af 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -37,7 +37,8 @@
 
     public static final String FLAGS_PREF_NAME = "featureFlags";
 
-    private FeatureFlags() { }
+    private FeatureFlags() {
+    }
 
     public static boolean showFlagTogglerUi(Context context) {
         return Utilities.IS_DEBUG_DEVICE && Utilities.isDevelopersOptionsEnabled(context);
@@ -61,7 +62,7 @@
      * To add a new flag that can be toggled through the flags UI:
      *
      * Declare a new ToggleableFlag below. Give it a unique key (e.g. "QSB_ON_FIRST_SCREEN"),
-     *    and set a default value for the flag. This will be the default value on Debug builds.
+     * and set a default value for the flag. This will be the default value on Debug builds.
      */
     public static final BooleanFlag ENABLE_INPUT_CONSUMER_REASON_LOGGING = getDebugFlag(
             "ENABLE_INPUT_CONSUMER_REASON_LOGGING",
@@ -158,14 +159,14 @@
     /**
      * Enables region sampling for text color: Needs system health assessment before turning on
      */
-    public static final BooleanFlag ENABLE_REGION_SAMPLING =  getDebugFlag(
+    public static final BooleanFlag ENABLE_REGION_SAMPLING = getDebugFlag(
             "ENABLE_REGION_SAMPLING", false,
             "Enable region sampling to determine color of text on screen.");
 
     public static final BooleanFlag ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS =
             getDebugFlag(
-            "ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS", false,
-            "Always use hardware optimization for folder animations.");
+                    "ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS", false,
+                    "Always use hardware optimization for folder animations.");
 
     public static final BooleanFlag SEPARATE_RECENTS_ACTIVITY = getDebugFlag(
             "SEPARATE_RECENTS_ACTIVITY", false,
@@ -254,11 +255,6 @@
     public static final BooleanFlag ENABLE_ONE_SEARCH_MOTION = new DeviceFlag(
             "ENABLE_ONE_SEARCH_MOTION", true, "Enables animations in OneSearch.");
 
-    public static final BooleanFlag ENABLE_KEYBOARD_TRANSITION_SYNC = new DeviceFlag(
-            "ENABLE_KEYBOARD_TRANSITION_SYNC", IS_STUDIO_BUILD,
-            "Enable option to synchronize the keyboard open and close animations when transitioning"
-                    + " between home and all apps");
-
     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");
@@ -297,6 +293,13 @@
     public static final BooleanFlag POPUP_MATERIAL_U = new DeviceFlag(
             "POPUP_MATERIAL_U", false, "Switch popup UX to use material U");
 
+    public static final BooleanFlag SHOW_HOME_GARDENING = new DeviceFlag(
+            "SHOW_HOME_GARDENING", false,
+            "Show the new home gardening mode");
+
+    public static final BooleanFlag ENABLE_TRANSIENT_TASKBAR = getDebugFlag(
+            "ENABLE_TRANSIENT_TASKBAR", false, "Enables transient taskbar.");
+
     public static void initialize(Context context) {
         synchronized (sDebugFlags) {
             for (DebugFlag flag : sDebugFlags) {
diff --git a/src/com/android/launcher3/dragndrop/SpringLoadedDragController.java b/src/com/android/launcher3/dragndrop/SpringLoadedDragController.java
index fb8a1bc..08e50dd 100644
--- a/src/com/android/launcher3/dragndrop/SpringLoadedDragController.java
+++ b/src/com/android/launcher3/dragndrop/SpringLoadedDragController.java
@@ -20,12 +20,14 @@
 import com.android.launcher3.CellLayout;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.OnAlarmListener;
+import com.android.launcher3.Utilities;
 import com.android.launcher3.Workspace;
 
 public class SpringLoadedDragController implements OnAlarmListener {
     // how long the user must hover over a mini-screen before it unshrinks
-    final long ENTER_SPRING_LOAD_HOVER_TIME = 500;
-    final long ENTER_SPRING_LOAD_CANCEL_HOVER_TIME = 950;
+    private static final long ENTER_SPRING_LOAD_HOVER_TIME = 500;
+    private static final long ENTER_SPRING_LOAD_HOVER_TIME_IN_TEST = 1500;
+    private static final long ENTER_SPRING_LOAD_CANCEL_HOVER_TIME = 950;
 
     Alarm mAlarm;
 
@@ -39,6 +41,13 @@
         mAlarm.setOnAlarmListener(this);
     }
 
+    private long getEnterSpringLoadHoverTime() {
+        // Some TAPL tests are flaky on Cuttlefish with a low waiting time
+        return Utilities.IS_RUNNING_IN_TEST_HARNESS
+                ? ENTER_SPRING_LOAD_HOVER_TIME_IN_TEST
+                : ENTER_SPRING_LOAD_HOVER_TIME;
+    }
+
     public void cancel() {
         mAlarm.cancelAlarm();
     }
@@ -46,8 +55,8 @@
     // Set a new alarm to expire for the screen that we are hovering over now
     public void setAlarm(CellLayout cl) {
         mAlarm.cancelAlarm();
-        mAlarm.setAlarm((cl == null) ? ENTER_SPRING_LOAD_CANCEL_HOVER_TIME :
-            ENTER_SPRING_LOAD_HOVER_TIME);
+        mAlarm.setAlarm((cl == null) ? ENTER_SPRING_LOAD_CANCEL_HOVER_TIME
+                : getEnterSpringLoadHoverTime());
         mScreen = cl;
     }
 
diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
index 9afca4f..ceebc2e 100644
--- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
@@ -504,9 +504,9 @@
             DeviceProfile dp, boolean isRtl) {
         int spaceAboveSnapshot = dp.overviewTaskThumbnailTopMarginPx;
         int totalThumbnailHeight = parentHeight - spaceAboveSnapshot;
-        int dividerBar = splitBoundsConfig.appsStackedVertically
-                ? (int) (splitBoundsConfig.dividerHeightPercent * parentHeight)
-                : (int) (splitBoundsConfig.dividerWidthPercent * parentWidth);
+        int dividerBar = Math.round(totalThumbnailHeight * (splitBoundsConfig.appsStackedVertically
+                ? splitBoundsConfig.dividerHeightPercent
+                : splitBoundsConfig.dividerWidthPercent));
         int primarySnapshotHeight;
         int primarySnapshotWidth;
         int secondarySnapshotHeight;
diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
index bc1b634..55afc28 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -50,6 +50,7 @@
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
+import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.util.DisplayController;
 import com.android.launcher3.util.SplitConfigurationOptions;
 import com.android.launcher3.util.SplitConfigurationOptions.SplitBounds;
@@ -524,7 +525,9 @@
         out.setRotation(getDegreesRotated());
         int distanceToEdge;
         if ((DisplayController.getNavigationMode(out.getContext()) == THREE_BUTTONS)
-                && (dp.isTwoPanels || dp.isTablet)) {
+                && (dp.isTwoPanels || dp.isTablet)
+                // If taskbar is in overview, overview action has dedicated space above nav buttons
+                && !FeatureFlags.ENABLE_TASKBAR_IN_OVERVIEW.get()) {
             // If 3-button nav is active, align the splitInstructionsView with it.
             distanceToEdge = dp.getTaskbarOffsetY()
                     + ((dp.taskbarSize - splitInstructionsHeight) / 2);
@@ -561,8 +564,12 @@
         int insetCorrectionX = (dp.getInsets().right - dp.getInsets().left) / 2;
         // Adjust for any insets on the bottom edge
         int insetCorrectionY = dp.getInsets().bottom;
+        // Adjust for taskbar in overview
+        int taskbarCorrectionY =
+                dp.isTaskbarPresent && FeatureFlags.ENABLE_TASKBAR_IN_OVERVIEW.get()
+                        ? dp.taskbarSize : 0;
         out.setTranslationX(insetCorrectionX + threeButtonNavShift);
-        out.setTranslationY(-distanceToEdge + insetCorrectionY);
+        out.setTranslationY(-distanceToEdge + insetCorrectionY - taskbarCorrectionY);
         FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) out.getLayoutParams();
         lp.gravity = CENTER_HORIZONTAL | BOTTOM;
         out.setLayoutParams(lp);
@@ -630,9 +637,9 @@
             DeviceProfile dp, boolean isRtl) {
         int spaceAboveSnapshot = dp.overviewTaskThumbnailTopMarginPx;
         int totalThumbnailHeight = parentHeight - spaceAboveSnapshot;
-        int dividerBar = splitBoundsConfig.appsStackedVertically
-                ? (int) (splitBoundsConfig.dividerHeightPercent * parentHeight)
-                : (int) (splitBoundsConfig.dividerWidthPercent * parentWidth);
+        int dividerBar = Math.round(splitBoundsConfig.appsStackedVertically
+                ? splitBoundsConfig.dividerHeightPercent * totalThumbnailHeight
+                : splitBoundsConfig.dividerWidthPercent * totalThumbnailHeight);
         int primarySnapshotHeight;
         int primarySnapshotWidth;
         int secondarySnapshotHeight;
@@ -662,6 +669,16 @@
             secondarySnapshotHeight = totalThumbnailHeight - primarySnapshotHeight - dividerBar;
             int translationY = primarySnapshotHeight + spaceAboveSnapshot + dividerBar;
             secondarySnapshot.setTranslationY(translationY);
+
+            FrameLayout.LayoutParams primaryParams =
+                    (FrameLayout.LayoutParams) primarySnapshot.getLayoutParams();
+            FrameLayout.LayoutParams secondaryParams =
+                    (FrameLayout.LayoutParams) secondarySnapshot.getLayoutParams();
+            secondaryParams.topMargin = 0;
+            primaryParams.topMargin = spaceAboveSnapshot;
+
+            // Reset unused translations
+            primarySnapshot.setTranslationY(0);
             secondarySnapshot.setTranslationX(0);
             primarySnapshot.setTranslationX(0);
         }
diff --git a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
index 55bb5e8..a616a8b 100644
--- a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
@@ -121,9 +121,9 @@
         // the screen. This is to preserve consistency when the user rotates: From the user's POV,
         // the primary should always be on the left.
         if (desiredStagePosition == SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT) {
-            outRect.top += (int) (outRect.height() * (topLeftTaskPercent + dividerBarPercent));
+            outRect.top += (int) (outRect.height() * ((1 - topLeftTaskPercent)));
         } else {
-            outRect.bottom = outRect.top + (int) (outRect.height() * topLeftTaskPercent);
+            outRect.bottom -= (int) (outRect.height() * (topLeftTaskPercent + dividerBarPercent));
         }
     }
 
@@ -266,6 +266,49 @@
         secondaryIconView.setLayoutParams(secondaryIconParams);
     }
 
+    @Override
+    public void measureGroupedTaskViewThumbnailBounds(View primarySnapshot, View secondarySnapshot,
+            int parentWidth, int parentHeight, SplitBounds splitBoundsConfig, DeviceProfile dp,
+            boolean isRtl) {
+        FrameLayout.LayoutParams primaryParams =
+                (FrameLayout.LayoutParams) primarySnapshot.getLayoutParams();
+        FrameLayout.LayoutParams secondaryParams =
+                (FrameLayout.LayoutParams) secondarySnapshot.getLayoutParams();
+
+        // Swap the margins that are set in TaskView#setRecentsOrientedState()
+        secondaryParams.topMargin = dp.overviewTaskThumbnailTopMarginPx;
+        primaryParams.topMargin = 0;
+
+        // Measure and layout the thumbnails bottom up, since the primary is on the visual left
+        // (portrait bottom) and secondary is on the right (portrait top)
+        int spaceAboveSnapshot = dp.overviewTaskThumbnailTopMarginPx;
+        int totalThumbnailHeight = parentHeight - spaceAboveSnapshot;
+        int dividerBar = Math.round(totalThumbnailHeight * (splitBoundsConfig.appsStackedVertically
+                ? splitBoundsConfig.dividerHeightPercent
+                : splitBoundsConfig.dividerWidthPercent));
+        int primarySnapshotHeight;
+        int primarySnapshotWidth;
+        int secondarySnapshotHeight;
+        int secondarySnapshotWidth;
+
+        float taskPercent = splitBoundsConfig.appsStackedVertically ?
+                splitBoundsConfig.topTaskPercent : splitBoundsConfig.leftTaskPercent;
+        primarySnapshotWidth = parentWidth;
+        primarySnapshotHeight = (int) (totalThumbnailHeight * (taskPercent));
+
+        secondarySnapshotWidth = parentWidth;
+        secondarySnapshotHeight = totalThumbnailHeight - primarySnapshotHeight - dividerBar;
+        secondarySnapshot.setTranslationY(0);
+        primarySnapshot.setTranslationY(secondarySnapshotHeight + spaceAboveSnapshot + dividerBar);
+        primarySnapshot.measure(
+                View.MeasureSpec.makeMeasureSpec(primarySnapshotWidth, View.MeasureSpec.EXACTLY),
+                View.MeasureSpec.makeMeasureSpec(primarySnapshotHeight, View.MeasureSpec.EXACTLY));
+        secondarySnapshot.measure(
+                View.MeasureSpec.makeMeasureSpec(secondarySnapshotWidth, View.MeasureSpec.EXACTLY),
+                View.MeasureSpec.makeMeasureSpec(secondarySnapshotHeight,
+                        View.MeasureSpec.EXACTLY));
+    }
+
     /* ---------- The following are only used by TaskViewTouchHandler. ---------- */
 
     @Override