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

Commit 5e2d6932 authored by Steven Terrell's avatar Steven Terrell
Browse files

Log AppJankStats Widget Category and State

This change maps the widget categories and states reported by the system
to the atom enum value and logs them to statsd.

Bug: 374607503
Flag: android.app.jank.detailed_app_jank_metrics_logging_enabled
Test: atest CoreAppJankTestCases
Change-Id: Ic43f82193d7750b6c0a2a6e9b80fa32595f5cfb3
parent 560388cb
Loading
Loading
Loading
Loading
+103 −10
Original line number Diff line number Diff line
@@ -34,11 +34,13 @@ import java.util.List;
/**
 * This class is responsible for associating frames received from SurfaceFlinger to active widget
 * states and logging those states back to the platform.
 *
 * @hide
 */
@FlaggedApi(Flags.FLAG_DETAILED_APP_JANK_METRICS_API)
public class JankDataProcessor {

    private static final String TAG = "JankDataProcessor";
    private static final boolean DEBUG_LOGGING = false;
    private static final int MAX_IN_MEMORY_STATS = 25;
    private static final int LOG_BATCH_FREQUENCY = 50;
    private int mCurrentBatchCount = 0;
@@ -54,6 +56,7 @@ public class JankDataProcessor {

    /**
     * Called once per batch of JankData.
     *
     * @param jankData     data received from SurfaceFlinger to be processed
     * @param activityName name of the activity that is tracking jank metrics.
     * @param appUid       the uid of the app.
@@ -211,8 +214,6 @@ public class JankDataProcessor {
     * clear any pending widget states.
     */
    public void logMetricCounts() {
        //TODO b/374607503 when api changes are in add enum mapping for category and state.

        try {
            mPendingJankStats.values().forEach(stat -> {
                        FrameworkStatsLog.write(
@@ -221,15 +222,16 @@ public class JankDataProcessor {
                                /*activity name*/ stat.getActivityName(),
                                /*widget id*/ stat.getWidgetId(),
                                /*refresh rate*/ stat.getRefreshRate(),
                                /*widget category*/ 0,
                                /*widget state*/ 0,
                                /*widget category*/ widgetCategoryToInt(stat.getWidgetCategory()),
                                /*widget state*/ widgetStateToInt(stat.getWidgetState()),
                                /*total frames*/ stat.getTotalFrames(),
                                /*janky frames*/ stat.getJankyFrames(),
                                /*histogram*/ stat.mFrameOverrunBuckets);
                                /*histogram*/ stat.getFrameOverrunBuckets());
                        Log.d(stat.mActivityName, stat.toString());
                        // return the pending stat to the pool it will be reset the next time its
                        // used.
                        mPendingJankStatsPool.release(stat);

                    }
            );
            // All stats have been recorded and added back to the pool for reuse, clear the pending
@@ -241,6 +243,96 @@ public class JankDataProcessor {
        }
    }

    private int widgetCategoryToInt(String widgetCategory) {
        switch (widgetCategory) {
            case AppJankStats.WIDGET_CATEGORY_SCROLL -> {
                return FrameworkStatsLog
                        .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_STATE__SCROLLING;
            }
            case AppJankStats.WIDGET_CATEGORY_ANIMATION -> {
                return FrameworkStatsLog
                        .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_TYPE__ANIMATION;
            }
            case AppJankStats.WIDGET_CATEGORY_MEDIA -> {
                return FrameworkStatsLog
                        .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_TYPE__MEDIA;
            }
            case AppJankStats.WIDGET_CATEGORY_NAVIGATION -> {
                return FrameworkStatsLog
                        .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_TYPE__NAVIGATION;
            }
            case AppJankStats.WIDGET_CATEGORY_KEYBOARD -> {
                return FrameworkStatsLog
                        .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_TYPE__KEYBOARD;
            }
            case AppJankStats.WIDGET_CATEGORY_OTHER -> {
                return FrameworkStatsLog
                        .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_TYPE__OTHER;
            }
            default -> {
                if (DEBUG_LOGGING) {
                    Log.d(TAG, "Default Category Logged: "
                            + AppJankStats.WIDGET_CATEGORY_UNSPECIFIED);
                }
                return FrameworkStatsLog
                        .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_TYPE__WIDGET_CATEGORY_UNSPECIFIED;
            }
        }
    }

    private int widgetStateToInt(String widgetState) {
        switch (widgetState) {
            case AppJankStats.WIDGET_STATE_NONE -> {
                return FrameworkStatsLog
                        .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_STATE__NONE;
            }
            case AppJankStats.WIDGET_STATE_SCROLLING -> {
                return FrameworkStatsLog
                        .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_STATE__SCROLLING;
            }
            case AppJankStats.WIDGET_STATE_FLINGING -> {
                return FrameworkStatsLog
                        .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_STATE__FLINGING;
            }
            case AppJankStats.WIDGET_STATE_SWIPING -> {
                return FrameworkStatsLog
                        .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_STATE__SWIPING;
            }
            case AppJankStats.WIDGET_STATE_DRAGGING -> {
                return FrameworkStatsLog
                        .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_STATE__DRAGGING;
            }
            case AppJankStats.WIDGET_STATE_ZOOMING -> {
                return FrameworkStatsLog
                        .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_STATE__ZOOMING;
            }
            case AppJankStats.WIDGET_STATE_ANIMATING -> {
                return FrameworkStatsLog
                        .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_STATE__ANIMATING;
            }
            case AppJankStats.WIDGET_STATE_PLAYBACK -> {
                return FrameworkStatsLog
                        .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_STATE__PLAYBACK;
            }
            case AppJankStats.WIDGET_STATE_TAPPING -> {
                return FrameworkStatsLog
                        .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_STATE__TAPPING;
            }
            case AppJankStats.WIDGET_STATE_PREDICTIVE_BACK -> {
                return FrameworkStatsLog
                        .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_STATE__PREDICTIVE_BACK;
            }
            default -> {
                if (DEBUG_LOGGING) {
                    Log.d(TAG, "Default State Logged: "
                            + AppJankStats.WIDGET_STATE_UNSPECIFIED);
                }
                return FrameworkStatsLog
                        .JANK_FRAME_COUNT_BY_WIDGET_REPORTED__WIDGET_STATE__WIDGET_STATE_UNSPECIFIED;
            }
        }
    }

    public static final class PendingJankStat {
        private static final int NANOS_PER_MS = 1000000;
        public long processedVsyncId = -1;
@@ -279,6 +371,7 @@ public class JankDataProcessor {
        // Histogram of frame duration overruns encoded in predetermined buckets.
        public PendingJankStat() {
        }

        public long getProcessedVsyncId() {
            return processedVsyncId;
        }