blob: 3a0132a01835e9aa6f360484529502e765ad6f6b [file] [log] [blame]
package org.robolectric.shadows;
import static android.os.Build.VERSION_CODES.N;
import static org.robolectric.shadow.api.Shadow.directlyOn;
import android.animation.AnimationHandler;
import android.animation.ValueAnimator;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.RealObject;
import org.robolectric.annotation.Resetter;
import org.robolectric.util.ReflectionHelpers;
@Implements(ValueAnimator.class)
public class ShadowValueAnimator {
@RealObject
private ValueAnimator realObject;
private int actualRepeatCount;
@Resetter
public static void reset() {
/* ValueAnimator.sAnimationHandler is a static thread local that otherwise would survive between
* tests. The AnimationHandler.mAnimationScheduled is set to true when the scheduleAnimation() is
* called and the reset to false when run() is called by the Choreographer. If an animation is
* already scheduled, it will not post to the Choreographer. This is a problem if a previous
* test leaves animations on the Choreographers callback queue without running them as it will
* cause the AnimationHandler not to post a callback. We reset the thread local here so a new
* one will be created for each test with a fresh state.
*/
if (RuntimeEnvironment.getApiLevel() >= N) {
ThreadLocal<AnimationHandler> animatorHandlerTL =
ReflectionHelpers.getStaticField(AnimationHandler.class, "sAnimatorHandler");
animatorHandlerTL.remove();
} else {
ReflectionHelpers.callStaticMethod(ValueAnimator.class, "clearAllAnimations");
ThreadLocal<AnimationHandler> animatorHandlerTL =
ReflectionHelpers.getStaticField(ValueAnimator.class, "sAnimationHandler");
animatorHandlerTL.remove();
}
}
@Implementation
protected void setRepeatCount(int count) {
actualRepeatCount = count;
if (count == ValueAnimator.INFINITE) {
count = 1;
}
directlyOn(realObject, ValueAnimator.class).setRepeatCount(count);
}
/**
* Returns the value that was set as the repeat count. This is otherwise the same
* as getRepeatCount(), except when the count was set to infinite.
*
* @return Repeat count.
*/
public int getActualRepeatCount() {
return actualRepeatCount;
}
}