Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1247)

Unified Diff: base/android/java/src/org/chromium/base/AnimationFrameTimeHistogram.java

Issue 949613002: [Android] Add animation frame time histogram class. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: ns -> ms renaming, excluded AppMenu Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/android/base_jni_registrar.cc ('k') | base/base.gyp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/android/java/src/org/chromium/base/AnimationFrameTimeHistogram.java
diff --git a/base/android/java/src/org/chromium/base/AnimationFrameTimeHistogram.java b/base/android/java/src/org/chromium/base/AnimationFrameTimeHistogram.java
new file mode 100644
index 0000000000000000000000000000000000000000..ad5cdd815bfcf81fe85952085f4f1656b04f185a
--- /dev/null
+++ b/base/android/java/src/org/chromium/base/AnimationFrameTimeHistogram.java
@@ -0,0 +1,145 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.base;
+
+import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.TimeAnimator;
+import android.animation.TimeAnimator.TimeListener;
+import android.util.Log;
+
+/**
+ * Record Android animation frame rate and save it to UMA histogram. This is mainly for monitoring
+ * any jankiness of short Chrome Android animations. It is limited to few seconds of recording.
+ */
+public class AnimationFrameTimeHistogram {
+ private static final String TAG = "AnimationFrameTimeHistogram";
+ private static final int MAX_FRAME_TIME_NUM = 600; // 10 sec on 60 fps.
+
+ private final Recorder mRecorder = new Recorder();
+ private final String mHistogramName;
+
+ /**
+ * @param histogramName The histogram name that the recorded frame times will be saved.
+ * This must be also defined in histograms.xml
+ * @return An AnimatorListener instance that records frame time histogram on start and end
+ * automatically.
+ */
+ public static AnimatorListener getAnimatorRecorder(final String histogramName) {
+ return new AnimatorListenerAdapter() {
+ private final AnimationFrameTimeHistogram mAnimationFrameTimeHistogram =
+ new AnimationFrameTimeHistogram(histogramName);
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mAnimationFrameTimeHistogram.startRecording();
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mAnimationFrameTimeHistogram.endRecording();
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ mAnimationFrameTimeHistogram.endRecording();
+ }
+ };
+ }
+
+ /**
+ * @param histogramName The histogram name that the recorded frame times will be saved.
+ * This must be also defined in histograms.xml
+ */
+ public AnimationFrameTimeHistogram(String histogramName) {
+ mHistogramName = histogramName;
+ }
+
+ /**
+ * Start recording frame times. The recording can fail if it exceeds a few seconds.
+ */
+ public void startRecording() {
+ mRecorder.startRecording();
+ }
+
+ /**
+ * End recording and save it to histogram. It won't save histogram if the recording wasn't
+ * successful.
+ */
+ public void endRecording() {
+ if (mRecorder.endRecording()) {
+ nativeSaveHistogram(mHistogramName,
+ mRecorder.getFrameTimesMs(), mRecorder.getFrameTimesCount());
+ }
+ mRecorder.cleanUp();
+ }
+
+ /**
+ * Record Android animation frame rate and return the result.
+ */
+ private static class Recorder implements TimeListener {
+ // TODO(kkimlabs): If we can use in the future, migrate to Choreographer for minimal
+ // workload.
+ private final TimeAnimator mAnimator = new TimeAnimator();
+ private long[] mFrameTimesMs;
+ private int mFrameTimesCount;
+
+ private Recorder() {
+ mAnimator.setTimeListener(this);
+ }
+
+ private void startRecording() {
+ assert !mAnimator.isRunning();
+ mFrameTimesCount = 0;
+ mFrameTimesMs = new long[MAX_FRAME_TIME_NUM];
+ mAnimator.start();
+ }
+
+ /**
+ * @return Whether the recording was successful. If successful, the result is available via
+ * getFrameTimesNs and getFrameTimesCount.
+ */
+ private boolean endRecording() {
+ boolean succeeded = mAnimator.isStarted();
+ mAnimator.end();
+ return succeeded;
+ }
+
+ private long[] getFrameTimesMs() {
+ return mFrameTimesMs;
+ }
+
+ private int getFrameTimesCount() {
+ return mFrameTimesCount;
+ }
+
+ /**
+ * Deallocates the temporary buffer to record frame times. Must be called after ending
+ * the recording and getting the result.
+ */
+ private void cleanUp() {
+ mFrameTimesMs = null;
+ }
+
+ @Override
+ public void onTimeUpdate(TimeAnimator animation, long totalTime, long deltaTime) {
+ if (mFrameTimesCount == mFrameTimesMs.length) {
+ mAnimator.end();
+ cleanUp();
+ Log.w(TAG, "Animation frame time recording reached the maximum number. It's either"
+ + "the animation took too long or recording end is not called.");
+ return;
+ }
+
+ // deltaTime is 0 for the first frame.
+ if (deltaTime > 0) {
+ mFrameTimesMs[mFrameTimesCount++] = deltaTime;
+ }
+ }
+ }
+
+ private native void nativeSaveHistogram(String histogramName, long[] frameTimesMs, int count);
+}
« no previous file with comments | « base/android/base_jni_registrar.cc ('k') | base/base.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698