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

Commit 7b67734f authored by Doris Liu's avatar Doris Liu Committed by Android (Google) Code Review
Browse files

Merge "Fix behavior change for animators without a start delay"

parents 9994a2b1 f57bfe2f
Loading
Loading
Loading
Loading
+56 −51
Original line number Diff line number Diff line
@@ -603,27 +603,28 @@ public final class AnimatorSet extends Animator {
        createDependencyGraph();

        // Now that all dependencies are set up, start the animations that should be started.
        boolean setIsEmpty = false;
        if (mStartDelay > 0) {
            start(mRootNode);
        if (mListeners != null) {
            ArrayList<AnimatorListener> tmpListeners =
                    (ArrayList<AnimatorListener>) mListeners.clone();
            int numListeners = tmpListeners.size();
            for (int i = 0; i < numListeners; ++i) {
                tmpListeners.get(i).onAnimationStart(this);
            }
        } else if (mNodes.size() > 1) {
            // No delay, but there are other animators in the set
            onChildAnimatorEnded(mDelayAnim);
        } else {
            // Set is empty, no delay, no other animation. Skip to end in this case
            setIsEmpty = true;
        }
        if (mNodes.size() == 0 && mStartDelay == 0) {
            // Handle unusual case where empty AnimatorSet is started - should send out
            // end event immediately since the event will not be sent out at all otherwise
            mStarted = false;

        if (mListeners != null) {
            ArrayList<AnimatorListener> tmpListeners =
                    (ArrayList<AnimatorListener>) mListeners.clone();
            int numListeners = tmpListeners.size();
            for (int i = 0; i < numListeners; ++i) {
                    tmpListeners.get(i).onAnimationEnd(this);
                tmpListeners.get(i).onAnimationStart(this);
            }
        }
        if (setIsEmpty) {
            // In the case of empty AnimatorSet, we will trigger the onAnimationEnd() right away.
            onChildAnimatorEnded(mDelayAnim);
        }
    }

@@ -751,25 +752,39 @@ public final class AnimatorSet extends Animator {
        public void onAnimationEnd(Animator animation) {
            animation.removeListener(this);
            mAnimatorSet.mPlayingSet.remove(animation);
            Node animNode = mAnimatorSet.mNodeMap.get(animation);
            mAnimatorSet.onChildAnimatorEnded(animation);
        }

        // Nothing to do
        public void onAnimationRepeat(Animator animation) {
        }

        // Nothing to do
        public void onAnimationStart(Animator animation) {
        }

    }

    private void onChildAnimatorEnded(Animator animation) {
        Node animNode = mNodeMap.get(animation);
        animNode.mEnded = true;

            if (!mAnimatorSet.mTerminated) {
        if (!mTerminated) {
            List<Node> children = animNode.mChildNodes;
            // Start children animations, if any.
            int childrenSize = children == null ? 0 : children.size();
            for (int i = 0; i < childrenSize; i++) {
                if (children.get(i).mLatestParent == animNode) {
                        mAnimatorSet.start(children.get(i));
                    start(children.get(i));
                }
            }
            // Listeners are already notified of the AnimatorSet ending in cancel() or
            // end(); the logic below only kicks in when animations end normally
            boolean allDone = true;
            // Traverse the tree and find if there's any unfinished node
                int size = mAnimatorSet.mNodes.size();
            int size = mNodes.size();
            for (int i = 0; i < size; i++) {
                    if (!mAnimatorSet.mNodes.get(i).mEnded) {
                if (!mNodes.get(i).mEnded) {
                    allDone = false;
                    break;
                }
@@ -777,28 +792,18 @@ public final class AnimatorSet extends Animator {
            if (allDone) {
                // If this was the last child animation to end, then notify listeners that this
                // AnimatorSet has ended
                    if (mAnimatorSet.mListeners != null) {
                if (mListeners != null) {
                    ArrayList<AnimatorListener> tmpListeners =
                                (ArrayList<AnimatorListener>) mAnimatorSet.mListeners.clone();
                            (ArrayList<AnimatorListener>) mListeners.clone();
                    int numListeners = tmpListeners.size();
                    for (int i = 0; i < numListeners; ++i) {
                            tmpListeners.get(i).onAnimationEnd(mAnimatorSet);
                        }
                    }
                    mAnimatorSet.mStarted = false;
                    mAnimatorSet.mPaused = false;
                }
                        tmpListeners.get(i).onAnimationEnd(this);
                    }
                }

        // Nothing to do
        public void onAnimationRepeat(Animator animation) {
                mStarted = false;
                mPaused = false;
            }

        // Nothing to do
        public void onAnimationStart(Animator animation) {
        }

    }

    /**
+13 −3
Original line number Diff line number Diff line
@@ -932,6 +932,13 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio
        updateScaledDuration(); // in case the scale factor has changed since creation time
        AnimationHandler animationHandler = AnimationHandler.getInstance();
        animationHandler.addAnimationFrameCallback(this, mStartDelay);

        if (mStartDelay == 0) {
            // If there's no start delay, init the animation and notify start listeners right away
            // Otherwise, postpone this until the first frame after the start delay.
            startAnimation();
            setCurrentFraction(mSeekFraction == -1 ? 0 : mSeekFraction);
        }
    }

    @Override
@@ -1075,6 +1082,7 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio
        mStartListenersCalled = false;
        mPlayingBackwards = false;
        mReversing = false;
        mLastFrameTime = 0;
        mCurrentIteration = 0;
        if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
            Trace.asyncTraceEnd(Trace.TRACE_TAG_VIEW, getNameForTrace(),
@@ -1184,12 +1192,13 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio
     * @hide
     */
    public final void doAnimationFrame(long frameTime) {
        mLastFrameTime = frameTime;
        AnimationHandler handler = AnimationHandler.getInstance();
        if (!mRunning) {
        if (mLastFrameTime == 0) {
            // First frame
            handler.addOneShotCommitCallback(this);
            if (mStartDelay > 0) {
                startAnimation();
            }
            if (mSeekFraction < 0) {
                mStartTime = frameTime;
            } else {
@@ -1199,6 +1208,7 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio
            }
            mStartTimeCommitted = false; // allow start time to be compensated for jank
        }
        mLastFrameTime = frameTime;
        if (mPaused) {
            if (mPauseTime < 0) {
                mPauseTime = frameTime;