diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java index 0d4ad382222fd..a33b2f18819e3 100644 --- a/core/java/com/android/internal/jank/InteractionJankMonitor.java +++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java @@ -41,6 +41,8 @@ import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_IN import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_TRANSITION_TO_AOD; import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LOCKSCREEN_UNLOCK_ANIMATION; import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__NOTIFICATION_SHADE_SWIPE; +import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__ONE_HANDED_ENTER_TRANSITION; +import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__ONE_HANDED_EXIT_TRANSITION; import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__PIP_TRANSITION; import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SCREEN_OFF; import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SCREEN_OFF_SHOW_AOD; @@ -181,6 +183,8 @@ public class InteractionJankMonitor { public static final int CUJ_SPLASHSCREEN_EXIT_ANIM = 39; public static final int CUJ_SCREEN_OFF = 40; public static final int CUJ_SCREEN_OFF_SHOW_AOD = 41; + public static final int CUJ_ONE_HANDED_ENTER_TRANSITION = 42; + public static final int CUJ_ONE_HANDED_EXIT_TRANSITION = 43; private static final int NO_STATSD_LOGGING = -1; @@ -231,6 +235,8 @@ public class InteractionJankMonitor { UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SPLASHSCREEN_EXIT_ANIM, UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SCREEN_OFF, UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SCREEN_OFF_SHOW_AOD, + UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__ONE_HANDED_ENTER_TRANSITION, + UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__ONE_HANDED_EXIT_TRANSITION, }; private static volatile InteractionJankMonitor sInstance; @@ -293,6 +299,8 @@ public class InteractionJankMonitor { CUJ_SPLASHSCREEN_EXIT_ANIM, CUJ_SCREEN_OFF, CUJ_SCREEN_OFF_SHOW_AOD, + CUJ_ONE_HANDED_ENTER_TRANSITION, + CUJ_ONE_HANDED_EXIT_TRANSITION, }) @Retention(RetentionPolicy.SOURCE) public @interface CujType { @@ -712,6 +720,10 @@ public class InteractionJankMonitor { return "SCREEN_OFF"; case CUJ_SCREEN_OFF_SHOW_AOD: return "SCREEN_OFF_SHOW_AOD"; + case CUJ_ONE_HANDED_ENTER_TRANSITION: + return "ONE_HANDED_ENTER_TRANSITION"; + case CUJ_ONE_HANDED_EXIT_TRANSITION: + return "ONE_HANDED_EXIT_TRANSITION"; } return "UNKNOWN"; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java index 4f01dc60452e5..cc37caec52255 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java @@ -22,6 +22,7 @@ import android.content.pm.LauncherApps; import android.os.Handler; import android.view.WindowManager; +import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.logging.UiEventLogger; import com.android.internal.statusbar.IStatusBarService; import com.android.launcher3.icons.IconProvider; @@ -143,10 +144,10 @@ public class WMShellModule { static OneHandedController provideOneHandedController(Context context, WindowManager windowManager, DisplayController displayController, DisplayLayout displayLayout, TaskStackListenerImpl taskStackListener, - UiEventLogger uiEventLogger, @ShellMainThread ShellExecutor mainExecutor, - @ShellMainThread Handler mainHandler) { + UiEventLogger uiEventLogger, InteractionJankMonitor jankMonitor, + @ShellMainThread ShellExecutor mainExecutor, @ShellMainThread Handler mainHandler) { return OneHandedController.create(context, windowManager, displayController, displayLayout, - taskStackListener, uiEventLogger, mainExecutor, mainHandler); + taskStackListener, jankMonitor, uiEventLogger, mainExecutor, mainHandler); } // diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java index c9c73fd8f191c..96f82fa5ce36c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java @@ -45,6 +45,7 @@ import android.window.WindowContainerTransaction; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; +import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.logging.UiEventLogger; import com.android.wm.shell.R; import com.android.wm.shell.common.DisplayChangeController; @@ -194,7 +195,8 @@ public class OneHandedController implements RemoteCallable, public static OneHandedController create( Context context, WindowManager windowManager, DisplayController displayController, DisplayLayout displayLayout, TaskStackListenerImpl taskStackListener, - UiEventLogger uiEventLogger, ShellExecutor mainExecutor, Handler mainHandler) { + InteractionJankMonitor jankMonitor, UiEventLogger uiEventLogger, + ShellExecutor mainExecutor, Handler mainHandler) { OneHandedSettingsUtil settingsUtil = new OneHandedSettingsUtil(); OneHandedAccessibilityUtil accessibilityUtil = new OneHandedAccessibilityUtil(context); OneHandedTimeoutHandler timeoutHandler = new OneHandedTimeoutHandler(mainExecutor); @@ -210,13 +212,13 @@ public class OneHandedController implements RemoteCallable, mainExecutor); OneHandedDisplayAreaOrganizer organizer = new OneHandedDisplayAreaOrganizer( context, displayLayout, settingsUtil, animationController, tutorialHandler, - oneHandedBackgroundPanelOrganizer, mainExecutor); + oneHandedBackgroundPanelOrganizer, jankMonitor, mainExecutor); OneHandedUiEventLogger oneHandedUiEventsLogger = new OneHandedUiEventLogger(uiEventLogger); IOverlayManager overlayManager = IOverlayManager.Stub.asInterface( ServiceManager.getService(Context.OVERLAY_SERVICE)); return new OneHandedController(context, displayController, oneHandedBackgroundPanelOrganizer, organizer, touchHandler, tutorialHandler, - settingsUtil, accessibilityUtil, timeoutHandler, oneHandedState, + settingsUtil, accessibilityUtil, timeoutHandler, oneHandedState, jankMonitor, oneHandedUiEventsLogger, overlayManager, taskStackListener, mainExecutor, mainHandler); } @@ -232,6 +234,7 @@ public class OneHandedController implements RemoteCallable, OneHandedAccessibilityUtil oneHandedAccessibilityUtil, OneHandedTimeoutHandler timeoutHandler, OneHandedState state, + InteractionJankMonitor jankMonitor, OneHandedUiEventLogger uiEventsLogger, IOverlayManager overlayManager, TaskStackListenerImpl taskStackListener, diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java index ec3ef5a27fe0a..87eb40cbde62f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java @@ -16,12 +16,15 @@ package com.android.wm.shell.onehanded; +import static com.android.internal.jank.InteractionJankMonitor.CUJ_ONE_HANDED_ENTER_TRANSITION; +import static com.android.internal.jank.InteractionJankMonitor.CUJ_ONE_HANDED_EXIT_TRANSITION; import static com.android.wm.shell.onehanded.OneHandedAnimationController.TRANSITION_DIRECTION_EXIT; import static com.android.wm.shell.onehanded.OneHandedAnimationController.TRANSITION_DIRECTION_TRIGGER; import android.content.Context; import android.graphics.Rect; import android.os.SystemProperties; +import android.text.TextUtils; import android.util.ArrayMap; import android.view.SurfaceControl; import android.window.DisplayAreaAppearedInfo; @@ -34,6 +37,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; +import com.android.internal.jank.InteractionJankMonitor; import com.android.wm.shell.R; import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.ShellExecutor; @@ -41,6 +45,7 @@ import com.android.wm.shell.common.ShellExecutor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; +import java.util.Map; /** * Manages OneHanded display areas such as offset. @@ -62,6 +67,8 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer { private final Rect mLastVisualDisplayBounds = new Rect(); private final Rect mDefaultDisplayBounds = new Rect(); private final OneHandedSettingsUtil mOneHandedSettingsUtil; + private final InteractionJankMonitor mJankMonitor; + private final Context mContext; private boolean mIsReady; private float mLastVisualOffset = 0; @@ -95,7 +102,11 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer { public void onOneHandedAnimationEnd(SurfaceControl.Transaction tx, OneHandedAnimationController.OneHandedTransitionAnimator animator) { mAnimationController.removeAnimator(animator.getToken()); + final boolean isEntering = animator.getTransitionDirection() + == TRANSITION_DIRECTION_TRIGGER; if (mAnimationController.isAnimatorsConsumed()) { + endCUJTracing(isEntering ? CUJ_ONE_HANDED_ENTER_TRANSITION + : CUJ_ONE_HANDED_EXIT_TRANSITION); finishOffset((int) animator.getDestinationOffset(), animator.getTransitionDirection()); } @@ -105,7 +116,11 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer { public void onOneHandedAnimationCancel( OneHandedAnimationController.OneHandedTransitionAnimator animator) { mAnimationController.removeAnimator(animator.getToken()); + final boolean isEntering = animator.getTransitionDirection() + == TRANSITION_DIRECTION_TRIGGER; if (mAnimationController.isAnimatorsConsumed()) { + cancelCUJTracing(isEntering ? CUJ_ONE_HANDED_ENTER_TRANSITION + : CUJ_ONE_HANDED_EXIT_TRANSITION); finishOffset((int) animator.getDestinationOffset(), animator.getTransitionDirection()); } @@ -121,11 +136,14 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer { OneHandedAnimationController animationController, OneHandedTutorialHandler tutorialHandler, OneHandedBackgroundPanelOrganizer oneHandedBackgroundGradientOrganizer, + InteractionJankMonitor jankMonitor, ShellExecutor mainExecutor) { super(mainExecutor); + mContext = context; setDisplayLayout(displayLayout); mOneHandedSettingsUtil = oneHandedSettingsUtil; mAnimationController = animationController; + mJankMonitor = jankMonitor; final int animationDurationConfig = context.getResources().getInteger( R.integer.config_one_handed_translate_animation_duration); mEnterExitAnimationDurationMs = @@ -197,6 +215,11 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer { final int direction = yOffset > 0 ? TRANSITION_DIRECTION_TRIGGER : TRANSITION_DIRECTION_EXIT; + if (direction == TRANSITION_DIRECTION_TRIGGER) { + beginCUJTracing(CUJ_ONE_HANDED_ENTER_TRANSITION, "enterOneHanded"); + } else { + beginCUJTracing(CUJ_ONE_HANDED_EXIT_TRANSITION, "stopOneHanded"); + } mDisplayAreaTokenMap.forEach( (token, leash) -> { animateWindows(token, leash, fromPos, yOffset, direction, @@ -302,6 +325,26 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer { mTransitionCallbacks.add(callback); } + void beginCUJTracing(@InteractionJankMonitor.CujType int cujType, @Nullable String tag) { + final Map.Entry firstEntry = + getDisplayAreaTokenMap().entrySet().iterator().next(); + final InteractionJankMonitor.Configuration.Builder builder = + InteractionJankMonitor.Configuration.Builder.withSurface( + cujType, mContext, firstEntry.getValue()); + if (!TextUtils.isEmpty(tag)) { + builder.setTag(tag); + } + mJankMonitor.begin(builder); + } + + void endCUJTracing(@InteractionJankMonitor.CujType int cujType) { + mJankMonitor.end(cujType); + } + + void cancelCUJTracing(@InteractionJankMonitor.CujType int cujType) { + mJankMonitor.cancel(cujType); + } + void dump(@NonNull PrintWriter pw) { final String innerPrefix = " "; pw.println(TAG); diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java index 16bc50750e1d8..636e875bed7e0 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java @@ -46,6 +46,7 @@ import android.window.WindowContainerTransaction; import androidx.test.filters.SmallTest; +import com.android.internal.jank.InteractionJankMonitor; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.ShellExecutor; @@ -86,6 +87,8 @@ public class OneHandedControllerTest extends OneHandedTestCase { @Mock OneHandedUiEventLogger mMockUiEventLogger; @Mock + InteractionJankMonitor mMockJankMonitor; + @Mock IOverlayManager mMockOverlayManager; @Mock TaskStackListenerImpl mMockTaskStackListener; @@ -139,6 +142,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { mOneHandedAccessibilityUtil, mSpiedTimeoutHandler, mSpiedTransitionState, + mMockJankMonitor, mMockUiEventLogger, mMockOverlayManager, mMockTaskStackListener, diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizerTest.java index 1d92a48c25fda..df21163c68cd4 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizerTest.java @@ -50,6 +50,7 @@ import android.window.WindowContainerTransaction; import androidx.test.filters.SmallTest; +import com.android.internal.jank.InteractionJankMonitor; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.ShellExecutor; @@ -99,6 +100,8 @@ public class OneHandedDisplayAreaOrganizerTest extends OneHandedTestCase { ShellExecutor mMockShellMainExecutor; @Mock OneHandedSettingsUtil mMockSettingsUitl; + @Mock + InteractionJankMonitor mJankMonitor; List mDisplayAreaAppearedInfoList = new ArrayList<>(); @@ -141,6 +144,7 @@ public class OneHandedDisplayAreaOrganizerTest extends OneHandedTestCase { mMockAnimationController, mTutorialHandler, mMockBackgroundOrganizer, + mJankMonitor, mMockShellMainExecutor)); for (int i = 0; i < DISPLAYAREA_INFO_COUNT; i++) { @@ -428,6 +432,7 @@ public class OneHandedDisplayAreaOrganizerTest extends OneHandedTestCase { mMockAnimationController, mTutorialHandler, mMockBackgroundOrganizer, + mJankMonitor, mMockShellMainExecutor)); assertThat(testSpiedDisplayAreaOrganizer.isReady()).isFalse(); diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedStateTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedStateTest.java index bea69c5d80ef7..58399b6444fa8 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedStateTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedStateTest.java @@ -40,6 +40,7 @@ import android.view.SurfaceControl; import androidx.test.filters.SmallTest; +import com.android.internal.jank.InteractionJankMonitor; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.ShellExecutor; @@ -78,6 +79,8 @@ public class OneHandedStateTest extends OneHandedTestCase { @Mock OneHandedUiEventLogger mMockUiEventLogger; @Mock + InteractionJankMonitor mMockJankMonitor; + @Mock IOverlayManager mMockOverlayManager; @Mock TaskStackListenerImpl mMockTaskStackListener; @@ -128,6 +131,7 @@ public class OneHandedStateTest extends OneHandedTestCase { mOneHandedAccessibilityUtil, mSpiedTimeoutHandler, mSpiedState, + mMockJankMonitor, mMockUiEventLogger, mMockOverlayManager, mMockTaskStackListener,