diff options
| author | Marcin Oczeretko <marcinoc@google.com> | 2020-09-01 07:45:51 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2020-09-01 07:45:51 +0000 |
| commit | d64cb948ded210ff2f37071568e999b627684663 (patch) | |
| tree | 78d3e91e11d7a5e266546d1ec22f0e9e468a2c5e /core/java | |
| parent | 75b905479b59c2ed1122cd21e278117205cc67a0 (diff) | |
| parent | d4430329bcc11602a8dbca6eb3fba69957e8bdb0 (diff) | |
Merge "Report per-interaction frame statistics to statsd"
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/com/android/internal/jank/FrameTracker.java | 77 | ||||
| -rw-r--r-- | core/java/com/android/internal/jank/InteractionJankMonitor.java | 22 |
2 files changed, 55 insertions, 44 deletions
diff --git a/core/java/com/android/internal/jank/FrameTracker.java b/core/java/com/android/internal/jank/FrameTracker.java index f9a2ecc10dc8..e5c845059a0d 100644 --- a/core/java/com/android/internal/jank/FrameTracker.java +++ b/core/java/com/android/internal/jank/FrameTracker.java @@ -26,6 +26,7 @@ import android.view.ThreadedRenderer; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.jank.InteractionJankMonitor.Session; +import com.android.internal.util.FrameworkStatsLog; /** * @hide @@ -34,18 +35,19 @@ public class FrameTracker implements HardwareRendererObserver.OnFrameMetricsAvai private static final String TAG = FrameTracker.class.getSimpleName(); private static final boolean DEBUG = false; //TODO (163431584): need also consider other refresh rates. - private static final long CRITERIA = 1000000000 / 60; - @VisibleForTesting - public static final long UNKNOWN_TIMESTAMP = -1; + private static final long JANK_THRESHOLD_NANOS = 1000000000 / 60; + private static final long UNKNOWN_TIMESTAMP = -1; - @VisibleForTesting - public long mBeginTime = UNKNOWN_TIMESTAMP; - @VisibleForTesting - public long mEndTime = UNKNOWN_TIMESTAMP; - public boolean mShouldTriggerTrace; - public HardwareRendererObserver mObserver; - public ThreadedRendererWrapper mRendererWrapper; - public FrameMetricsWrapper mMetricsWrapper; + private final HardwareRendererObserver mObserver; + private final ThreadedRendererWrapper mRendererWrapper; + private final FrameMetricsWrapper mMetricsWrapper; + + private long mBeginTime = UNKNOWN_TIMESTAMP; + private long mEndTime = UNKNOWN_TIMESTAMP; + private boolean mShouldTriggerTrace; + private long mTotalFramesCount = 0; + private long mMissedFramesCount = 0; + private long mMaxFrameTimeNanos = 0; private Session mSession; @@ -108,37 +110,6 @@ public class FrameTracker implements HardwareRendererObserver.OnFrameMetricsAvai Trace.endAsyncSection(mSession.getName(), (int) mBeginTime); } - /** - * Check if we had a janky frame according to the metrics. - * @param metrics frame metrics - * @return true if it is a janky frame - */ - @VisibleForTesting - public boolean isJankyFrame(FrameMetricsWrapper metrics) { - long totalDurationMs = metrics.getMetric(FrameMetrics.TOTAL_DURATION); - boolean isFirstFrame = metrics.getMetric(FrameMetrics.FIRST_DRAW_FRAME) == 1; - boolean isJanky = !isFirstFrame && totalDurationMs - CRITERIA > 0; - - if (DEBUG) { - StringBuilder sb = new StringBuilder(); - sb.append(isJanky).append(","); - sb.append(metrics.getMetric(FrameMetrics.FIRST_DRAW_FRAME)).append(","); - sb.append(metrics.getMetric(FrameMetrics.INPUT_HANDLING_DURATION)).append(","); - sb.append(metrics.getMetric(FrameMetrics.ANIMATION_DURATION)).append(","); - sb.append(metrics.getMetric(FrameMetrics.LAYOUT_MEASURE_DURATION)).append(","); - sb.append(metrics.getMetric(FrameMetrics.DRAW_DURATION)).append(","); - sb.append(metrics.getMetric(FrameMetrics.SYNC_DURATION)).append(","); - sb.append(metrics.getMetric(FrameMetrics.COMMAND_ISSUE_DURATION)).append(","); - sb.append(metrics.getMetric(FrameMetrics.SWAP_BUFFERS_DURATION)).append(","); - sb.append(totalDurationMs).append(","); - sb.append(metrics.getMetric(FrameMetrics.INTENDED_VSYNC_TIMESTAMP)).append(","); - sb.append(metrics.getMetric(FrameMetrics.VSYNC_TIMESTAMP)).append(","); - Log.v(TAG, "metrics=" + sb.toString()); - } - - return isJanky; - } - @Override public void onFrameMetricsAvailable(int dropCountSinceLastInvocation) { // Since this callback might come a little bit late after the end() call. @@ -160,11 +131,29 @@ public class FrameTracker implements HardwareRendererObserver.OnFrameMetricsAvai } triggerPerfetto(); } + if (mSession.logToStatsd()) { + FrameworkStatsLog.write( + FrameworkStatsLog.UI_INTERACTION_FRAME_INFO_REPORTED, + mSession.getStatsdInteractionType(), + mTotalFramesCount, + mMissedFramesCount, + mMaxFrameTimeNanos); + } return; } - // The frame is in the duration of the CUJ, check if it catches the deadline. - if (isJankyFrame(mMetricsWrapper)) { + long totalDurationNanos = mMetricsWrapper.getMetric(FrameMetrics.TOTAL_DURATION); + boolean isFirstFrame = mMetricsWrapper.getMetric(FrameMetrics.FIRST_DRAW_FRAME) == 1; + boolean isJankyFrame = !isFirstFrame && totalDurationNanos > JANK_THRESHOLD_NANOS; + + mTotalFramesCount += 1; + + if (!isFirstFrame) { + mMaxFrameTimeNanos = Math.max(totalDurationNanos, mMaxFrameTimeNanos); + } + + if (isJankyFrame) { + mMissedFramesCount += 1; mShouldTriggerTrace = true; } } diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java index 6bfb178bc102..5a0cbf9e93e4 100644 --- a/core/java/com/android/internal/jank/InteractionJankMonitor.java +++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java @@ -16,6 +16,8 @@ package com.android.internal.jank; +import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__NOTIFICATION_SHADE_SWIPE; + import android.annotation.IntDef; import android.annotation.NonNull; import android.os.HandlerThread; @@ -37,9 +39,20 @@ public class InteractionJankMonitor { private static final String TAG = InteractionJankMonitor.class.getSimpleName(); private static final boolean DEBUG = false; private static final Object LOCK = new Object(); + + // Every value must have a corresponding entry in CUJ_STATSD_INTERACTION_TYPE. public static final int CUJ_NOTIFICATION_SHADE_MOTION = 0; public static final int CUJ_NOTIFICATION_SHADE_GESTURE = 1; + private static final int NO_STATSD_LOGGING = -1; + + // Used to convert CujType to InteractionType enum value for statsd logging. + // Use NO_STATSD_LOGGING in case the measurement for a given CUJ should not be logged to statsd. + private static final int[] CUJ_TO_STATSD_INTERACTION_TYPE = { + NO_STATSD_LOGGING, + UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__NOTIFICATION_SHADE_SWIPE, + }; + private static ThreadedRenderer sRenderer; private static Map<String, FrameTracker> sRunningTracker; private static HandlerThread sWorker; @@ -173,6 +186,15 @@ public class InteractionJankMonitor { return mId; } + public int getStatsdInteractionType() { + return CUJ_TO_STATSD_INTERACTION_TYPE[mId]; + } + + /** Describes whether the measurement from this session should be written to statsd. */ + public boolean logToStatsd() { + return getStatsdInteractionType() != NO_STATSD_LOGGING; + } + public String getName() { return "CujType<" + mId + ">"; } |
