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

Commit 675cc35c authored by Ahan Wu's avatar Ahan Wu
Browse files

Collect the max number of successive missed frames metric.

Bug: 229226106
Test: check the trace in the bug
Test: atest InteractionJankMonitor FrameTrackerTest
Change-Id: If3e496b0178eca0555d14ce99bc462365805c4e1
parent 7d250655
Loading
Loading
Loading
Loading
+17 −5
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@ import android.os.Trace;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;
import android.util.StatsLog;
import android.view.Choreographer;
import android.view.FrameMetrics;
import android.view.SurfaceControl;
@@ -481,6 +480,8 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
        int missedFramesCount = 0;
        int missedAppFramesCount = 0;
        int missedSfFramesCount = 0;
        int maxSuccessiveMissedFramesCount = 0;
        int successiveMissedFramesCount = 0;

        for (int i = 0; i < mJankInfos.size(); i++) {
            JankInfo info = mJankInfos.valueAt(i);
@@ -510,6 +511,11 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
                }
                if (missedFrame) {
                    missedFramesCount++;
                    successiveMissedFramesCount++;
                } else {
                    maxSuccessiveMissedFramesCount = Math.max(
                            maxSuccessiveMissedFramesCount, successiveMissedFramesCount);
                    successiveMissedFramesCount = 0;
                }
                // TODO (b/174755489): Early latch currently gets fired way too often, so we have
                // to ignore it for now.
@@ -524,6 +530,8 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
                }
            }
        }
        maxSuccessiveMissedFramesCount = Math.max(
                maxSuccessiveMissedFramesCount, successiveMissedFramesCount);

        // Log the frame stats as counters to make them easily accessible in traces.
        Trace.traceCounter(Trace.TRACE_TAG_APP, mSession.getName() + "#missedFrames",
@@ -536,6 +544,8 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
                totalFramesCount);
        Trace.traceCounter(Trace.TRACE_TAG_APP, mSession.getName() + "#maxFrameTimeMillis",
                (int) (maxFrameTimeNanos / NANOS_IN_MILLISECOND));
        Trace.traceCounter(Trace.TRACE_TAG_APP, mSession.getName() + "#maxSuccessiveMissedFrames",
                maxSuccessiveMissedFramesCount);

        // Trigger perfetto if necessary.
        if (shouldTriggerPerfetto(missedFramesCount, (int) maxFrameTimeNanos)) {
@@ -549,7 +559,8 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
                    missedFramesCount,
                    maxFrameTimeNanos, /* will be 0 if mSurfaceOnly == true */
                    missedSfFramesCount,
                    missedAppFramesCount);
                    missedAppFramesCount,
                    maxSuccessiveMissedFramesCount);
        }
        if (DEBUG) {
            Log.i(TAG, "finish: CUJ=" + mSession.getName()
@@ -558,7 +569,8 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
                    + " missedAppFrames=" + missedAppFramesCount
                    + " missedSfFrames=" + missedSfFramesCount
                    + " missedFrames=" + missedFramesCount
                    + " maxFrameTimeMillis=" + maxFrameTimeNanos / NANOS_IN_MILLISECOND);
                    + " maxFrameTimeMillis=" + maxFrameTimeNanos / NANOS_IN_MILLISECOND
                    + " maxSuccessiveMissedFramesCount=" + maxSuccessiveMissedFramesCount);
        }
    }

@@ -694,8 +706,8 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener

    public static class StatsLogWrapper {
        public void write(int code,
                int arg1, long arg2, long arg3, long arg4, long arg5, long arg6) {
            FrameworkStatsLog.write(code, arg1, arg2, arg3, arg4, arg5, arg6);
                int arg1, long arg2, long arg3, long arg4, long arg5, long arg6, long arg7) {
            FrameworkStatsLog.write(code, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
        }
    }

+47 −9
Original line number Diff line number Diff line
@@ -162,7 +162,8 @@ public class FrameTrackerTest {
                eq(0L) /* missedFrames */,
                eq(5000000L) /* maxFrameTimeNanos */,
                eq(0L) /* missedSfFramesCount */,
                eq(0L) /* missedAppFramesCount */);
                eq(0L) /* missedAppFramesCount */,
                eq(0L) /* maxSuccessiveMissedFramesCount */);
    }

    @Test
@@ -196,7 +197,8 @@ public class FrameTrackerTest {
                eq(1L) /* missedFrames */,
                eq(40000000L) /* maxFrameTimeNanos */,
                eq(1L) /* missedSfFramesCount */,
                eq(0L) /* missedAppFramesCount */);
                eq(0L) /* missedAppFramesCount */,
                eq(1L) /* maxSuccessiveMissedFramesCount */);
    }

    @Test
@@ -230,7 +232,8 @@ public class FrameTrackerTest {
                eq(0L) /* missedFrames */,
                eq(4000000L) /* maxFrameTimeNanos */,
                eq(0L) /* missedSfFramesCount */,
                eq(0L) /* missedAppFramesCount */);
                eq(0L) /* missedAppFramesCount */,
                eq(0L) /* maxSuccessiveMissedFramesCount */);
    }

    @Test
@@ -264,7 +267,8 @@ public class FrameTrackerTest {
                eq(1L) /* missedFrames */,
                eq(40000000L) /* maxFrameTimeNanos */,
                eq(0L) /* missedSfFramesCount */,
                eq(1L) /* missedAppFramesCount */);
                eq(1L) /* missedAppFramesCount */,
                eq(1L) /* maxSuccessiveMissedFramesCount */);
    }

    @Test
@@ -301,7 +305,8 @@ public class FrameTrackerTest {
                eq(1L) /* missedFrames */,
                eq(50000000L) /* maxFrameTimeNanos */,
                eq(0L) /* missedSfFramesCount */,
                eq(1L) /* missedAppFramesCount */);
                eq(1L) /* missedAppFramesCount */,
                eq(1L) /* maxSuccessiveMissedFramesCount */);
    }

    /**
@@ -340,7 +345,8 @@ public class FrameTrackerTest {
                eq(0L) /* missedFrames */,
                eq(4000000L) /* maxFrameTimeNanos */,
                eq(0L) /* missedSfFramesCount */,
                eq(0L) /* missedAppFramesCount */);
                eq(0L) /* missedAppFramesCount */,
                eq(0L) /* maxSuccessiveMissedFramesCount */);
    }

    @Test
@@ -462,7 +468,8 @@ public class FrameTrackerTest {
                eq(1L) /* missedFrames */,
                eq(0L) /* maxFrameTimeNanos */,
                eq(0L) /* missedSfFramesCount */,
                eq(1L) /* missedAppFramesCount */);
                eq(1L) /* missedAppFramesCount */,
                eq(1L) /* maxSuccessiveMissedFramesCount */);
    }

    @Test
@@ -496,7 +503,8 @@ public class FrameTrackerTest {
                eq(0L) /* missedFrames */,
                eq(0L) /* maxFrameTimeNanos */,
                eq(0L) /* missedSfFramesCount */,
                eq(0L) /* missedAppFramesCount */);
                eq(0L) /* missedAppFramesCount */,
                eq(0L) /* maxSuccessiveMissedFramesCount */);
    }

    @Test
@@ -530,7 +538,37 @@ public class FrameTrackerTest {
                eq(0L) /* missedFrames */,
                eq(0L) /* maxFrameTimeNanos */,
                eq(0L) /* missedSfFramesCount */,
                eq(0L) /* missedAppFramesCount */);
                eq(0L) /* missedAppFramesCount */,
                eq(0L) /* maxSuccessiveMissedFramesCount */);
    }

    @Test
    public void testMaxSuccessiveMissedFramesCount() {
        FrameTracker tracker = spyFrameTracker(
                CUJ_WALLPAPER_TRANSITION, CUJ_POSTFIX, /* surfaceOnly= */ true);
        when(mChoreographer.getVsyncId()).thenReturn(100L);
        tracker.begin();
        verify(mSurfaceControlWrapper).addJankStatsListener(any(), any());
        sendFrame(tracker, JANK_SURFACEFLINGER_DEADLINE_MISSED, 100L);
        sendFrame(tracker, JANK_SURFACEFLINGER_DEADLINE_MISSED, 101L);
        sendFrame(tracker, JANK_APP_DEADLINE_MISSED, 102L);
        sendFrame(tracker, JANK_NONE, 103L);
        sendFrame(tracker, JANK_APP_DEADLINE_MISSED, 104L);
        sendFrame(tracker, JANK_APP_DEADLINE_MISSED, 105L);
        when(mChoreographer.getVsyncId()).thenReturn(106L);
        tracker.end(FrameTracker.REASON_END_NORMAL);
        sendFrame(tracker, JANK_SURFACEFLINGER_DEADLINE_MISSED, 106L);
        sendFrame(tracker, JANK_SURFACEFLINGER_DEADLINE_MISSED, 107L);
        verify(mSurfaceControlWrapper).removeJankStatsListener(any());
        verify(tracker).triggerPerfetto();
        verify(mStatsLog).write(eq(UI_INTERACTION_FRAME_INFO_REPORTED),
                eq(CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_WALLPAPER_TRANSITION]),
                eq(6L) /* totalFrames */,
                eq(5L) /* missedFrames */,
                eq(0L) /* maxFrameTimeNanos */,
                eq(2L) /* missedSfFramesCount */,
                eq(3L) /* missedAppFramesCount */,
                eq(3L) /* maxSuccessiveMissedFramesCount */);
    }

    private void sendFirstWindowFrame(FrameTracker tracker, long durationMillis,