Loading core/java/android/app/jank/JankDataProcessor.java +103 −10 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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. Loading Loading @@ -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( Loading @@ -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 Loading @@ -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; Loading Loading @@ -279,6 +371,7 @@ public class JankDataProcessor { // Histogram of frame duration overruns encoded in predetermined buckets. public PendingJankStat() { } public long getProcessedVsyncId() { return processedVsyncId; } Loading Loading
core/java/android/app/jank/JankDataProcessor.java +103 −10 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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. Loading Loading @@ -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( Loading @@ -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 Loading @@ -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; Loading Loading @@ -279,6 +371,7 @@ public class JankDataProcessor { // Histogram of frame duration overruns encoded in predetermined buckets. public PendingJankStat() { } public long getProcessedVsyncId() { return processedVsyncId; } Loading