TaskView has fullscreen progress instead of boolean

This way we can update the insets of the adjacent task throughout
the swipe up from an app.

Bug: 111699315
Change-Id: Ieeaa5b6667e44f82e7e097acb9f0552609b15809
diff --git a/quickstep/src/com/android/quickstep/QuickScrubController.java b/quickstep/src/com/android/quickstep/QuickScrubController.java
index c44ccd3..b07f8af 100644
--- a/quickstep/src/com/android/quickstep/QuickScrubController.java
+++ b/quickstep/src/com/android/quickstep/QuickScrubController.java
@@ -126,11 +126,13 @@
         if (mIsQuickSwitch) {
             mShouldSwitchToNext = true;
             mPrevProgressDelta = 0;
-            if (mRecentsView.getTaskViewCount() > 0) {
-                mRecentsView.getTaskViewAt(0).setFullscreen(true);
+            TaskView runningTaskView = mRecentsView.getRunningTaskView();
+            TaskView nextTaskView = mRecentsView.getNextTaskView();
+            if (runningTaskView != null) {
+                runningTaskView.setFullscreenProgress(1);
             }
-            if (mRecentsView.getTaskViewCount() > 1) {
-                mRecentsView.getTaskViewAt(1).setFullscreen(true);
+            if (nextTaskView != null) {
+                nextTaskView.setFullscreenProgress(1);
             }
         }
 
@@ -161,11 +163,13 @@
                     mWaitingForTaskLaunch = false;
                     if (mIsQuickSwitch) {
                         mIsQuickSwitch = false;
-                        if (mRecentsView.getTaskViewCount() > 0) {
-                            mRecentsView.getTaskViewAt(0).setFullscreen(false);
+                        TaskView runningTaskView = mRecentsView.getRunningTaskView();
+                        TaskView nextTaskView = mRecentsView.getNextTaskView();
+                        if (runningTaskView != null) {
+                            runningTaskView.setFullscreenProgress(0);
                         }
-                        if (mRecentsView.getTaskViewCount() > 1) {
-                            mRecentsView.getTaskViewAt(1).setFullscreen(false);
+                        if (nextTaskView != null) {
+                            nextTaskView.setFullscreenProgress(0);
                         }
                     }
 
@@ -267,12 +271,12 @@
 
     public void onQuickScrubProgress(float progress) {
         if (mIsQuickSwitch) {
-            TaskView currentPage = mRecentsView.getTaskViewAt(0);
-            TaskView nextPage = mRecentsView.getTaskViewAt(1);
+            TaskView currentPage = mRecentsView.getRunningTaskView();
+            TaskView nextPage = mRecentsView.getNextTaskView();
             if (currentPage == null || nextPage == null) {
                 return;
             }
-            if (!mFinishedTransitionToQuickScrub) {
+            if (!mFinishedTransitionToQuickScrub || mStartProgress <= 0) {
                 mStartProgress = mEndProgress = progress;
             } else {
                 float progressDelta = progress - mEndProgress;
diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
index c403e27..98e26ef 100644
--- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -615,6 +615,11 @@
                     HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
             }
         }
+        // Update insets of the next previous task, as we might switch to it.
+        TaskView nextTaskView = mRecentsView == null ? null : mRecentsView.getNextTaskView();
+        if (mInteractionType == INTERACTION_NORMAL && nextTaskView != null) {
+            nextTaskView.setFullscreenProgress(1 - mCurrentShift.value);
+        }
 
         if (mLauncherTransitionController == null || mLauncherTransitionController
                 .getAnimationPlayer().isStarted()) {
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 854e728..7842fa4 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -760,14 +760,14 @@
         if (runningTaskView == null) {
             // Launch the first task
             if (getTaskViewCount() > 0) {
-                ((TaskView) getChildAt(0)).launchTask(true /* animate */);
+                getTaskViewAt(0).launchTask(true /* animate */);
             }
         } else {
-            // Get the next launch task
-            int runningTaskIndex = indexOfChild(runningTaskView);
-            int nextTaskIndex = Math.max(0, Math.min(getTaskViewCount() - 1, runningTaskIndex + 1));
-            if (nextTaskIndex < getTaskViewCount()) {
-                ((TaskView) getChildAt(nextTaskIndex)).launchTask(true /* animate */);
+            TaskView nextTaskView = getNextTaskView();
+            if (nextTaskView != null) {
+                nextTaskView.launchTask(true /* animate */);
+            } else {
+                runningTaskView.launchTask(true /* animate */);
             }
         }
     }
@@ -1140,6 +1140,19 @@
         child.setAlpha(mContentAlpha);
     }
 
+    /**
+     * @return The most recent task that is older than the currently running task. If there is
+     * currently no running task or there is no task older than it, then return null.
+     */
+    @Nullable
+    public TaskView getNextTaskView() {
+        TaskView runningTaskView = getRunningTaskView();
+        if (runningTaskView == null) {
+            return null;
+        }
+        return getTaskViewAt(indexOfChild(runningTaskView) + 1);
+    }
+
     public TaskView getTaskViewAt(int index) {
         View child = getChildAt(index);
         return child == mClearAllButton ? null : (TaskView) child;
@@ -1261,12 +1274,14 @@
                         toScale, toTranslationY);
                 scaleAndTranslation[1] = -scaleAndTranslation[1];
                 anim.play(createAnimForChild(adjacentTask, scaleAndTranslation));
+                anim.play(ObjectAnimator.ofFloat(adjacentTask, TaskView.FULLSCREEN_PROGRESS, 1));
             }
             if (taskIndex + 1 < getTaskViewCount()) {
                 TaskView adjacentTask = getTaskViewAt(taskIndex + 1);
                 float[] scaleAndTranslation = getAdjacentScaleAndTranslation(centerTask,
                         toScale, toTranslationY);
                 anim.play(createAnimForChild(adjacentTask, scaleAndTranslation));
+                anim.play(ObjectAnimator.ofFloat(adjacentTask, TaskView.FULLSCREEN_PROGRESS, 1));
             }
         } else {
             // We are launching an adjacent task, so parallax the center and other adjacent task.
diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
index 6c5ddd8..c2403a3 100644
--- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -81,6 +81,7 @@
 
     private float mClipBottom = -1;
     private Rect mScaledInsets = new Rect();
+    private boolean mIsRotated;
 
     private Task mTask;
     private ThumbnailData mThumbnailData;
@@ -144,7 +145,7 @@
 
     /**
      * Sets the alpha of the dim layer on top of this view.
-     *
+     * <p>
      * If dimAlpha is 0, no dimming is applied; if dimAlpha is 1, the thumbnail will be black.
      */
     public void setDimAlpha(float dimAlpha) {
@@ -188,13 +189,18 @@
 
     @Override
     protected void onDraw(Canvas canvas) {
-        if (((TaskView) getParent()).isFullscreen()) {
+        float fullscreenProgress = ((TaskView) getParent()).getFullscreenProgress();
+        if (mIsRotated) {
+            // Don't show insets in the wrong orientation.
+            fullscreenProgress = 0;
+        }
+        if (fullscreenProgress > 0) {
             // Draw the insets if we're being drawn fullscreen (we do this for quick switch).
             drawOnCanvas(canvas,
-                    -mScaledInsets.left,
-                    -mScaledInsets.top,
-                    getMeasuredWidth() + mScaledInsets.right,
-                    getMeasuredHeight() + mScaledInsets.bottom,
+                    -mScaledInsets.left * fullscreenProgress,
+                    -mScaledInsets.top * fullscreenProgress,
+                    getMeasuredWidth() + mScaledInsets.right * fullscreenProgress,
+                    getMeasuredHeight() + mScaledInsets.bottom * fullscreenProgress,
                     mCornerRadius);
         } else {
             drawOnCanvas(canvas, 0, 0, getMeasuredWidth(), getMeasuredHeight(), mCornerRadius);
@@ -241,11 +247,11 @@
     }
 
     private void updateThumbnailMatrix() {
-        boolean rotate = false;
+        mIsRotated = false;
         mClipBottom = -1;
         if (mBitmapShader != null && mThumbnailData != null) {
             float scale = mThumbnailData.scale;
-            Rect thumbnailInsets  = mThumbnailData.insets;
+            Rect thumbnailInsets = mThumbnailData.insets;
             final float thumbnailWidth = mThumbnailData.thumbnail.getWidth() -
                     (thumbnailInsets.left + thumbnailInsets.right) * scale;
             final float thumbnailHeight = mThumbnailData.thumbnail.getHeight() -
@@ -262,12 +268,12 @@
                 final Configuration configuration =
                         getContext().getResources().getConfiguration();
                 // Rotate the screenshot if not in multi-window mode
-                rotate = FeatureFlags.OVERVIEW_USE_SCREENSHOT_ORIENTATION &&
+                mIsRotated = FeatureFlags.OVERVIEW_USE_SCREENSHOT_ORIENTATION &&
                         configuration.orientation != mThumbnailData.orientation &&
                         !mActivity.isInMultiWindowModeCompat() &&
                         mThumbnailData.windowingMode == WINDOWING_MODE_FULLSCREEN;
                 // Scale the screenshot to always fit the width of the card.
-                thumbnailScale = rotate
+                thumbnailScale = mIsRotated
                         ? getMeasuredWidth() / thumbnailHeight
                         : getMeasuredWidth() / thumbnailWidth;
             }
@@ -275,7 +281,7 @@
             mScaledInsets.set(thumbnailInsets);
             Utilities.scaleRect(mScaledInsets, thumbnailScale);
 
-            if (rotate) {
+            if (mIsRotated) {
                 int rotationDir = profile.isVerticalBarLayout() && !profile.isSeascape() ? -1 : 1;
                 mMatrix.setRotate(90 * rotationDir);
                 int newLeftInset = rotationDir == 1 ? thumbnailInsets.bottom : thumbnailInsets.top;
@@ -299,7 +305,7 @@
             mMatrix.postScale(thumbnailScale, thumbnailScale);
             mBitmapShader.setLocalMatrix(mMatrix);
 
-            float bitmapHeight = Math.max((rotate ? thumbnailWidth : thumbnailHeight)
+            float bitmapHeight = Math.max((mIsRotated ? thumbnailWidth : thumbnailHeight)
                     * thumbnailScale, 0);
             if (Math.round(bitmapHeight) < getMeasuredHeight()) {
                 mClipBottom = bitmapHeight;
@@ -307,7 +313,7 @@
             mPaint.setShader(mBitmapShader);
         }
 
-        if (rotate) {
+        if (mIsRotated) {
             // The overlay doesn't really work when the screenshot is rotated, so don't add it.
             mOverlay.reset();
         } else {
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index c2d7d78..bb6f514 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -102,6 +102,19 @@
                 }
             };
 
+    public static final FloatProperty<TaskView> FULLSCREEN_PROGRESS =
+            new FloatProperty<TaskView>("fullscreenProgress") {
+                @Override
+                public void setValue(TaskView taskView, float v) {
+                    taskView.setFullscreenProgress(v);
+                }
+
+                @Override
+                public Float get(TaskView taskView) {
+                    return taskView.mFullscreenProgress;
+                }
+            };
+
     private static final FloatProperty<TaskView> FOCUS_TRANSITION =
             new FloatProperty<TaskView>("focusTransition") {
                 @Override
@@ -140,7 +153,7 @@
     private DigitalWellBeingToast mDigitalWellBeingToast;
     private float mCurveScale;
     private float mZoomScale;
-    private boolean mIsFullscreen;
+    private float mFullscreenProgress;
 
     private Animator mIconAndDimAnimator;
     private float mFocusTransitionProgress = 1;
@@ -341,6 +354,10 @@
         setTranslationZ(0);
         setAlpha(1f);
         setIconScaleAndDim(1);
+        if (!getRecentsView().getQuickScrubController().isQuickSwitch()) {
+            // Reset full screen progress unless we are doing back to back quick switch.
+            setFullscreenProgress(0);
+        }
     }
 
     @Override
@@ -499,15 +516,21 @@
 
     /**
      * Hides the icon and shows insets when this TaskView is about to be shown fullscreen.
+     * @param progress: 0 = show icon and no insets; 1 = don't show icon and show full insets.
      */
-    public void setFullscreen(boolean isFullscreen) {
-        mIsFullscreen = isFullscreen;
-        mIconView.setVisibility(mIsFullscreen ? INVISIBLE : VISIBLE);
-        setClipChildren(!mIsFullscreen);
-        setClipToPadding(!mIsFullscreen);
+    public void setFullscreenProgress(float progress) {
+        if (progress == mFullscreenProgress) {
+            return;
+        }
+        mFullscreenProgress = progress;
+        boolean isFullscreen = mFullscreenProgress > 0;
+        mIconView.setVisibility(isFullscreen ? INVISIBLE : VISIBLE);
+        setClipChildren(!isFullscreen);
+        setClipToPadding(!isFullscreen);
+        getThumbnail().invalidate();
     }
 
-    public boolean isFullscreen() {
-        return mIsFullscreen;
+    public float getFullscreenProgress() {
+        return mFullscreenProgress;
     }
 }