Loading core/java/com/android/internal/jank/FrameTracker.java +29 −11 Original line number Diff line number Diff line Loading @@ -98,6 +98,7 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener private final Handler mHandler; private final ChoreographerWrapper mChoreographer; private final Object mLock = InteractionJankMonitor.getInstance().getLock(); private final boolean mDeferMonitoring; @VisibleForTesting public final boolean mSurfaceOnly; Loading Loading @@ -153,6 +154,7 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener mHandler = handler; mChoreographer = choreographer; mSurfaceControlWrapper = surfaceControlWrapper; mDeferMonitoring = config.shouldDeferMonitor(); // HWUI instrumentation init. mRendererWrapper = mSurfaceOnly ? null : renderer; Loading Loading @@ -228,12 +230,25 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener */ public void begin() { synchronized (mLock) { mBeginVsyncId = mChoreographer.getVsyncId() + 1; final long currentVsync = mChoreographer.getVsyncId(); // In normal case, we should begin at the next frame, // the id of the next frame is not simply increased by 1, // but we can exclude the current frame at least. mBeginVsyncId = mDeferMonitoring ? currentVsync + 1 : currentVsync; if (DEBUG) { Log.d(TAG, "begin: " + mSession.getName() + ", begin=" + mBeginVsyncId); Log.d(TAG, "begin: " + mSession.getName() + ", begin=" + mBeginVsyncId + ", defer=" + mDeferMonitoring); } if (mSurfaceControl != null) { if (mDeferMonitoring) { // Normal case, we begin the instrument from the very beginning, // except the first frame. postTraceStartMarker(); } else { // If we don't begin the instrument from the very beginning, // there is no need to skip the frame where the begin invocation happens. beginInternal(); } mSurfaceControlWrapper.addJankStatsListener(this, mSurfaceControl); } if (!mSurfaceOnly) { Loading @@ -247,7 +262,11 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener */ @VisibleForTesting public void postTraceStartMarker() { mChoreographer.mChoreographer.postCallback(Choreographer.CALLBACK_INPUT, () -> { mChoreographer.mChoreographer.postCallback( Choreographer.CALLBACK_INPUT, this::beginInternal, null); } private void beginInternal() { synchronized (mLock) { if (mCancelled || mEndVsyncId != INVALID_ID) { return; Loading @@ -255,7 +274,6 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener mTracingStarted = true; Trace.beginAsyncSection(mSession.getName(), (int) mBeginVsyncId); } }, null); } /** Loading core/java/com/android/internal/jank/InteractionJankMonitor.java +24 −2 Original line number Diff line number Diff line Loading @@ -717,6 +717,7 @@ public class InteractionJankMonitor { private final boolean mSurfaceOnly; private final SurfaceControl mSurfaceControl; private final @CujType int mCujType; private final boolean mDeferMonitor; /** * A builder for building Configuration. {@link #setView(View)} is essential Loading @@ -733,6 +734,7 @@ public class InteractionJankMonitor { private boolean mAttrSurfaceOnly; private SurfaceControl mAttrSurfaceControl; private @CujType int mAttrCujType; private boolean mAttrDeferMonitor = true; /** * Creates a builder which instruments only surface. Loading Loading @@ -822,6 +824,16 @@ public class InteractionJankMonitor { return this; } /** * Indicates if the instrument should be deferred to the next frame. * @param defer true if the instrument should be deferred to the next frame. * @return builder */ public Builder setDeferMonitorForAnimationStart(boolean defer) { mAttrDeferMonitor = defer; return this; } /** * Builds the {@link Configuration} instance * @return the instance of {@link Configuration} Loading @@ -830,12 +842,14 @@ public class InteractionJankMonitor { public Configuration build() throws IllegalArgumentException { return new Configuration( mAttrCujType, mAttrView, mAttrTag, mAttrTimeout, mAttrSurfaceOnly, mAttrContext, mAttrSurfaceControl); mAttrSurfaceOnly, mAttrContext, mAttrSurfaceControl, mAttrDeferMonitor); } } private Configuration(@CujType int cuj, View view, String tag, long timeout, boolean surfaceOnly, Context context, SurfaceControl surfaceControl) { boolean surfaceOnly, Context context, SurfaceControl surfaceControl, boolean deferMonitor) { mCujType = cuj; mTag = tag; mTimeout = timeout; Loading @@ -845,6 +859,7 @@ public class InteractionJankMonitor { ? context : (view != null ? view.getContext().getApplicationContext() : null); mSurfaceControl = surfaceControl; mDeferMonitor = deferMonitor; validate(); } Loading Loading @@ -901,6 +916,13 @@ public class InteractionJankMonitor { Context getContext() { return mContext; } /** * @return true if the monitoring should be deferred to the next frame, false otherwise. */ public boolean shouldDeferMonitor() { return mDeferMonitor; } } /** Loading packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java +12 −1 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.os.Trace; import android.text.format.DateFormat; import android.util.FloatProperty; import android.util.Log; import android.view.Choreographer; import android.view.InsetsFlags; import android.view.InsetsVisibilities; import android.view.View; Loading @@ -44,6 +45,7 @@ import androidx.annotation.NonNull; import com.android.internal.annotations.GuardedBy; import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.jank.InteractionJankMonitor.Configuration; import com.android.internal.logging.UiEventLogger; import com.android.systemui.DejankUtils; import com.android.systemui.Dumpable; Loading Loading @@ -352,8 +354,17 @@ public class StatusBarStateControllerImpl implements } private void beginInteractionJankMonitor() { final boolean shouldPost = (mIsDozing && mDozeAmount == 0) || (!mIsDozing && mDozeAmount == 1); if (mInteractionJankMonitor != null && mView != null && mView.isAttachedToWindow()) { mInteractionJankMonitor.begin(mView, getCujType()); if (shouldPost) { Choreographer.getInstance().postCallback( Choreographer.CALLBACK_ANIMATION, this::beginInteractionJankMonitor, null); } else { Configuration.Builder builder = Configuration.Builder.withView(getCujType(), mView) .setDeferMonitorForAnimationStart(false); mInteractionJankMonitor.begin(builder); } } } Loading Loading
core/java/com/android/internal/jank/FrameTracker.java +29 −11 Original line number Diff line number Diff line Loading @@ -98,6 +98,7 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener private final Handler mHandler; private final ChoreographerWrapper mChoreographer; private final Object mLock = InteractionJankMonitor.getInstance().getLock(); private final boolean mDeferMonitoring; @VisibleForTesting public final boolean mSurfaceOnly; Loading Loading @@ -153,6 +154,7 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener mHandler = handler; mChoreographer = choreographer; mSurfaceControlWrapper = surfaceControlWrapper; mDeferMonitoring = config.shouldDeferMonitor(); // HWUI instrumentation init. mRendererWrapper = mSurfaceOnly ? null : renderer; Loading Loading @@ -228,12 +230,25 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener */ public void begin() { synchronized (mLock) { mBeginVsyncId = mChoreographer.getVsyncId() + 1; final long currentVsync = mChoreographer.getVsyncId(); // In normal case, we should begin at the next frame, // the id of the next frame is not simply increased by 1, // but we can exclude the current frame at least. mBeginVsyncId = mDeferMonitoring ? currentVsync + 1 : currentVsync; if (DEBUG) { Log.d(TAG, "begin: " + mSession.getName() + ", begin=" + mBeginVsyncId); Log.d(TAG, "begin: " + mSession.getName() + ", begin=" + mBeginVsyncId + ", defer=" + mDeferMonitoring); } if (mSurfaceControl != null) { if (mDeferMonitoring) { // Normal case, we begin the instrument from the very beginning, // except the first frame. postTraceStartMarker(); } else { // If we don't begin the instrument from the very beginning, // there is no need to skip the frame where the begin invocation happens. beginInternal(); } mSurfaceControlWrapper.addJankStatsListener(this, mSurfaceControl); } if (!mSurfaceOnly) { Loading @@ -247,7 +262,11 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener */ @VisibleForTesting public void postTraceStartMarker() { mChoreographer.mChoreographer.postCallback(Choreographer.CALLBACK_INPUT, () -> { mChoreographer.mChoreographer.postCallback( Choreographer.CALLBACK_INPUT, this::beginInternal, null); } private void beginInternal() { synchronized (mLock) { if (mCancelled || mEndVsyncId != INVALID_ID) { return; Loading @@ -255,7 +274,6 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener mTracingStarted = true; Trace.beginAsyncSection(mSession.getName(), (int) mBeginVsyncId); } }, null); } /** Loading
core/java/com/android/internal/jank/InteractionJankMonitor.java +24 −2 Original line number Diff line number Diff line Loading @@ -717,6 +717,7 @@ public class InteractionJankMonitor { private final boolean mSurfaceOnly; private final SurfaceControl mSurfaceControl; private final @CujType int mCujType; private final boolean mDeferMonitor; /** * A builder for building Configuration. {@link #setView(View)} is essential Loading @@ -733,6 +734,7 @@ public class InteractionJankMonitor { private boolean mAttrSurfaceOnly; private SurfaceControl mAttrSurfaceControl; private @CujType int mAttrCujType; private boolean mAttrDeferMonitor = true; /** * Creates a builder which instruments only surface. Loading Loading @@ -822,6 +824,16 @@ public class InteractionJankMonitor { return this; } /** * Indicates if the instrument should be deferred to the next frame. * @param defer true if the instrument should be deferred to the next frame. * @return builder */ public Builder setDeferMonitorForAnimationStart(boolean defer) { mAttrDeferMonitor = defer; return this; } /** * Builds the {@link Configuration} instance * @return the instance of {@link Configuration} Loading @@ -830,12 +842,14 @@ public class InteractionJankMonitor { public Configuration build() throws IllegalArgumentException { return new Configuration( mAttrCujType, mAttrView, mAttrTag, mAttrTimeout, mAttrSurfaceOnly, mAttrContext, mAttrSurfaceControl); mAttrSurfaceOnly, mAttrContext, mAttrSurfaceControl, mAttrDeferMonitor); } } private Configuration(@CujType int cuj, View view, String tag, long timeout, boolean surfaceOnly, Context context, SurfaceControl surfaceControl) { boolean surfaceOnly, Context context, SurfaceControl surfaceControl, boolean deferMonitor) { mCujType = cuj; mTag = tag; mTimeout = timeout; Loading @@ -845,6 +859,7 @@ public class InteractionJankMonitor { ? context : (view != null ? view.getContext().getApplicationContext() : null); mSurfaceControl = surfaceControl; mDeferMonitor = deferMonitor; validate(); } Loading Loading @@ -901,6 +916,13 @@ public class InteractionJankMonitor { Context getContext() { return mContext; } /** * @return true if the monitoring should be deferred to the next frame, false otherwise. */ public boolean shouldDeferMonitor() { return mDeferMonitor; } } /** Loading
packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java +12 −1 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.os.Trace; import android.text.format.DateFormat; import android.util.FloatProperty; import android.util.Log; import android.view.Choreographer; import android.view.InsetsFlags; import android.view.InsetsVisibilities; import android.view.View; Loading @@ -44,6 +45,7 @@ import androidx.annotation.NonNull; import com.android.internal.annotations.GuardedBy; import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.jank.InteractionJankMonitor.Configuration; import com.android.internal.logging.UiEventLogger; import com.android.systemui.DejankUtils; import com.android.systemui.Dumpable; Loading Loading @@ -352,8 +354,17 @@ public class StatusBarStateControllerImpl implements } private void beginInteractionJankMonitor() { final boolean shouldPost = (mIsDozing && mDozeAmount == 0) || (!mIsDozing && mDozeAmount == 1); if (mInteractionJankMonitor != null && mView != null && mView.isAttachedToWindow()) { mInteractionJankMonitor.begin(mView, getCujType()); if (shouldPost) { Choreographer.getInstance().postCallback( Choreographer.CALLBACK_ANIMATION, this::beginInteractionJankMonitor, null); } else { Configuration.Builder builder = Configuration.Builder.withView(getCujType(), mView) .setDeferMonitorForAnimationStart(false); mInteractionJankMonitor.begin(builder); } } } Loading