From f567e7e2faba82a9278cd1626c00ebe5fa36b467 Mon Sep 17 00:00:00 2001 From: vinayjoglekar Date: Wed, 20 Nov 2024 14:38:31 +0000 Subject: [PATCH] Fix animation while hiding Desktop tasks during split 1. Scale down desktop tasks 2. Change translation start when all desktop tasks need to hidden Fix: 378447894 Flag: com.android.launcher3.enable_large_desktop_windowing_tile Test: Manual: Add desktop window and split focussed task, desktop task(s)(also in RTL) Change-Id: I25c11d654539efc6529a2e995d8d00cbf73c870d --- .../quickstep/util/SplitAnimationTimings.java | 11 +++ .../android/quickstep/views/RecentsView.java | 73 +++++++++++++++---- 2 files changed, 69 insertions(+), 15 deletions(-) diff --git a/quickstep/src/com/android/quickstep/util/SplitAnimationTimings.java b/quickstep/src/com/android/quickstep/util/SplitAnimationTimings.java index 90569b49a4..3a6d9b027b 100644 --- a/quickstep/src/com/android/quickstep/util/SplitAnimationTimings.java +++ b/quickstep/src/com/android/quickstep/util/SplitAnimationTimings.java @@ -17,6 +17,7 @@ package com.android.quickstep.util; import static com.android.app.animation.Interpolators.LINEAR; +import static com.android.app.animation.Interpolators.STANDARD; import android.view.animation.Interpolator; @@ -38,6 +39,8 @@ public interface SplitAnimationTimings { int TABLET_APP_PAIR_LAUNCH_DURATION = 998; /** Total duration (ms) for launching an app pair from its icon on phones. */ int PHONE_APP_PAIR_LAUNCH_DURATION = 915; + /** Total duration (ms) for fading out desktop tasks in split mode. */ + int DESKTOP_FADE_OUT_DURATION = 200; // Initialize timing classes so they can be accessed statically SplitAnimationTimings TABLET_OVERVIEW_TO_SPLIT = new TabletOverviewToSplitTimings(); @@ -83,6 +86,10 @@ public interface SplitAnimationTimings { return (float) getStagedRectSlideEnd() / getDuration(); } + default float getDesktopFadeSplitAnimationEndOffset() { + return (float) DESKTOP_FADE_OUT_DURATION / getDuration(); + } + // DEFAULT VALUES: We define default values here so that SplitAnimationTimings can be used // flexibly in animation-running functions, e.g. a single function that handles 2 types of split // animations. The values are not intended to be used, and can safely be removed if refactoring @@ -124,5 +131,9 @@ public interface SplitAnimationTimings { default float getAppRevealEndOffset() { return 0; } default Interpolator getCellSplitInterpolator() { return LINEAR; } default Interpolator getIconFadeInterpolator() { return LINEAR; } + + default Interpolator getDesktopTaskScaleInterpolator() { + return STANDARD; + } } diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 6ab3e286a5..fbefd04b84 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -29,7 +29,7 @@ import static com.android.app.animation.Interpolators.EMPHASIZED_DECELERATE; import static com.android.app.animation.Interpolators.FAST_OUT_SLOW_IN; import static com.android.app.animation.Interpolators.FINAL_FRAME; import static com.android.app.animation.Interpolators.LINEAR; -import static com.android.app.animation.Interpolators.OVERSHOOT_0_75; +import static com.android.app.animation.Interpolators.EMPHASIZED; import static com.android.app.animation.Interpolators.clampToProgress; import static com.android.launcher3.AbstractFloatingView.TYPE_REBIND_SAFE; import static com.android.launcher3.AbstractFloatingView.TYPE_TASK_MENU; @@ -3649,6 +3649,7 @@ public abstract class RecentsView< // Grid specific properties. boolean isFocusedTaskDismissed = false; boolean isStagingFocusedTask = false; + boolean isSlidingTasks = false; TaskView nextFocusedTaskView = null; boolean nextFocusedTaskFromTop = false; float dismissedTaskWidth = 0; @@ -3704,6 +3705,7 @@ public abstract class RecentsView< scrollDiffPerPage = Math.abs(oldScroll[1] - oldScroll[0]); } + isSlidingTasks = isStagingFocusedTask || areAllDesktopTasksDismissed; float dismissTranslationInterpolationEnd = 1; boolean closeGapBetweenClearAll = false; boolean isClearAllHidden = isClearAllHidden(); @@ -3844,14 +3846,14 @@ public abstract class RecentsView< AnimUtils.getDeviceOverviewToSplitTimings(mContainer.getDeviceProfile().isTablet); int distanceFromDismissedTask = 1; - int stagingTranslation = 0; - if (isStagingFocusedTask || areAllDesktopTasksDismissed) { + int slidingTranslation = 0; + if (isSlidingTasks) { int nextSnappedPage = isStagingFocusedTask ? indexOfChild(mUtils.getFirstSmallTaskView(getTaskViews())) : mUtils.getDesktopTaskViewCount(getTaskViews()); - stagingTranslation = getPagedOrientationHandler().getPrimaryScroll(this) + slidingTranslation = getPagedOrientationHandler().getPrimaryScroll(this) - getScrollForPage(nextSnappedPage); - stagingTranslation += mIsRtl ? newClearAllShortTotalWidthTranslation + slidingTranslation += mIsRtl ? newClearAllShortTotalWidthTranslation : -newClearAllShortTotalWidthTranslation; } mDismissPrimaryTranslations = new int[taskCount]; @@ -3879,12 +3881,12 @@ public abstract class RecentsView< // Animate task with index >= dismissed index and in the same row as the // dismissed index or next focused index. Offset successive task dismissal // durations for a staggered effect. - int staggerColumn = isStagingFocusedTask + int staggerColumn = isSlidingTasks ? (int) Math.ceil(distanceFromDismissedTask / 2f) : distanceFromDismissedTask; // Set timings based on if user is initiating splitscreen on the focused task, // or splitting/dismissing some other task. - float animationStartProgress = isStagingFocusedTask + float animationStartProgress = isSlidingTasks ? Utilities.boundToRange( splitTimings.getGridSlideStartOffset() + (splitTimings.getGridSlideStaggerOffset() @@ -3895,7 +3897,7 @@ public abstract class RecentsView< INITIAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET + ADDITIONAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET * staggerColumn, 0f, dismissTranslationInterpolationEnd); - float animationEndProgress = isStagingFocusedTask + float animationEndProgress = isSlidingTasks ? Utilities.boundToRange( splitTimings.getGridSlideStartOffset() + (splitTimings.getGridSlideStaggerOffset() * staggerColumn) @@ -3903,7 +3905,8 @@ public abstract class RecentsView< 0f, dismissTranslationInterpolationEnd) : dismissTranslationInterpolationEnd; - Interpolator dismissInterpolator = isStagingFocusedTask ? OVERSHOOT_0_75 : LINEAR; + + Interpolator dismissInterpolator = isSlidingTasks ? EMPHASIZED : LINEAR; float primaryTranslation = 0; if (taskView == nextFocusedTaskView) { @@ -3930,14 +3933,30 @@ public abstract class RecentsView< primaryTranslation += nextFocusedTaskView != null ? nextFocusedTaskWidth : dismissedTaskWidth; } - primaryTranslation += mIsRtl ? stagingTranslation : -stagingTranslation; + if (!(taskView instanceof DesktopTaskView)) { + primaryTranslation += mIsRtl ? slidingTranslation : -slidingTranslation; + } if (primaryTranslation != 0) { float finalTranslation = mIsRtl ? primaryTranslation : -primaryTranslation; - anim.setFloat(taskView, taskView.getPrimaryDismissTranslationProperty(), - finalTranslation, + float startTranslation = 0; + if (!(taskView instanceof DesktopTaskView) && slidingTranslation != 0) { + startTranslation = isTaskViewVisible(taskView) ? 0 + : finalTranslation + (mIsRtl ? -mLastComputedTaskSize.right + : mLastComputedTaskSize.right); + animationStartProgress = Utilities.boundToRange( + animationStartProgress + + splitTimings.getDesktopFadeSplitAnimationEndOffset(), + 0f, + dismissTranslationInterpolationEnd); + } + Animator dismissAnimator = ObjectAnimator.ofFloat(taskView, + taskView.getPrimaryDismissTranslationProperty(), + startTranslation, finalTranslation); + dismissAnimator.setInterpolator( clampToProgress(dismissInterpolator, animationStartProgress, animationEndProgress)); + anim.add(dismissAnimator); mDismissPrimaryTranslations[i] = (int) finalTranslation; distanceFromDismissedTask++; } @@ -5114,13 +5133,37 @@ public abstract class RecentsView< */ public void handleDesktopTaskInSplitSelectState(PendingAnimation builder, Interpolator deskTopFadeInterPolator) { + SplitAnimationTimings timings = AnimUtils.getDeviceOverviewToSplitTimings( + mContainer.getDeviceProfile().isTablet); if (enableLargeDesktopWindowingTile()) { - for (TaskView taskView : getTaskViews()) { + for (int i = 0; i < getTaskViewCount(); i++) { + TaskView taskView = requireTaskViewAt(i); if (taskView instanceof DesktopTaskView) { - // Correcting the animation for split mode since we hide DW in split. + // Setting pivot to scale down from screen centre. + if (i >= mCurrentPage - 1 && i <= mCurrentPage + 1) { + float pivotX; + if (i == mCurrentPage - 1) { + pivotX = mIsRtl ? taskView.getWidth() / 2f - mPageSpacing + - taskView.getWidth() + : taskView.getWidth() / 2f + mPageSpacing + taskView.getWidth(); + } else if (i == mCurrentPage) { + pivotX = taskView.getWidth() / 2f; + } else { + pivotX = mIsRtl ? taskView.getWidth() + mPageSpacing + + taskView.getWidth() + : taskView.getWidth() - mPageSpacing - taskView.getWidth(); + } + taskView.setPivotX(pivotX); + taskView.setPivotY(taskView.getHeight() / 2f); + builder.add(ObjectAnimator + .ofFloat(taskView, TaskView.DISMISS_SCALE, 0.95f), + clampToProgress(timings.getDesktopTaskScaleInterpolator(), 0f, + timings.getDesktopFadeSplitAnimationEndOffset())); + } builder.addFloat(taskView.getSplitAlphaProperty(), MULTI_PROPERTY_VALUE, 1f, 0f, - clampToProgress(deskTopFadeInterPolator, 0f, 0.1f)); + clampToProgress(deskTopFadeInterPolator, 0f, + timings.getDesktopFadeSplitAnimationEndOffset())); } } }