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

Commit 0722af75 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Ensure the deferred callback does not finish next animation"

parents 6c8d4e0d 1d5856c2
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -82,6 +82,11 @@ class SurfaceAnimator {
                    return;
                }
                final Runnable resetAndInvokeFinish = () -> {
                    // We need to check again if the animation has been replaced with a new
                    // animation because the animatable may defer to finish.
                    if (anim != mAnimation) {
                        return;
                    }
                    reset(mAnimatable.getPendingTransaction(), true /* destroyLeash */);
                    if (animationFinishedCallback != null) {
                        animationFinishedCallback.run();
+32 −7
Original line number Diff line number Diff line
@@ -181,15 +181,10 @@ public class SurfaceAnimatorTest extends WindowTestsBase {
    public void testDeferFinish() {

        // Start animation
        mDeferFinishAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec,
                true /* hidden */);
        final ArgumentCaptor<OnAnimationFinishedCallback> callbackCaptor = ArgumentCaptor.forClass(
                OnAnimationFinishedCallback.class);
        assertAnimating(mDeferFinishAnimatable);
        verify(mSpec).startAnimation(any(), any(), callbackCaptor.capture());
        final OnAnimationFinishedCallback onFinishedCallback = startDeferFinishAnimatable(mSpec);

        // Finish the animation but then make sure we are deferring.
        callbackCaptor.getValue().onAnimationFinished(mSpec);
        onFinishedCallback.onAnimationFinished(mSpec);
        assertAnimating(mDeferFinishAnimatable);

        // Now end defer finishing.
@@ -199,6 +194,36 @@ public class SurfaceAnimatorTest extends WindowTestsBase {
        verify(mTransaction).remove(eq(mDeferFinishAnimatable.mLeash));
    }

    @Test
    public void testDeferFinishDoNotFinishNextAnimation() {
        // Start the first animation.
        final OnAnimationFinishedCallback onFinishedCallback = startDeferFinishAnimatable(mSpec);
        onFinishedCallback.onAnimationFinished(mSpec);
        // The callback is the resetAndInvokeFinish in {@link SurfaceAnimator#getFinishedCallback}.
        final Runnable firstDeferFinishCallback = mDeferFinishAnimatable.mEndDeferFinishCallback;

        // Start the second animation.
        mDeferFinishAnimatable.mSurfaceAnimator.cancelAnimation();
        startDeferFinishAnimatable(mSpec2);
        mDeferFinishAnimatable.mFinishedCallbackCalled = false;

        // Simulate the first deferred callback is executed from
        // {@link AnimatingAppWindowTokenRegistry#endDeferringFinished}.
        firstDeferFinishCallback.run();
        // The second animation should not be finished.
        assertFalse(mDeferFinishAnimatable.mFinishedCallbackCalled);
    }

    private OnAnimationFinishedCallback startDeferFinishAnimatable(AnimationAdapter anim) {
        mDeferFinishAnimatable.mSurfaceAnimator.startAnimation(mTransaction, anim,
                true /* hidden */);
        final ArgumentCaptor<OnAnimationFinishedCallback> callbackCaptor = ArgumentCaptor.forClass(
                OnAnimationFinishedCallback.class);
        assertAnimating(mDeferFinishAnimatable);
        verify(anim).startAnimation(any(), any(), callbackCaptor.capture());
        return callbackCaptor.getValue();
    }

    private void assertAnimating(MyAnimatable animatable) {
        assertTrue(animatable.mSurfaceAnimator.isAnimating());
        assertNotNull(animatable.mSurfaceAnimator.getAnimation());