Fix split select scroll range when TaskView aren't shifting

- There is an edge case that when ClearAllButton is visible, no split translation is applied, the offset adjustment needs to be calculated differently in that case
- Also, apply the scrollOffset to the TaskViews / ClearAllButton instead of updating min/max scroll

Bug: 200537659
Test: Split right in grid, split left with clear all button, split left without clear all button
Change-Id: I869c448bbec6aec8fa070e47193a692be6f75e84
diff --git a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
index d74b6c5..2fa8b07 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
@@ -16,6 +16,7 @@
 
 package com.android.launcher3.uioverrides;
 
+import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT;
 import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE_IN_OUT;
 import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
 import static com.android.launcher3.anim.Interpolators.INSTANT;
@@ -72,6 +73,8 @@
         getTaskModalnessProperty().set(mRecentsView, state.getOverviewModalness());
         RECENTS_GRID_PROGRESS.set(mRecentsView,
                 state.displayOverviewTasksAsGrid(mLauncher.getDeviceProfile()) ? 1f : 0f);
+
+        applySplitScrollOffset(state);
     }
 
     @Override
@@ -117,6 +120,16 @@
         boolean showAsGrid = toState.displayOverviewTasksAsGrid(mLauncher.getDeviceProfile());
         setter.setFloat(mRecentsView, RECENTS_GRID_PROGRESS, showAsGrid ? 1f : 0f,
                 showAsGrid ? INSTANT : FINAL_FRAME);
+
+        applySplitScrollOffset(toState);
+    }
+
+    private void applySplitScrollOffset(@NonNull final LauncherState state) {
+        if (state == OVERVIEW_SPLIT_SELECT) {
+            mRecentsView.applySplitPrimaryScrollOffset();
+        } else {
+            mRecentsView.resetSplitPrimaryScrollOffset();
+        }
     }
 
     abstract FloatProperty getTaskModalnessProperty();
diff --git a/quickstep/src/com/android/quickstep/views/ClearAllButton.java b/quickstep/src/com/android/quickstep/views/ClearAllButton.java
index 22c87b0..86be210 100644
--- a/quickstep/src/com/android/quickstep/views/ClearAllButton.java
+++ b/quickstep/src/com/android/quickstep/views/ClearAllButton.java
@@ -66,6 +66,7 @@
     private float mGridTranslationPrimary;
     private float mGridScrollOffset;
     private float mScrollOffsetPrimary;
+    private float mSplitSelectScrollOffsetPrimary;
 
     private int mSidePadding;
 
@@ -167,6 +168,10 @@
         mScrollOffsetPrimary = scrollOffsetPrimary;
     }
 
+    public void setSplitSelectScrollOffsetPrimary(float splitSelectScrollOffsetPrimary) {
+        mSplitSelectScrollOffsetPrimary = splitSelectScrollOffsetPrimary;
+    }
+
     public float getScrollAdjustment(boolean fullscreenEnabled, boolean gridEnabled) {
         float scrollAdjustment = 0;
         if (fullscreenEnabled) {
@@ -176,6 +181,7 @@
             scrollAdjustment += mGridTranslationPrimary + mGridScrollOffset;
         }
         scrollAdjustment += mScrollOffsetPrimary;
+        scrollAdjustment += mSplitSelectScrollOffsetPrimary;
         return scrollAdjustment;
     }
 
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 023a926..af78cf6 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -2643,8 +2643,7 @@
      * and then animates it into the split position that was desired
      */
     private void createInitialSplitSelectAnimation(PendingAnimation anim) {
-        float placeholderHeight = getResources().getDimension(R.dimen.split_placeholder_size);
-        mOrientationHandler.getInitialSplitPlaceholderBounds((int) placeholderHeight,
+        mOrientationHandler.getInitialSplitPlaceholderBounds(mSplitPlaceholderSize,
                 mActivity.getDeviceProfile(),
                 mSplitSelectStateController.getActiveSplitStagePosition(), mTempRect);
 
@@ -3238,14 +3237,13 @@
         }
 
         Rect splitBounds = new Rect();
-        float placeholderSize = getResources().getDimension(R.dimen.split_placeholder_size);
         // This acts as a best approximation on where the splitplaceholder view would be,
         // doesn't need to be exact necessarily. This also doesn't need to take translations
         // into account since placeholder view is not translated
         if (stagePosition == SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT) {
-            splitBounds.set((int) (getWidth() - placeholderSize), 0, getWidth(), getHeight());
+            splitBounds.set(getWidth() - mSplitPlaceholderSize, 0, getWidth(), getHeight());
         } else {
-            splitBounds.set(0, 0, (int) (placeholderSize), getHeight());
+            splitBounds.set(0, 0, mSplitPlaceholderSize, getHeight());
         }
         Rect taskBounds = new Rect();
         int taskCount = getTaskViewCount();
@@ -3746,6 +3744,50 @@
     }
 
     /**
+     * Apply scroll offset to children of RecentsView when entering split select.
+     */
+    public void applySplitPrimaryScrollOffset() {
+        if (!mActivity.getDeviceProfile().isLandscape || !showAsGrid()) {
+            return;
+        }
+
+        @StagePosition int position = mSplitSelectStateController.getActiveSplitStagePosition();
+        boolean shouldShiftThumbnailsForSplitSelect = shouldShiftThumbnailsForSplitSelect(
+                position);
+        boolean expandLeft = false;
+        boolean expandRight = false;
+        if (mIsRtl) {
+            if (position == SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT
+                    && shouldShiftThumbnailsForSplitSelect) {
+                expandLeft = true;
+            } else if (position == SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT) {
+                if (shouldShiftThumbnailsForSplitSelect) {
+                    expandRight = true;
+                } else {
+                    expandLeft = true;
+                }
+            }
+        } // TODO(b/200537659): Handle system RTL.
+        if (expandRight) {
+            for (int i = 0; i < getTaskViewCount(); i++) {
+                getTaskViewAt(i).setSplitScrollOffsetPrimary(mSplitPlaceholderSize);
+            }
+        } else if (expandLeft) {
+            mClearAllButton.setSplitSelectScrollOffsetPrimary(-mSplitPlaceholderSize);
+        }
+    }
+
+    /**
+     * Reset scroll offset on children of RecentsView when exiting split select.
+     */
+    public void resetSplitPrimaryScrollOffset() {
+        for (int i = 0; i < getTaskViewCount(); i++) {
+            getTaskViewAt(i).setSplitScrollOffsetPrimary(0);
+        }
+        mClearAllButton.setSplitSelectScrollOffsetPrimary(0);
+    }
+
+    /**
      * Resets the visuals when exit modal state.
      */
     public void resetModalVisuals() {
@@ -4357,27 +4399,16 @@
     @Override
     protected int computeMinScroll() {
         if (getTaskViewCount() > 0) {
-            int minScroll;
-            boolean isLandscapeGridSplit = mActivity.getDeviceProfile().isLandscape
-                    && showAsGrid() && isSplitSelectionActive();
             if (mIsRtl) {
                 // If we aren't showing the clear all button, use the rightmost task as the min
                 // scroll.
-                minScroll = getScrollForPage(mDisallowScrollToClearAll ? indexOfChild(
+                return getScrollForPage(mDisallowScrollToClearAll ? indexOfChild(
                         getTaskViewAt(getTaskViewCount() - 1)) : indexOfChild(mClearAllButton));
-                if (isLandscapeGridSplit
-                        && mSplitSelectStateController.getActiveSplitStagePosition()
-                        == SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT) {
-                    minScroll -= mSplitPlaceholderSize;
-                }
             } else {
                 TaskView focusedTaskView = mShowAsGridLastOnLayout ? getFocusedTaskView() : null;
-                minScroll = getScrollForPage(focusedTaskView != null ? indexOfChild(focusedTaskView)
+                return getScrollForPage(focusedTaskView != null ? indexOfChild(focusedTaskView)
                         : 0);
-                // TODO(b/200537659): Adjust according to mSplitPlaceholderSize when
-                //  isLandscapeGridSplit is true.
             }
-            return minScroll;
         }
         return super.computeMinScroll();
     }
@@ -4385,27 +4416,16 @@
     @Override
     protected int computeMaxScroll() {
         if (getTaskViewCount() > 0) {
-            int maxScroll;
-            boolean isLandscapeGridSplit = mActivity.getDeviceProfile().isLandscape
-                    && showAsGrid() && isSplitSelectionActive();
             if (mIsRtl) {
                 TaskView focusedTaskView = mShowAsGridLastOnLayout ? getFocusedTaskView() : null;
-                maxScroll = getScrollForPage(focusedTaskView != null ? indexOfChild(focusedTaskView)
+                return getScrollForPage(focusedTaskView != null ? indexOfChild(focusedTaskView)
                         : 0);
-                if (isLandscapeGridSplit
-                        && mSplitSelectStateController.getActiveSplitStagePosition()
-                        == SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT) {
-                    maxScroll += mSplitPlaceholderSize;
-                }
             } else {
                 // If we aren't showing the clear all button, use the leftmost task as the min
                 // scroll.
-                maxScroll = getScrollForPage(mDisallowScrollToClearAll ? indexOfChild(
+                return getScrollForPage(mDisallowScrollToClearAll ? indexOfChild(
                         getTaskViewAt(getTaskViewCount() - 1)) : indexOfChild(mClearAllButton));
-                // TODO(b/200537659): Adjust according to mSplitPlaceholderSize when
-                //  isLandscapeGridSplit is true.
             }
-            return maxScroll;
         }
         return super.computeMaxScroll();
     }
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index ea8282f..31a73e9 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -389,6 +389,7 @@
     // Used when in SplitScreenSelectState
     private float mSplitSelectTranslationY;
     private float mSplitSelectTranslationX;
+    private float mSplitSelectScrollOffsetPrimary;
 
     private ObjectAnimator mIconAndDimAnimator;
     private float mIconScaleAnimStartProgress = 0;
@@ -1031,6 +1032,11 @@
         mSplitSelectTranslationY = y;
         applyTranslationY();
     }
+
+    public void setSplitScrollOffsetPrimary(float splitSelectScrollOffsetPrimary) {
+        mSplitSelectScrollOffsetPrimary = splitSelectScrollOffsetPrimary;
+    }
+
     private void setDismissTranslationX(float x) {
         mDismissTranslationX = x;
         applyTranslationX();
@@ -1101,6 +1107,7 @@
         } else {
             scrollAdjustment += getPrimaryNonGridTranslationProperty().get(this);
         }
+        scrollAdjustment += mSplitSelectScrollOffsetPrimary;
         return scrollAdjustment;
     }