From 09603bfb39cf1aabb244b63dbf15eacf75f32388 Mon Sep 17 00:00:00 2001 From: Johannes Gallmann Date: Thu, 5 Dec 2024 13:56:08 +0000 Subject: [PATCH] Play workspace reveal animation for predictive back-to-home Bug: 382453424 Test: Manual, i.e. tested back-to-home and back-to-allapps animation on phones, tablets and foldables, including interruptions. Flag: EXEMPT bugfix Change-Id: Iece001b6b9edd9ca7a909e3ccbe8ebdff2e71d9f --- .../launcher3/QuickstepTransitionManager.java | 43 +++++++++---------- .../taskbar/LauncherTaskbarUIController.java | 3 +- .../uioverrides/QuickstepLauncher.java | 4 -- .../LauncherBackAnimationController.java | 23 +++++++++- .../quickstep/LauncherSwipeHandlerV2.java | 4 +- .../android/quickstep/util/BackAnimState.kt | 10 ++--- .../util/ScalingWorkspaceRevealAnim.kt | 37 ++++++++-------- 7 files changed, 69 insertions(+), 55 deletions(-) diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java index 2759816fa5..a3984ab302 100644 --- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java @@ -1670,7 +1670,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener || mLauncher.getWorkspace().isOverlayShown() || shouldPlayFallbackClosingAnimation(appTargets); - boolean playWorkspaceReveal = !fromPredictiveBack; + boolean playWorkspaceReveal = true; boolean skipAllAppsScale = false; if (!playFallBackAnimation) { PointF velocity; @@ -1689,12 +1689,12 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener // Skip scaling all apps, otherwise FloatingIconView will get wrong // layout bounds. skipAllAppsScale = true; - } else if (!fromPredictiveBack) { + } else { if (enableScalingRevealHomeAnimation()) { anim.play( - new ScalingWorkspaceRevealAnim( - mLauncher, rectFSpringAnim, - rectFSpringAnim.getTargetRect()).getAnimators()); + new ScalingWorkspaceRevealAnim(mLauncher, rectFSpringAnim, + rectFSpringAnim.getTargetRect(), + !fromPredictiveBack /* playAlphaReveal */).getAnimators()); } else { anim.play(new StaggeredWorkspaceAnim(mLauncher, velocity.y, true /* animateOverviewScrim */, launcherView).getAnimators()); @@ -1713,6 +1713,20 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener anim.play(getFallbackClosingWindowAnimators(appTargets)); } + AnimatorListenerAdapter endListener = new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + super.onAnimationEnd(animation); + AccessibilityManagerCompat.sendTestProtocolEventToTest( + mLauncher, WALLPAPER_OPEN_ANIMATION_FINISHED_MESSAGE); + } + }; + if (rectFSpringAnim != null) { + rectFSpringAnim.addAnimatorListener(endListener); + } else { + anim.addListener(endListener); + } + // Normally, we run the launcher content animation when we are transitioning // home, but if home is already visible, then we don't want to animate the // contents of launcher unless we know that we are animating home as a result @@ -1721,16 +1735,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener // targets list because it is already visible). In that case, we force // invisibility on touch down, and only reset it after the animation to home // is initialized. - if (launcherIsForceInvisibleOrOpening || fromPredictiveBack) { - AnimatorListenerAdapter endListener = new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - super.onAnimationEnd(animation); - AccessibilityManagerCompat.sendTestProtocolEventToTest( - mLauncher, WALLPAPER_OPEN_ANIMATION_FINISHED_MESSAGE); - } - }; - + if (launcherIsForceInvisibleOrOpening) { if (rectFSpringAnim != null && anim.getChildAnimations().isEmpty()) { addCujInstrumentation(rectFSpringAnim, Cuj.CUJ_LAUNCHER_APP_CLOSE_TO_HOME); } else { @@ -1739,16 +1744,10 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener : Cuj.CUJ_LAUNCHER_APP_CLOSE_TO_HOME); } - if (fromPredictiveBack && rectFSpringAnim != null) { - rectFSpringAnim.addAnimatorListener(endListener); - } else { - anim.addListener(endListener); - } - // Only register the content animation for cancellation when state changes mLauncher.getStateManager().setCurrentAnimation(anim); - if (mLauncher.isInState(LauncherState.ALL_APPS) && !fromPredictiveBack) { + if (mLauncher.isInState(LauncherState.ALL_APPS)) { Pair contentAnimator = getLauncherContentAnimator(false, LAUNCHER_RESUME_START_DELAY, skipAllAppsScale); diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java index f0129b4501..24636c3dd4 100644 --- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java @@ -214,8 +214,7 @@ public class LauncherTaskbarUIController extends TaskbarUIController { private int getTaskbarAnimationDuration(boolean isVisible) { // fast animation duration since we will not be playing workspace reveal animation. - boolean shouldOverrideToFastAnimation = - !isHotseatIconOnTopWhenAligned() || mLauncher.getPredictiveBackToHomeInProgress(); + boolean shouldOverrideToFastAnimation = !isHotseatIconOnTopWhenAligned(); boolean isPinnedTaskbar = DisplayController.isPinnedTaskbar(mLauncher); if (isVisible || isPinnedTaskbar) { return getTaskbarToHomeDuration(shouldOverrideToFastAnimation, isPinnedTaskbar); diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index cc51adc260..4a911a694c 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -1328,10 +1328,6 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer, mTISBindHelper.setPredictiveBackToHomeInProgress(isInProgress); } - public boolean getPredictiveBackToHomeInProgress() { - return mIsPredictiveBackToHomeInProgress; - } - @Override public boolean areDesktopTasksVisible() { DesktopVisibilityController desktopVisibilityController = getDesktopVisibilityController(); diff --git a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java index 4bd9ffbf45..1d79e8570f 100644 --- a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java +++ b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java @@ -51,11 +51,14 @@ import android.window.BackMotionEvent; import android.window.BackProgressAnimator; import android.window.IBackAnimationHandoffHandler; import android.window.IOnBackInvokedCallback; + +import com.android.app.animation.Animations; import com.android.app.animation.Interpolators; import com.android.internal.policy.SystemBarUtils; import com.android.internal.view.AppearanceRegion; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BubbleTextView; +import com.android.launcher3.LauncherState; import com.android.launcher3.QuickstepTransitionManager; import com.android.launcher3.R; import com.android.launcher3.Utilities; @@ -65,6 +68,7 @@ import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.NavigationMode; import com.android.launcher3.widget.LauncherAppWidgetHostView; import com.android.quickstep.util.BackAnimState; +import com.android.quickstep.util.ScalingWorkspaceRevealAnim; import com.android.systemui.shared.system.QuickStepContract; import java.lang.ref.WeakReference; @@ -87,7 +91,7 @@ import java.lang.ref.WeakReference; */ public class LauncherBackAnimationController { private static final int SCRIM_FADE_DURATION = 233; - private static final float MIN_WINDOW_SCALE = 0.85f; + private static final float MIN_WINDOW_SCALE = 0.75f; private static final float MAX_SCRIM_ALPHA_DARK = 0.8f; private static final float MAX_SCRIM_ALPHA_LIGHT = 0.2f; @@ -318,6 +322,12 @@ public class LauncherBackAnimationController { addScrimLayer(); } applyTransaction(); + if (!mLauncher.getWorkspace().isOverlayShown() + && !mLauncher.isInState(LauncherState.ALL_APPS)) { + Animations.cancelOngoingAnimation(mLauncher.getWorkspace()); + Animations.cancelOngoingAnimation(mLauncher.getHotseat()); + setLauncherScale(ScalingWorkspaceRevealAnim.MIN_SIZE); + } } private void setLauncherTargetViewVisible(boolean isVisible) { @@ -328,6 +338,13 @@ public class LauncherBackAnimationController { } } + private void setLauncherScale(float scale) { + mLauncher.getWorkspace().setScaleX(scale); + mLauncher.getWorkspace().setScaleY(scale); + mLauncher.getHotseat().setScaleX(scale); + mLauncher.getHotseat().setScaleY(scale); + } + void addScrimLayer() { SurfaceControl parent = mLauncherTarget != null ? mLauncherTarget.leash : null; if (parent == null || !parent.isValid()) { @@ -500,6 +517,10 @@ public class LauncherBackAnimationController { if (mScrimLayer != null) { removeScrimLayer(); } + if (!mLauncher.getWorkspace().isOverlayShown() + && !mLauncher.isInState(LauncherState.ALL_APPS)) { + setLauncherScale(ScalingWorkspaceRevealAnim.MAX_SIZE); + } } private void startTransitionAnimations(BackAnimState backAnim) { diff --git a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java index 6087dc214e..112b40ccb8 100644 --- a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java +++ b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java @@ -329,7 +329,7 @@ public class LauncherSwipeHandlerV2 extends AbsSwipeUpHandler< protected void playScalingRevealAnimation() { if (mContainer != null) { new ScalingWorkspaceRevealAnim(mContainer, mSiblingAnimation, - getWindowTargetRect()).start(); + getWindowTargetRect(), true /* playAlphaReveal */).start(); } } @@ -379,7 +379,7 @@ public class LauncherSwipeHandlerV2 extends AbsSwipeUpHandler< if (mContainer != null) { new ScalingWorkspaceRevealAnim( mContainer, null /* siblingAnimation */, - null /* windowTargetRect */).start(); + null /* windowTargetRect */, true /* playAlphaReveal */).start(); } } } diff --git a/quickstep/src/com/android/quickstep/util/BackAnimState.kt b/quickstep/src/com/android/quickstep/util/BackAnimState.kt index 9009eaa263..c78d4a02cb 100644 --- a/quickstep/src/com/android/quickstep/util/BackAnimState.kt +++ b/quickstep/src/com/android/quickstep/util/BackAnimState.kt @@ -36,14 +36,10 @@ class AnimatorBackState(private val springAnim: RectFSpringAnim?, private val an BackAnimState { override fun addOnAnimCompleteCallback(r: Runnable) { - val springAnimWait = RunnableList() - springAnim?.addAnimatorListener(forEndCallback(springAnimWait::executeAllAndDestroy)) - ?: springAnimWait.executeAllAndDestroy() - val animWait = RunnableList() - anim?.addListener( - forEndCallback(Runnable { springAnimWait.add(animWait::executeAllAndDestroy) }) - ) ?: springAnimWait.add(animWait::executeAllAndDestroy) + springAnim?.addAnimatorListener(forEndCallback(animWait::executeAllAndDestroy)) + ?: anim?.addListener(forEndCallback(animWait::executeAllAndDestroy)) + ?: animWait.executeAllAndDestroy() animWait.add(r) } diff --git a/quickstep/src/com/android/quickstep/util/ScalingWorkspaceRevealAnim.kt b/quickstep/src/com/android/quickstep/util/ScalingWorkspaceRevealAnim.kt index f719bed5e7..63eae921b0 100644 --- a/quickstep/src/com/android/quickstep/util/ScalingWorkspaceRevealAnim.kt +++ b/quickstep/src/com/android/quickstep/util/ScalingWorkspaceRevealAnim.kt @@ -54,14 +54,15 @@ class ScalingWorkspaceRevealAnim( private val launcher: QuickstepLauncher, siblingAnimation: RectFSpringAnim?, windowTargetRect: RectF?, + playAlphaReveal: Boolean = true, ) { companion object { private const val FADE_DURATION_MS = 200L private const val SCALE_DURATION_MS = 1000L private const val MAX_ALPHA = 1f private const val MIN_ALPHA = 0f - private const val MAX_SIZE = 1f - private const val MIN_SIZE = 0.85f + internal const val MAX_SIZE = 1f + internal const val MIN_SIZE = 0.85f /** * Custom interpolator for both the home and wallpaper scaling. Necessary because EMPHASIZED @@ -132,21 +133,23 @@ class ScalingWorkspaceRevealAnim( SCALE_INTERPOLATOR, ) - // Fade in quickly at the beginning of the animation, so the content doesn't look like it's - // popping into existence out of nowhere. - val fadeClamp = FADE_DURATION_MS.toFloat() / SCALE_DURATION_MS - workspace.alpha = MIN_ALPHA - animation.setViewAlpha( - workspace, - MAX_ALPHA, - Interpolators.clampToProgress(LINEAR, 0f, fadeClamp), - ) - hotseat.alpha = MIN_ALPHA - animation.setViewAlpha( - hotseat, - MAX_ALPHA, - Interpolators.clampToProgress(LINEAR, 0f, fadeClamp), - ) + if (playAlphaReveal) { + // Fade in quickly at the beginning of the animation, so the content doesn't look like + // it's popping into existence out of nowhere. + val fadeClamp = FADE_DURATION_MS.toFloat() / SCALE_DURATION_MS + workspace.alpha = MIN_ALPHA + animation.setViewAlpha( + workspace, + MAX_ALPHA, + Interpolators.clampToProgress(LINEAR, 0f, fadeClamp), + ) + hotseat.alpha = MIN_ALPHA + animation.setViewAlpha( + hotseat, + MAX_ALPHA, + Interpolators.clampToProgress(LINEAR, 0f, fadeClamp), + ) + } val transitionConfig = StateAnimationConfig()