diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java index 3797e87995..7076f58d94 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -220,6 +220,8 @@ public class WindowTransformSwipeHandler protected Runnable mGestureEndCallback; protected GestureEndTarget mGestureEndTarget; + // Either RectFSpringAnim (if animating home) or ObjectAnimator (from mCurrentShift) otherwise + private RunningWindowAnim mRunningWindowAnim; private boolean mIsShelfPeeking; private DeviceProfile mDp; private int mTransitionDragLength; @@ -805,7 +807,7 @@ public class WindowTransformSwipeHandler @UiThread private InputConsumer createNewInputProxyHandler() { - mCurrentShift.finishAnimation(); + endRunningWindowAnim(); if (mLauncherTransitionController != null) { mLauncherTransitionController.getAnimationPlayer().end(); } @@ -817,6 +819,12 @@ public class WindowTransformSwipeHandler return OverviewInputConsumer.newInstance(mActivityControlHelper, null, true); } + private void endRunningWindowAnim() { + if (mRunningWindowAnim != null) { + mRunningWindowAnim.end(); + } + } + @UiThread private void handleNormalGestureEnd(float endVelocity, boolean isFling, PointF velocity, boolean isCancel) { @@ -984,6 +992,7 @@ public class WindowTransformSwipeHandler } }); windowAnim.start(velocityPxPerMs); + mRunningWindowAnim = RunningWindowAnim.wrap(windowAnim); mLauncherTransitionController = null; } else { ValueAnimator windowAnim = mCurrentShift.animateToValue(start, end); @@ -1002,6 +1011,7 @@ public class WindowTransformSwipeHandler } }); windowAnim.start(); + mRunningWindowAnim = RunningWindowAnim.wrap(windowAnim); } // Always play the entire launcher animation when going home, since it is separate from // the animation that has been controlled thus far. @@ -1111,7 +1121,7 @@ public class WindowTransformSwipeHandler false /* animate */, true /* freezeTaskList */); }); } - TOUCH_INTERACTION_LOG.addLog("finishRecentsAnimation", false); + TOUCH_INTERACTION_LOG.addLog("finishRecentsAnimation", true); doLogGesture(NEW_TASK); reset(); } @@ -1133,7 +1143,7 @@ public class WindowTransformSwipeHandler } private void invalidateHandler() { - mCurrentShift.finishAnimation(); + endRunningWindowAnim(); if (mGestureEndCallback != null) { mGestureEndCallback.run(); @@ -1281,4 +1291,16 @@ public class WindowTransformSwipeHandler return app.isNotInRecents || app.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME; } + + private interface RunningWindowAnim { + void end(); + + static RunningWindowAnim wrap(Animator animator) { + return animator::end; + } + + static RunningWindowAnim wrap(RectFSpringAnim rectFSpringAnim) { + return rectFSpringAnim::end; + } + } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java index 2edeb3aec2..7159e7c721 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java @@ -23,6 +23,9 @@ import android.graphics.PointF; import android.graphics.RectF; import android.util.FloatProperty; +import androidx.dynamicanimation.animation.DynamicAnimation.OnAnimationEndListener; +import androidx.dynamicanimation.animation.FloatPropertyCompat; + import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.FlingSpringAnim; @@ -30,9 +33,6 @@ import com.android.launcher3.anim.FlingSpringAnim; import java.util.ArrayList; import java.util.List; -import androidx.dynamicanimation.animation.DynamicAnimation.OnAnimationEndListener; -import androidx.dynamicanimation.animation.FloatPropertyCompat; - /** * Applies spring forces to animate from a starting rect to a target rect, * while providing update callbacks to the caller. @@ -98,6 +98,10 @@ public class RectFSpringAnim { private float mCurrentCenterX; private float mCurrentCenterY; private float mCurrentScaleProgress; + private FlingSpringAnim mRectXAnim; + private FlingSpringAnim mRectYAnim; + private ValueAnimator mRectScaleAnim; + private boolean mAnimsStarted; private boolean mRectXAnimEnded; private boolean mRectYAnimEnded; private boolean mRectScaleAnimEnded; @@ -127,15 +131,15 @@ public class RectFSpringAnim { mRectYAnimEnded = true; maybeOnEnd(); }); - FlingSpringAnim rectXAnim = new FlingSpringAnim(this, RECT_CENTER_X, mCurrentCenterX, + mRectXAnim = new FlingSpringAnim(this, RECT_CENTER_X, mCurrentCenterX, mTargetRect.centerX(), velocityPxPerMs.x * 1000, onXEndListener); - FlingSpringAnim rectYAnim = new FlingSpringAnim(this, RECT_CENTER_Y, mCurrentCenterY, + mRectYAnim = new FlingSpringAnim(this, RECT_CENTER_Y, mCurrentCenterY, mTargetRect.centerY(), velocityPxPerMs.y * 1000, onYEndListener); - ValueAnimator rectScaleAnim = ObjectAnimator.ofPropertyValuesHolder(this, + mRectScaleAnim = ObjectAnimator.ofPropertyValuesHolder(this, PropertyValuesHolder.ofFloat(RECT_SCALE_PROGRESS, 1)) .setDuration(RECT_SCALE_DURATION); - rectScaleAnim.addListener(new AnimationSuccessListener() { + mRectScaleAnim.addListener(new AnimationSuccessListener() { @Override public void onAnimationSuccess(Animator animator) { mRectScaleAnimEnded = true; @@ -143,14 +147,23 @@ public class RectFSpringAnim { } }); - rectXAnim.start(); - rectYAnim.start(); - rectScaleAnim.start(); + mRectXAnim.start(); + mRectYAnim.start(); + mRectScaleAnim.start(); + mAnimsStarted = true; for (Animator.AnimatorListener animatorListener : mAnimatorListeners) { animatorListener.onAnimationStart(null); } } + public void end() { + if (mAnimsStarted) { + mRectXAnim.end(); + mRectYAnim.end(); + mRectScaleAnim.end(); + } + } + private void onUpdate() { if (!mOnUpdateListeners.isEmpty()) { float currentWidth = Utilities.mapRange(mCurrentScaleProgress, mStartRect.width(), @@ -166,7 +179,8 @@ public class RectFSpringAnim { } private void maybeOnEnd() { - if (mRectXAnimEnded && mRectYAnimEnded && mRectScaleAnimEnded) { + if (mAnimsStarted && mRectXAnimEnded && mRectYAnimEnded && mRectScaleAnimEnded) { + mAnimsStarted = false; for (Animator.AnimatorListener animatorListener : mAnimatorListeners) { animatorListener.onAnimationEnd(null); } diff --git a/src/com/android/launcher3/anim/FlingSpringAnim.java b/src/com/android/launcher3/anim/FlingSpringAnim.java index 3d21d82a25..45d49e8706 100644 --- a/src/com/android/launcher3/anim/FlingSpringAnim.java +++ b/src/com/android/launcher3/anim/FlingSpringAnim.java @@ -34,6 +34,7 @@ public class FlingSpringAnim { private static final float SPRING_DAMPING = SpringForce.DAMPING_RATIO_LOW_BOUNCY; private final FlingAnimation mFlingAnim; + private SpringAnimation mSpringAnim; public FlingSpringAnim(K object, FloatPropertyCompat property, float startPosition, float targetPosition, float startVelocity, OnAnimationEndListener onEndListener) { @@ -44,17 +45,24 @@ public class FlingSpringAnim { .setMinValue(Math.min(startPosition, targetPosition)) .setMaxValue(Math.max(startPosition, targetPosition)); mFlingAnim.addEndListener(((animation, canceled, value, velocity) -> { - SpringAnimation springAnim = new SpringAnimation(object, property) + mSpringAnim = new SpringAnimation(object, property) .setStartVelocity(velocity) .setSpring(new SpringForce(targetPosition) .setStiffness(SPRING_STIFFNESS) .setDampingRatio(SPRING_DAMPING)); - springAnim.addEndListener(onEndListener); - springAnim.start(); + mSpringAnim.addEndListener(onEndListener); + mSpringAnim.start(); })); } public void start() { mFlingAnim.start(); } + + public void end() { + mFlingAnim.cancel(); + if (mSpringAnim.canSkipToEnd()) { + mSpringAnim.skipToEnd(); + } + } }