summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Doris Liu <tianliu@google.com> 2015-08-27 14:56:30 -0700
committer Doris Liu <tianliu@google.com> 2015-08-27 16:13:48 -0700
commit3dbaae1ef4f221b3626810f4ba19eec068dd6304 (patch)
treecaf8b0d2304a5545aa1c00d2544277032eeb16a9
parent2916fa11eea3e119b8f24bea4daa861294951813 (diff)
Prevents recursive call into end() or cancel()
end() and cancel() in ValueAnimator will trigger onAnimationCancel or onAnimationEnd callback on its listeners. If additional end() or cancel() request comes from the callback, a loop will be formed. Therefore, we need to mark when the end is reuqested so we do not process end() or cancel() request multiple times during one animation run, and also effectively terminate the loop. Bug: 23596652 Change-Id: Iefb69eb8969071b43124c09d7cccbe9ff5ba5dcc
-rw-r--r--core/java/android/animation/ValueAnimator.java22
1 files changed, 20 insertions, 2 deletions
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index 065631cf29e6..da9a8c8d8900 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -185,6 +185,11 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio
*/
boolean mInitialized = false;
+ /**
+ * Flag that tracks whether animation has been requested to end.
+ */
+ private boolean mAnimationEndRequested = false;
+
//
// Backing variables
//
@@ -915,6 +920,7 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio
mStarted = true;
mPaused = false;
mRunning = false;
+ mAnimationEndRequested = false;
updateScaledDuration(); // in case the scale factor has changed since creation time
AnimationHandler animationHandler = AnimationHandler.getInstance();
animationHandler.addAnimationFrameCallback(this, mStartDelay);
@@ -930,9 +936,15 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio
if (Looper.myLooper() == null) {
throw new AndroidRuntimeException("Animators may only be run on Looper threads");
}
+
+ // If end has already been requested, through a previous end() or cancel() call, no-op
+ // until animation starts again.
+ if (mAnimationEndRequested) {
+ return;
+ }
+
// Only cancel if the animation is actually running or has been started and is about
// to run
-
// Only notify listeners if the animator has actually started
if ((mStarted || mRunning) && mListeners != null) {
if (!mRunning) {
@@ -1029,9 +1041,14 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio
* Called internally to end an animation by removing it from the animations list. Must be
* called on the UI thread.
*/
- private void endAnimation() {
+ private void endAnimation() {
+ if (mAnimationEndRequested) {
+ return;
+ }
AnimationHandler handler = AnimationHandler.getInstance();
handler.removeCallback(this);
+
+ mAnimationEndRequested = true;
mPaused = false;
if ((mStarted || mRunning) && mListeners != null) {
if (!mRunning) {
@@ -1256,6 +1273,7 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio
anim.mStartListenersCalled = false;
anim.mStartTime = 0;
anim.mStartTimeCommitted = false;
+ anim.mAnimationEndRequested = false;
anim.mPauseTime = 0;
anim.mLastFrameTime = 0;
anim.mCurrentFraction = 0;