summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
authorMarcin Oczeretko <marcinoc@google.com>2020-09-01 07:45:51 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2020-09-01 07:45:51 +0000
commitd64cb948ded210ff2f37071568e999b627684663 (patch)
tree78d3e91e11d7a5e266546d1ec22f0e9e468a2c5e /core/java
parent75b905479b59c2ed1122cd21e278117205cc67a0 (diff)
parentd4430329bcc11602a8dbca6eb3fba69957e8bdb0 (diff)
Merge "Report per-interaction frame statistics to statsd"
Diffstat (limited to 'core/java')
-rw-r--r--core/java/com/android/internal/jank/FrameTracker.java77
-rw-r--r--core/java/com/android/internal/jank/InteractionJankMonitor.java22
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 + ">";
}