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

Commit 9d8fca87 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Notify onAnimationCancel when canceling with pending end callback

It is expected to receive cancel callback if the animator is still
running even if the last frame is done. Otherwise app may have
unexpected behavior if its onAnimationCancel and onAnimationFinish
have dependency.

Fix: 399819784
Flag: com.android.window.flags.system_ui_post_animation_end
Test: ValueAnimatorTests#testCancelOnPendingEndListener
Change-Id: Id9814fabab1feafe9f4bfb6957d6c624712720f4
parent ee510382
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -681,7 +681,7 @@ public abstract class Animator implements Cloneable {
        AnimationHandler.getInstance().removePendingEndAnimationCallback(mPendingEndCallback);
        mPendingEndCallback = null;
        if (notifyListeners) {
            notifyEndListeners(false /* isReversing */);
            completeEndAnimation(false /* isReversing */, "notifyAnimEndNow");
        }
        return true;
    }
+6 −1
Original line number Diff line number Diff line
@@ -1182,7 +1182,12 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio
        // If end has already been requested, through a previous end() or cancel() call, no-op
        // until animation starts again.
        if (mAnimationEndRequested) {
            consumePendingEndListeners(true /* notifyListeners */);
            if (consumePendingEndListeners(false /* notifyListeners */)) {
                if (mRunning) {
                    notifyListeners(AnimatorCaller.ON_CANCEL, false /* isReversing */);
                }
                completeEndAnimation(false /* isReversing */, "notifyAnimEndByCancel");
            }
            return;
        }

+17 −4
Original line number Diff line number Diff line
@@ -924,7 +924,7 @@ public class ValueAnimatorTests {

    @Test
    public void testCancelOnPendingEndListener() throws Throwable {
        testPendingEndListener(ValueAnimator::cancel);
        testPendingEndListener(ValueAnimator::cancel, true /* expectCancel */);
    }

    @Test
@@ -935,11 +935,11 @@ public class ValueAnimatorTests {
            if (animator.isRunning() && animator.isStarted()) {
                animator.end();
            }
        });
        }, false /* expectCancel */);
    }

    private void testPendingEndListener(Consumer<ValueAnimator> finishOnLastFrame)
            throws Throwable {
    private void testPendingEndListener(Consumer<ValueAnimator> finishOnLastFrame,
            boolean expectCancel) throws Throwable {
        final boolean[] endCalledImmediately = new boolean[1];
        final CountDownLatch endLatch = new CountDownLatch(1);
        final Handler handler = new Handler(Looper.getMainLooper());
@@ -963,6 +963,13 @@ public class ValueAnimatorTests {
            handler.post(va::start);
            assertThat(endLatch.await(1, TimeUnit.SECONDS)).isTrue();
            assertThat(endCalledImmediately[0]).isTrue();
            assertThat(va.isRunning()).isFalse();
            if (expectCancel) {
                assertThat(listener.mCancelSeq).isEqualTo(1);
                assertThat(listener.mEndSeq).isEqualTo(2);
            } else {
                assertThat(listener.mCancelSeq).isEqualTo(0);
            }
        } finally {
            ValueAnimator.setPostNotifyEndListenerEnabled(false);
        }
@@ -1262,6 +1269,10 @@ public class ValueAnimatorTests {
        long startTime = -1;
        long endTime = -1;

        private int mCallbackSeq;
        int mCancelSeq;
        int mEndSeq;

        @Override
        public void onAnimationStart(Animator animation) {
            startCalled = true;
@@ -1272,11 +1283,13 @@ public class ValueAnimatorTests {
        public void onAnimationEnd(Animator animation) {
            endCalled = true;
            endTime = SystemClock.uptimeMillis();
            mEndSeq = ++mCallbackSeq;
        }

        @Override
        public void onAnimationCancel(Animator animation) {
            cancelCalled = true;
            mCancelSeq = ++mCallbackSeq;
        }

        @Override