2/ Instrument jank of One-handed mode trigger and exit transition
Add 2 CUJs for one handed mode transition 1. ONE_HANDED_ENTER_TRANSITION 2. ONE_HANDED_EXIT_TRANSITION - [STATE_ENTERING] Detect swipe down gesture: Begin of enter CUJ - [STATE_ENTERING] Tap shortcut to trigger: Begin of enter CUJ - [STATE_ACTIVE] Transition end of enter: End of enter CUJ - [STATE_EXITING] Detect swipe up gesture: Begin of exit CUJ - [STATE_EXITING] Tap shortcut to exit: Begin of exit CUJ - [STATE_NONE] Transition end of exit: End of exit CUJ Test: see trace in comment Bug: 201032904 Change-Id: I29258a1bbbe567c935d467621a85fbdfe2397d54
This commit is contained in:
@@ -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";
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -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<OneHandedController>,
|
||||
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<OneHandedController>,
|
||||
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<OneHandedController>,
|
||||
OneHandedAccessibilityUtil oneHandedAccessibilityUtil,
|
||||
OneHandedTimeoutHandler timeoutHandler,
|
||||
OneHandedState state,
|
||||
InteractionJankMonitor jankMonitor,
|
||||
OneHandedUiEventLogger uiEventsLogger,
|
||||
IOverlayManager overlayManager,
|
||||
TaskStackListenerImpl taskStackListener,
|
||||
|
||||
@@ -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<WindowContainerToken, SurfaceControl> 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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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<DisplayAreaAppearedInfo> 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();
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user