Fix currentAnimationTimeMillis to use vsync time

Bug: 30674719
Change-Id: I71f51eea971e43cbe85bb0713a1c457a1b3243b3
This commit is contained in:
John Reck
2016-08-05 07:58:37 -07:00
parent b11cc6cbd3
commit a2acb4f077
2 changed files with 36 additions and 1 deletions

View File

@@ -25,6 +25,7 @@ import android.os.SystemProperties;
import android.os.Trace;
import android.util.Log;
import android.util.TimeUtils;
import android.view.animation.AnimationUtils;
import java.io.PrintWriter;
@@ -608,6 +609,7 @@ public final class Choreographer {
try {
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Choreographer#doFrame");
AnimationUtils.lockAnimationClock(frameTimeNanos / TimeUtils.NANOS_PER_MS);
mFrameInfo.markInputHandlingStart();
doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos);
@@ -620,6 +622,7 @@ public final class Choreographer {
doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos);
} finally {
AnimationUtils.unlockAnimationClock();
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}

View File

@@ -44,6 +44,31 @@ public class AnimationUtils {
private static final int TOGETHER = 0;
private static final int SEQUENTIALLY = 1;
private static class AnimationState {
boolean animationClockLocked;
long currentVsyncTimeMillis;
long lastReportedTimeMillis;
};
private static ThreadLocal<AnimationState> sAnimationState
= new ThreadLocal<AnimationState>() {
@Override
protected AnimationState initialValue() {
return new AnimationState();
}
};
/** @hide */
public static void lockAnimationClock(long vsyncMillis) {
AnimationState state = sAnimationState.get();
state.animationClockLocked = true;
state.currentVsyncTimeMillis = vsyncMillis;
}
/** @hide */
public static void unlockAnimationClock() {
sAnimationState.get().animationClockLocked = false;
}
/**
* Returns the current animation time in milliseconds. This time should be used when invoking
@@ -56,7 +81,14 @@ public class AnimationUtils {
* @see android.os.SystemClock
*/
public static long currentAnimationTimeMillis() {
return SystemClock.uptimeMillis();
AnimationState state = sAnimationState.get();
if (state.animationClockLocked) {
// It's important that time never rewinds
return Math.max(state.currentVsyncTimeMillis,
state.lastReportedTimeMillis);
}
state.lastReportedTimeMillis = SystemClock.uptimeMillis();
return state.lastReportedTimeMillis;
}
/**