Merge "Removing ENABLE_LOCAL_COLOR_POPUPS feature flag" into tm-qpr-dev
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index cd60879..c0b6657 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -289,6 +289,8 @@
     <dimen name="transient_taskbar_key_shadow_distance">10dp</dimen>
     <dimen name="transient_taskbar_stashed_size">32dp</dimen>
     <dimen name="transient_taskbar_icon_spacing">10dp</dimen>
+    <!-- An additional touch slop to prevent x-axis movement during the swipe up to show taskbar -->
+    <dimen name="transient_taskbar_clamped_offset_bound">16dp</dimen>
     <!-- Taskbar swipe up thresholds -->
     <dimen name="taskbar_app_window_threshold">150dp</dimen>
     <dimen name="taskbar_home_overview_threshold">225dp</dimen>
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index dcad873..59dbd4b 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -1678,9 +1678,10 @@
                 mLauncher.getStateManager().moveToRestState();
             }
 
+            RectF windowTargetBounds =
+                    new RectF(getWindowTargetBounds(appTargets, getRotationChange(appTargets)));
             Pair<RectFSpringAnim, AnimatorSet> pair = createWallpaperOpenAnimations(
-                    appTargets, wallpaperTargets, mFromUnlock,
-                    new RectF(0, 0, mDeviceProfile.widthPx, mDeviceProfile.heightPx),
+                    appTargets, wallpaperTargets, mFromUnlock, windowTargetBounds,
                     QuickStepContract.getWindowCornerRadius(mLauncher));
 
             mLauncher.clearForceInvisibleFlag(INVISIBLE_ALL);
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index f51bc55..13ca58d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -762,9 +762,7 @@
             });
         } else if (tag instanceof WorkspaceItemInfo) {
             WorkspaceItemInfo info = (WorkspaceItemInfo) tag;
-            if (info.isDisabled()) {
-                ItemClickHandler.handleDisabledItemClicked(info, this);
-            } else {
+            if (!info.isDisabled() || !ItemClickHandler.handleDisabledItemClicked(info, this)) {
                 TaskbarUIController taskbarUIController = mControllers.uiController;
                 RecentsView recents = taskbarUIController.getRecentsView();
                 if (recents != null
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
index 3045eca..a26f5e5 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
@@ -207,8 +207,13 @@
 
                     if (FeatureFlags.ENABLE_TASKBAR_POPUP_MENU.get()
                             && !shouldStartDrag(0)) {
-                        // Immediately close the popup menu.
-                        mDragView.setOnAnimationEndCallback(() -> callOnDragStart());
+                        mDragView.setOnAnimationEndCallback(() -> {
+                            // Drag might be cancelled during the DragView animation, so check
+                            // mIsPreDrag again.
+                            if (mIsInPreDrag) {
+                                callOnDragStart();
+                            }
+                        });
                     }
                 }
 
@@ -305,6 +310,9 @@
         if (mDisallowGlobalDrag) {
             AbstractFloatingView.closeAllOpenViewsExcept(mActivity, TYPE_TASKBAR_ALL_APPS);
         } else {
+            // stash the transient taskbar
+            mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true);
+
             AbstractFloatingView.closeAllOpenViews(mActivity);
         }
 
@@ -413,6 +421,9 @@
                     if (dragEvent.getResult()) {
                         maybeOnDragEnd();
                     } else {
+                        // un-stash the transient taskbar in case drag and drop was canceled
+                        mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(false);
+
                         // This will take care of calling maybeOnDragEnd() after the animation
                         animateGlobalDragViewToOriginalPosition(btv, dragEvent);
                     }
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
index ea5df87..d790b4b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
@@ -186,6 +186,10 @@
         animatorSet.play(stashController.applyStateWithoutStart(duration));
         animatorSet.play(applyState(duration, false));
 
+        if (mTaskBarRecentsAnimationListener != null) {
+            mTaskBarRecentsAnimationListener.endGestureStateOverride(
+                    !mLauncher.isInState(LauncherState.OVERVIEW));
+        }
         mTaskBarRecentsAnimationListener = new TaskBarRecentsAnimationListener(callbacks);
         callbacks.addListener(mTaskBarRecentsAnimationListener);
         ((RecentsView) mLauncher.getOverviewPanel()).setTaskLaunchListener(() ->
diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java
index 6c7bdbf..019e5a6 100644
--- a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java
@@ -61,6 +61,11 @@
         public void onTaskStackChanged() {
             mProxyView.close(false);
         }
+
+        @Override
+        public void onTaskMovedToFront(int taskId) {
+            mProxyView.close(false);
+        }
     };
 
     private DeviceProfile mLauncherDeviceProfile;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
index fe0bca6..e3d386c 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
@@ -28,9 +28,9 @@
 import com.android.launcher3.util.MainThreadInitializedObject;
 import com.android.systemui.plugins.Plugin;
 import com.android.systemui.plugins.PluginListener;
+import com.android.systemui.plugins.PluginManager;
 import com.android.systemui.shared.plugins.PluginActionManager;
 import com.android.systemui.shared.plugins.PluginInstance;
-import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.shared.plugins.PluginManagerImpl;
 import com.android.systemui.shared.plugins.PluginPrefs;
 import com.android.systemui.shared.system.UncaughtExceptionPreHandlerManager;
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index b09e531..4b35859 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -95,6 +95,7 @@
 import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.AnimationSuccessListener;
 import com.android.launcher3.anim.AnimatorPlaybackController;
+import com.android.launcher3.dragndrop.DragView;
 import com.android.launcher3.logging.StatsLogManager;
 import com.android.launcher3.logging.StatsLogManager.StatsLogger;
 import com.android.launcher3.statemanager.BaseState;
@@ -287,7 +288,7 @@
     private AnimatorControllerWithResistance mLauncherTransitionController;
     private boolean mHasEndedLauncherTransition;
 
-    private AnimationFactory mAnimationFactory = (t, s) -> { };
+    private AnimationFactory mAnimationFactory = (t) -> { };
 
     private boolean mWasLauncherAlreadyVisible;
 
@@ -317,6 +318,9 @@
     private final int mTaskbarAppWindowThreshold;
     private final int mTaskbarCatchUpThreshold;
     private boolean mTaskbarAlreadyOpen;
+    private final boolean mIsTransientTaskbar;
+    // Only used when mIsTransientTaskbar is true.
+    private boolean mHasReachedHomeOverviewThreshold;
 
     public AbsSwipeUpHandler(Context context, RecentsAnimationDeviceState deviceState,
             TaskAnimationManager taskAnimationManager, GestureState gestureState,
@@ -343,6 +347,7 @@
         mTaskbarAppWindowThreshold = res
                 .getDimensionPixelSize(R.dimen.taskbar_app_window_threshold);
         mTaskbarCatchUpThreshold = res.getDimensionPixelSize(R.dimen.taskbar_catch_up_threshold);
+        mIsTransientTaskbar = DisplayController.isTransientTaskbar(mActivity);
 
         mQuickSwitchScaleScrollThreshold = res
                 .getDimension(R.dimen.quick_switch_scaling_scroll_threshold);
@@ -531,9 +536,7 @@
             Runnable initAnimFactory = () -> {
                 mAnimationFactory = mActivityInterface.prepareRecentsUI(mDeviceState,
                         mWasLauncherAlreadyVisible, this::onAnimatorPlaybackControllerCreated);
-                maybeUpdateRecentsAttachedState(
-                        false /* animate */,
-                        new ActiveGestureLog.CompoundString("on Launcher start (animate=false)"));
+                maybeUpdateRecentsAttachedState(false /* animate */);
                 if (mGestureState.getEndTarget() != null) {
                     // Update the end target in case the gesture ended before we init.
                     mAnimationFactory.setEndTarget(mGestureState.getEndTarget());
@@ -638,8 +641,7 @@
     }
 
     private void initializeLauncherAnimationController() {
-        buildAnimationController(new ActiveGestureLog.CompoundString(
-                "initializing launcher animation controller"));
+        buildAnimationController();
 
         Object traceToken = TraceHelper.INSTANCE.beginSection("logToggleRecents",
                 TraceHelper.FLAG_IGNORE_BINDERS);
@@ -658,11 +660,7 @@
             @Override
             public void onMotionPauseDetected() {
                 mHasMotionEverBeenPaused = true;
-                maybeUpdateRecentsAttachedState(
-                        true/* animate */,
-                        true/* moveFocusedTask */,
-                        new ActiveGestureLog.CompoundString(
-                                "motion pause detected (animate=true)"));
+                maybeUpdateRecentsAttachedState(true/* animate */, true/* moveFocusedTask */);
                 Optional.ofNullable(mActivityInterface.getTaskbarController())
                         .ifPresent(TaskbarUIController::startTranslationSpring);
                 performHapticFeedback();
@@ -675,13 +673,12 @@
         };
     }
 
-    private void maybeUpdateRecentsAttachedState(ActiveGestureLog.CompoundString reason) {
-        maybeUpdateRecentsAttachedState(true /* animate */, reason.append(" (animate=true)"));
+    private void maybeUpdateRecentsAttachedState() {
+        maybeUpdateRecentsAttachedState(true /* animate */);
     }
 
-    private void maybeUpdateRecentsAttachedState(
-            boolean animate, ActiveGestureLog.CompoundString reason) {
-        maybeUpdateRecentsAttachedState(animate, false /* moveFocusedTask */, reason);
+    private void maybeUpdateRecentsAttachedState(boolean animate) {
+        maybeUpdateRecentsAttachedState(animate, false /* moveFocusedTask */);
     }
 
     /**
@@ -693,8 +690,7 @@
      * @param animate whether to animate when attaching RecentsView
      * @param moveFocusedTask whether to move focused task to front when attaching
      */
-    private void maybeUpdateRecentsAttachedState(
-            boolean animate, boolean moveFocusedTask, ActiveGestureLog.CompoundString reason) {
+    private void maybeUpdateRecentsAttachedState(boolean animate, boolean moveFocusedTask) {
         if (!mDeviceState.isFullyGesturalNavMode() || mRecentsView == null) {
             return;
         }
@@ -704,25 +700,14 @@
         final boolean recentsAttachedToAppWindow;
         if (mGestureState.getEndTarget() != null) {
             recentsAttachedToAppWindow = mGestureState.getEndTarget().recentsAttachedToAppWindow;
-            reason.append("; gesture state end target != null (attached=")
-                    .append(Boolean.toString(recentsAttachedToAppWindow))
-                    .append(")");
         } else if (mContinuingLastGesture
                 && mRecentsView.getRunningTaskIndex() != mRecentsView.getNextPage()) {
             recentsAttachedToAppWindow = true;
-            reason.append("; continuing last gesture (attached=true)");
         } else if (runningTaskTarget != null && isNotInRecents(runningTaskTarget)) {
             // The window is going away so make sure recents is always visible in this case.
             recentsAttachedToAppWindow = true;
-            reason.append("; make sure recents is always visible (attached=true)");
         } else {
             recentsAttachedToAppWindow = mHasMotionEverBeenPaused || mIsLikelyToStartNewTask;
-            reason.append(mHasMotionEverBeenPaused
-                            ? "; motion has been paused"
-                            : "; gesture is likely to start a new task")
-                    .append(" (attached=")
-                    .append(Boolean.toString(recentsAttachedToAppWindow))
-                    .append(")");
         }
         if (moveFocusedTask && !mAnimationFactory.hasRecentsEverAttachedToAppWindow()
                 && recentsAttachedToAppWindow) {
@@ -730,8 +715,7 @@
             // TaskView jumping to new position as we move the tasks.
             mRecentsView.moveFocusedTaskToFront();
         }
-        mAnimationFactory.setRecentsAttachedToAppWindow(
-                recentsAttachedToAppWindow, animate, reason);
+        mAnimationFactory.setRecentsAttachedToAppWindow(recentsAttachedToAppWindow, animate);
 
         // Reapply window transform throughout the attach animation, as the animation affects how
         // much the window is bound by overscroll (vs moving freely).
@@ -750,30 +734,38 @@
         }
     }
 
-    public void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask) {
-        setIsLikelyToStartNewTask(
-                isLikelyToStartNewTask,
-                true /* animate */,
-                new ActiveGestureLog.CompoundString(
-                        "setting gesture likely to start (animate=true)"));
+    /**
+     * Sets whether or not we should clamp the scroll offset.
+     * This is used to avoid x-axis movement when swiping up transient taskbar.
+     * @param clampScrollOffset When true, we clamp the scroll to 0 before the clamp threshold is
+     *                          met.
+     */
+    public void setClampScrollOffset(boolean clampScrollOffset) {
+        if (mRecentsView == null) {
+            mStateCallback.runOnceAtState(STATE_LAUNCHER_PRESENT,
+                    () -> mRecentsView.setClampScrollOffset(clampScrollOffset));
+            return;
+        }
+        mRecentsView.setClampScrollOffset(clampScrollOffset);
     }
 
-    private void setIsLikelyToStartNewTask(
-            boolean isLikelyToStartNewTask,
-            boolean animate,
-            ActiveGestureLog.CompoundString reason) {
+    public void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask) {
+        setIsLikelyToStartNewTask(isLikelyToStartNewTask, true /* animate */);
+    }
+
+    private void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask, boolean animate) {
         if (mIsLikelyToStartNewTask != isLikelyToStartNewTask) {
             mIsLikelyToStartNewTask = isLikelyToStartNewTask;
-            maybeUpdateRecentsAttachedState(animate, reason);
+            maybeUpdateRecentsAttachedState(animate);
         }
     }
 
-    private void buildAnimationController(ActiveGestureLog.CompoundString reason) {
+    private void buildAnimationController() {
         if (!canCreateNewOrUpdateExistingLauncherTransitionController()) {
             return;
         }
         initTransitionEndpoints(mActivity.getDeviceProfile());
-        mAnimationFactory.createActivityInterface(mTransitionDragLength, reason);
+        mAnimationFactory.createActivityInterface(mTransitionDragLength);
     }
 
     /**
@@ -788,7 +780,7 @@
     @Override
     public WindowInsets onApplyWindowInsets(View view, WindowInsets windowInsets) {
         WindowInsets result = view.onApplyWindowInsets(windowInsets);
-        buildAnimationController(new ActiveGestureLog.CompoundString("applying window insets"));
+        buildAnimationController();
         // Reapply the current shift to ensure it takes new insets into account, e.g. when long
         // pressing to stash taskbar without moving the finger.
         updateFinalShift();
@@ -819,7 +811,7 @@
     @UiThread
     @Override
     public void updateFinalShift() {
-        final boolean passed = mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW;
+        final boolean passed = hasReachedHomeOverviewThreshold();
         if (passed != mPassedOverviewThreshold) {
             mPassedOverviewThreshold = passed;
             if (mDeviceState.isTwoButtonNavMode() && !mGestureState.isHandlingAtomicEvent()) {
@@ -962,10 +954,7 @@
             });
         }
         notifyGestureStartedAsync();
-        setIsLikelyToStartNewTask(
-                isLikelyToStartNewTask,
-                false /* animate */,
-                new ActiveGestureLog.CompoundString("on gesture started (animate=false)"));
+        setIsLikelyToStartNewTask(isLikelyToStartNewTask, false /* animate */);
         mStateCallback.setStateOnUiThread(STATE_GESTURE_STARTED);
         mGestureStarted = true;
     }
@@ -1046,8 +1035,7 @@
 
     private void onSettledOnEndTarget() {
         // Fast-finish the attaching animation if it's still running.
-        maybeUpdateRecentsAttachedState(false, new ActiveGestureLog.CompoundString(
-                "on settled on end target (animate=false)"));
+        maybeUpdateRecentsAttachedState(false);
         final GestureEndTarget endTarget = mGestureState.getEndTarget();
         // Wait until the given View (if supplied) draws before resuming the last task.
         View postResumeLastTask = mActivityInterface.onSettledOnEndTarget(endTarget);
@@ -1145,16 +1133,16 @@
         }
 
         if (!mDeviceState.isFullyGesturalNavMode()) {
-            return (!hasReachedOverviewThreshold() && willGoToNewTask) ? NEW_TASK : RECENTS;
+            return (!hasReachedHomeOverviewThreshold() && willGoToNewTask) ? NEW_TASK : RECENTS;
         }
         return willGoToNewTask ? NEW_TASK : HOME;
     }
 
     private GestureEndTarget calculateEndTargetForNonFling(PointF velocity) {
         final boolean isScrollingToNewTask = isScrollingToNewTask();
-        final boolean reachedOverviewThreshold = hasReachedOverviewThreshold();
+        final boolean reachedHomeOverviewThreshold = hasReachedHomeOverviewThreshold();
         if (!mDeviceState.isFullyGesturalNavMode()) {
-            return reachedOverviewThreshold && mGestureStarted
+            return reachedHomeOverviewThreshold && mGestureStarted
                     ? RECENTS
                     : (isScrollingToNewTask ? NEW_TASK : LAST_TASK);
         }
@@ -1170,7 +1158,7 @@
             return RECENTS;
         } else if (isScrollingToNewTask) {
             return NEW_TASK;
-        } else if (reachedOverviewThreshold) {
+        } else if (reachedHomeOverviewThreshold) {
             return HOME;
         }
         return LAST_TASK;
@@ -1189,8 +1177,22 @@
         return runningTaskIndex >= 0 && mRecentsView.getNextPage() != runningTaskIndex;
     }
 
-    private boolean hasReachedOverviewThreshold() {
-        return getTaskbarProgress() > MIN_PROGRESS_FOR_OVERVIEW;
+    /**
+     * Sets whether the current swipe has reached the threshold where if user lets go they would
+     * go to either the home state or overview state.
+     */
+    public void setHasReachedHomeOverviewThreshold(boolean hasReachedHomeOverviewThreshold) {
+        mHasReachedHomeOverviewThreshold = hasReachedHomeOverviewThreshold;
+    }
+
+    /**
+     * Returns true iff swipe has reached the overview threshold.
+     */
+    public boolean hasReachedHomeOverviewThreshold() {
+        if (mIsTransientTaskbar) {
+            return mHasReachedHomeOverviewThreshold;
+        }
+        return mCurrentShift.value > MIN_PROGRESS_FOR_OVERVIEW;
     }
 
     @UiThread
@@ -1357,12 +1359,15 @@
     @UiThread
     private void animateToProgressInternal(float start, float end, long duration,
             Interpolator interpolator, GestureEndTarget target, PointF velocityPxPerMs) {
-        maybeUpdateRecentsAttachedState(new ActiveGestureLog.CompoundString(
-                "animate to progress internal"));
+        maybeUpdateRecentsAttachedState();
 
         // If we are transitioning to launcher, then listen for the activity to be restarted while
         // the transition is in progress
         if (mGestureState.getEndTarget().isLauncher) {
+            // This is also called when the launcher is resumed, in order to clear the pending
+            // widgets that have yet to be configured.
+            DragView.removeAllViews(mActivity);
+
             TaskStackChangeListeners.getInstance().registerTaskStackListener(
                     mActivityRestartListener);
 
@@ -1677,9 +1682,7 @@
                     mRecentsView.post(mRecentsView::resetTaskVisuals);
                 }
                 // Make sure recents is in its final state
-                maybeUpdateRecentsAttachedState(
-                        false, new ActiveGestureLog.CompoundString(
-                                "setting up window animation (animate=false)"));
+                maybeUpdateRecentsAttachedState(false);
                 mActivityInterface.onSwipeUpToHomeComplete(mDeviceState);
             }
         });
@@ -2267,7 +2270,7 @@
      * There is also a catch up period so that the window can start moving 1:1 with the swipe.
      */
     private float getTaskbarProgress() {
-        if (!DisplayController.isTransientTaskbar(mContext)) {
+        if (!mIsTransientTaskbar) {
             return mCurrentShift.value;
         }
 
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index 2c3ba85..274b686 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -60,7 +60,6 @@
 import com.android.launcher3.util.DisplayController;
 import com.android.launcher3.util.NavigationMode;
 import com.android.launcher3.views.ScrimView;
-import com.android.quickstep.util.ActiveGestureLog;
 import com.android.quickstep.util.ActivityInitListener;
 import com.android.quickstep.util.AnimatorControllerWithResistance;
 import com.android.quickstep.views.RecentsView;
@@ -399,16 +398,14 @@
 
     public interface AnimationFactory {
 
-        void createActivityInterface(long transitionLength, ActiveGestureLog.CompoundString reason);
+        void createActivityInterface(long transitionLength);
 
         /**
          * @param attached Whether to show RecentsView alongside the app window. If false, recents
          *                 will be hidden by some property we can animate, e.g. alpha.
          * @param animate Whether to animate recents to/from its new attached state.
-         * @param reason Explanation for why this method is being called with the given param values
          */
-        default void setRecentsAttachedToAppWindow(
-                boolean attached, boolean animate, ActiveGestureLog.CompoundString reason) { }
+        default void setRecentsAttachedToAppWindow(boolean attached, boolean animate) { }
 
         default boolean isRecentsAttachedToAppWindow() {
             return false;
@@ -450,8 +447,7 @@
         }
 
         @Override
-        public void createActivityInterface(
-                long transitionLength, ActiveGestureLog.CompoundString reason) {
+        public void createActivityInterface(long transitionLength) {
             PendingAnimation pa = new PendingAnimation(transitionLength * 2);
             createBackgroundToOverviewAnim(mActivity, pa);
             AnimatorPlaybackController controller = pa.createPlaybackController();
@@ -474,29 +470,13 @@
             // (because we set the animation as the current state animation), so we reapply the
             // attached state here as well to ensure recents is shown/hidden appropriately.
             if (DisplayController.getNavigationMode(mActivity) == NavigationMode.NO_BUTTON) {
-                setRecentsAttachedToAppWindow(
-                        mIsAttachedToWindow,
-                        false,
-                        reason.append("; reapplying the attached state (attached=")
-                                .append(Boolean.toString(mIsAttachedToWindow))
-                                .append(", animate=false)"));
+                setRecentsAttachedToAppWindow(mIsAttachedToWindow, false);
             }
         }
 
         @Override
-        public void setRecentsAttachedToAppWindow(
-                boolean attached, boolean animate, ActiveGestureLog.CompoundString reason) {
-            // TODO(b/244593270): remove these logs; too verbose
-            ActiveGestureLog.INSTANCE.addLog(
-                    new ActiveGestureLog.CompoundString("setRecentsAttachedToAppWindow: attached=")
-                            .append(Boolean.toString(attached))
-                            .append(", animate=")
-                            .append(Boolean.toString(animate))
-                            .append(", reason=")
-                            .append(reason));
+        public void setRecentsAttachedToAppWindow(boolean attached, boolean animate) {
             if (mIsAttachedToWindow == attached && animate) {
-                ActiveGestureLog.INSTANCE.addLog(new ActiveGestureLog.CompoundString(
-                        "setRecentsAttachedToAppWindow: exiting early"));
                 return;
             }
             mActivity.getStateManager()
@@ -525,11 +505,6 @@
             float fromTranslation = ADJACENT_PAGE_HORIZONTAL_OFFSET.get(
                     mActivity.getOverviewPanel());
             float toTranslation = attached ? 0 : 1;
-            ActiveGestureLog.INSTANCE.addLog(new ActiveGestureLog.CompoundString(
-                    "setRecentsAttachedToAppWindow: fromTranslation=")
-                    .append(Float.toString(fromTranslation))
-                    .append(", toTranslation=")
-                    .append(Float.toString(toTranslation)));
 
             Animator translationAnimator = mActivity.getStateManager().createStateElementAnimation(
                     INDEX_RECENTS_TRANSLATE_X_ANIM, fromTranslation, toTranslation);
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
index 8410149..db7e087 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
@@ -53,6 +53,7 @@
 import com.android.quickstep.RecentsAnimationController;
 import com.android.quickstep.RecentsAnimationDeviceState;
 import com.android.quickstep.RecentsAnimationTargets;
+import com.android.quickstep.RemoteAnimationTargets;
 import com.android.quickstep.TaskAnimationManager;
 import com.android.quickstep.util.SurfaceTransaction.SurfaceProperties;
 import com.android.quickstep.util.TransformParams;
@@ -226,6 +227,10 @@
                     mStateCallback.setState(STATE_HANDLER_INVALIDATED);
                 }
             });
+            RemoteAnimationTargets targets = mTransformParams.getTargetSet();
+            if (targets != null) {
+                targets.addReleaseCheck(new DeviceLockedReleaseCheck(animator));
+            }
             animator.start();
         } else {
             mStateCallback.setState(STATE_HANDLER_INVALIDATED);
@@ -304,4 +309,27 @@
     public boolean allowInterceptByParent() {
         return !mThresholdCrossed;
     }
+
+    private static final class DeviceLockedReleaseCheck extends
+            RemoteAnimationTargets.ReleaseCheck {
+
+        private DeviceLockedReleaseCheck(Animator animator) {
+            setCanRelease(true);
+
+            animator.addListener(new AnimatorListenerAdapter() {
+
+                @Override
+                public void onAnimationStart(Animator animation) {
+                    super.onAnimationStart(animation);
+                    setCanRelease(false);
+                }
+
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    super.onAnimationEnd(animation);
+                    setCanRelease(true);
+                }
+            });
+        }
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
index b3d3c3d..f842fd0 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
@@ -36,7 +36,6 @@
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.content.Intent;
-import android.content.res.Resources;
 import android.graphics.PointF;
 import android.os.Build;
 import android.util.Log;
@@ -151,10 +150,6 @@
         mHandlerFactory = handlerFactory;
         mActivityInterface = mGestureState.getActivityInterface();
 
-        Resources res = base.getResources();
-        mTaskbarHomeOverviewThreshold = res
-                .getDimensionPixelSize(R.dimen.taskbar_home_overview_threshold);
-
         mMotionPauseDetector = new MotionPauseDetector(base, false,
                 mNavBarPosition.isLeftEdge() || mNavBarPosition.isRightEdge()
                         ? MotionEvent.AXIS_X : MotionEvent.AXIS_Y);
@@ -168,6 +163,8 @@
         TaskbarUIController controller = mActivityInterface.getTaskbarController();
         mTaskbarAlreadyOpen = controller != null && !controller.isTaskbarStashed();
         mIsTransientTaskbar = DisplayController.isTransientTaskbar(base);
+        mTaskbarHomeOverviewThreshold = base.getResources()
+                .getDimensionPixelSize(R.dimen.taskbar_home_overview_threshold);
 
         boolean continuingPreviousGesture = mTaskAnimationManager.isRecentsAnimationRunning();
         mIsDeferredDownTarget = !continuingPreviousGesture && isDeferredDownTarget;
@@ -340,13 +337,12 @@
                     }
 
                     if (mDeviceState.isFullyGesturalNavMode()) {
-                        float minDisplacement = mMotionPauseMinDisplacement;
-
-                        if (mIsTransientTaskbar && !mTaskbarAlreadyOpen) {
-                            minDisplacement += mTaskbarHomeOverviewThreshold;
+                        boolean minSwipeMet = upDist >= mMotionPauseMinDisplacement;
+                        if (mIsTransientTaskbar) {
+                            minSwipeMet = upDist >= mTaskbarHomeOverviewThreshold;
+                            mInteractionHandler.setHasReachedHomeOverviewThreshold(minSwipeMet);
                         }
-
-                        mMotionPauseDetector.setDisallowPause(upDist < minDisplacement
+                        mMotionPauseDetector.setDisallowPause(!minSwipeMet
                                 || isLikelyToStartNewTask);
                         mMotionPauseDetector.addPosition(ev);
                         mInteractionHandler.setIsLikelyToStartNewTask(isLikelyToStartNewTask);
@@ -382,6 +378,9 @@
         mInteractionHandler.onGestureStarted(isLikelyToStartNewTask);
 
         mInteractionHandler.setTaskbarAlreadyOpen(mTaskbarAlreadyOpen);
+        if (mIsTransientTaskbar && !mTaskbarAlreadyOpen && !isLikelyToStartNewTask) {
+            mInteractionHandler.setClampScrollOffset(true);
+        }
     }
 
     private void startTouchTrackingForWindowAnimation(long touchTimeMs) {
@@ -477,6 +476,9 @@
     @UiThread
     private void onInteractionGestureFinished() {
         Preconditions.assertUIThread();
+        if (mInteractionHandler != null) {
+            mInteractionHandler.setClampScrollOffset(false);
+        }
         removeListener();
         mInteractionHandler = null;
         cleanupAfterGesture();
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 80b41a7..5a26f32 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -498,6 +498,9 @@
     private boolean mOverviewFullscreenEnabled;
     private boolean mOverviewSelectEnabled;
 
+    private boolean mShouldClampScrollOffset;
+    private int mClampedScrollOffsetBound;
+
     private float mAdjacentPageHorizontalOffset = 0;
     protected float mTaskViewsSecondaryTranslation = 0;
     protected float mTaskViewsPrimarySplitTranslation = 0;
@@ -752,6 +755,8 @@
         mSplitPlaceholderInset = getResources().getDimensionPixelSize(
                 R.dimen.split_placeholder_inset);
         mSquaredTouchSlop = squaredTouchSlop(context);
+        mClampedScrollOffsetBound = getResources().getDimensionPixelSize(
+                R.dimen.transient_taskbar_clamped_offset_bound);
 
         mEmptyIcon = context.getDrawable(R.drawable.ic_empty_recents);
         mEmptyIcon.setCallback(this);
@@ -5055,9 +5060,35 @@
     }
 
     /**
+     * Sets whether or not we should clamp the scroll offset.
+     * This is used to avoid x-axis movement when swiping up transient taskbar.
+     * Should only be set at the beginning and end of the gesture, otherwise a jump may occur.
+     * @param clampScrollOffset When true, we clamp the scroll to 0 before the clamp threshold is
+     *                          met.
+     */
+    public void setClampScrollOffset(boolean clampScrollOffset) {
+        mShouldClampScrollOffset = clampScrollOffset;
+    }
+
+    /**
      * Returns how many pixels the page is offset on the currently laid out dominant axis.
      */
     public int getScrollOffset(int pageIndex) {
+        int unboundedOffset = getUnclampedScrollOffset(pageIndex);
+        if (!mShouldClampScrollOffset) {
+            return unboundedOffset;
+        }
+        if (Math.abs(unboundedOffset) < mClampedScrollOffsetBound) {
+            return 0;
+        }
+        return unboundedOffset
+                - Math.round(Math.signum(unboundedOffset) * mClampedScrollOffsetBound);
+    }
+
+    /**
+     * Returns how many pixels the page is offset on the currently laid out dominant axis.
+     */
+    private int getUnclampedScrollOffset(int pageIndex) {
         if (pageIndex == -1) {
             return 0;
         }
diff --git a/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt b/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt
index 6d47281..0c96539 100644
--- a/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt
+++ b/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt
@@ -94,8 +94,13 @@
         params.setProgress(/* fullscreenProgress= */ 1.0f, /* parentScale= */ 1.0f,
                 /* taskViewScale= */ 1.0f,  /* previewWidth= */ 0, dp, mPreviewPositionHelper)
 
+        // Probably  unhelpful, but also unclear how to test otherwise ¯\_(ツ)_/¯
+        val fullscreenTaskHeight = (dp.heightPx - dp.taskbarSize) *
+                (1 - (splitBounds.topTaskPercent + splitBounds.dividerHeightPercent))
+        val canvasScreenRatio = canvasHeight / fullscreenTaskHeight
+        val expectedBottomHint = dp.taskbarSize * canvasScreenRatio
         assertThat(params.mCurrentDrawnInsets.bottom)
-                .isWithin(1f).of((dp.taskbarSize * TASK_SCALE))
+                .isWithin(1f).of(expectedBottomHint)
     }
 
     @Test
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 3b92ac4..50b7563 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -368,6 +368,7 @@
     <dimen name="transient_taskbar_shadow_blur">0dp</dimen>
     <dimen name="transient_taskbar_key_shadow_distance">0dp</dimen>
     <dimen name="transient_taskbar_stashed_size">0dp</dimen>
+    <dimen name="transient_taskbar_clamped_offset_bound">0dp</dimen>
     <!-- Note that this applies to both sides of all icons, so visible space is double this. -->
     <dimen name="transient_taskbar_icon_spacing">0dp</dimen>
     <!-- Note that this applies to both sides of all icons, so visible space is double this. -->
diff --git a/res/xml/paddings_handhelds.xml b/res/xml/paddings_handhelds.xml
new file mode 100644
index 0000000..b9549a6
--- /dev/null
+++ b/res/xml/paddings_handhelds.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!-- Putting in the test/xml folder gives an error that maxEmptySpace doesn't exist -->
+<device-paddings xmlns:launcher="http://schemas.android.com/apk/res-auto" >
+
+    <device-padding
+        launcher:maxEmptySpace="9999dp">
+        <workspaceTopPadding
+            launcher:a="0.48"
+            launcher:b="0"/>
+        <workspaceBottomPadding
+            launcher:a="0.52"
+            launcher:b="0"/>
+        <hotseatBottomPadding
+            launcher:a="0"
+            launcher:b="0"/>
+    </device-padding>
+</device-paddings>
\ No newline at end of file
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 3cb3461..92530ea 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -498,10 +498,11 @@
         extraSpace = updateAvailableDimensions(res);
 
         // Now that we have all of the variables calculated, we can tune certain sizes.
-        if (isScalableGrid && inv.devicePaddings != null) {
+        if (isScalableGrid && inv.devicePaddingId != INVALID_RESOURCE_HANDLE) {
             // Paddings were created assuming no scaling, so we first unscale the extra space.
             int unscaledExtraSpace = (int) (extraSpace / cellScaleToFit);
-            DevicePadding padding = inv.devicePaddings.getDevicePadding(unscaledExtraSpace);
+            DevicePaddings devicePaddings = new DevicePaddings(context, inv.devicePaddingId);
+            DevicePadding padding = devicePaddings.getDevicePadding(unscaledExtraSpace);
 
             int paddingWorkspaceTop = padding.getWorkspaceTopPadding(unscaledExtraSpace);
             int paddingWorkspaceBottom = padding.getWorkspaceBottomPadding(unscaledExtraSpace);
@@ -1565,10 +1566,11 @@
         writer.println(prefix + pxToDpStr("extraSpace", extraSpace));
         writer.println(prefix + pxToDpStr("unscaled extraSpace", extraSpace / iconScale));
 
-        if (inv.devicePaddings != null) {
+        if (inv.devicePaddingId != INVALID_RESOURCE_HANDLE) {
             int unscaledExtraSpace = (int) (extraSpace / iconScale);
+            DevicePaddings devicePaddings = new DevicePaddings(context, inv.devicePaddingId);
             writer.println(prefix + pxToDpStr("maxEmptySpace",
-                    inv.devicePaddings.getDevicePadding(unscaledExtraSpace).getMaxEmptySpacePx()));
+                    devicePaddings.getDevicePadding(unscaledExtraSpace).getMaxEmptySpacePx()));
         }
         writer.println(prefix + pxToDpStr("workspaceTopPadding", workspaceTopPadding));
         writer.println(prefix + pxToDpStr("workspaceBottomPadding", workspaceBottomPadding));
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 87f5210..1f97535 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -47,9 +47,9 @@
 
 import androidx.annotation.DimenRes;
 import androidx.annotation.IntDef;
-import androidx.annotation.Nullable;
 import androidx.annotation.StyleRes;
 import androidx.annotation.VisibleForTesting;
+import androidx.annotation.XmlRes;
 import androidx.core.content.res.ResourcesCompat;
 
 import com.android.launcher3.icons.DotRenderer;
@@ -172,7 +172,8 @@
      * Do not query directly. see {@link DeviceProfile#isScalableGrid}.
      */
     protected boolean isScalable;
-    public int devicePaddingId;
+    @XmlRes
+    public int devicePaddingId = INVALID_RESOURCE_HANDLE;
 
     public String dbFile;
     public int defaultLayoutId;
@@ -184,9 +185,6 @@
      */
     public List<DeviceProfile> supportedProfiles = Collections.EMPTY_LIST;
 
-    @Nullable
-    public DevicePaddings devicePaddings;
-
     public Point defaultWallpaperSize;
     public Rect defaultWidgetPadding;
 
@@ -385,10 +383,6 @@
         allAppsIconSize = displayOption.allAppsIconSizes;
         allAppsIconTextSize = displayOption.allAppsIconTextSizes;
 
-        if (devicePaddingId != 0) {
-            devicePaddings = new DevicePaddings(context, devicePaddingId);
-        }
-
         inlineQsb = closestProfile.inlineQsb;
 
         // If the partner customization apk contains any grid overrides, apply them
@@ -826,7 +820,7 @@
             isScalable = a.getBoolean(
                     R.styleable.GridDisplayOption_isScalable, false);
             devicePaddingId = a.getResourceId(
-                    R.styleable.GridDisplayOption_devicePaddingId, 0);
+                    R.styleable.GridDisplayOption_devicePaddingId, INVALID_RESOURCE_HANDLE);
 
             int deviceCategory = a.getInt(R.styleable.GridDisplayOption_deviceCategory,
                     DEVICE_CATEGORY_ALL);
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 517bbf8..191d063 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -2385,6 +2385,9 @@
         ItemInfo item = d.dragInfo;
         final View child = (mDragInfo == null) ? null : mDragInfo.cell;
         if (!nearestDropOccupied) {
+            mDragTargetLayout.performReorder((int) mDragViewVisualCenter[0],
+                    (int) mDragViewVisualCenter[1], minSpanX, minSpanY, item.spanX, item.spanY,
+                    child, mTargetCell, new int[2], CellLayout.MODE_SHOW_REORDER_HINT);
             mDragTargetLayout.visualizeDropLocation(mTargetCell[0], mTargetCell[1],
                     item.spanX, item.spanY, d);
         } else if ((mDragMode == DRAG_MODE_NONE || mDragMode == DRAG_MODE_REORDER)
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index d522d88..982f6a9 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -269,6 +269,10 @@
             "ENABLE_SEARCH_RESULT_BACKGROUND_DRAWABLES", false,
             "Enable option to replace decorator-based search result backgrounds with drawables");
 
+    public static final BooleanFlag TWO_PREDICTED_ROWS_ALL_APPS_SEARCH = new DeviceFlag(
+            "TWO_PREDICTED_ROWS_ALL_APPS_SEARCH", false,
+            "Use 2 rows of app predictions in All Apps search zero-state");
+
     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");
diff --git a/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt b/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt
index fe30fdc..4e166ce 100644
--- a/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt
+++ b/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt
@@ -16,7 +16,6 @@
 package com.android.launcher3
 
 import android.content.Context
-import android.graphics.Point
 import android.graphics.PointF
 import android.graphics.Rect
 import android.util.SparseArray
@@ -26,7 +25,6 @@
 import com.android.launcher3.util.WindowBounds
 import org.junit.Before
 import org.mockito.ArgumentMatchers.any
-import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.Mockito.mock
 import java.io.PrintWriter
 import java.io.StringWriter
@@ -42,9 +40,6 @@
     protected var transposeLayoutWithOrientation: Boolean = false
     protected var useTwoPanels: Boolean = false
     protected var isGestureMode: Boolean = true
-    protected var devicePaddingsMock: DevicePaddings = mock(DevicePaddings::class.java)
-    protected var staticdevicePaddingsMock: DevicePaddings.DevicePadding =
-            mock(DevicePaddings.DevicePadding::class.java)
 
     @Before
     fun setUp() {
@@ -83,11 +78,6 @@
         whenever(info.isTablet(any())).thenReturn(false)
         whenever(info.getDensityDpi()).thenReturn(420)
         whenever(info.smallestSizeDp(any())).thenReturn(411f)
-        whenever(devicePaddingsMock.getDevicePadding(anyInt())).thenReturn(staticdevicePaddingsMock)
-        whenever(staticdevicePaddingsMock.getWorkspaceTopPadding(anyInt())).thenReturn(95)
-        whenever(staticdevicePaddingsMock.getWorkspaceBottomPadding(anyInt())).thenReturn(116)
-        whenever(staticdevicePaddingsMock.maxEmptySpacePx)
-                .thenReturn(if (isVerticalBar) if (isGestureMode) 131 else 184 else 315)
 
         this.isGestureMode = isGestureMode
         transposeLayoutWithOrientation = true
@@ -152,7 +142,7 @@
 
             inlineQsb = BooleanArray(4) { false }
 
-            devicePaddings = devicePaddingsMock
+            devicePaddingId = R.xml.paddings_handhelds
         }
     }
 
@@ -169,13 +159,6 @@
         whenever(info.isTablet(any())).thenReturn(true)
         whenever(info.getDensityDpi()).thenReturn(320)
         whenever(info.smallestSizeDp(any())).thenReturn(800f)
-        whenever(devicePaddingsMock.getDevicePadding(anyInt())).thenReturn(staticdevicePaddingsMock)
-        whenever(staticdevicePaddingsMock.getWorkspaceTopPadding(anyInt()))
-                .thenReturn(if (isLandscape) 32 else 159)
-        whenever(staticdevicePaddingsMock.getWorkspaceBottomPadding(anyInt()))
-                .thenReturn(if (isLandscape) 72 else 203)
-        whenever(staticdevicePaddingsMock.maxEmptySpacePx).thenReturn(if (isLandscape) 200 else 19998)
-
 
         this.isGestureMode = isGestureMode
         useTwoPanels = false
@@ -246,7 +229,7 @@
                     false
             )
 
-            devicePaddings = devicePaddingsMock
+            devicePaddingId = R.xml.paddings_handhelds
         }
     }
 
@@ -263,15 +246,6 @@
         whenever(info.isTablet(any())).thenReturn(true)
         whenever(info.getDensityDpi()).thenReturn(420)
         whenever(info.smallestSizeDp(any())).thenReturn(700f)
-        whenever(devicePaddingsMock.getDevicePadding(anyInt())).thenReturn(staticdevicePaddingsMock)
-
-        val topPadding = if (isLandscape) 18 else 89
-        val bottomPadding = if (isLandscape) 39 else 146
-        val maxEmptySpace = if (isLandscape) 131 else 236
-        whenever(staticdevicePaddingsMock.getWorkspaceTopPadding(anyInt())).thenReturn(topPadding)
-        whenever(staticdevicePaddingsMock.getWorkspaceBottomPadding(anyInt()))
-                .thenReturn(bottomPadding)
-        whenever(staticdevicePaddingsMock.maxEmptySpacePx).thenReturn(maxEmptySpace)
 
         this.isGestureMode = isGestureMode
         useTwoPanels = true
@@ -342,7 +316,7 @@
                     false
             )
 
-            devicePaddings = devicePaddingsMock
+            devicePaddingId = R.xml.paddings_handhelds
         }
     }