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

Commit a4ccd6db authored by Jeff DeCew's avatar Jeff DeCew Committed by Android (Google) Code Review
Browse files

Merge "Ensure AnimatorTestRule timing is perfectly synchronized." into main

parents ea833fb1 0d7d665e
Loading
Loading
Loading
Loading
+17 −4
Original line number Diff line number Diff line
@@ -68,13 +68,26 @@ public final class AnimatorTestRule implements TestRule {

    private final Object mLock = new Object();
    private final TestHandler mTestHandler = new TestHandler();
    private final long mStartTime;
    private long mTotalTimeDelta = 0;

    /**
     * Construct an AnimatorTestRule with a custom start time.
     * @see #AnimatorTestRule()
     */
    public AnimatorTestRule(long startTime) {
        mStartTime = startTime;
    }

    /**
     * initializing the start time with {@link SystemClock#uptimeMillis()} reduces the discrepancies
     * with various internals of classes like ValueAnimator which can sometimes read that clock via
     * Construct an AnimatorTestRule with a start time of {@link SystemClock#uptimeMillis()}.
     * Initializing the start time with this clock reduces the discrepancies with various internals
     * of classes like ValueAnimator which can sometimes read that clock via
     * {@link android.view.animation.AnimationUtils#currentAnimationTimeMillis()}.
     */
    private final long mStartTime = SystemClock.uptimeMillis();
    private long mTotalTimeDelta = 0;
    public AnimatorTestRule() {
        this(SystemClock.uptimeMillis());
    }

    @NonNull
    @Override
+18 −1
Original line number Diff line number Diff line
@@ -28,11 +28,21 @@ import org.junit.runners.model.Statement
 * advanced together.
 */
class AnimatorTestRule : TestRule {
    // Create the androidx rule, which initializes start time to SystemClock.uptimeMillis(),
    // then copy that time to the platform rule so that the two clocks are in sync.
    private val androidxRule = androidx.core.animation.AnimatorTestRule()
    private val platformRule = android.animation.AnimatorTestRule()
    private val platformRule = android.animation.AnimatorTestRule(androidxRule.startTime)
    private val advanceAndroidXTimeBy =
        Consumer<Long> { timeDelta -> androidxRule.advanceTimeBy(timeDelta) }

    /** Access the mStartTime field; bypassing the restriction of being on a looper thread. */
    private val androidx.core.animation.AnimatorTestRule.startTime: Long
        get() =
            javaClass.getDeclaredField("mStartTime").let { field ->
                field.isAccessible = true
                field.getLong(this)
            }

    /**
     * Chain is for simplicity not to force a particular order; order should not matter, because
     * each rule affects a different AnimationHandler classes, and no callbacks to code under test
@@ -55,4 +65,11 @@ class AnimatorTestRule : TestRule {
        //  animation from one to start later than the other.
        platformRule.advanceTimeBy(timeDelta, advanceAndroidXTimeBy)
    }

    /**
     * Returns the current time in milliseconds tracked by the AnimationHandlers. Note that this is
     * a different time than the time tracked by {@link SystemClock}.
     */
    val currentTime: Long
        get() = androidxRule.currentTime
}