summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Vania Desmonda <vaniadesmonda@google.com> 2024-10-22 09:37:47 +0000
committer Vania Desmonda <vaniadesmonda@google.com> 2024-10-22 09:37:47 +0000
commita1923cc340f45a2b4276920f7c1b1057b3013726 (patch)
treedf69b6d4471100b666ca6773eee3cec10cec0d00
parent44bf6e08babecdf1edbf4d3f9ee7cbf2a4ba71c8 (diff)
Add log resize start and end on all resize triggers.
Fixes: 373592364 Test: atest DesktopModeEventLoggerTest Flag: com.android.window.flags.enable_resizing_metrics Change-Id: If01e0cf026bdb5d242ed372c5e21c5c5fcb49868
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt112
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt62
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java1
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java53
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java21
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java60
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java9
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java17
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeEventLoggerTest.kt51
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt154
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt49
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java5
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java10
15 files changed, 522 insertions, 96 deletions
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 427df1784506..4c2588984500 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
@@ -267,7 +267,8 @@ public abstract class WMShellModule {
AppHandleEducationController appHandleEducationController,
WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository,
Optional<DesktopActivityOrientationChangeHandler> desktopActivityOrientationHandler,
- FocusTransitionObserver focusTransitionObserver) {
+ FocusTransitionObserver focusTransitionObserver,
+ DesktopModeEventLogger desktopModeEventLogger) {
if (DesktopModeStatus.canEnterDesktopMode(context)) {
return new DesktopModeWindowDecorViewModel(
context,
@@ -295,7 +296,8 @@ public abstract class WMShellModule {
appHandleEducationController,
windowDecorCaptionHandleRepository,
desktopActivityOrientationHandler,
- focusTransitionObserver);
+ focusTransitionObserver,
+ desktopModeEventLogger);
}
return new CaptionWindowDecorViewModel(
context,
@@ -647,7 +649,8 @@ public abstract class WMShellModule {
Optional<RecentTasksController> recentTasksController,
InteractionJankMonitor interactionJankMonitor,
InputManager inputManager,
- FocusTransitionObserver focusTransitionObserver) {
+ FocusTransitionObserver focusTransitionObserver,
+ DesktopModeEventLogger desktopModeEventLogger) {
return new DesktopTasksController(context, shellInit, shellCommandHandler, shellController,
displayController, shellTaskOrganizer, syncQueue, rootTaskDisplayAreaOrganizer,
dragAndDropController, transitions, keyguardManager,
@@ -659,7 +662,8 @@ public abstract class WMShellModule {
desktopModeLoggerTransitionObserver, launchAdjacentController,
recentsTransitionHandler, multiInstanceHelper, mainExecutor, desktopTasksLimiter,
recentTasksController.orElse(null), interactionJankMonitor, mainHandler,
- inputManager, focusTransitionObserver);
+ inputManager, focusTransitionObserver,
+ desktopModeEventLogger);
}
@WMSingleton
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt
index 8ebe503a3816..255ca6e2511f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt
@@ -16,11 +16,20 @@
package com.android.wm.shell.desktopmode
+import android.app.ActivityManager.RunningTaskInfo
+import android.util.Size
+import android.view.InputDevice.SOURCE_MOUSE
+import android.view.InputDevice.SOURCE_TOUCHSCREEN
+import android.view.MotionEvent
+import android.view.MotionEvent.TOOL_TYPE_FINGER
+import android.view.MotionEvent.TOOL_TYPE_MOUSE
+import android.view.MotionEvent.TOOL_TYPE_STYLUS
import com.android.internal.annotations.VisibleForTesting
import com.android.internal.protolog.ProtoLog
import com.android.internal.util.FrameworkStatsLog
import com.android.window.flags.Flags
import com.android.wm.shell.EventLogTags
+import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
import java.security.SecureRandom
import java.util.Random
@@ -176,7 +185,13 @@ class DesktopModeEventLogger {
* Logs that a task resize event is starting with [taskSizeUpdate] within a Desktop mode
* session.
*/
- fun logTaskResizingStarted(taskSizeUpdate: TaskSizeUpdate) {
+ fun logTaskResizingStarted(
+ resizeTrigger: ResizeTrigger,
+ motionEvent: MotionEvent?,
+ taskInfo: RunningTaskInfo,
+ displayController: DisplayController? = null,
+ displayLayoutSize: Size? = null,
+ ) {
if (!Flags.enableResizingMetrics()) return
val sessionId = currentSessionId.get()
@@ -188,11 +203,19 @@ class DesktopModeEventLogger {
return
}
+ val taskSizeUpdate = createTaskSizeUpdate(
+ resizeTrigger,
+ motionEvent,
+ taskInfo,
+ displayController = displayController,
+ displayLayoutSize = displayLayoutSize,
+ )
+
ProtoLog.v(
WM_SHELL_DESKTOP_MODE,
- "DesktopModeLogger: Logging task resize is starting, session: %s taskId: %s",
+ "DesktopModeLogger: Logging task resize is starting, session: %s, taskSizeUpdate: %s",
sessionId,
- taskSizeUpdate.instanceId
+ taskSizeUpdate
)
logTaskSizeUpdated(
FrameworkStatsLog.DESKTOP_MODE_TASK_SIZE_UPDATED__RESIZING_STAGE__START_RESIZING_STAGE,
@@ -203,7 +226,15 @@ class DesktopModeEventLogger {
/**
* Logs that a task resize event is ending with [taskSizeUpdate] within a Desktop mode session.
*/
- fun logTaskResizingEnded(taskSizeUpdate: TaskSizeUpdate) {
+ fun logTaskResizingEnded(
+ resizeTrigger: ResizeTrigger,
+ motionEvent: MotionEvent?,
+ taskInfo: RunningTaskInfo,
+ taskHeight: Int? = null,
+ taskWidth: Int? = null,
+ displayController: DisplayController? = null,
+ displayLayoutSize: Size? = null,
+ ) {
if (!Flags.enableResizingMetrics()) return
val sessionId = currentSessionId.get()
@@ -215,18 +246,61 @@ class DesktopModeEventLogger {
return
}
+ val taskSizeUpdate = createTaskSizeUpdate(
+ resizeTrigger,
+ motionEvent,
+ taskInfo,
+ taskHeight,
+ taskWidth,
+ displayController,
+ displayLayoutSize,
+ )
+
ProtoLog.v(
WM_SHELL_DESKTOP_MODE,
- "DesktopModeLogger: Logging task resize is ending, session: %s taskId: %s",
+ "DesktopModeLogger: Logging task resize is ending, session: %s, taskSizeUpdate: %s",
sessionId,
- taskSizeUpdate.instanceId
+ taskSizeUpdate
)
+
logTaskSizeUpdated(
FrameworkStatsLog.DESKTOP_MODE_TASK_SIZE_UPDATED__RESIZING_STAGE__END_RESIZING_STAGE,
sessionId, taskSizeUpdate
)
}
+ private fun createTaskSizeUpdate(
+ resizeTrigger: ResizeTrigger,
+ motionEvent: MotionEvent?,
+ taskInfo: RunningTaskInfo,
+ taskHeight: Int? = null,
+ taskWidth: Int? = null,
+ displayController: DisplayController? = null,
+ displayLayoutSize: Size? = null,
+ ): TaskSizeUpdate {
+ val taskBounds = taskInfo.configuration.windowConfiguration.bounds
+
+ val height = taskHeight ?: taskBounds.height()
+ val width = taskWidth ?: taskBounds.width()
+
+ val displaySize = when {
+ displayLayoutSize != null -> displayLayoutSize.height * displayLayoutSize.width
+ displayController != null -> displayController.getDisplayLayout(taskInfo.displayId)
+ ?.let { it.height() * it.width() }
+ else -> null
+ }
+
+ return TaskSizeUpdate(
+ resizeTrigger,
+ getInputMethodFromMotionEvent(motionEvent),
+ taskInfo.taskId,
+ taskInfo.effectiveUid,
+ height,
+ width,
+ displaySize,
+ )
+ }
+
fun logTaskInfoStateInit() {
logTaskUpdate(
FrameworkStatsLog.DESKTOP_MODE_SESSION_TASK_UPDATE__TASK_EVENT__TASK_INIT_STATSD,
@@ -238,7 +312,8 @@ class DesktopModeEventLogger {
taskHeight = 0,
taskWidth = 0,
taskX = 0,
- taskY = 0)
+ taskY = 0
+ )
)
}
@@ -314,7 +389,7 @@ class DesktopModeEventLogger {
/* task_width */
taskSizeUpdate.taskWidth,
/* display_area */
- taskSizeUpdate.displayArea
+ taskSizeUpdate.displayArea ?: -1
)
}
@@ -364,9 +439,24 @@ class DesktopModeEventLogger {
val uid: Int,
val taskHeight: Int,
val taskWidth: Int,
- val displayArea: Int,
+ val displayArea: Int?,
)
+ private fun getInputMethodFromMotionEvent(e: MotionEvent?): InputMethod {
+ if (e == null) return InputMethod.UNKNOWN_INPUT_METHOD
+
+ val toolType = e.getToolType(
+ e.findPointerIndex(e.getPointerId(0))
+ )
+ return when {
+ toolType == TOOL_TYPE_STYLUS -> InputMethod.STYLUS
+ toolType == TOOL_TYPE_MOUSE -> InputMethod.MOUSE
+ toolType == TOOL_TYPE_FINGER && e.source == SOURCE_MOUSE -> InputMethod.TOUCHPAD
+ toolType == TOOL_TYPE_FINGER && e.source == SOURCE_TOUCHSCREEN -> InputMethod.TOUCH
+ else -> InputMethod.UNKNOWN_INPUT_METHOD
+ }
+ }
+
// Default value used when the task was not minimized.
@VisibleForTesting
const val UNSET_MINIMIZE_REASON =
@@ -499,6 +589,10 @@ class DesktopModeEventLogger {
FrameworkStatsLog
.DESKTOP_MODE_TASK_SIZE_UPDATED__RESIZE_TRIGGER__SNAP_RIGHT_MENU_RESIZE_TRIGGER
),
+ MAXIMIZE_MENU(
+ FrameworkStatsLog
+ .DESKTOP_MODE_TASK_SIZE_UPDATED__RESIZE_TRIGGER__MAXIMIZE_MENU_RESIZE_TRIGGER
+ ),
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
index b505bee469fe..69776cd4740a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
@@ -46,6 +46,7 @@ import android.util.Size
import android.view.Display.DEFAULT_DISPLAY
import android.view.DragEvent
import android.view.KeyEvent
+import android.view.MotionEvent
import android.view.SurfaceControl
import android.view.WindowManager.TRANSIT_CHANGE
import android.view.WindowManager.TRANSIT_CLOSE
@@ -125,7 +126,7 @@ import java.io.PrintWriter
import java.util.Optional
import java.util.concurrent.Executor
import java.util.function.Consumer
-
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger
/** Handles moving tasks in and out of desktop */
class DesktopTasksController(
private val context: Context,
@@ -158,6 +159,7 @@ class DesktopTasksController(
@ShellMainThread private val handler: Handler,
private val inputManager: InputManager,
private val focusTransitionObserver: FocusTransitionObserver,
+ private val desktopModeEventLogger: DesktopModeEventLogger,
) :
RemoteCallable<DesktopTasksController>,
Transitions.TransitionHandler,
@@ -747,7 +749,11 @@ class DesktopTasksController(
* bounds) and a free floating state (either the last saved bounds if available or the default
* bounds otherwise).
*/
- fun toggleDesktopTaskSize(taskInfo: RunningTaskInfo) {
+ fun toggleDesktopTaskSize(
+ taskInfo: RunningTaskInfo,
+ resizeTrigger: ResizeTrigger,
+ motionEvent: MotionEvent?,
+ ) {
val displayLayout = displayController.getDisplayLayout(taskInfo.displayId) ?: return
val stableBounds = Rect().apply { displayLayout.getStableBounds(this) }
@@ -794,7 +800,10 @@ class DesktopTasksController(
taskbarDesktopTaskListener?.onTaskbarCornerRoundingUpdate(doesAnyTaskRequireTaskbarRounding)
val wct = WindowContainerTransaction().setBounds(taskInfo.token, destinationBounds)
-
+ desktopModeEventLogger.logTaskResizingEnded(
+ resizeTrigger, motionEvent, taskInfo, destinationBounds.height(),
+ destinationBounds.width(), displayController
+ )
toggleResizeDesktopTaskTransitionHandler.startTransition(wct)
}
@@ -884,9 +893,19 @@ class DesktopTasksController(
taskInfo: RunningTaskInfo,
taskSurface: SurfaceControl,
currentDragBounds: Rect,
- position: SnapPosition
+ position: SnapPosition,
+ resizeTrigger: ResizeTrigger,
+ motionEvent: MotionEvent?,
) {
val destinationBounds = getSnapBounds(taskInfo, position)
+ desktopModeEventLogger.logTaskResizingEnded(
+ resizeTrigger,
+ motionEvent,
+ taskInfo,
+ destinationBounds.height(),
+ destinationBounds.width(),
+ displayController,
+ )
if (destinationBounds == taskInfo.configuration.windowConfiguration.bounds) {
// Handle the case where we attempt to snap resize when already snap resized: the task
// position won't need to change but we want to animate the surface going back to the
@@ -915,7 +934,8 @@ class DesktopTasksController(
position: SnapPosition,
taskSurface: SurfaceControl,
currentDragBounds: Rect,
- dragStartBounds: Rect
+ dragStartBounds: Rect,
+ motionEvent: MotionEvent,
) {
releaseVisualIndicator()
if (!taskInfo.isResizeable && DISABLE_NON_RESIZABLE_APP_SNAP_RESIZE.isTrue()) {
@@ -932,10 +952,25 @@ class DesktopTasksController(
isResizable = taskInfo.isResizeable,
)
} else {
+ val resizeTrigger = if (position == SnapPosition.LEFT) {
+ ResizeTrigger.DRAG_LEFT
+ } else {
+ ResizeTrigger.DRAG_RIGHT
+ }
+ desktopModeEventLogger.logTaskResizingStarted(
+ resizeTrigger, motionEvent, taskInfo, displayController
+ )
interactionJankMonitor.begin(
taskSurface, context, handler, CUJ_DESKTOP_MODE_SNAP_RESIZE, "drag_resizable"
)
- snapToHalfScreen(taskInfo, taskSurface, currentDragBounds, position)
+ snapToHalfScreen(
+ taskInfo,
+ taskSurface,
+ currentDragBounds,
+ position,
+ resizeTrigger,
+ motionEvent,
+ )
}
}
@@ -1735,6 +1770,7 @@ class DesktopTasksController(
currentDragBounds: Rect,
validDragArea: Rect,
dragStartBounds: Rect,
+ motionEvent: MotionEvent,
) {
if (taskInfo.configuration.windowConfiguration.windowingMode != WINDOWING_MODE_FREEFORM) {
return
@@ -1755,12 +1791,22 @@ class DesktopTasksController(
}
IndicatorType.TO_SPLIT_LEFT_INDICATOR -> {
handleSnapResizingTask(
- taskInfo, SnapPosition.LEFT, taskSurface, currentDragBounds, dragStartBounds
+ taskInfo,
+ SnapPosition.LEFT,
+ taskSurface,
+ currentDragBounds,
+ dragStartBounds,
+ motionEvent,
)
}
IndicatorType.TO_SPLIT_RIGHT_INDICATOR -> {
handleSnapResizingTask(
- taskInfo, SnapPosition.RIGHT, taskSurface, currentDragBounds, dragStartBounds
+ taskInfo,
+ SnapPosition.RIGHT,
+ taskSurface,
+ currentDragBounds,
+ dragStartBounds,
+ motionEvent,
)
}
IndicatorType.NO_INDICATOR -> {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
index 509cb85c96cd..fde01eefee17 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
@@ -274,6 +274,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
closeDragResizeListener();
mDragResizeListener = new DragResizeInputListener(
mContext,
+ mTaskInfo,
mHandler,
mChoreographer,
mDisplay.getDisplayId(),
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index a06b4a2e09d4..a775cbc6c9f3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -32,6 +32,7 @@ import static android.view.WindowInsets.Type.statusBars;
import static com.android.internal.jank.Cuj.CUJ_DESKTOP_MODE_ENTER_MODE_APP_HANDLE_MENU;
import static com.android.wm.shell.compatui.AppCompatUtils.isTopActivityExemptFromDesktopWindowing;
+import static com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger;
import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR;
import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_LEFT_INDICATOR;
import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_RIGHT_INDICATOR;
@@ -103,6 +104,7 @@ import com.android.wm.shell.common.MultiInstanceHelper;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.desktopmode.DesktopActivityOrientationChangeHandler;
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger;
import com.android.wm.shell.desktopmode.DesktopModeVisualIndicator;
import com.android.wm.shell.desktopmode.DesktopRepository;
import com.android.wm.shell.desktopmode.DesktopTasksController;
@@ -221,6 +223,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
};
private final TaskPositionerFactory mTaskPositionerFactory;
private final FocusTransitionObserver mFocusTransitionObserver;
+ private final DesktopModeEventLogger mDesktopModeEventLogger;
public DesktopModeWindowDecorViewModel(
Context context,
@@ -248,7 +251,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
AppHandleEducationController appHandleEducationController,
WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository,
Optional<DesktopActivityOrientationChangeHandler> activityOrientationChangeHandler,
- FocusTransitionObserver focusTransitionObserver) {
+ FocusTransitionObserver focusTransitionObserver,
+ DesktopModeEventLogger desktopModeEventLogger) {
this(
context,
shellExecutor,
@@ -281,7 +285,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
windowDecorCaptionHandleRepository,
activityOrientationChangeHandler,
new TaskPositionerFactory(),
- focusTransitionObserver);
+ focusTransitionObserver,
+ desktopModeEventLogger);
}
@VisibleForTesting
@@ -317,7 +322,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository,
Optional<DesktopActivityOrientationChangeHandler> activityOrientationChangeHandler,
TaskPositionerFactory taskPositionerFactory,
- FocusTransitionObserver focusTransitionObserver) {
+ FocusTransitionObserver focusTransitionObserver,
+ DesktopModeEventLogger desktopModeEventLogger) {
mContext = context;
mMainExecutor = shellExecutor;
mMainHandler = mainHandler;
@@ -378,6 +384,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
};
mTaskPositionerFactory = taskPositionerFactory;
mFocusTransitionObserver = focusTransitionObserver;
+ mDesktopModeEventLogger = desktopModeEventLogger;
shellInit.addInitCallback(this::onInit, this);
}
@@ -547,15 +554,20 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
>= MANAGE_WINDOWS_MINIMUM_INSTANCES);
}
- private void onMaximizeOrRestore(int taskId, String source) {
+ private void onMaximizeOrRestore(int taskId, String source, ResizeTrigger resizeTrigger,
+ MotionEvent motionEvent) {
final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskId);
if (decoration == null) {
return;
}
+ mDesktopModeEventLogger.logTaskResizingStarted(resizeTrigger, motionEvent,
+ decoration.mTaskInfo,
+ mDisplayController, /* displayLayoutSize= */ null);
mInteractionJankMonitor.begin(
decoration.mTaskSurface, mContext, mMainHandler,
Cuj.CUJ_DESKTOP_MODE_MAXIMIZE_WINDOW, source);
- mDesktopTasksController.toggleDesktopTaskSize(decoration.mTaskInfo);
+ mDesktopTasksController.toggleDesktopTaskSize(decoration.mTaskInfo, resizeTrigger,
+ motionEvent);
decoration.closeHandleMenu();
decoration.closeMaximizeMenu();
}
@@ -568,7 +580,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
mDesktopTasksController.toggleDesktopTaskFullImmersiveState(decoration.mTaskInfo);
}
- private void onSnapResize(int taskId, boolean left) {
+ private void onSnapResize(int taskId, boolean left, MotionEvent motionEvent) {
final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskId);
if (decoration == null) {
return;
@@ -579,13 +591,20 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
Toast.makeText(mContext,
R.string.desktop_mode_non_resizable_snap_text, Toast.LENGTH_SHORT).show();
} else {
+ ResizeTrigger resizeTrigger =
+ left ? ResizeTrigger.SNAP_LEFT_MENU : ResizeTrigger.SNAP_RIGHT_MENU;
+ mDesktopModeEventLogger.logTaskResizingStarted(resizeTrigger, motionEvent,
+ decoration.mTaskInfo,
+ mDisplayController, /* displayLayoutSize= */ null);
mInteractionJankMonitor.begin(decoration.mTaskSurface, mContext, mMainHandler,
Cuj.CUJ_DESKTOP_MODE_SNAP_RESIZE, "maximize_menu_resizable");
mDesktopTasksController.snapToHalfScreen(
decoration.mTaskInfo,
decoration.mTaskSurface,
decoration.mTaskInfo.configuration.windowConfiguration.getBounds(),
- left ? SnapPosition.LEFT : SnapPosition.RIGHT);
+ left ? SnapPosition.LEFT : SnapPosition.RIGHT,
+ resizeTrigger,
+ motionEvent);
}
decoration.closeHandleMenu();
@@ -737,6 +756,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
private boolean mTouchscreenInUse;
private boolean mHasLongClicked;
private int mDragPointerId = -1;
+ private MotionEvent mMotionEvent;
private DesktopModeTouchEventListener(
RunningTaskInfo taskInfo,
@@ -798,7 +818,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
} else {
// Full immersive is disabled or task doesn't request/support it, so just
// toggle between maximize/restore states.
- onMaximizeOrRestore(decoration.mTaskInfo.taskId, "caption_bar_button");
+ onMaximizeOrRestore(decoration.mTaskInfo.taskId, "caption_bar_button",
+ ResizeTrigger.MAXIMIZE_BUTTON, mMotionEvent);
}
} else if (id == R.id.minimize_window) {
mDesktopTasksController.minimizeTask(decoration.mTaskInfo);
@@ -807,6 +828,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
@Override
public boolean onTouch(View v, MotionEvent e) {
+ mMotionEvent = e;
final int id = v.getId();
final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(mTaskId);
if ((e.getSource() & SOURCE_TOUCHSCREEN) == SOURCE_TOUCHSCREEN) {
@@ -897,6 +919,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
*/
@Override
public boolean onGenericMotion(View v, MotionEvent ev) {
+ mMotionEvent = ev;
final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(mTaskId);
final int id = v.getId();
if (ev.getAction() == ACTION_HOVER_ENTER && id == R.id.maximize_window) {
@@ -1040,7 +1063,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
taskInfo, decoration.mTaskSurface, position,
new PointF(e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx)),
newTaskBounds, decoration.calculateValidDragArea(),
- new Rect(mOnDragStartInitialBounds));
+ new Rect(mOnDragStartInitialBounds), e);
if (touchingButton && !mHasLongClicked) {
// We need the input event to not be consumed here to end the ripple
// effect on the touched button. We will reset drag state in the ensuing
@@ -1087,7 +1110,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
// Disallow double-tap to resize when in full immersive.
return false;
}
- onMaximizeOrRestore(mTaskId, "double_tap");
+ onMaximizeOrRestore(mTaskId, "double_tap", ResizeTrigger.DOUBLE_TAP_APP_HEADER, e);
return true;
}
}
@@ -1484,7 +1507,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
mGenericLinksParser,
mAssistContentRequester,
mMultiInstanceHelper,
- mWindowDecorCaptionHandleRepository);
+ mWindowDecorCaptionHandleRepository,
+ mDesktopModeEventLogger);
mWindowDecorByTaskId.put(taskInfo.taskId, windowDecoration);
final TaskPositioner taskPositioner = mTaskPositionerFactory.create(
@@ -1501,15 +1525,16 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
final DesktopModeTouchEventListener touchEventListener =
new DesktopModeTouchEventListener(taskInfo, taskPositioner);
windowDecoration.setOnMaximizeOrRestoreClickListener(() -> {
- onMaximizeOrRestore(taskInfo.taskId, "maximize_menu");
+ onMaximizeOrRestore(taskInfo.taskId, "maximize_menu", ResizeTrigger.MAXIMIZE_MENU,
+ touchEventListener.mMotionEvent);
return Unit.INSTANCE;
});
windowDecoration.setOnLeftSnapClickListener(() -> {
- onSnapResize(taskInfo.taskId, true /* isLeft */);
+ onSnapResize(taskInfo.taskId, /* isLeft= */ true, touchEventListener.mMotionEvent);
return Unit.INSTANCE;
});
windowDecoration.setOnRightSnapClickListener(() -> {
- onSnapResize(taskInfo.taskId, false /* isLeft */);
+ onSnapResize(taskInfo.taskId, /* isLeft= */ false, touchEventListener.mMotionEvent);
return Unit.INSTANCE;
});
windowDecoration.setOnToDesktopClickListener(desktopModeTransitionSource -> {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
index 6eb20b9e3ae5..d94f3a9a70c6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
@@ -94,6 +94,7 @@ import com.android.wm.shell.common.MultiInstanceHelper;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.desktopmode.CaptionState;
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger;
import com.android.wm.shell.desktopmode.DesktopRepository;
import com.android.wm.shell.desktopmode.WindowDecorCaptionHandleRepository;
import com.android.wm.shell.shared.annotations.ShellBackgroundThread;
@@ -216,7 +217,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
AppToWebGenericLinksParser genericLinksParser,
AssistContentRequester assistContentRequester,
MultiInstanceHelper multiInstanceHelper,
- WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository) {
+ WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository,
+ DesktopModeEventLogger desktopModeEventLogger) {
this (context, userContext, displayController, splitScreenController, desktopRepository,
taskOrganizer, taskInfo, taskSurface, handler, bgExecutor, choreographer, syncQueue,
appHeaderViewHolderFactory, rootTaskDisplayAreaOrganizer, genericLinksParser,
@@ -227,7 +229,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
new SurfaceControlViewHostFactory() {},
DefaultMaximizeMenuFactory.INSTANCE,
DefaultHandleMenuFactory.INSTANCE, multiInstanceHelper,
- windowDecorCaptionHandleRepository);
+ windowDecorCaptionHandleRepository, desktopModeEventLogger);
}
DesktopModeWindowDecoration(
@@ -256,11 +258,12 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
MaximizeMenuFactory maximizeMenuFactory,
HandleMenuFactory handleMenuFactory,
MultiInstanceHelper multiInstanceHelper,
- WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository) {
+ WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository,
+ DesktopModeEventLogger desktopModeEventLogger) {
super(context, userContext, displayController, taskOrganizer, taskInfo, taskSurface,
surfaceControlBuilderSupplier, surfaceControlTransactionSupplier,
windowContainerTransactionSupplier, surfaceControlSupplier,
- surfaceControlViewHostFactory);
+ surfaceControlViewHostFactory, desktopModeEventLogger);
mSplitScreenController = splitScreenController;
mHandler = handler;
mBgExecutor = bgExecutor;
@@ -605,6 +608,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
Trace.beginSection("DesktopModeWindowDecoration#relayout-DragResizeInputListener");
mDragResizeListener = new DragResizeInputListener(
mContext,
+ mTaskInfo,
mHandler,
mChoreographer,
mDisplay.getDisplayId(),
@@ -612,7 +616,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
mDragPositioningCallback,
mSurfaceControlBuilderSupplier,
mSurfaceControlTransactionSupplier,
- mDisplayController);
+ mDisplayController,
+ mDesktopModeEventLogger);
Trace.endSection();
}
@@ -1700,7 +1705,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
AppToWebGenericLinksParser genericLinksParser,
AssistContentRequester assistContentRequester,
MultiInstanceHelper multiInstanceHelper,
- WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository) {
+ WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository,
+ DesktopModeEventLogger desktopModeEventLogger) {
return new DesktopModeWindowDecoration(
context,
userContext,
@@ -1719,7 +1725,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
genericLinksParser,
assistContentRequester,
multiInstanceHelper,
- windowDecorCaptionHandleRepository);
+ windowDecorCaptionHandleRepository,
+ desktopModeEventLogger);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
index 4ff394e2b1a9..420409705b05 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
@@ -29,10 +29,12 @@ import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE
import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_LEFT;
import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_RIGHT;
import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_TOP;
+import static com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger;
import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.isEdgeResizePermitted;
import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.isEventFromTouchscreen;
import android.annotation.NonNull;
+import android.app.ActivityManager.RunningTaskInfo;
import android.content.Context;
import android.graphics.Point;
import android.graphics.Rect;
@@ -59,6 +61,7 @@ import android.window.InputTransferToken;
import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayLayout;
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger;
import java.util.function.Consumer;
import java.util.function.Supplier;
@@ -83,14 +86,17 @@ class DragResizeInputListener implements AutoCloseable {
private final TaskResizeInputEventReceiver mInputEventReceiver;
private final Context mContext;
+ private final RunningTaskInfo mTaskInfo;
private final SurfaceControl mInputSinkSurface;
private final IBinder mSinkClientToken;
private final InputChannel mSinkInputChannel;
private final DisplayController mDisplayController;
+ private final DesktopModeEventLogger mDesktopModeEventLogger;
private final Region mTouchRegion = new Region();
DragResizeInputListener(
Context context,
+ RunningTaskInfo taskInfo,
Handler handler,
Choreographer choreographer,
int displayId,
@@ -98,12 +104,15 @@ class DragResizeInputListener implements AutoCloseable {
DragPositioningCallback callback,
Supplier<SurfaceControl.Builder> surfaceControlBuilderSupplier,
Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier,
- DisplayController displayController) {
+ DisplayController displayController,
+ DesktopModeEventLogger desktopModeEventLogger) {
mContext = context;
+ mTaskInfo = taskInfo;
mSurfaceControlTransactionSupplier = surfaceControlTransactionSupplier;
mDisplayId = displayId;
mDecorationSurface = decorationSurface;
mDisplayController = displayController;
+ mDesktopModeEventLogger = desktopModeEventLogger;
mClientToken = new Binder();
final InputTransferToken inputTransferToken = new InputTransferToken();
mInputChannel = new InputChannel();
@@ -125,11 +134,12 @@ class DragResizeInputListener implements AutoCloseable {
e.rethrowFromSystemServer();
}
- mInputEventReceiver = new TaskResizeInputEventReceiver(context, mInputChannel, callback,
+ mInputEventReceiver = new TaskResizeInputEventReceiver(context, mTaskInfo, mInputChannel,
+ callback,
handler, choreographer, () -> {
final DisplayLayout layout = mDisplayController.getDisplayLayout(mDisplayId);
return new Size(layout.width(), layout.height());
- }, this::updateSinkInputChannel);
+ }, this::updateSinkInputChannel, mDesktopModeEventLogger);
mInputEventReceiver.setTouchSlop(ViewConfiguration.get(context).getScaledTouchSlop());
mInputSinkSurface = surfaceControlBuilderSupplier.get()
@@ -163,6 +173,22 @@ class DragResizeInputListener implements AutoCloseable {
}
}
+ DragResizeInputListener(
+ Context context,
+ RunningTaskInfo taskInfo,
+ Handler handler,
+ Choreographer choreographer,
+ int displayId,
+ SurfaceControl decorationSurface,
+ DragPositioningCallback callback,
+ Supplier<SurfaceControl.Builder> surfaceControlBuilderSupplier,
+ Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier,
+ DisplayController displayController) {
+ this(context, taskInfo, handler, choreographer, displayId, decorationSurface, callback,
+ surfaceControlBuilderSupplier, surfaceControlTransactionSupplier, displayController,
+ new DesktopModeEventLogger());
+ }
+
/**
* Updates the geometry (the touch region) of this drag resize handler.
*
@@ -274,6 +300,7 @@ class DragResizeInputListener implements AutoCloseable {
private static class TaskResizeInputEventReceiver extends InputEventReceiver implements
DragDetector.MotionEventHandler {
@NonNull private final Context mContext;
+ @NonNull private final RunningTaskInfo mTaskInfo;
private final InputManager mInputManager;
@NonNull private final InputChannel mInputChannel;
@NonNull private final DragPositioningCallback mCallback;
@@ -282,6 +309,7 @@ class DragResizeInputListener implements AutoCloseable {
@NonNull private final DragDetector mDragDetector;
@NonNull private final Supplier<Size> mDisplayLayoutSizeSupplier;
@NonNull private final Consumer<Region> mTouchRegionConsumer;
+ @NonNull private final DesktopModeEventLogger mDesktopModeEventLogger;
private final Rect mTmpRect = new Rect();
private boolean mConsumeBatchEventScheduled;
private DragResizeWindowGeometry mDragResizeWindowGeometry;
@@ -293,15 +321,24 @@ class DragResizeInputListener implements AutoCloseable {
// resize events. For example, if multiple fingers are touching the screen, then each one
// has a separate pointer id, but we only accept drag input from one.
private int mDragPointerId = -1;
+ // The type of resizing that is currently being done. Used to track the same resize trigger
+ // on start and end of the resizing action.
+ private ResizeTrigger mResizeTrigger = ResizeTrigger.UNKNOWN_RESIZE_TRIGGER;
+ // The last MotionEvent on ACTION_DOWN, used to track the input tool type and source for
+ // logging the start and end of the resizing action.
+ private MotionEvent mLastMotionEventOnDown;
private TaskResizeInputEventReceiver(@NonNull Context context,
+ @NonNull RunningTaskInfo taskInfo,
@NonNull InputChannel inputChannel,
@NonNull DragPositioningCallback callback, @NonNull Handler handler,
@NonNull Choreographer choreographer,
@NonNull Supplier<Size> displayLayoutSizeSupplier,
- @NonNull Consumer<Region> touchRegionConsumer) {
+ @NonNull Consumer<Region> touchRegionConsumer,
+ @NonNull DesktopModeEventLogger desktopModeEventLogger) {
super(inputChannel, handler.getLooper());
mContext = context;
+ mTaskInfo = taskInfo;
mInputManager = context.getSystemService(InputManager.class);
mInputChannel = inputChannel;
mCallback = callback;
@@ -322,6 +359,7 @@ class DragResizeInputListener implements AutoCloseable {
ViewConfiguration.get(mContext).getScaledTouchSlop());
mDisplayLayoutSizeSupplier = displayLayoutSizeSupplier;
mTouchRegionConsumer = touchRegionConsumer;
+ mDesktopModeEventLogger = desktopModeEventLogger;
}
/**
@@ -395,6 +433,7 @@ class DragResizeInputListener implements AutoCloseable {
@Override
public boolean handleMotionEvent(View v, MotionEvent e) {
boolean result = false;
+
// Check if this is a touch event vs mouse event.
// Touch events are tracked in four corners. Other events are tracked in resize edges.
switch (e.getActionMasked()) {
@@ -416,6 +455,13 @@ class DragResizeInputListener implements AutoCloseable {
"%s: Handling action down, update ctrlType to %d", TAG, ctrlType);
mDragStartTaskBounds = mCallback.onDragPositioningStart(ctrlType,
rawX, rawY);
+ mLastMotionEventOnDown = e;
+ mResizeTrigger = (ctrlType == CTRL_TYPE_BOTTOM || ctrlType == CTRL_TYPE_TOP
+ || ctrlType == CTRL_TYPE_RIGHT || ctrlType == CTRL_TYPE_LEFT)
+ ? ResizeTrigger.EDGE : ResizeTrigger.CORNER;
+ mDesktopModeEventLogger.logTaskResizingStarted(mResizeTrigger,
+ e, mTaskInfo, /* displayController= */ null,
+ /* displayLayoutSize= */ mDisplayLayoutSizeSupplier.get());
// Increase the input sink region to cover the whole screen; this is to
// prevent input and focus from going to other tasks during a drag resize.
updateInputSinkRegionForDrag(mDragStartTaskBounds);
@@ -464,6 +510,12 @@ class DragResizeInputListener implements AutoCloseable {
if (taskBounds.equals(mDragStartTaskBounds)) {
mTouchRegionConsumer.accept(mTouchRegion);
}
+
+ mDesktopModeEventLogger.logTaskResizingEnded(mResizeTrigger,
+ mLastMotionEventOnDown, mTaskInfo, taskBounds.height(),
+ taskBounds.width(),
+ /* displayController= */ null,
+ /* displayLayoutSize= */ mDisplayLayoutSizeSupplier.get());
}
mShouldHandleEvents = false;
mDragPointerId = -1;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java
index 33d1c260cb84..844ceb304bde 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java
@@ -181,7 +181,7 @@ final class DragResizeWindowGeometry {
}
private boolean isInEdgeResizeBounds(float x, float y) {
- return calculateEdgeResizeCtrlType(x, y) != 0;
+ return calculateEdgeResizeCtrlType(x, y) != CTRL_TYPE_UNDEFINED;
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
index 6b3b357f2f7b..34cc0986c83f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
@@ -58,6 +58,7 @@ import android.window.WindowContainerTransaction;
import com.android.internal.annotations.VisibleForTesting;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.windowdecor.WindowDecoration.RelayoutParams.OccludingCaptionElement;
import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalViewHostViewContainer;
@@ -111,6 +112,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
final Context mContext;
final @NonNull Context mUserContext;
final @NonNull DisplayController mDisplayController;
+ final @NonNull DesktopModeEventLogger mDesktopModeEventLogger;
final ShellTaskOrganizer mTaskOrganizer;
final Supplier<SurfaceControl.Builder> mSurfaceControlBuilderSupplier;
final Supplier<SurfaceControl.Transaction> mSurfaceControlTransactionSupplier;
@@ -163,7 +165,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
this(context, userContext, displayController, taskOrganizer, taskInfo, taskSurface,
SurfaceControl.Builder::new, SurfaceControl.Transaction::new,
WindowContainerTransaction::new, SurfaceControl::new,
- new SurfaceControlViewHostFactory() {});
+ new SurfaceControlViewHostFactory() {}, new DesktopModeEventLogger());
}
WindowDecoration(
@@ -177,13 +179,16 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier,
Supplier<WindowContainerTransaction> windowContainerTransactionSupplier,
Supplier<SurfaceControl> surfaceControlSupplier,
- SurfaceControlViewHostFactory surfaceControlViewHostFactory) {
+ SurfaceControlViewHostFactory surfaceControlViewHostFactory,
+ @NonNull DesktopModeEventLogger desktopModeEventLogger
+ ) {
mContext = context;
mUserContext = userContext;
mDisplayController = displayController;
mTaskOrganizer = taskOrganizer;
mTaskInfo = taskInfo;
mTaskSurface = cloneSurfaceControl(taskSurface, surfaceControlSupplier);
+ mDesktopModeEventLogger = desktopModeEventLogger;
mSurfaceControlBuilderSupplier = surfaceControlBuilderSupplier;
mSurfaceControlTransactionSupplier = surfaceControlTransactionSupplier;
mWindowContainerTransactionSupplier = windowContainerTransactionSupplier;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java
index e6bd05b82be9..f935ac76bbeb 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java
@@ -40,6 +40,8 @@ public final class TestRunningTaskInfoBuilder {
private WindowContainerToken mToken = createMockWCToken();
private int mParentTaskId = INVALID_TASK_ID;
+ private int mUid = INVALID_TASK_ID;
+ private int mTaskId = INVALID_TASK_ID;
private Intent mBaseIntent = new Intent();
private @WindowConfiguration.ActivityType int mActivityType = ACTIVITY_TYPE_STANDARD;
private @WindowConfiguration.WindowingMode int mWindowingMode = WINDOWING_MODE_UNDEFINED;
@@ -73,6 +75,18 @@ public final class TestRunningTaskInfoBuilder {
return this;
}
+ /** Sets the task info's effective UID. */
+ public TestRunningTaskInfoBuilder setUid(int uid) {
+ mUid = uid;
+ return this;
+ }
+
+ /** Sets the task info's UID. */
+ public TestRunningTaskInfoBuilder setTaskId(int taskId) {
+ mTaskId = taskId;
+ return this;
+ }
+
/**
* Set {@link ActivityManager.RunningTaskInfo#baseIntent} for the task info, by default
* an empty intent is assigned
@@ -132,7 +146,8 @@ public final class TestRunningTaskInfoBuilder {
public ActivityManager.RunningTaskInfo build() {
final ActivityManager.RunningTaskInfo info = new ActivityManager.RunningTaskInfo();
- info.taskId = sNextTaskId++;
+ info.taskId = (mTaskId == INVALID_TASK_ID) ? sNextTaskId++ : mTaskId;
+ info.effectiveUid = mUid;
info.baseIntent = mBaseIntent;
info.parentTaskId = mParentTaskId;
info.displayId = mDisplayId;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeEventLoggerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeEventLoggerTest.kt
index 0825b6b0d7be..2a82e6e4f7b8 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeEventLoggerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeEventLoggerTest.kt
@@ -16,9 +16,12 @@
package com.android.wm.shell.desktopmode
+import android.app.ActivityManager.RunningTaskInfo
+import android.graphics.Rect
import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.SetFlagsRule
import com.android.dx.mockito.inline.extended.ExtendedMockito.clearInvocations
+import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
import com.android.dx.mockito.inline.extended.ExtendedMockito.staticMockMarker
import com.android.dx.mockito.inline.extended.ExtendedMockito.verify
import com.android.dx.mockito.inline.extended.ExtendedMockito.verifyZeroInteractions
@@ -27,6 +30,9 @@ import com.android.modules.utils.testing.ExtendedMockitoRule
import com.android.window.flags.Flags
import com.android.wm.shell.EventLogTags
import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.TestRunningTaskInfoBuilder
+import com.android.wm.shell.common.DisplayController
+import com.android.wm.shell.common.DisplayLayout
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.EnterReason
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ExitReason
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.InputMethod
@@ -39,9 +45,13 @@ import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.UNSET_M
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.UNSET_UNMINIMIZE_REASON
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.UnminimizeReason
import com.google.common.truth.Truth.assertThat
+import org.junit.Before
import org.junit.Rule
import org.junit.Test
+import org.mockito.ArgumentMatchers.anyInt
import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
/**
* Tests for [DesktopModeEventLogger].
@@ -49,6 +59,8 @@ import org.mockito.kotlin.eq
class DesktopModeEventLoggerTest : ShellTestCase() {
private val desktopModeEventLogger = DesktopModeEventLogger()
+ val displayController = mock<DisplayController>()
+ val displayLayout = mock<DisplayLayout>()
@JvmField
@Rule(order = 0)
@@ -60,6 +72,13 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
@Rule(order = 1)
val setFlagsRule = SetFlagsRule()
+ @Before
+ fun setUp() {
+ doReturn(displayLayout).whenever(displayController).getDisplayLayout(anyInt())
+ doReturn(DISPLAY_WIDTH).whenever(displayLayout).width()
+ doReturn(DISPLAY_HEIGHT).whenever(displayLayout).height()
+ }
+
@Test
fun logSessionEnter_logsEnterReasonWithNewSessionId() {
desktopModeEventLogger.logSessionEnter(EnterReason.KEYBOARD_SHORTCUT_ENTER)
@@ -467,7 +486,8 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
@Test
fun logTaskResizingStarted_noOngoingSession_doesNotLog() {
- desktopModeEventLogger.logTaskResizingStarted(TASK_SIZE_UPDATE)
+ desktopModeEventLogger.logTaskResizingStarted(ResizeTrigger.CORNER,
+ null, createTaskInfo())
verifyZeroInteractions(staticMockMarker(FrameworkStatsLog::class.java))
verifyZeroInteractions(staticMockMarker(EventLogTags::class.java))
@@ -478,13 +498,14 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
fun logTaskResizingStarted_logsTaskSizeUpdatedWithStartResizingStage() {
val sessionId = startDesktopModeSession()
- desktopModeEventLogger.logTaskResizingStarted(TASK_SIZE_UPDATE)
+ desktopModeEventLogger.logTaskResizingStarted(ResizeTrigger.CORNER,
+ null, createTaskInfo(), displayController)
verify {
FrameworkStatsLog.write(
eq(FrameworkStatsLog.DESKTOP_MODE_TASK_SIZE_UPDATED),
/* resize_trigger */
- eq(FrameworkStatsLog.DESKTOP_MODE_TASK_SIZE_UPDATED__RESIZE_TRIGGER__UNKNOWN_RESIZE_TRIGGER),
+ eq(FrameworkStatsLog.DESKTOP_MODE_TASK_SIZE_UPDATED__RESIZE_TRIGGER__CORNER_RESIZE_TRIGGER),
/* resizing_stage */
eq(FrameworkStatsLog.DESKTOP_MODE_TASK_SIZE_UPDATED__RESIZING_STAGE__START_RESIZING_STAGE),
/* input_method */
@@ -500,7 +521,7 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
/* task_width */
eq(TASK_SIZE_UPDATE.taskWidth),
/* display_area */
- eq(TASK_SIZE_UPDATE.displayArea),
+ eq(DISPLAY_AREA),
)
}
verifyZeroInteractions(staticMockMarker(FrameworkStatsLog::class.java))
@@ -508,7 +529,8 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
@Test
fun logTaskResizingEnded_noOngoingSession_doesNotLog() {
- desktopModeEventLogger.logTaskResizingEnded(TASK_SIZE_UPDATE)
+ desktopModeEventLogger.logTaskResizingEnded(ResizeTrigger.CORNER,
+ null, createTaskInfo())
verifyZeroInteractions(staticMockMarker(FrameworkStatsLog::class.java))
verifyZeroInteractions(staticMockMarker(EventLogTags::class.java))
@@ -519,13 +541,14 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
fun logTaskResizingEnded_logsTaskSizeUpdatedWithEndResizingStage() {
val sessionId = startDesktopModeSession()
- desktopModeEventLogger.logTaskResizingEnded(TASK_SIZE_UPDATE)
+ desktopModeEventLogger.logTaskResizingEnded(ResizeTrigger.CORNER,
+ null, createTaskInfo(), displayController = displayController)
verify {
FrameworkStatsLog.write(
eq(FrameworkStatsLog.DESKTOP_MODE_TASK_SIZE_UPDATED),
/* resize_trigger */
- eq(FrameworkStatsLog.DESKTOP_MODE_TASK_SIZE_UPDATED__RESIZE_TRIGGER__UNKNOWN_RESIZE_TRIGGER),
+ eq(FrameworkStatsLog.DESKTOP_MODE_TASK_SIZE_UPDATED__RESIZE_TRIGGER__CORNER_RESIZE_TRIGGER),
/* resizing_stage */
eq(FrameworkStatsLog.DESKTOP_MODE_TASK_SIZE_UPDATED__RESIZING_STAGE__END_RESIZING_STAGE),
/* input_method */
@@ -541,7 +564,7 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
/* task_width */
eq(TASK_SIZE_UPDATE.taskWidth),
/* display_area */
- eq(TASK_SIZE_UPDATE.displayArea),
+ eq(DISPLAY_AREA),
)
}
verifyZeroInteractions(staticMockMarker(FrameworkStatsLog::class.java))
@@ -585,8 +608,14 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
}
}
+ private fun createTaskInfo(): RunningTaskInfo {
+ return TestRunningTaskInfoBuilder().setTaskId(TASK_ID)
+ .setUid(TASK_UID)
+ .setBounds(Rect(TASK_X, TASK_Y, TASK_WIDTH, TASK_HEIGHT))
+ .build()
+ }
+
private companion object {
- private const val sessionId = 1
private const val TASK_ID = 1
private const val TASK_UID = 1
private const val TASK_X = 0
@@ -594,7 +623,9 @@ class DesktopModeEventLoggerTest : ShellTestCase() {
private const val TASK_HEIGHT = 100
private const val TASK_WIDTH = 100
private const val TASK_COUNT = 1
- private const val DISPLAY_AREA = 1000
+ private const val DISPLAY_WIDTH = 500
+ private const val DISPLAY_HEIGHT = 500
+ private const val DISPLAY_AREA = DISPLAY_HEIGHT * DISPLAY_WIDTH
private val TASK_UPDATE = TaskUpdate(
TASK_ID, TASK_UID, TASK_HEIGHT, TASK_WIDTH, TASK_X, TASK_Y,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
index 55b44ac935ea..61943568e7d4 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
@@ -54,6 +54,7 @@ import android.view.Display.DEFAULT_DISPLAY
import android.view.DragEvent
import android.view.Gravity
import android.view.KeyEvent
+import android.view.MotionEvent
import android.view.SurfaceControl
import android.view.WindowInsets
import android.view.WindowManager
@@ -99,6 +100,7 @@ import com.android.wm.shell.common.LaunchAdjacentController
import com.android.wm.shell.common.MultiInstanceHelper
import com.android.wm.shell.common.ShellExecutor
import com.android.wm.shell.common.SyncTransactionQueue
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger
import com.android.wm.shell.desktopmode.DesktopTasksController.SnapPosition
import com.android.wm.shell.desktopmode.DesktopTasksController.TaskbarDesktopTaskListener
import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
@@ -214,9 +216,11 @@ class DesktopTasksControllerTest : ShellTestCase() {
@Mock private lateinit var taskbarDesktopTaskListener: TaskbarDesktopTaskListener
@Mock private lateinit var freeformTaskTransitionStarter: FreeformTaskTransitionStarter
@Mock private lateinit var mockHandler: Handler
+ @Mock private lateinit var desktopModeEventLogger: DesktopModeEventLogger
@Mock lateinit var persistentRepository: DesktopPersistentRepository
@Mock private lateinit var mockInputManager: InputManager
@Mock private lateinit var mockFocusTransitionObserver: FocusTransitionObserver
+ @Mock lateinit var motionEvent: MotionEvent
private lateinit var mockitoSession: StaticMockitoSession
private lateinit var controller: DesktopTasksController
@@ -329,6 +333,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
mockHandler,
mockInputManager,
mockFocusTransitionObserver,
+ desktopModeEventLogger,
)
}
@@ -357,9 +362,17 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task1 = setUpFreeformTask()
val argumentCaptor = ArgumentCaptor.forClass(Boolean::class.java)
- controller.toggleDesktopTaskSize(task1)
- verify(taskbarDesktopTaskListener).onTaskbarCornerRoundingUpdate(argumentCaptor.capture())
+ controller.toggleDesktopTaskSize(task1, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
+ verify(taskbarDesktopTaskListener).onTaskbarCornerRoundingUpdate(argumentCaptor.capture())
+ verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
+ ResizeTrigger.MAXIMIZE_BUTTON,
+ motionEvent,
+ task1,
+ STABLE_BOUNDS.height(),
+ STABLE_BOUNDS.width(),
+ displayController
+ )
assertThat(argumentCaptor.value).isTrue()
}
@@ -376,9 +389,17 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task1 = setUpFreeformTask(bounds = stableBounds, active = true)
val argumentCaptor = ArgumentCaptor.forClass(Boolean::class.java)
- controller.toggleDesktopTaskSize(task1)
- verify(taskbarDesktopTaskListener).onTaskbarCornerRoundingUpdate(argumentCaptor.capture())
+ controller.toggleDesktopTaskSize(task1, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
+ verify(taskbarDesktopTaskListener).onTaskbarCornerRoundingUpdate(argumentCaptor.capture())
+ verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
+ ResizeTrigger.MAXIMIZE_BUTTON,
+ motionEvent,
+ task1,
+ 0,
+ 0,
+ displayController
+ )
assertThat(argumentCaptor.value).isFalse()
}
@@ -2860,7 +2881,8 @@ class DesktopTasksControllerTest : ShellTestCase() {
PointF(200f, -200f), /* inputCoordinate */
Rect(100, -100, 500, 1000), /* currentDragBounds */
Rect(0, 50, 2000, 2000), /* validDragArea */
- Rect() /* dragStartBounds */ )
+ Rect() /* dragStartBounds */,
+ motionEvent)
val rectAfterEnd = Rect(100, 50, 500, 1150)
verify(transitions)
.startTransition(
@@ -2895,7 +2917,8 @@ class DesktopTasksControllerTest : ShellTestCase() {
PointF(200f, 300f), /* inputCoordinate */
currentDragBounds, /* currentDragBounds */
Rect(0, 50, 2000, 2000) /* validDragArea */,
- Rect() /* dragStartBounds */)
+ Rect() /* dragStartBounds */,
+ motionEvent)
verify(transitions)
@@ -3142,10 +3165,19 @@ class DesktopTasksControllerTest : ShellTestCase() {
val bounds = Rect(0, 0, 100, 100)
val task = setUpFreeformTask(DEFAULT_DISPLAY, bounds)
- controller.toggleDesktopTaskSize(task)
+ controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
+
// Assert bounds set to stable bounds
val wct = getLatestToggleResizeDesktopTaskWct()
assertThat(findBoundsChange(wct, task)).isEqualTo(STABLE_BOUNDS)
+ verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
+ ResizeTrigger.MAXIMIZE_BUTTON,
+ motionEvent,
+ task,
+ STABLE_BOUNDS.height(),
+ STABLE_BOUNDS.width(),
+ displayController
+ )
}
@Test
@@ -3164,10 +3196,18 @@ class DesktopTasksControllerTest : ShellTestCase() {
STABLE_BOUNDS.left, STABLE_BOUNDS.top, STABLE_BOUNDS.right / 2, STABLE_BOUNDS.bottom
)
- controller.snapToHalfScreen(task, mockSurface, currentDragBounds, SnapPosition.LEFT)
+ controller.snapToHalfScreen(task, mockSurface, currentDragBounds, SnapPosition.LEFT, ResizeTrigger.SNAP_LEFT_MENU, motionEvent)
// Assert bounds set to stable bounds
val wct = getLatestToggleResizeDesktopTaskWct(currentDragBounds)
assertThat(findBoundsChange(wct, task)).isEqualTo(expectedBounds)
+ verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
+ ResizeTrigger.SNAP_LEFT_MENU,
+ motionEvent,
+ task,
+ expectedBounds.height(),
+ expectedBounds.width(),
+ displayController
+ )
}
@Test
@@ -3187,7 +3227,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
// Attempt to snap left again
val currentDragBounds = Rect(bounds).apply { offset(-100, 0) }
- controller.snapToHalfScreen(task, mockSurface, currentDragBounds, SnapPosition.LEFT)
+ controller.snapToHalfScreen(task, mockSurface, currentDragBounds, SnapPosition.LEFT, ResizeTrigger.SNAP_LEFT_MENU, motionEvent)
// Assert that task is NOT updated via WCT
verify(toggleResizeDesktopTaskTransitionHandler, never()).startTransition(any(), any())
@@ -3200,6 +3240,14 @@ class DesktopTasksControllerTest : ShellTestCase() {
eq(bounds),
eq(true)
)
+ verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
+ ResizeTrigger.SNAP_LEFT_MENU,
+ motionEvent,
+ task,
+ bounds.height(),
+ bounds.width(),
+ displayController
+ )
}
@Test
@@ -3210,12 +3258,22 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
val preDragBounds = Rect(100, 100, 400, 500)
val currentDragBounds = Rect(0, 100, 300, 500)
+ val expectedBounds =
+ Rect(STABLE_BOUNDS.left, STABLE_BOUNDS.top, STABLE_BOUNDS.right / 2, STABLE_BOUNDS.bottom)
controller.handleSnapResizingTask(
- task, SnapPosition.LEFT, mockSurface, currentDragBounds, preDragBounds)
+ task, SnapPosition.LEFT, mockSurface, currentDragBounds, preDragBounds, motionEvent
+ )
val wct = getLatestToggleResizeDesktopTaskWct(currentDragBounds)
assertThat(findBoundsChange(wct, task)).isEqualTo(
- Rect(STABLE_BOUNDS.left, STABLE_BOUNDS.top, STABLE_BOUNDS.right / 2, STABLE_BOUNDS.bottom))
+ expectedBounds
+ )
+ verify(desktopModeEventLogger, times(1)).logTaskResizingStarted(
+ ResizeTrigger.DRAG_LEFT,
+ motionEvent,
+ task,
+ displayController
+ )
}
@Test
@@ -3228,7 +3286,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
val currentDragBounds = Rect(0, 100, 300, 500)
controller.handleSnapResizingTask(
- task, SnapPosition.LEFT, mockSurface, currentDragBounds, preDragBounds)
+ task, SnapPosition.LEFT, mockSurface, currentDragBounds, preDragBounds, motionEvent)
verify(mReturnToDragStartAnimator).start(
eq(task.taskId),
eq(mockSurface),
@@ -3236,6 +3294,13 @@ class DesktopTasksControllerTest : ShellTestCase() {
eq(preDragBounds),
eq(false)
)
+ verify(desktopModeEventLogger, never()).logTaskResizingStarted(
+ any(),
+ any(),
+ any(),
+ any(),
+ any()
+ )
}
@Test
@@ -3254,10 +3319,19 @@ class DesktopTasksControllerTest : ShellTestCase() {
// Bounds should be 1000 x 500, vertically centered in the 1000 x 1000 stable bounds
val expectedBounds = Rect(STABLE_BOUNDS.left, 250, STABLE_BOUNDS.right, 750)
- controller.toggleDesktopTaskSize(task)
+ controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
+
// Assert bounds set to stable bounds
val wct = getLatestToggleResizeDesktopTaskWct()
assertThat(findBoundsChange(wct, task)).isEqualTo(expectedBounds)
+ verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
+ ResizeTrigger.MAXIMIZE_BUTTON,
+ motionEvent,
+ task,
+ expectedBounds.height(),
+ expectedBounds.width(),
+ displayController
+ )
}
@Test
@@ -3265,8 +3339,12 @@ class DesktopTasksControllerTest : ShellTestCase() {
val bounds = Rect(0, 0, 100, 100)
val task = setUpFreeformTask(DEFAULT_DISPLAY, bounds)
- controller.toggleDesktopTaskSize(task)
+ controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
assertThat(taskRepository.removeBoundsBeforeMaximize(task.taskId)).isEqualTo(bounds)
+ verify(desktopModeEventLogger, never()).logTaskResizingEnded(
+ any(), any(), any(), any(),
+ any(), any(), any()
+ )
}
@Test
@@ -3275,15 +3353,23 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task = setUpFreeformTask(DEFAULT_DISPLAY, boundsBeforeMaximize)
// Maximize
- controller.toggleDesktopTaskSize(task)
+ controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
task.configuration.windowConfiguration.bounds.set(STABLE_BOUNDS)
// Restore
- controller.toggleDesktopTaskSize(task)
+ controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
// Assert bounds set to last bounds before maximize
val wct = getLatestToggleResizeDesktopTaskWct()
assertThat(findBoundsChange(wct, task)).isEqualTo(boundsBeforeMaximize)
+ verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
+ ResizeTrigger.MAXIMIZE_BUTTON,
+ motionEvent,
+ task,
+ boundsBeforeMaximize.height(),
+ boundsBeforeMaximize.width(),
+ displayController
+ )
}
@Test
@@ -3294,16 +3380,24 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
// Maximize
- controller.toggleDesktopTaskSize(task)
+ controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
task.configuration.windowConfiguration.bounds.set(STABLE_BOUNDS.left,
boundsBeforeMaximize.top, STABLE_BOUNDS.right, boundsBeforeMaximize.bottom)
// Restore
- controller.toggleDesktopTaskSize(task)
+ controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
// Assert bounds set to last bounds before maximize
val wct = getLatestToggleResizeDesktopTaskWct()
assertThat(findBoundsChange(wct, task)).isEqualTo(boundsBeforeMaximize)
+ verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
+ ResizeTrigger.MAXIMIZE_BUTTON,
+ motionEvent,
+ task,
+ boundsBeforeMaximize.height(),
+ boundsBeforeMaximize.width(),
+ displayController
+ )
}
@Test
@@ -3314,16 +3408,24 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
// Maximize
- controller.toggleDesktopTaskSize(task)
+ controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
task.configuration.windowConfiguration.bounds.set(boundsBeforeMaximize.left,
STABLE_BOUNDS.top, boundsBeforeMaximize.right, STABLE_BOUNDS.bottom)
// Restore
- controller.toggleDesktopTaskSize(task)
+ controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
// Assert bounds set to last bounds before maximize
val wct = getLatestToggleResizeDesktopTaskWct()
assertThat(findBoundsChange(wct, task)).isEqualTo(boundsBeforeMaximize)
+ verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
+ ResizeTrigger.MAXIMIZE_BUTTON,
+ motionEvent,
+ task,
+ boundsBeforeMaximize.height(),
+ boundsBeforeMaximize.width(),
+ displayController
+ )
}
@Test
@@ -3332,14 +3434,22 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task = setUpFreeformTask(DEFAULT_DISPLAY, boundsBeforeMaximize)
// Maximize
- controller.toggleDesktopTaskSize(task)
+ controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
task.configuration.windowConfiguration.bounds.set(STABLE_BOUNDS)
// Restore
- controller.toggleDesktopTaskSize(task)
+ controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
// Assert last bounds before maximize removed after use
assertThat(taskRepository.removeBoundsBeforeMaximize(task.taskId)).isNull()
+ verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
+ ResizeTrigger.MAXIMIZE_BUTTON,
+ motionEvent,
+ task,
+ boundsBeforeMaximize.height(),
+ boundsBeforeMaximize.width(),
+ displayController
+ )
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
index 175fbd2396e3..1839b8a367fe 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
@@ -87,6 +87,8 @@ import com.android.wm.shell.common.MultiInstanceHelper
import com.android.wm.shell.common.ShellExecutor
import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.desktopmode.DesktopActivityOrientationChangeHandler
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger
import com.android.wm.shell.desktopmode.DesktopRepository
import com.android.wm.shell.desktopmode.DesktopTasksController
import com.android.wm.shell.desktopmode.DesktopTasksController.SnapPosition
@@ -194,7 +196,11 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
@Mock private lateinit var mockAppHandleEducationController: AppHandleEducationController
@Mock private lateinit var mockFocusTransitionObserver: FocusTransitionObserver
@Mock private lateinit var mockCaptionHandleRepository: WindowDecorCaptionHandleRepository
+ @Mock private lateinit var motionEvent: MotionEvent
+ @Mock lateinit var displayController: DisplayController
+ @Mock lateinit var displayLayout: DisplayLayout
private lateinit var spyContext: TestableContext
+ private lateinit var desktopModeEventLogger: DesktopModeEventLogger
private val transactionFactory = Supplier<SurfaceControl.Transaction> {
SurfaceControl.Transaction()
@@ -224,6 +230,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
shellInit = ShellInit(mockShellExecutor)
windowDecorByTaskIdSpy.clear()
spyContext.addMockSystemService(InputManager::class.java, mockInputManager)
+ desktopModeEventLogger = mock<DesktopModeEventLogger>()
desktopModeWindowDecorViewModel = DesktopModeWindowDecorViewModel(
spyContext,
mockShellExecutor,
@@ -256,7 +263,8 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
mockCaptionHandleRepository,
Optional.of(mockActivityOrientationChangeHandler),
mockTaskPositionerFactory,
- mockFocusTransitionObserver
+ mockFocusTransitionObserver,
+ desktopModeEventLogger
)
desktopModeWindowDecorViewModel.setSplitScreenController(mockSplitScreenController)
whenever(mockDisplayController.getDisplayLayout(any())).thenReturn(mockDisplayLayout)
@@ -299,6 +307,10 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
argumentCaptor<DesktopModeKeyguardChangeListener>()
verify(mockShellController).addKeyguardChangeListener(keyguardChangedCaptor.capture())
desktopModeOnKeyguardChangedListener = keyguardChangedCaptor.firstValue
+ whenever(displayController.getDisplayLayout(anyInt())).thenReturn(displayLayout)
+ whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
+ (i.arguments.first() as Rect).set(STABLE_BOUNDS)
+ }
}
@After
@@ -612,7 +624,11 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
maxOrRestoreListenerCaptor.value.invoke()
- verify(mockDesktopTasksController).toggleDesktopTaskSize(decor.mTaskInfo)
+ verify(mockDesktopTasksController).toggleDesktopTaskSize(
+ decor.mTaskInfo,
+ ResizeTrigger.MAXIMIZE_MENU,
+ null
+ )
}
@Test
@@ -647,7 +663,9 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
eq(decor.mTaskInfo),
taskSurfaceCaptor.capture(),
eq(currentBounds),
- eq(SnapPosition.LEFT)
+ eq(SnapPosition.LEFT),
+ eq(ResizeTrigger.SNAP_LEFT_MENU),
+ eq(null)
)
assertEquals(taskSurfaceCaptor.firstValue, decor.mTaskSurface)
}
@@ -685,7 +703,9 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
eq(decor.mTaskInfo),
taskSurfaceCaptor.capture(),
eq(currentBounds),
- eq(SnapPosition.LEFT)
+ eq(SnapPosition.LEFT),
+ eq(ResizeTrigger.SNAP_LEFT_MENU),
+ eq(null)
)
assertEquals(decor.mTaskSurface, taskSurfaceCaptor.firstValue)
}
@@ -704,7 +724,9 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
onLeftSnapClickListenerCaptor.value.invoke()
verify(mockDesktopTasksController, never())
- .snapToHalfScreen(eq(decor.mTaskInfo), any(), eq(currentBounds), eq(SnapPosition.LEFT))
+ .snapToHalfScreen(eq(decor.mTaskInfo), any(), eq(currentBounds), eq(SnapPosition.LEFT),
+ eq(ResizeTrigger.MAXIMIZE_BUTTON),
+ eq(null))
verify(mockToast).show()
}
@@ -725,7 +747,9 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
eq(decor.mTaskInfo),
taskSurfaceCaptor.capture(),
eq(currentBounds),
- eq(SnapPosition.RIGHT)
+ eq(SnapPosition.RIGHT),
+ eq(ResizeTrigger.SNAP_RIGHT_MENU),
+ eq(null)
)
assertEquals(decor.mTaskSurface, taskSurfaceCaptor.firstValue)
}
@@ -763,7 +787,9 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
eq(decor.mTaskInfo),
taskSurfaceCaptor.capture(),
eq(currentBounds),
- eq(SnapPosition.RIGHT)
+ eq(SnapPosition.RIGHT),
+ eq(ResizeTrigger.SNAP_RIGHT_MENU),
+ eq(null)
)
assertEquals(decor.mTaskSurface, taskSurfaceCaptor.firstValue)
}
@@ -782,7 +808,9 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
onRightSnapClickListenerCaptor.value.invoke()
verify(mockDesktopTasksController, never())
- .snapToHalfScreen(eq(decor.mTaskInfo), any(), eq(currentBounds), eq(SnapPosition.RIGHT))
+ .snapToHalfScreen(eq(decor.mTaskInfo), any(), eq(currentBounds), eq(SnapPosition.RIGHT),
+ eq(ResizeTrigger.MAXIMIZE_BUTTON),
+ eq(null))
verify(mockToast).show()
}
@@ -1247,7 +1275,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
onClickListenerCaptor.value.onClick(view)
verify(mockDesktopTasksController)
- .toggleDesktopTaskSize(decor.mTaskInfo)
+ .toggleDesktopTaskSize(decor.mTaskInfo, ResizeTrigger.MAXIMIZE_BUTTON, null)
}
private fun createOpenTaskDecoration(
@@ -1337,7 +1365,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
whenever(
mockDesktopModeWindowDecorFactory.create(
any(), any(), any(), any(), any(), any(), eq(task), any(), any(), any(), any(),
- any(), any(), any(), any(), any(), any(), any())
+ any(), any(), any(), any(), any(), any(), any(), any())
).thenReturn(decoration)
decoration.mTaskInfo = task
whenever(decoration.user).thenReturn(mockUserHandle)
@@ -1378,5 +1406,6 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() {
private const val TAG = "DesktopModeWindowDecorViewModelTests"
private val STABLE_INSETS = Rect(0, 100, 0, 0)
private val INITIAL_BOUNDS = Rect(0, 0, 100, 100)
+ private val STABLE_BOUNDS = Rect(0, 0, 1000, 1000)
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
index 320887212f54..0afb6c10b549 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
@@ -106,6 +106,7 @@ import com.android.wm.shell.common.MultiInstanceHelper;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.desktopmode.CaptionState;
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger;
import com.android.wm.shell.desktopmode.DesktopRepository;
import com.android.wm.shell.desktopmode.WindowDecorCaptionHandleRepository;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
@@ -210,6 +211,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
private MultiInstanceHelper mMockMultiInstanceHelper;
@Mock
private WindowDecorCaptionHandleRepository mMockCaptionHandleRepository;
+ @Mock
+ private DesktopModeEventLogger mDesktopModeEventLogger;
@Captor
private ArgumentCaptor<Function1<Boolean, Unit>> mOnMaxMenuHoverChangeListener;
@Captor
@@ -1400,7 +1403,7 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase {
mMockTransactionSupplier, WindowContainerTransaction::new, SurfaceControl::new,
new WindowManagerWrapper(mMockWindowManager), mMockSurfaceControlViewHostFactory,
maximizeMenuFactory, mMockHandleMenuFactory,
- mMockMultiInstanceHelper, mMockCaptionHandleRepository);
+ mMockMultiInstanceHelper, mMockCaptionHandleRepository, mDesktopModeEventLogger);
windowDecor.setCaptionListeners(mMockTouchEventListener, mMockTouchEventListener,
mMockTouchEventListener, mMockTouchEventListener);
windowDecor.setExclusionRegionListener(mMockExclusionRegionListener);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
index fb17ae93030d..cb7fadee9822 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
@@ -83,6 +83,7 @@ import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.TestRunningTaskInfoBuilder;
import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.tests.R;
import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalViewContainer;
@@ -138,6 +139,8 @@ public class WindowDecorationTests extends ShellTestCase {
private SurfaceSyncGroup mMockSurfaceSyncGroup;
@Mock
private SurfaceControl mMockTaskSurface;
+ @Mock
+ private DesktopModeEventLogger mDesktopModeEventLogger;
private final List<SurfaceControl.Transaction> mMockSurfaceControlTransactions =
new ArrayList<>();
@@ -1014,7 +1017,7 @@ public class WindowDecorationTests extends ShellTestCase {
new MockObjectSupplier<>(mMockSurfaceControlTransactions,
() -> mock(SurfaceControl.Transaction.class)),
() -> mMockWindowContainerTransaction, () -> mMockTaskSurface,
- mMockSurfaceControlViewHostFactory);
+ mMockSurfaceControlViewHostFactory, mDesktopModeEventLogger);
}
private class MockObjectSupplier<T> implements Supplier<T> {
@@ -1054,11 +1057,12 @@ public class WindowDecorationTests extends ShellTestCase {
Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier,
Supplier<WindowContainerTransaction> windowContainerTransactionSupplier,
Supplier<SurfaceControl> surfaceControlSupplier,
- SurfaceControlViewHostFactory surfaceControlViewHostFactory) {
+ SurfaceControlViewHostFactory surfaceControlViewHostFactory,
+ DesktopModeEventLogger desktopModeEventLogger) {
super(context, userContext, displayController, taskOrganizer, taskInfo, taskSurface,
surfaceControlBuilderSupplier, surfaceControlTransactionSupplier,
windowContainerTransactionSupplier, surfaceControlSupplier,
- surfaceControlViewHostFactory);
+ surfaceControlViewHostFactory, desktopModeEventLogger);
}
@Override