Preparation for adding the AddDesktopButton to the view hierarchy

- Update the logic of `getRunningTaskExpectedIndex` to make sure it
  will still work with the AddDesktopButton added as the first child
  of the RecentsView.
- Introduce `mTaskAlignmentTranslationY` to ClearAllButton, and set
  it through RecentsView. Thus, the logic can be used by the
  AddDesktopButton as well. etc.

Flag: EXEMPT refactor
Bug: 382057498
Test: Manual
Change-Id: I6d0c031fe1fc0b4c198b9c890a27a69d911d38d9
diff --git a/quickstep/src/com/android/quickstep/views/ClearAllButton.java b/quickstep/src/com/android/quickstep/views/ClearAllButton.java
index 72f97df..2426697 100644
--- a/quickstep/src/com/android/quickstep/views/ClearAllButton.java
+++ b/quickstep/src/com/android/quickstep/views/ClearAllButton.java
@@ -30,7 +30,6 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
-import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Flags;
 import com.android.launcher3.R;
 import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
@@ -66,7 +65,6 @@
                 }
             };
 
-    private final RecentsViewContainer mContainer;
     private float mScrollAlpha = 1;
     private float mContentAlpha = 1;
     private float mVisibilityAlpha = 1;
@@ -78,6 +76,7 @@
     private float mNormalTranslationPrimary;
     private float mFullscreenTranslationPrimary;
     private float mGridTranslationPrimary;
+    private float mTaskAlignmentTranslationY;
     private float mGridScrollOffset;
     private float mScrollOffsetPrimary;
 
@@ -90,7 +89,6 @@
     public ClearAllButton(Context context, AttributeSet attrs) {
         super(context, attrs);
         mIsRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
-        mContainer = RecentsViewContainer.containerFromContext(context);
 
         if (Flags.enableFocusOutline()) {
             TypedArray styledAttrs = context.obtainStyledAttributes(attrs,
@@ -241,6 +239,15 @@
         applyPrimaryTranslation();
     }
 
+    /**
+     * Sets `mTaskAlignmentTranslationY` to the given `value`. In order to put the button at the
+     * middle in the secondary coordinate.
+     */
+    public void setTaskAlignmentTranslationY(float value) {
+        mTaskAlignmentTranslationY = value;
+        applySecondaryTranslation();
+    }
+
     public void setGridTranslationPrimary(float gridTranslationPrimary) {
         mGridTranslationPrimary = gridTranslationPrimary;
         applyPrimaryTranslation();
@@ -299,7 +306,7 @@
         RecentsPagedOrientationHandler orientationHandler =
                 recentsView.getPagedOrientationHandler();
         orientationHandler.getPrimaryViewTranslate().set(this,
-                orientationHandler.getPrimaryValue(0f, getOriginalTranslationY())
+                orientationHandler.getPrimaryValue(0f, mTaskAlignmentTranslationY)
                         + mNormalTranslationPrimary + getFullscreenTrans(
                         mFullscreenTranslationPrimary) + getGridTrans(mGridTranslationPrimary));
     }
@@ -313,7 +320,7 @@
         RecentsPagedOrientationHandler orientationHandler =
                 recentsView.getPagedOrientationHandler();
         orientationHandler.getSecondaryViewTranslate().set(this,
-                orientationHandler.getSecondaryValue(0f, getOriginalTranslationY()));
+                orientationHandler.getSecondaryValue(0f, mTaskAlignmentTranslationY));
     }
 
     private float getFullscreenTrans(float endTranslation) {
@@ -323,15 +330,4 @@
     private float getGridTrans(float endTranslation) {
         return mGridProgress > 0 ? endTranslation : 0;
     }
-
-    /**
-     * Get the Y translation that is set in the original layout position, before scrolling.
-     */
-    private float getOriginalTranslationY() {
-        DeviceProfile deviceProfile = mContainer.getDeviceProfile();
-        if (deviceProfile.isTablet) {
-            return deviceProfile.overviewRowSpacing;
-        }
-        return deviceProfile.overviewTaskThumbnailTopMarginPx / 2.0f;
-    }
 }
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index e621d0c..b6c976d 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -1834,20 +1834,23 @@
     }
 
     private int getRunningTaskExpectedIndex(TaskView runningTaskView) {
+        int firstTaskViewIndex = indexOfChild(getFirstTaskView());
         if (mContainer.getDeviceProfile().isTablet) {
             if (runningTaskView instanceof DesktopTaskView) {
-                return 0; // Desktop running task is always in front.
+                return firstTaskViewIndex; // Desktop running task is always in front.
             } else if (enableLargeDesktopWindowingTile()) {
-                return getDesktopTaskViewCount(); // Other running task is behind desktop tasks.
+                // Other running task is behind desktop tasks.
+                return getDesktopTaskViewCount() + firstTaskViewIndex;
             } else {
-                return 0;
+                return firstTaskViewIndex;
             }
         } else {
             int currentIndex = indexOfChild(runningTaskView);
             if (currentIndex != -1) {
                 return currentIndex; // Keep the position if running task already in layout.
             } else {
-                return 0; // New running task are added to the front to begin with.
+                // New running task are added to the front to begin with.
+                return firstTaskViewIndex;
             }
         }
     }
@@ -1988,9 +1991,7 @@
             }
         }
 
-        if (!taskGroups.isEmpty()) {
-            addView(mClearAllButton);
-        }
+        addView(mClearAllButton);
 
         // Keep same previous focused task
         TaskView newFocusedTaskView = null;
@@ -2093,7 +2094,7 @@
         CollectionsKt
                 .filter(getTaskViews(), taskView -> !isGestureActive() || !taskView.isRunningTask())
                 .forEach(this::removeView);
-        if (!hasTaskViews() && indexOfChild(mClearAllButton) != -1) {
+        if (!hasTaskViews()) {
             removeView(mClearAllButton);
         }
     }
@@ -2321,6 +2322,9 @@
 
         mClearAllButton.setFullscreenTranslationPrimary(accumulatedTranslationX);
 
+        float taskAlignmentTranslationY = getTaskAlignmentTranslationY();
+        mClearAllButton.setTaskAlignmentTranslationY(taskAlignmentTranslationY);
+
         updateGridProperties();
     }
 
@@ -2347,6 +2351,19 @@
         return getTaskBounds(mSelectedTask);
     }
 
+    /**
+     * Get the Y translation that should be applied to the non-TaskView item inside the RecentsView
+     * (ClearAllButton and AddDesktopButton) in the original layout position, before scrolling. This
+     * is done to make sure the button is aligned to the middle of Task thumbnail in y coordinate.
+     */
+    private float getTaskAlignmentTranslationY() {
+        DeviceProfile deviceProfile = mContainer.getDeviceProfile();
+        if (deviceProfile.isTablet) {
+            return deviceProfile.overviewRowSpacing;
+        }
+        return deviceProfile.overviewTaskThumbnailTopMarginPx / 2.0f;
+    }
+
     private Rect getTaskBounds(TaskView taskView) {
         int selectedPage = indexOfChild(taskView);
         int primaryScroll = getPagedOrientationHandler().getPrimaryScroll(this);
@@ -2625,7 +2642,6 @@
         setFocusedTaskViewId(INVALID_TASK_ID);
         mAnyTaskHasBeenDismissed = false;
 
-
         if (enableRefactorTaskThumbnail()) {
             // TODO(b/353917593): RecentsView is never destroyed, so its dependencies need to
             //  be cleaned up during the reset, but re-created when RecentsView is "resumed".
@@ -4049,7 +4065,7 @@
                                 pageToSnapTo = indexOfChild(mClearAllButton);
                             } else if (isClearAllHidden) {
                                 // Snap to focused task if clear all is hidden.
-                                pageToSnapTo = 0;
+                                pageToSnapTo = indexOfChild(getFirstTaskView());
                             }
                         } else {
                             // Get the id of the task view we will snap to based on the current
@@ -4067,7 +4083,7 @@
                                     } else {
                                         // Won't focus next task in split select, so snap to the
                                         // first task.
-                                        pageToSnapTo = 0;
+                                        pageToSnapTo = indexOfChild(getFirstTaskView());
                                         calculateScrollDiff = false;
                                     }
                                 } else {