Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9d6f7c05 authored by Johannes Gallmann's avatar Johannes Gallmann Committed by Android (Google) Code Review
Browse files

Merge "Respect velocity for cross activity back animations" into main

parents 67e9be91 699be317
Loading
Loading
Loading
Loading
+19 −5
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ import com.android.internal.dynamicanimation.animation.SpringForce;
 *
 * @hide
 */
public class BackProgressAnimator {
public class BackProgressAnimator implements DynamicAnimation.OnAnimationUpdateListener {
    /**
     *  A factor to scale the input progress by, so that it works better with the spring.
     *  We divide the output progress by this value before sending it to apps, so that apps
@@ -43,6 +43,7 @@ public class BackProgressAnimator {
    private final SpringAnimation mSpring;
    private ProgressCallback mCallback;
    private float mProgress = 0;
    private float mVelocity = 0;
    private BackMotionEvent mLastBackEvent;
    private boolean mBackAnimationInProgress = false;
    @Nullable
@@ -67,7 +68,6 @@ public class BackProgressAnimator {
                @Override
                public void setValue(BackProgressAnimator animator, float value) {
                    animator.setProgress(value);
                    animator.updateProgressValue(value);
                }

                @Override
@@ -76,6 +76,11 @@ public class BackProgressAnimator {
                }
            };

    @Override
    public void onAnimationUpdate(DynamicAnimation animation, float value, float velocity) {
        updateProgressValue(value, velocity);
    }


    /** A callback to be invoked when there's a progress value update from the animator. */
    public interface ProgressCallback {
@@ -85,6 +90,7 @@ public class BackProgressAnimator {

    public BackProgressAnimator() {
        mSpring = new SpringAnimation(this, PROGRESS_PROP);
        mSpring.addUpdateListener(this);
        mSpring.setSpring(new SpringForce()
                .setStiffness(SpringForce.STIFFNESS_MEDIUM)
                .setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY));
@@ -117,7 +123,7 @@ public class BackProgressAnimator {
        mLastBackEvent = event;
        mCallback = callback;
        mBackAnimationInProgress = true;
        updateProgressValue(0);
        updateProgressValue(0, 0);
    }

    /**
@@ -126,7 +132,7 @@ public class BackProgressAnimator {
    public void reset() {
        if (mBackCancelledFinishRunnable != null) {
            // Ensure that last progress value that apps see is 0
            updateProgressValue(0);
            updateProgressValue(0, 0);
            invokeBackCancelledRunnable();
        }
        mSpring.animateToFinalPosition(0);
@@ -167,7 +173,15 @@ public class BackProgressAnimator {
        return mBackAnimationInProgress;
    }

    private void updateProgressValue(float progress) {
    /**
     * @return The last recorded velocity. Unit: change in progress per second
     */
    public float getVelocity() {
        return mVelocity / SCALE_FACTOR;
    }

    private void updateProgressValue(float progress, float velocity) {
        mVelocity = velocity;
        if (mLastBackEvent == null || mCallback == null || !mBackAnimationInProgress) {
            return;
        }
+33 −4
Original line number Diff line number Diff line
@@ -41,6 +41,9 @@ import android.window.BackMotionEvent
import android.window.BackNavigationInfo
import android.window.BackProgressAnimator
import android.window.IOnBackInvokedCallback
import com.android.internal.dynamicanimation.animation.FloatValueHolder
import com.android.internal.dynamicanimation.animation.SpringAnimation
import com.android.internal.dynamicanimation.animation.SpringForce
import com.android.internal.jank.Cuj
import com.android.internal.policy.ScreenDecorationsUtils
import com.android.internal.protolog.common.ProtoLog
@@ -70,6 +73,7 @@ abstract class CrossActivityBackAnimation(

    protected val backAnimRect = Rect()
    private val cropRect = Rect()
    private val tempRectF = RectF()

    private var cornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(context)

@@ -98,6 +102,12 @@ abstract class CrossActivityBackAnimation(
    private var rightLetterboxLayer: SurfaceControl? = null
    private var letterboxColor: Int = 0

    private val postCommitFlingScale = FloatValueHolder(SPRING_SCALE)
    private var lastPostCommitFlingScale = SPRING_SCALE
    private val postCommitFlingSpring = SpringForce(SPRING_SCALE)
            .setStiffness(SpringForce.STIFFNESS_LOW)
            .setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY)

    /** Background color to be used during the animation, also see [getBackgroundColor] */
    protected var customizedBackgroundColor = 0

@@ -231,7 +241,7 @@ abstract class CrossActivityBackAnimation(
        return deltaY
    }

    protected open fun onGestureCommitted() {
    protected open fun onGestureCommitted(velocity: Float) {
        if (
            closingTarget?.leash == null ||
                enteringTarget?.leash == null ||
@@ -242,6 +252,14 @@ abstract class CrossActivityBackAnimation(
            return
        }

        // kick off spring animation with the current velocity from the pre-commit phase, this
        // affects the scaling of the closing activity during post-commit
        val flingAnimation = SpringAnimation(postCommitFlingScale, SPRING_SCALE)
            .setStartVelocity(min(0f, -velocity * SPRING_SCALE))
            .setStartValue(SPRING_SCALE)
            .setSpring(postCommitFlingSpring)
        flingAnimation.start()

        val valueAnimator = ValueAnimator.ofFloat(1f, 0f).setDuration(POST_COMMIT_DURATION)
        valueAnimator.addUpdateListener { animation: ValueAnimator ->
            val progress = animation.animatedFraction
@@ -291,6 +309,7 @@ abstract class CrossActivityBackAnimation(
        removeLetterbox()
        isLetterboxed = false
        enteringHasSameLetterbox = false
        lastPostCommitFlingScale = SPRING_SCALE
    }

    protected fun applyTransform(
@@ -300,7 +319,15 @@ abstract class CrossActivityBackAnimation(
        baseTransformation: Transformation? = null
    ) {
        if (leash == null || !leash.isValid) return
        val scale = rect.width() / backAnimRect.width()
        tempRectF.set(rect)
        if (leash == closingTarget?.leash) {
            lastPostCommitFlingScale = (postCommitFlingScale.value / SPRING_SCALE).coerceIn(
                    minimumValue = MAX_FLING_SCALE, maximumValue = lastPostCommitFlingScale
            )
            // apply an additional scale to the closing target to account for fling velocity
            tempRectF.scaleCentered(lastPostCommitFlingScale)
        }
        val scale = tempRectF.width() / backAnimRect.width()
        val matrix = baseTransformation?.matrix ?: transformMatrix.apply { reset() }
        val scalePivotX =
            if (isLetterboxed && enteringHasSameLetterbox) {
@@ -309,7 +336,7 @@ abstract class CrossActivityBackAnimation(
                0f
            }
        matrix.postScale(scale, scale, scalePivotX, 0f)
        matrix.postTranslate(rect.left, rect.top)
        matrix.postTranslate(tempRectF.left, tempRectF.top)
        transaction
            .setAlpha(leash, keepMinimumAlpha(alpha))
            .setMatrix(leash, matrix, tmpFloat9)
@@ -461,7 +488,7 @@ abstract class CrossActivityBackAnimation(

        override fun onBackInvoked() {
            progressAnimator.reset()
            onGestureCommitted()
            onGestureCommitted(progressAnimator.velocity)
        }
    }

@@ -497,6 +524,8 @@ abstract class CrossActivityBackAnimation(
        private const val MAX_SCRIM_ALPHA_DARK = 0.8f
        private const val MAX_SCRIM_ALPHA_LIGHT = 0.2f
        private const val POST_COMMIT_DURATION = 300L
        private const val SPRING_SCALE = 100f
        private const val MAX_FLING_SCALE = 0.6f
    }
}

+2 −2
Original line number Diff line number Diff line
@@ -56,7 +56,7 @@ constructor(
        targetEnteringRect.scaleCentered(MAX_SCALE)
    }

    override fun onGestureCommitted() {
    override fun onGestureCommitted(velocity: Float) {
        // We enter phase 2 of the animation, the starting coordinates for phase 2 are the current
        // coordinate of the gesture driven phase. Let's update the start and target rects and kick
        // off the animator in the superclass
@@ -65,7 +65,7 @@ constructor(
        targetEnteringRect.set(backAnimRect)
        targetClosingRect.set(backAnimRect)
        targetClosingRect.offset(currentClosingRect.left + enteringStartOffset, 0f)
        super.onGestureCommitted()
        super.onGestureCommitted(velocity)
    }

    override fun onPostCommitProgress(linearProgress: Float) {