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

Commit c60451d0 authored by Ahan Wu's avatar Ahan Wu
Browse files

Defer the instrument of AOD transition per doze amount

When the doze changes, StatusBar#updateDozing will be invoked at the
first frame, usually make the following one be regarded as janky,
but it is unperceptible by the users, so ignore it.

Bug: 201987244
Test: Capture the trace manually
Change-Id: Iac739d23eb0fdc988bd52076bdccca4665e28d18
parent d7015099
Loading
Loading
Loading
Loading
+29 −11
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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) {
@@ -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;
@@ -255,7 +274,6 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener
            mTracingStarted = true;
            Trace.beginAsyncSection(mSession.getName(), (int) mBeginVsyncId);
        }
        }, null);
    }

    /**
+24 −2
Original line number Diff line number Diff line
@@ -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
@@ -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.
@@ -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}
@@ -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;
@@ -845,6 +859,7 @@ public class InteractionJankMonitor {
                    ? context
                    : (view != null ? view.getContext().getApplicationContext() : null);
            mSurfaceControl = surfaceControl;
            mDeferMonitor = deferMonitor;
            validate();
        }

@@ -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;
        }
    }

    /**
+12 −1
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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);
            }
        }
    }