diff options
2 files changed, 220 insertions, 127 deletions
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 5de3be4bbfc0..8f7e52ea2108 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 @@ -677,11 +677,7 @@ class DesktopTasksController( // Bring other apps to front first. bringDesktopAppsToFrontBeforeShowingNewTask(displayId, wct, task.taskId) } - if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) { - prepareMoveTaskToDesk(wct, task, deskId) - } else { - addMoveToDesktopChanges(wct, task) - } + addMoveToDeskTaskChanges(wct = wct, task = task, deskId = deskId) return taskIdToMinimize } @@ -1260,6 +1256,8 @@ class DesktopTasksController( * Move [task] to display with [displayId]. * * No-op if task is already on that display per [RunningTaskInfo.displayId]. + * + * TODO: b/399411604 - split this up into smaller functions. */ private fun moveToDisplay(task: RunningTaskInfo, displayId: Int) { logV("moveToDisplay: taskId=%d displayId=%d", task.taskId, displayId) @@ -1315,16 +1313,20 @@ class DesktopTasksController( // TODO: b/393977830 and b/397437641 - do not assume that freeform==desktop. if (!task.isFreeform) { - addMoveToDesktopChanges(wct, task, displayId) - } else if (Flags.enableMoveToNextDisplayShortcut()) { - applyFreeformDisplayChange(wct, task, displayId) + addMoveToDeskTaskChanges(wct = wct, task = task, deskId = destinationDeskId) + } else { + if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) { + desksOrganizer.moveTaskToDesk(wct, destinationDeskId, task) + } + if (Flags.enableMoveToNextDisplayShortcut()) { + applyFreeformDisplayChange(wct, task, displayId) + } } - if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) { - desksOrganizer.moveTaskToDesk(wct, destinationDeskId, task) - } else { + if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) { wct.reparent(task.token, displayAreaInfo.token, /* onTop= */ true) } + addDeskActivationChanges(destinationDeskId, wct) val activationRunnable: RunOnTransitStart = { transition -> desksTransitionObserver.addPendingTransition( @@ -2062,12 +2064,13 @@ class DesktopTasksController( triggerTask?.let { task -> when { // Check if freeform task launch during recents should be handled - shouldHandleMidRecentsFreeformLaunch -> handleMidRecentsFreeformTaskLaunch(task) + shouldHandleMidRecentsFreeformLaunch -> + handleMidRecentsFreeformTaskLaunch(task, transition) // Check if the closing task needs to be handled TransitionUtil.isClosingType(request.type) -> handleTaskClosing(task, transition, request.type) // Check if the top task shouldn't be allowed to enter desktop mode - isIncompatibleTask(task) -> handleIncompatibleTaskLaunch(task) + isIncompatibleTask(task) -> handleIncompatibleTaskLaunch(task, transition) // Check if fullscreen task should be updated task.isFullscreen -> handleFullscreenTaskLaunch(task, transition) // Check if freeform task should be updated @@ -2306,20 +2309,23 @@ class DesktopTasksController( * This is a special case where we want to launch the task in fullscreen instead of freeform. */ private fun handleMidRecentsFreeformTaskLaunch( - task: RunningTaskInfo + task: RunningTaskInfo, + transition: IBinder, ): WindowContainerTransaction? { logV("DesktopTasksController: handleMidRecentsFreeformTaskLaunch") val wct = WindowContainerTransaction() - addMoveToFullscreenChanges( - wct = wct, - taskInfo = task, - willExitDesktop = - willExitDesktop( - triggerTaskId = task.taskId, - displayId = task.displayId, - forceExitDesktop = true, - ), - ) + val runOnTransitStart = + addMoveToFullscreenChanges( + wct = wct, + taskInfo = task, + willExitDesktop = + willExitDesktop( + triggerTaskId = task.taskId, + displayId = task.displayId, + forceExitDesktop = true, + ), + ) + runOnTransitStart?.invoke(transition) wct.reorder(task.token, true) return wct } @@ -2343,16 +2349,18 @@ class DesktopTasksController( // launched. We should make this task go to fullscreen instead of freeform. Note // that this means any re-launch of a freeform window outside of desktop will be in // fullscreen as long as default-desktop flag is disabled. - addMoveToFullscreenChanges( - wct = wct, - taskInfo = task, - willExitDesktop = - willExitDesktop( - triggerTaskId = task.taskId, - displayId = task.displayId, - forceExitDesktop = true, - ), - ) + val runOnTransitStart = + addMoveToFullscreenChanges( + wct = wct, + taskInfo = task, + willExitDesktop = + willExitDesktop( + triggerTaskId = task.taskId, + displayId = task.displayId, + forceExitDesktop = true, + ), + ) + runOnTransitStart?.invoke(transition) return wct } bringDesktopAppsToFrontBeforeShowingNewTask(task.displayId, wct, task.taskId) @@ -2416,7 +2424,8 @@ class DesktopTasksController( if (shouldFullscreenTaskLaunchSwitchToDesktop(task)) { logD("Switch fullscreen task to freeform on transition: taskId=%d", task.taskId) return WindowContainerTransaction().also { wct -> - addMoveToDesktopChanges(wct, task) + val deskId = getDefaultDeskId(task.displayId) + addMoveToDeskTaskChanges(wct = wct, task = task, deskId = deskId) // In some launches home task is moved behind new task being launched. Make sure // that's not the case for launches in desktop. Also, if this launch is the first // one to trigger the desktop mode (e.g., when [forceEnterDesktop()]), activate the @@ -2447,7 +2456,8 @@ class DesktopTasksController( // If a freeform task receives a request for a fullscreen launch, apply the same // changes we do for similar transitions. The task not having WINDOWING_MODE_UNDEFINED // set when needed can interfere with future split / multi-instance transitions. - return WindowContainerTransaction().also { wct -> + val wct = WindowContainerTransaction() + val runOnTransitStart = addMoveToFullscreenChanges( wct = wct, taskInfo = task, @@ -2458,7 +2468,8 @@ class DesktopTasksController( forceExitDesktop = true, ), ) - } + runOnTransitStart?.invoke(transition) + return wct } return null } @@ -2473,7 +2484,10 @@ class DesktopTasksController( * If a task is not compatible with desktop mode freeform, it should always be launched in * fullscreen. */ - private fun handleIncompatibleTaskLaunch(task: RunningTaskInfo): WindowContainerTransaction? { + private fun handleIncompatibleTaskLaunch( + task: RunningTaskInfo, + transition: IBinder, + ): WindowContainerTransaction? { logV("handleIncompatibleTaskLaunch") if (!isDesktopModeShowing(task.displayId) && !forceEnterDesktop(task.displayId)) return null // Only update task repository for transparent task. @@ -2485,7 +2499,8 @@ class DesktopTasksController( } // Already fullscreen, no-op. if (task.isFullscreen) return null - return WindowContainerTransaction().also { wct -> + val wct = WindowContainerTransaction() + val runOnTransitStart = addMoveToFullscreenChanges( wct = wct, taskInfo = task, @@ -2496,7 +2511,8 @@ class DesktopTasksController( forceExitDesktop = true, ), ) - } + runOnTransitStart?.invoke(transition) + return wct } /** @@ -2543,55 +2559,44 @@ class DesktopTasksController( } /** - * Apply all changes required when task is first added to desktop. Uses the task's current - * display by default to apply initial bounds and placement relative to the display. Use a - * different [displayId] if the task should be moved to a different display. + * Applies the [wct] changes needed when a task is first moving to a desk. + * + * Note that this recalculates the initial bounds of the task, so it should not be used when + * transferring a task between desks. + * + * TODO: b/362720497 - this should be improved to be reusable by desk-to-desk CUJs where + * [DesksOrganizer.moveTaskToDesk] needs to be called and even cross-display CUJs where + * [applyFreeformDisplayChange] needs to be called. Potentially by comparing source vs + * destination desk ids and display ids, or adding extra arguments to the function. */ - @VisibleForTesting - @Deprecated("Deprecated with multiple desks", ReplaceWith("prepareMoveTaskToDesk()")) - fun addMoveToDesktopChanges( + fun addMoveToDeskTaskChanges( wct: WindowContainerTransaction, - taskInfo: RunningTaskInfo, - displayId: Int = taskInfo.displayId, - ) { - val displayLayout = displayController.getDisplayLayout(displayId) ?: return - val tdaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(displayId)!! - val tdaWindowingMode = tdaInfo.configuration.windowConfiguration.windowingMode - // TODO: b/397437641 - reconsider the windowing mode choice when multiple desks is enabled. - val targetWindowingMode = - if (tdaWindowingMode == WINDOWING_MODE_FREEFORM) { - // Display windowing is freeform, set to undefined and inherit it - WINDOWING_MODE_UNDEFINED - } else { - WINDOWING_MODE_FREEFORM - } - val initialBounds = getInitialBounds(displayLayout, taskInfo, displayId) - - if (canChangeTaskPosition(taskInfo)) { - wct.setBounds(taskInfo.token, initialBounds) - } - wct.setWindowingMode(taskInfo.token, targetWindowingMode) - wct.reorder(taskInfo.token, /* onTop= */ true) - if (useDesktopOverrideDensity()) { - wct.setDensityDpi(taskInfo.token, DESKTOP_DENSITY_OVERRIDE) - } - } - - private fun prepareMoveTaskToDesk( - wct: WindowContainerTransaction, - taskInfo: RunningTaskInfo, + task: RunningTaskInfo, deskId: Int, ) { - if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) return - val displayId = taskRepository.getDisplayForDesk(deskId) - val displayLayout = displayController.getDisplayLayout(displayId) ?: return - val initialBounds = getInitialBounds(displayLayout, taskInfo, displayId) - if (canChangeTaskPosition(taskInfo)) { - wct.setBounds(taskInfo.token, initialBounds) + val targetDisplayId = taskRepository.getDisplayForDesk(deskId) + val displayLayout = displayController.getDisplayLayout(targetDisplayId) ?: return + val initialBounds = getInitialBounds(displayLayout, task, targetDisplayId) + if (canChangeTaskPosition(task)) { + wct.setBounds(task.token, initialBounds) + } + if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) { + desksOrganizer.moveTaskToDesk(wct = wct, deskId = deskId, task = task) + } else { + val tdaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(targetDisplayId)!! + val tdaWindowingMode = tdaInfo.configuration.windowConfiguration.windowingMode + val targetWindowingMode = + if (tdaWindowingMode == WINDOWING_MODE_FREEFORM) { + // Display windowing is freeform, set to undefined and inherit it + WINDOWING_MODE_UNDEFINED + } else { + WINDOWING_MODE_FREEFORM + } + wct.setWindowingMode(task.token, targetWindowingMode) + wct.reorder(task.token, /* onTop= */ true) } - desksOrganizer.moveTaskToDesk(wct, deskId = deskId, task = taskInfo) if (useDesktopOverrideDensity()) { - wct.setDensityDpi(taskInfo.token, DESKTOP_DENSITY_OVERRIDE) + wct.setDensityDpi(task.token, DESKTOP_DENSITY_OVERRIDE) } } 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 b0785df3542e..63bf6841dba4 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 @@ -1114,44 +1114,44 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() } @Test - fun addMoveToDesktopChanges_gravityLeft_noBoundsApplied() { + fun addMoveToDeskTaskChanges_gravityLeft_noBoundsApplied() { setUpLandscapeDisplay() val task = setUpFullscreenTask(gravity = Gravity.LEFT) val wct = WindowContainerTransaction() - controller.addMoveToDesktopChanges(wct, task) + controller.addMoveToDeskTaskChanges(wct, task, deskId = 0) val finalBounds = findBoundsChange(wct, task) assertThat(finalBounds).isEqualTo(Rect()) } @Test - fun addMoveToDesktopChanges_gravityRight_noBoundsApplied() { + fun addMoveToDeskTaskChanges_gravityRight_noBoundsApplied() { setUpLandscapeDisplay() val task = setUpFullscreenTask(gravity = Gravity.RIGHT) val wct = WindowContainerTransaction() - controller.addMoveToDesktopChanges(wct, task) + controller.addMoveToDeskTaskChanges(wct, task, deskId = 0) val finalBounds = findBoundsChange(wct, task) assertThat(finalBounds).isEqualTo(Rect()) } @Test - fun addMoveToDesktopChanges_gravityTop_noBoundsApplied() { + fun addMoveToDeskTaskChanges_gravityTop_noBoundsApplied() { setUpLandscapeDisplay() val task = setUpFullscreenTask(gravity = Gravity.TOP) val wct = WindowContainerTransaction() - controller.addMoveToDesktopChanges(wct, task) + controller.addMoveToDeskTaskChanges(wct, task, deskId = 0) val finalBounds = findBoundsChange(wct, task) assertThat(finalBounds).isEqualTo(Rect()) } @Test - fun addMoveToDesktopChanges_gravityBottom_noBoundsApplied() { + fun addMoveToDeskTaskChanges_gravityBottom_noBoundsApplied() { setUpLandscapeDisplay() val task = setUpFullscreenTask(gravity = Gravity.BOTTOM) val wct = WindowContainerTransaction() - controller.addMoveToDesktopChanges(wct, task) + controller.addMoveToDeskTaskChanges(wct, task, deskId = 0) val finalBounds = findBoundsChange(wct, task) assertThat(finalBounds).isEqualTo(Rect()) @@ -1192,7 +1192,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() @Test @EnableFlags(Flags.FLAG_ENABLE_CASCADING_WINDOWS) - fun addMoveToDesktopChanges_positionBottomRight() { + fun addMoveToDeskTaskChanges_positionBottomRight() { setUpLandscapeDisplay() val stableBounds = Rect() displayLayout.getStableBoundsForDesktopMode(stableBounds) @@ -1201,7 +1201,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() val task = setUpFullscreenTask() val wct = WindowContainerTransaction() - controller.addMoveToDesktopChanges(wct, task) + controller.addMoveToDeskTaskChanges(wct, task, deskId = 0) val finalBounds = findBoundsChange(wct, task) assertThat(stableBounds.getDesktopTaskPosition(finalBounds!!)) @@ -1210,7 +1210,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() @Test @EnableFlags(Flags.FLAG_ENABLE_CASCADING_WINDOWS) - fun addMoveToDesktopChanges_positionTopLeft() { + fun addMoveToDeskTaskChanges_positionTopLeft() { setUpLandscapeDisplay() val stableBounds = Rect() displayLayout.getStableBoundsForDesktopMode(stableBounds) @@ -1219,7 +1219,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() val task = setUpFullscreenTask() val wct = WindowContainerTransaction() - controller.addMoveToDesktopChanges(wct, task) + controller.addMoveToDeskTaskChanges(wct, task, deskId = 0) val finalBounds = findBoundsChange(wct, task) assertThat(stableBounds.getDesktopTaskPosition(finalBounds!!)) @@ -1228,7 +1228,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() @Test @EnableFlags(Flags.FLAG_ENABLE_CASCADING_WINDOWS) - fun addMoveToDesktopChanges_positionBottomLeft() { + fun addMoveToDeskTaskChanges_positionBottomLeft() { setUpLandscapeDisplay() val stableBounds = Rect() displayLayout.getStableBoundsForDesktopMode(stableBounds) @@ -1237,7 +1237,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() val task = setUpFullscreenTask() val wct = WindowContainerTransaction() - controller.addMoveToDesktopChanges(wct, task) + controller.addMoveToDeskTaskChanges(wct, task, deskId = 0) val finalBounds = findBoundsChange(wct, task) assertThat(stableBounds.getDesktopTaskPosition(finalBounds!!)) @@ -1246,7 +1246,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() @Test @EnableFlags(Flags.FLAG_ENABLE_CASCADING_WINDOWS) - fun addMoveToDesktopChanges_positionTopRight() { + fun addMoveToDeskTaskChanges_positionTopRight() { setUpLandscapeDisplay() val stableBounds = Rect() displayLayout.getStableBoundsForDesktopMode(stableBounds) @@ -1255,7 +1255,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() val task = setUpFullscreenTask() val wct = WindowContainerTransaction() - controller.addMoveToDesktopChanges(wct, task) + controller.addMoveToDeskTaskChanges(wct, task, deskId = 0) val finalBounds = findBoundsChange(wct, task) assertThat(stableBounds.getDesktopTaskPosition(finalBounds!!)) @@ -1264,7 +1264,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() @Test @EnableFlags(Flags.FLAG_ENABLE_CASCADING_WINDOWS) - fun addMoveToDesktopChanges_positionResetsToCenter() { + fun addMoveToDeskTaskChanges_positionResetsToCenter() { setUpLandscapeDisplay() val stableBounds = Rect() displayLayout.getStableBoundsForDesktopMode(stableBounds) @@ -1273,7 +1273,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() val task = setUpFullscreenTask() val wct = WindowContainerTransaction() - controller.addMoveToDesktopChanges(wct, task) + controller.addMoveToDeskTaskChanges(wct, task, deskId = 0) val finalBounds = findBoundsChange(wct, task) assertThat(stableBounds.getDesktopTaskPosition(finalBounds!!)) @@ -1282,7 +1282,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() @Test @EnableFlags(Flags.FLAG_ENABLE_CASCADING_WINDOWS) - fun addMoveToDesktopChanges_lastWindowSnapLeft_positionResetsToCenter() { + fun addMoveToDeskTaskChanges_lastWindowSnapLeft_positionResetsToCenter() { setUpLandscapeDisplay() val stableBounds = Rect() displayLayout.getStableBoundsForDesktopMode(stableBounds) @@ -1294,7 +1294,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() val task = setUpFullscreenTask() val wct = WindowContainerTransaction() - controller.addMoveToDesktopChanges(wct, task) + controller.addMoveToDeskTaskChanges(wct, task, deskId = 0) val finalBounds = findBoundsChange(wct, task) assertThat(stableBounds.getDesktopTaskPosition(finalBounds!!)) @@ -1303,7 +1303,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() @Test @EnableFlags(Flags.FLAG_ENABLE_CASCADING_WINDOWS) - fun addMoveToDesktopChanges_lastWindowSnapRight_positionResetsToCenter() { + fun addMoveToDeskTaskChanges_lastWindowSnapRight_positionResetsToCenter() { setUpLandscapeDisplay() val stableBounds = Rect() displayLayout.getStableBoundsForDesktopMode(stableBounds) @@ -1321,7 +1321,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() val task = setUpFullscreenTask() val wct = WindowContainerTransaction() - controller.addMoveToDesktopChanges(wct, task) + controller.addMoveToDeskTaskChanges(wct, task, deskId = 0) val finalBounds = findBoundsChange(wct, task) assertThat(stableBounds.getDesktopTaskPosition(finalBounds!!)) @@ -1330,7 +1330,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() @Test @EnableFlags(Flags.FLAG_ENABLE_CASCADING_WINDOWS) - fun addMoveToDesktopChanges_lastWindowMaximised_positionResetsToCenter() { + fun addMoveToDeskTaskChanges_lastWindowMaximised_positionResetsToCenter() { setUpLandscapeDisplay() val stableBounds = Rect() displayLayout.getStableBoundsForDesktopMode(stableBounds) @@ -1340,7 +1340,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() val task = setUpFullscreenTask() val wct = WindowContainerTransaction() - controller.addMoveToDesktopChanges(wct, task) + controller.addMoveToDeskTaskChanges(wct, task, deskId = 0) val finalBounds = findBoundsChange(wct, task) assertThat(stableBounds.getDesktopTaskPosition(finalBounds!!)) @@ -1349,7 +1349,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() @Test @EnableFlags(Flags.FLAG_ENABLE_CASCADING_WINDOWS) - fun addMoveToDesktopChanges_defaultToCenterIfFree() { + fun addMoveToDeskTaskChanges_defaultToCenterIfFree() { setUpLandscapeDisplay() val stableBounds = Rect() displayLayout.getStableBoundsForDesktopMode(stableBounds) @@ -1367,7 +1367,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() val task = setUpFullscreenTask() val wct = WindowContainerTransaction() - controller.addMoveToDesktopChanges(wct, task) + controller.addMoveToDeskTaskChanges(wct, task, deskId = 0) val finalBounds = findBoundsChange(wct, task) assertThat(stableBounds.getDesktopTaskPosition(finalBounds!!)) @@ -1375,7 +1375,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() } @Test - fun addMoveToDesktopChanges_excludeCaptionFromAppBounds_nonResizableLandscape() { + fun addMoveToDeskTaskChanges_excludeCaptionFromAppBounds_nonResizableLandscape() { setUpLandscapeDisplay() val task = setUpFullscreenTask( @@ -1385,7 +1385,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() whenever(desktopModeCompatPolicy.shouldExcludeCaptionFromAppBounds(task)).thenReturn(true) val initialAspectRatio = calculateAspectRatio(task) val wct = WindowContainerTransaction() - controller.addMoveToDesktopChanges(wct, task) + controller.addMoveToDeskTaskChanges(wct, task, deskId = 0) val finalBounds = findBoundsChange(wct, task) val captionInsets = getAppHeaderHeight(context) @@ -1397,7 +1397,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() } @Test - fun addMoveToDesktopChanges_excludeCaptionFromAppBounds_nonResizablePortrait() { + fun addMoveToDeskTaskChanges_excludeCaptionFromAppBounds_nonResizablePortrait() { setUpLandscapeDisplay() val task = setUpFullscreenTask( @@ -1407,7 +1407,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() whenever(desktopModeCompatPolicy.shouldExcludeCaptionFromAppBounds(task)).thenReturn(true) val initialAspectRatio = calculateAspectRatio(task) val wct = WindowContainerTransaction() - controller.addMoveToDesktopChanges(wct, task) + controller.addMoveToDeskTaskChanges(wct, task, deskId = 0) val finalBounds = findBoundsChange(wct, task) val captionInsets = getAppHeaderHeight(context) @@ -1445,29 +1445,29 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() @Test @EnableFlags(Flags.FLAG_ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS) - fun addMoveToDesktopChanges_landscapeDevice_userFullscreenOverride_defaultPortraitBounds() { + fun addMoveToDeskTaskChanges_landscapeDevice_userFullscreenOverride_defaultPortraitBounds() { setUpLandscapeDisplay() val task = setUpFullscreenTask(enableUserFullscreenOverride = true) val wct = WindowContainerTransaction() - controller.addMoveToDesktopChanges(wct, task) + controller.addMoveToDeskTaskChanges(wct, task, deskId = 0) assertThat(findBoundsChange(wct, task)).isEqualTo(DEFAULT_LANDSCAPE_BOUNDS) } @Test @EnableFlags(Flags.FLAG_ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS) - fun addMoveToDesktopChanges_landscapeDevice_systemFullscreenOverride_defaultPortraitBounds() { + fun addMoveToDeskTaskChanges_landscapeDevice_systemFullscreenOverride_defaultPortraitBounds() { setUpLandscapeDisplay() val task = setUpFullscreenTask(enableSystemFullscreenOverride = true) val wct = WindowContainerTransaction() - controller.addMoveToDesktopChanges(wct, task) + controller.addMoveToDeskTaskChanges(wct, task, deskId = 0) assertThat(findBoundsChange(wct, task)).isEqualTo(DEFAULT_LANDSCAPE_BOUNDS) } @Test @EnableFlags(Flags.FLAG_ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS) - fun addMoveToDesktopChanges_landscapeDevice_portraitResizableApp_aspectRatioOverridden() { + fun addMoveToDeskTaskChanges_landscapeDevice_portraitResizableApp_aspectRatioOverridden() { setUpLandscapeDisplay() val task = setUpFullscreenTask( @@ -1476,36 +1476,36 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() aspectRatioOverrideApplied = true, ) val wct = WindowContainerTransaction() - controller.addMoveToDesktopChanges(wct, task) + controller.addMoveToDeskTaskChanges(wct, task, deskId = 0) assertThat(findBoundsChange(wct, task)).isEqualTo(UNRESIZABLE_PORTRAIT_BOUNDS) } @Test @EnableFlags(Flags.FLAG_ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS) - fun addMoveToDesktopChanges_portraitDevice_userFullscreenOverride_defaultPortraitBounds() { + fun addMoveToDeskTaskChanges_portraitDevice_userFullscreenOverride_defaultPortraitBounds() { setUpPortraitDisplay() val task = setUpFullscreenTask(enableUserFullscreenOverride = true) val wct = WindowContainerTransaction() - controller.addMoveToDesktopChanges(wct, task) + controller.addMoveToDeskTaskChanges(wct, task, deskId = 0) assertThat(findBoundsChange(wct, task)).isEqualTo(DEFAULT_PORTRAIT_BOUNDS) } @Test @EnableFlags(Flags.FLAG_ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS) - fun addMoveToDesktopChanges_portraitDevice_systemFullscreenOverride_defaultPortraitBounds() { + fun addMoveToDeskTaskChanges_portraitDevice_systemFullscreenOverride_defaultPortraitBounds() { setUpPortraitDisplay() val task = setUpFullscreenTask(enableSystemFullscreenOverride = true) val wct = WindowContainerTransaction() - controller.addMoveToDesktopChanges(wct, task) + controller.addMoveToDeskTaskChanges(wct, task, deskId = 0) assertThat(findBoundsChange(wct, task)).isEqualTo(DEFAULT_PORTRAIT_BOUNDS) } @Test @EnableFlags(Flags.FLAG_ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS) - fun addMoveToDesktopChanges_portraitDevice_landscapeResizableApp_aspectRatioOverridden() { + fun addMoveToDeskTaskChanges_portraitDevice_landscapeResizableApp_aspectRatioOverridden() { setUpPortraitDisplay() val task = setUpFullscreenTask( @@ -1515,7 +1515,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() aspectRatioOverrideApplied = true, ) val wct = WindowContainerTransaction() - controller.addMoveToDesktopChanges(wct, task) + controller.addMoveToDeskTaskChanges(wct, task, deskId = 0) assertThat(findBoundsChange(wct, task)).isEqualTo(UNRESIZABLE_LANDSCAPE_BOUNDS) } @@ -2824,7 +2824,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() } @Test - @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) fun moveToNextDisplay_toDesktopInOtherDisplay_bringsExistingTasksToFront() { val transition = Binder() val sourceDeskId = 0 @@ -2856,7 +2855,6 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() Flags.FLAG_ENABLE_PER_DISPLAY_DESKTOP_WALLPAPER_ACTIVITY, Flags.FLAG_ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER, ) - @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) fun moveToNextDisplay_toDesktopInOtherDisplay_movesHomeAndWallpaperToFront() { val homeTask = setUpHomeTask(displayId = SECOND_DISPLAY) whenever(desktopWallpaperActivityTokenProvider.getToken(SECOND_DISPLAY)) @@ -3506,6 +3504,39 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() } @Test + @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) + fun handleRequest_fullscreenTask_switchToDesktop_movesTaskToDesk() { + taskRepository.addDesk(displayId = DEFAULT_DISPLAY, deskId = 5) + setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = 5) + taskRepository.setActiveDesk(displayId = DEFAULT_DISPLAY, deskId = 5) + + val fullscreenTask = createFullscreenTask() + val wct = controller.handleRequest(Binder(), createTransition(fullscreenTask)) + + assertNotNull(wct, "should handle request") + verify(desksOrganizer).moveTaskToDesk(wct = wct, deskId = 5, task = fullscreenTask) + } + + @Test + @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) + fun handleRequest_fullscreenTaskThatWasInactiveInDesk_tracksDeskDeactivation() { + // Set up and existing desktop task in an active desk. + val inactiveInDeskTask = setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = 0) + taskRepository.setDeskInactive(deskId = 0) + + // Now the task is launching as fullscreen. + inactiveInDeskTask.configuration.windowConfiguration.windowingMode = + WINDOWING_MODE_FULLSCREEN + val transition = Binder() + val wct = controller.handleRequest(transition, createTransition(inactiveInDeskTask)) + + // Desk is deactivated. + assertNotNull(wct, "should handle request") + verify(desksTransitionsObserver) + .addPendingTransition(DeskTransition.DeactivateDesk(transition, deskId = 0)) + } + + @Test fun handleRequest_fullscreenTask_freeformVisible_returnSwitchToFreeformWCT() { val homeTask = setUpHomeTask() val freeformTask = setUpFreeformTask() @@ -3681,6 +3712,20 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() } @Test + @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) + fun handleRequest_freeformTaskFromInactiveDesk_tracksDeskDeactivation() { + val deskId = 0 + val freeformTask = setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = deskId) + taskRepository.setDeskInactive(deskId = deskId) + + val transition = Binder() + controller.handleRequest(transition, createTransition(freeformTask)) + + verify(desksTransitionsObserver) + .addPendingTransition(DeskTransition.DeactivateDesk(transition, deskId)) + } + + @Test fun handleRequest_freeformTask_relaunchActiveTask_taskBecomesUndefined() { val freeformTask = setUpFreeformTask() markTaskHidden(freeformTask) @@ -3928,6 +3973,24 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() } @Test + @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) + fun handleRequest_recentsAnimationRunning_relaunchActiveTask_tracksDeskDeactivation() { + // Set up a visible freeform task + val freeformTask = setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = 0) + markTaskVisible(freeformTask) + + // Mark recents animation running + recentsTransitionStateListener.onTransitionStateChanged(TRANSITION_STATE_ANIMATING) + + val transition = Binder() + controller.handleRequest(transition, createTransition(freeformTask)) + + desksTransitionsObserver.addPendingTransition( + DeskTransition.DeactivateDesk(transition, deskId = 0) + ) + } + + @Test @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY) fun handleRequest_topActivityTransparentWithoutDisplay_returnSwitchToFreeformWCT() { val freeformTask = setUpFreeformTask() @@ -4045,6 +4108,31 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() } @Test + @EnableFlags( + Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND, + Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY, + ) + fun handleRequest_systemUIActivityWithDisplayInFreeformTask_inDesktop_tracksDeskDeactivation() { + val deskId = 5 + taskRepository.addDesk(displayId = DEFAULT_DISPLAY, deskId = deskId) + taskRepository.setActiveDesk(displayId = DEFAULT_DISPLAY, deskId = deskId) + val systemUIPackageName = + context.resources.getString(com.android.internal.R.string.config_systemUi) + val baseComponent = ComponentName(systemUIPackageName, /* cls= */ "") + val task = + setUpFreeformTask(displayId = DEFAULT_DISPLAY).apply { + baseActivity = baseComponent + isTopActivityNoDisplay = false + } + + val transition = Binder() + controller.handleRequest(transition, createTransition(task)) + + verify(desksTransitionsObserver) + .addPendingTransition(DeskTransition.DeactivateDesk(transition, deskId)) + } + + @Test @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY) fun handleRequest_systemUIActivityWithoutDisplay_returnSwitchToFreeformWCT() { val freeformTask = setUpFreeformTask() |