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

Commit f00dda2e authored by Devarshi Bhatt's avatar Devarshi Bhatt Committed by Android (Google) Code Review
Browse files

Merge changes from topic "jank_monitor" into main

* changes:
  Remove InteractionJankMonitorUtils and usages.
  Add new API for starting a trace session with SurfaceControl input.
parents ff099c24 a35c28a2
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
@@ -322,6 +322,48 @@ public class InteractionJankMonitor {
        }
    }

    /**
     * Begins a trace session.
     *
     * @param surface a handle for the surface to begin tracing for.
     * @param context context to provide display and handler information.
     * @param cujType the specific {@link Cuj.CujType}.
     * @return boolean true if the tracker is started successfully, false otherwise.
     */
    public boolean begin(SurfaceControl surface, Context context, @Cuj.CujType int cujType) {
        try {
            return begin(Configuration.Builder.withSurface(cujType, context, surface));
        } catch (IllegalArgumentException ex) {
            Log.d(TAG, "Build configuration failed!", ex);
            return false;
        }
    }

    /**
     * Begins a trace session.
     *
     * @param surface a handle for the surface to begin tracing for.
     * @param context context to provide display and handler information.
     * @param cujType the specific {@link Cuj.CujType}.
     * @param tag a tag containing extra information about the interaction.
     * @return boolean true if the tracker is started successfully, false otherwise.
     */
    public boolean begin(SurfaceControl surface, Context context, @Cuj.CujType int cujType,
            String tag) {
        try {
            final Configuration.Builder builder =
                    Configuration.Builder.withSurface(cujType, context, surface);
            if (!TextUtils.isEmpty(tag)) {
                builder.setTag(tag);
            }
            return begin(builder);
        } catch (IllegalArgumentException ex) {
            Log.d(TAG, "Build configuration failed!", ex);
            return false;
        }
    }


    /**
     * Begins a trace session.
     *
+22 −1
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import android.os.Handler;
import android.os.HandlerThread;
import android.os.SystemClock;
import android.provider.DeviceConfig;
import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewAttachTestActivity;

@@ -67,6 +68,7 @@ public class InteractionJankMonitorTest {
    private View mView;
    private Handler mHandler;
    private HandlerThread mWorker;
    private SurfaceControl mSurfaceControl;

    @Rule
    public ActivityScenarioRule<ViewAttachTestActivity> mRule =
@@ -79,6 +81,9 @@ public class InteractionJankMonitorTest {
    public void setup() {
        mRule.getScenario().onActivity(activity -> mActivity = activity);
        mView = mActivity.getWindow().getDecorView();
        mSurfaceControl = mView.getViewRootImpl().getSurfaceControl();
        // Set mNativeObject to a non-zero value to make it a valid SurfaceControl.
        mSurfaceControl.mNativeObject = 1;
        assertThat(mView.isAttachedToWindow()).isTrue();

        mHandler = spy(new Handler(mActivity.getMainLooper()));
@@ -88,7 +93,7 @@ public class InteractionJankMonitorTest {
    }

    @Test
    public void testBeginEnd() {
    public void testBeginEnd_inputView() {
        InteractionJankMonitor monitor = createMockedInteractionJankMonitor();
        FrameTracker tracker = createMockedFrameTracker();
        doReturn(tracker).when(monitor).createFrameTracker(any());
@@ -102,6 +107,22 @@ public class InteractionJankMonitorTest {
        verify(tracker).end(REASON_END_NORMAL);
    }

    @Test
    public void testBeginEnd_inputSurfaceControl() {
        InteractionJankMonitor monitor = createMockedInteractionJankMonitor();
        FrameTracker tracker = createMockedFrameTracker();
        doReturn(tracker).when(monitor).createFrameTracker(any());
        doNothing().when(tracker).begin();
        doReturn(true).when(tracker).end(anyInt());

        // Simulate a trace session and see if begin / end are invoked.
        assertThat(monitor.begin(mSurfaceControl, mActivity.getApplicationContext(),
                Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE)).isTrue();
        verify(tracker).begin();
        assertThat(monitor.end(Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE)).isTrue();
        verify(tracker).end(REASON_END_NORMAL);
    }

    @Test
    public void testDisabledThroughDeviceConfig() {
        InteractionJankMonitor monitor = new InteractionJankMonitor(mWorker);
+5 −4
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@ import android.window.IOnBackInvokedCallback;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.jank.Cuj.CujType;
import com.android.wm.shell.common.InteractionJankMonitorUtils;
import com.android.internal.jank.InteractionJankMonitor;

/**
 * Used to register the animation callback and runner, it will trigger result if gesture was finish
@@ -86,20 +86,21 @@ public class BackAnimationRunner {
     */
    void startAnimation(RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers,
            RemoteAnimationTarget[] nonApps, Runnable finishedCallback) {
        InteractionJankMonitor interactionJankMonitor = InteractionJankMonitor.getInstance();
        final IRemoteAnimationFinishedCallback callback =
                new IRemoteAnimationFinishedCallback.Stub() {
                    @Override
                    public void onAnimationFinished() {
                        if (shouldMonitorCUJ(apps)) {
                            InteractionJankMonitorUtils.endTracing(mCujType);
                            interactionJankMonitor.end(mCujType);
                        }
                        finishedCallback.run();
                    }
                };
        mWaitingAnimation = false;
        if (shouldMonitorCUJ(apps)) {
            InteractionJankMonitorUtils.beginTracing(
                    mCujType, mContext, apps[0].leash, /* tag */ null);
            interactionJankMonitor.begin(
                    apps[0].leash, mContext, mCujType);
        }
        try {
            getRunner().onAnimationStart(TRANSIT_OLD_UNSET, apps, wallpapers,
+0 −84
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.wm.shell.common;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.text.TextUtils;
import android.view.SurfaceControl;
import android.view.View;

import com.android.internal.jank.Cuj.CujType;
import com.android.internal.jank.InteractionJankMonitor;

/** Utils class for simplfy InteractionJank trancing call */
public class InteractionJankMonitorUtils {

    /**
     * Begin a trace session.
     *
     * @param cujType the specific {@link CujType}.
     * @param view the view to trace
     * @param tag the tag to distinguish different flow of same type CUJ.
     */
    public static void beginTracing(@CujType int cujType,
            @NonNull View view, @Nullable String tag) {
        final InteractionJankMonitor.Configuration.Builder builder =
                InteractionJankMonitor.Configuration.Builder.withView(cujType, view);
        if (!TextUtils.isEmpty(tag)) {
            builder.setTag(tag);
        }
        InteractionJankMonitor.getInstance().begin(builder);
    }

    /**
     * Begin a trace session.
     *
     * @param cujType the specific {@link CujType}.
     * @param context the context
     * @param surface the surface to trace
     * @param tag the tag to distinguish different flow of same type CUJ.
     */
    public static void beginTracing(@CujType int cujType,
            @NonNull Context context, @NonNull SurfaceControl surface, @Nullable String tag) {
        final InteractionJankMonitor.Configuration.Builder builder =
                InteractionJankMonitor.Configuration.Builder.withSurface(cujType, context, surface);
        if (!TextUtils.isEmpty(tag)) {
            builder.setTag(tag);
        }
        InteractionJankMonitor.getInstance().begin(builder);
    }

    /**
     * End a trace session.
     *
     * @param cujType the specific {@link CujType}.
     */
    public static void endTracing(@CujType int cujType) {
        InteractionJankMonitor.getInstance().end(cujType);
    }

    /**
     * Cancel the trace session.
     *
     * @param cujType the specific {@link CujType}.
     */
    public static void cancelTracing(@CujType int cujType) {
        InteractionJankMonitor.getInstance().cancel(cujType);
    }
}
+11 −10
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ import android.window.WindowContainerTransaction;
import androidx.annotation.Nullable;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer;
@@ -67,7 +68,6 @@ import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.InteractionJankMonitorUtils;
import com.android.wm.shell.common.split.SplitScreenConstants.PersistentSnapPosition;
import com.android.wm.shell.common.split.SplitScreenConstants.SnapPosition;
import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition;
@@ -131,6 +131,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange

    private final boolean mDimNonImeSide;
    private final boolean mAllowLeftRightSplitInPortrait;
    private final InteractionJankMonitor mInteractionJankMonitor;
    private boolean mIsLeftRightSplit;
    private ValueAnimator mDividerFlingAnimator;

@@ -163,6 +164,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange

        mRootBounds.set(configuration.windowConfiguration.getBounds());
        mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds);
        mInteractionJankMonitor = InteractionJankMonitor.getInstance();
        resetDividerPosition();
        updateInvisibleRect();
    }
@@ -569,12 +571,11 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
    }

    void onStartDragging() {
        InteractionJankMonitorUtils.beginTracing(CUJ_SPLIT_SCREEN_RESIZE, mContext,
                getDividerLeash(), null /* tag */);
        mInteractionJankMonitor.begin(getDividerLeash(), mContext, CUJ_SPLIT_SCREEN_RESIZE);
    }

    void onDraggingCancelled() {
        InteractionJankMonitorUtils.cancelTracing(CUJ_SPLIT_SCREEN_RESIZE);
        mInteractionJankMonitor.cancel(CUJ_SPLIT_SCREEN_RESIZE);
    }

    void onDoubleTappedDivider() {
@@ -638,7 +639,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
            if (flingFinishedCallback != null) {
                flingFinishedCallback.run();
            }
            InteractionJankMonitorUtils.endTracing(
            mInteractionJankMonitor.end(
                    CUJ_SPLIT_SCREEN_RESIZE);
            return;
        }
@@ -661,7 +662,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
                if (flingFinishedCallback != null) {
                    flingFinishedCallback.run();
                }
                InteractionJankMonitorUtils.endTracing(
                mInteractionJankMonitor.end(
                        CUJ_SPLIT_SCREEN_RESIZE);
                mDividerFlingAnimator = null;
            }
@@ -707,8 +708,8 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
        set.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                InteractionJankMonitorUtils.beginTracing(CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER,
                        mContext, getDividerLeash(), null /*tag*/);
                mInteractionJankMonitor.begin(getDividerLeash(),
                        mContext, CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER);
            }

            @Override
@@ -716,12 +717,12 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
                mDividerPosition = dividerPos;
                updateBounds(mDividerPosition);
                finishCallback.accept(insets);
                InteractionJankMonitorUtils.endTracing(CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER);
                mInteractionJankMonitor.end(CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER);
            }

            @Override
            public void onAnimationCancel(Animator animation) {
                InteractionJankMonitorUtils.cancelTracing(CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER);
                mInteractionJankMonitor.cancel(CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER);
            }
        });
        set.start();
Loading