diff options
| author | Ahan Wu <ahanwu@google.com> | 2021-01-27 17:29:54 +0000 |
|---|---|---|
| committer | Ahan Wu <ahanwu@google.com> | 2021-02-22 19:24:56 +0000 |
| commit | 320858c56f14e6b7585ea4e5ff93190d7b23fa3d (patch) | |
| tree | 2244260634e0a10e7d477f9818a91c51256a52d1 /core/java | |
| parent | 318641ee43b42226efd57e962c410c8d27c8fefb (diff) | |
Send broadcast to notify the events of a CUJ session
Send broadcast to notify the CUJ events to who is interested in.
Bug: 171912046
Test: atest FrameworksCoreTests:InteractionJankMonitorTest
Test: atest FrameworksCoreTests:FrameTrackerTest
Change-Id: I91ab025385c635d15d7be6f7f12597e8900e2e5d
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/com/android/internal/jank/FrameTracker.java | 28 | ||||
| -rw-r--r-- | core/java/com/android/internal/jank/InteractionJankMonitor.java | 40 |
2 files changed, 65 insertions, 3 deletions
diff --git a/core/java/com/android/internal/jank/FrameTracker.java b/core/java/com/android/internal/jank/FrameTracker.java index e82cc737a395..342456a58091 100644 --- a/core/java/com/android/internal/jank/FrameTracker.java +++ b/core/java/com/android/internal/jank/FrameTracker.java @@ -25,6 +25,9 @@ import static android.view.SurfaceControl.JankData.JANK_SURFACEFLINGER_GPU_DEADL import static android.view.SurfaceControl.JankData.PREDICTION_ERROR; import static android.view.SurfaceControl.JankData.SURFACE_FLINGER_SCHEDULING; +import static com.android.internal.jank.InteractionJankMonitor.ACTION_METRICS_LOGGED; +import static com.android.internal.jank.InteractionJankMonitor.ACTION_SESSION_BEGIN; + import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.HardwareRendererObserver; @@ -72,6 +75,7 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener private long mEndVsyncId = INVALID_ID; private boolean mMetricsFinalized; private boolean mCancelled = false; + private FrameTrackerListener mListener; private static class JankInfo { long frameVsyncId; @@ -109,7 +113,7 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener @NonNull SurfaceControlWrapper surfaceControlWrapper, @NonNull ChoreographerWrapper choreographer, @NonNull FrameMetricsWrapper metrics, int traceThresholdMissedFrames, - int traceThresholdFrameTimeMillis) { + int traceThresholdFrameTimeMillis, @Nullable FrameTrackerListener listener) { mSession = session; mRendererWrapper = renderer; mMetricsWrapper = metrics; @@ -120,6 +124,7 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener mObserver = new HardwareRendererObserver(this, mMetricsWrapper.getTiming(), handler); mTraceThresholdMissedFrames = traceThresholdMissedFrames; mTraceThresholdFrameTimeMillis = traceThresholdFrameTimeMillis; + mListener = listener; // If the surface isn't valid yet, wait until it's created. if (viewRootWrapper.getSurfaceControl().isValid()) { @@ -165,11 +170,15 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener */ public synchronized void begin() { mBeginVsyncId = mChoreographer.getVsyncId() + 1; + mSession.setTimeStamp(System.nanoTime()); Trace.beginAsyncSection(mSession.getName(), (int) mBeginVsyncId); mRendererWrapper.addObserver(mObserver); if (mSurfaceControl != null) { mSurfaceControlWrapper.addJankStatsListener(this, mSurfaceControl); } + if (mListener != null) { + mListener.onNotifyCujEvents(mSession, ACTION_SESSION_BEGIN); + } } /** @@ -224,7 +233,6 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener } private boolean isInRange(long vsyncId) { - // It's possible that we may miss a callback for the frame with vsyncId == mEndVsyncId. // Because of that, we collect all frames even if they happen after the end so we eventually // have a frame after the end with both callbacks present. @@ -371,6 +379,9 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener missedAppFramesCount + missedSfFramesCounts, maxFrameTimeNanos, missedSfFramesCounts); + if (mListener != null) { + mListener.onNotifyCujEvents(mSession, ACTION_METRICS_LOGGED); + } } if (DEBUG) { Log.i(TAG, "FrameTracker: CUJ=" + mSession.getName() @@ -495,4 +506,17 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener return mChoreographer.getVsyncId(); } } + + /** + * A listener that notifies cuj events. + */ + public interface FrameTrackerListener { + /** + * Notify that the CUJ session was created. + * + * @param session the CUJ session + * @param action the specific action + */ + void onNotifyCujEvents(Session session, String action); + } } diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java index cba6af98a980..0294ec398484 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 android.content.Intent.FLAG_RECEIVER_REGISTERED_ONLY; + import static com.android.internal.jank.FrameTracker.ChoreographerWrapper; import static com.android.internal.jank.FrameTracker.SurfaceControlWrapper; import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_ALL_APPS_SCROLL; @@ -48,9 +50,12 @@ import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_IN import android.annotation.IntDef; import android.annotation.NonNull; +import android.content.Context; +import android.content.Intent; import android.os.Build; import android.os.HandlerExecutor; import android.os.HandlerThread; +import android.os.SystemProperties; import android.provider.DeviceConfig; import android.util.Log; import android.util.SparseArray; @@ -59,6 +64,7 @@ import android.view.View; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.jank.FrameTracker.FrameMetricsWrapper; +import com.android.internal.jank.FrameTracker.FrameTrackerListener; import com.android.internal.jank.FrameTracker.ThreadedRendererWrapper; import com.android.internal.jank.FrameTracker.ViewRootWrapper; import com.android.internal.util.PerfettoTrigger; @@ -74,6 +80,8 @@ import java.util.concurrent.TimeUnit; */ public class InteractionJankMonitor { private static final String TAG = InteractionJankMonitor.class.getSimpleName(); + private static final String ACTION_PREFIX = InteractionJankMonitor.class.getCanonicalName(); + private static final String DEFAULT_WORKER_NAME = TAG + "-Worker"; private static final long DEFAULT_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(5L); private static final String SETTINGS_ENABLED_KEY = "enabled"; @@ -90,6 +98,14 @@ public class InteractionJankMonitor { private static final int DEFAULT_TRACE_THRESHOLD_MISSED_FRAMES = 3; private static final int DEFAULT_TRACE_THRESHOLD_FRAME_TIME_MILLIS = 64; + public static final String ACTION_SESSION_BEGIN = ACTION_PREFIX + ".ACTION_SESSION_BEGIN"; + public static final String ACTION_SESSION_END = ACTION_PREFIX + ".ACTION_SESSION_END"; + public static final String ACTION_METRICS_LOGGED = ACTION_PREFIX + ".ACTION_METRICS_LOGGED"; + public static final String BUNDLE_KEY_CUJ_NAME = ACTION_PREFIX + ".CUJ_NAME"; + public static final String BUNDLE_KEY_TIMESTAMP = ACTION_PREFIX + ".TIMESTAMP"; + @VisibleForTesting + public static final String PROP_NOTIFY_CUJ_EVENT = "debug.notify_cuj_events"; + // Every value must have a corresponding entry in CUJ_STATSD_INTERACTION_TYPE. public static final int CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE = 0; public static final int CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE_LOCK = 1; @@ -256,15 +272,28 @@ public class InteractionJankMonitor { */ @VisibleForTesting public FrameTracker createFrameTracker(View v, Session session) { + final Context c = v.getContext().getApplicationContext(); synchronized (this) { + boolean needListener = SystemProperties.getBoolean(PROP_NOTIFY_CUJ_EVENT, false); + FrameTrackerListener eventsListener = + !needListener ? null : (s, act) -> notifyEvents(c, act, s); + return new FrameTracker(session, mWorker.getThreadHandler(), new ThreadedRendererWrapper(v.getThreadedRenderer()), new ViewRootWrapper(v.getViewRootImpl()), new SurfaceControlWrapper(), new ChoreographerWrapper(Choreographer.getInstance()), mMetrics, - mTraceThresholdMissedFrames, mTraceThresholdFrameTimeMillis); + mTraceThresholdMissedFrames, mTraceThresholdFrameTimeMillis, eventsListener); } } + private void notifyEvents(Context context, String action, Session session) { + Intent intent = new Intent(action); + intent.putExtra(BUNDLE_KEY_CUJ_NAME, getNameOfCuj(session.getCuj())); + intent.putExtra(BUNDLE_KEY_TIMESTAMP, session.getTimeStamp()); + intent.addFlags(FLAG_RECEIVER_REGISTERED_ONLY); + context.sendBroadcast(intent); + } + /** * Begin a trace session. * @@ -479,6 +508,7 @@ public class InteractionJankMonitor { public static class Session { @CujType private int mCujType; + private long mTimeStamp; public Session(@CujType int cujType) { mCujType = cujType; @@ -505,5 +535,13 @@ public class InteractionJankMonitor { public String getName() { return "J<" + getNameOfCuj(mCujType) + ">"; } + + public void setTimeStamp(long timeStamp) { + mTimeStamp = timeStamp; + } + + public long getTimeStamp() { + return mTimeStamp; + } } } |
