Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +80 −33 Original line number Diff line number Diff line Loading @@ -572,32 +572,12 @@ class DesktopTasksController( ) val taskIdToMinimize = if (Flags.enableMultipleDesktopsBackend()) { // Activate the desk first. prepareForDeskActivation(displayId, wct) desksOrganizer.activateDesk(wct, deskId) if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) { // TODO: 362720497 - do non-running tasks need to be restarted with // |wct#startTask|? } taskbarDesktopTaskListener?.onTaskbarCornerRoundingUpdate( doesAnyTaskRequireTaskbarRounding(displayId) prepareMoveTaskToDeskAndActivate( wct = wct, displayId = displayId, deskId = deskId, task = task, ) // TODO: 362720497 - activating a desk with the intention to move a new task to it // means we may need to minimize something in the activating desk. Do so here // similar // to how it's done in #bringDesktopAppsToFrontBeforeShowingNewTask instead of // returning null. null } else { // Bring other apps to front first. bringDesktopAppsToFrontBeforeShowingNewTask(task.displayId, wct, task.taskId) } if (Flags.enableMultipleDesktopsBackend()) { prepareMoveTaskToDesk(wct, task, deskId) } else { addMoveToDesktopChanges(wct, task) } val transition: IBinder if (remoteTransition != null) { Loading Loading @@ -630,6 +610,48 @@ class DesktopTasksController( } } /** * Applies the necessary changes and operations to [wct] to move a task into a desk and * activating that desk. This includes showing pre-existing tasks of that desk behind the new * task (but minimizing one of them if needed) and showing Home and the desktop wallpaper. * * @return the id of the task that is being minimized, if any. */ private fun prepareMoveTaskToDeskAndActivate( wct: WindowContainerTransaction, displayId: Int, deskId: Int, task: RunningTaskInfo, ): Int? { val taskIdToMinimize = if (Flags.enableMultipleDesktopsBackend()) { // Activate the desk first. prepareForDeskActivation(displayId, wct) desksOrganizer.activateDesk(wct, deskId) if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) { // TODO: b/362720497 - do non-running tasks need to be restarted with // |wct#startTask|? } taskbarDesktopTaskListener?.onTaskbarCornerRoundingUpdate( doesAnyTaskRequireTaskbarRounding(displayId) ) // TODO: b/362720497 - activating a desk with the intention to move a new task to // it means we may need to minimize something in the activating desk. Do so here // similar to how it's done in #bringDesktopAppsToFrontBeforeShowingNewTask // instead of returning null. null } else { // Bring other apps to front first. bringDesktopAppsToFrontBeforeShowingNewTask(displayId, wct, task.taskId) } if (Flags.enableMultipleDesktopsBackend()) { prepareMoveTaskToDesk(wct, task, deskId) } else { addMoveToDesktopChanges(wct, task) } return taskIdToMinimize } private fun invokeCallbackToOverview(transition: IBinder, callback: IMoveToDesktopCallback?) { // TODO: b/333524374 - Remove this later. // This is a temporary implementation for adding CUJ end and Loading Loading @@ -669,21 +691,34 @@ class DesktopTasksController( * [startDragToDesktop]. */ private fun finalizeDragToDesktop(taskInfo: RunningTaskInfo) { val deskId = checkNotNull(taskRepository.getDefaultDeskId(taskInfo.displayId)) { "Expected a default desk to exist" } ProtoLog.v( WM_SHELL_DESKTOP_MODE, "DesktopTasksController: finalizeDragToDesktop taskId=%d", "DesktopTasksController: finalizeDragToDesktop taskId=%d deskId=%d", taskInfo.taskId, deskId, ) val wct = WindowContainerTransaction() exitSplitIfApplicable(wct, taskInfo) if (!Flags.enableMultipleDesktopsBackend()) { // |moveHomeTask| is also called in |bringDesktopAppsToFrontBeforeShowingNewTask|, so // this shouldn't be necessary at all. if (Flags.enablePerDisplayDesktopWallpaperActivity()) { moveHomeTask(taskInfo.displayId, wct) } else { moveHomeTask(context.displayId, wct) } } val taskIdToMinimize = bringDesktopAppsToFrontBeforeShowingNewTask(taskInfo.displayId, wct, taskInfo.taskId) addMoveToDesktopChanges(wct, taskInfo) prepareMoveTaskToDeskAndActivate( wct = wct, displayId = taskInfo.displayId, deskId = deskId, task = taskInfo, ) val exitResult = desktopImmersiveController.exitImmersiveIfApplicable( wct = wct, Loading @@ -700,6 +735,18 @@ class DesktopTasksController( addPendingMinimizeTransition(it, taskId, MinimizeReason.TASK_LIMIT) } exitResult.asExit()?.runOnTransitionStart?.invoke(transition) if (Flags.enableMultipleDesktopsBackend()) { desksTransitionObserver.addPendingTransition( DeskTransition.ActiveDeskWithTask( token = transition, displayId = taskInfo.displayId, deskId = deskId, enterTaskId = taskInfo.taskId, ) ) } else { taskRepository.setActiveDesk(displayId = taskInfo.displayId, deskId = deskId) } } } Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +70 −0 Original line number Diff line number Diff line Loading @@ -4230,6 +4230,76 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() assertThat(findBoundsChange(wct, task)).isEqualTo(UNRESIZABLE_LANDSCAPE_BOUNDS) } @Test @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) fun dragToDesktop_movesTaskToDesk() { val spyController = spy(controller) whenever(spyController.getVisualIndicator()).thenReturn(desktopModeVisualIndicator) whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull())) .thenReturn(DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR) val task = setUpFullscreenTask(displayId = DEFAULT_DISPLAY) spyController.onDragPositioningEndThroughStatusBar(PointF(200f, 200f), task, mockSurface) val wct = getLatestDragToDesktopWct() verify(desksOrganizer).moveTaskToDesk(wct, deskId = 0, task) } @Test @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) fun dragToDesktop_activatesDesk() { val spyController = spy(controller) whenever(spyController.getVisualIndicator()).thenReturn(desktopModeVisualIndicator) whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull())) .thenReturn(DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR) val task = setUpFullscreenTask(displayId = DEFAULT_DISPLAY) spyController.onDragPositioningEndThroughStatusBar(PointF(200f, 200f), task, mockSurface) val wct = getLatestDragToDesktopWct() verify(desksOrganizer).activateDesk(wct, deskId = 0) } @Test @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) fun dragToDesktop_triggersEnterDesktopListener() { val spyController = spy(controller) whenever(spyController.getVisualIndicator()).thenReturn(desktopModeVisualIndicator) whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull())) .thenReturn(DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR) val task = setUpFullscreenTask(displayId = DEFAULT_DISPLAY) spyController.onDragPositioningEndThroughStatusBar(PointF(200f, 200f), task, mockSurface) verify(desktopModeEnterExitTransitionListener) .onEnterDesktopModeTransitionStarted(FREEFORM_ANIMATION_DURATION) } @Test @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) fun dragToDesktop_multipleDesks_addsPendingTransition() { val transition = Binder() val spyController = spy(controller) whenever(dragToDesktopTransitionHandler.finishDragToDesktopTransition(any())) .thenReturn(transition) whenever(spyController.getVisualIndicator()).thenReturn(desktopModeVisualIndicator) whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull())) .thenReturn(DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR) val task = setUpFullscreenTask(displayId = DEFAULT_DISPLAY) spyController.onDragPositioningEndThroughStatusBar(PointF(200f, 200f), task, mockSurface) verify(desksTransitionsObserver) .addPendingTransition( argThat { this is DeskTransition.ActiveDeskWithTask && this.token == transition && this.deskId == 0 && this.enterTaskId == task.taskId } ) } @Test fun onDesktopDragMove_endsOutsideValidDragArea_snapsToValidBounds() { val task = setUpFreeformTask() Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +80 −33 Original line number Diff line number Diff line Loading @@ -572,32 +572,12 @@ class DesktopTasksController( ) val taskIdToMinimize = if (Flags.enableMultipleDesktopsBackend()) { // Activate the desk first. prepareForDeskActivation(displayId, wct) desksOrganizer.activateDesk(wct, deskId) if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) { // TODO: 362720497 - do non-running tasks need to be restarted with // |wct#startTask|? } taskbarDesktopTaskListener?.onTaskbarCornerRoundingUpdate( doesAnyTaskRequireTaskbarRounding(displayId) prepareMoveTaskToDeskAndActivate( wct = wct, displayId = displayId, deskId = deskId, task = task, ) // TODO: 362720497 - activating a desk with the intention to move a new task to it // means we may need to minimize something in the activating desk. Do so here // similar // to how it's done in #bringDesktopAppsToFrontBeforeShowingNewTask instead of // returning null. null } else { // Bring other apps to front first. bringDesktopAppsToFrontBeforeShowingNewTask(task.displayId, wct, task.taskId) } if (Flags.enableMultipleDesktopsBackend()) { prepareMoveTaskToDesk(wct, task, deskId) } else { addMoveToDesktopChanges(wct, task) } val transition: IBinder if (remoteTransition != null) { Loading Loading @@ -630,6 +610,48 @@ class DesktopTasksController( } } /** * Applies the necessary changes and operations to [wct] to move a task into a desk and * activating that desk. This includes showing pre-existing tasks of that desk behind the new * task (but minimizing one of them if needed) and showing Home and the desktop wallpaper. * * @return the id of the task that is being minimized, if any. */ private fun prepareMoveTaskToDeskAndActivate( wct: WindowContainerTransaction, displayId: Int, deskId: Int, task: RunningTaskInfo, ): Int? { val taskIdToMinimize = if (Flags.enableMultipleDesktopsBackend()) { // Activate the desk first. prepareForDeskActivation(displayId, wct) desksOrganizer.activateDesk(wct, deskId) if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) { // TODO: b/362720497 - do non-running tasks need to be restarted with // |wct#startTask|? } taskbarDesktopTaskListener?.onTaskbarCornerRoundingUpdate( doesAnyTaskRequireTaskbarRounding(displayId) ) // TODO: b/362720497 - activating a desk with the intention to move a new task to // it means we may need to minimize something in the activating desk. Do so here // similar to how it's done in #bringDesktopAppsToFrontBeforeShowingNewTask // instead of returning null. null } else { // Bring other apps to front first. bringDesktopAppsToFrontBeforeShowingNewTask(displayId, wct, task.taskId) } if (Flags.enableMultipleDesktopsBackend()) { prepareMoveTaskToDesk(wct, task, deskId) } else { addMoveToDesktopChanges(wct, task) } return taskIdToMinimize } private fun invokeCallbackToOverview(transition: IBinder, callback: IMoveToDesktopCallback?) { // TODO: b/333524374 - Remove this later. // This is a temporary implementation for adding CUJ end and Loading Loading @@ -669,21 +691,34 @@ class DesktopTasksController( * [startDragToDesktop]. */ private fun finalizeDragToDesktop(taskInfo: RunningTaskInfo) { val deskId = checkNotNull(taskRepository.getDefaultDeskId(taskInfo.displayId)) { "Expected a default desk to exist" } ProtoLog.v( WM_SHELL_DESKTOP_MODE, "DesktopTasksController: finalizeDragToDesktop taskId=%d", "DesktopTasksController: finalizeDragToDesktop taskId=%d deskId=%d", taskInfo.taskId, deskId, ) val wct = WindowContainerTransaction() exitSplitIfApplicable(wct, taskInfo) if (!Flags.enableMultipleDesktopsBackend()) { // |moveHomeTask| is also called in |bringDesktopAppsToFrontBeforeShowingNewTask|, so // this shouldn't be necessary at all. if (Flags.enablePerDisplayDesktopWallpaperActivity()) { moveHomeTask(taskInfo.displayId, wct) } else { moveHomeTask(context.displayId, wct) } } val taskIdToMinimize = bringDesktopAppsToFrontBeforeShowingNewTask(taskInfo.displayId, wct, taskInfo.taskId) addMoveToDesktopChanges(wct, taskInfo) prepareMoveTaskToDeskAndActivate( wct = wct, displayId = taskInfo.displayId, deskId = deskId, task = taskInfo, ) val exitResult = desktopImmersiveController.exitImmersiveIfApplicable( wct = wct, Loading @@ -700,6 +735,18 @@ class DesktopTasksController( addPendingMinimizeTransition(it, taskId, MinimizeReason.TASK_LIMIT) } exitResult.asExit()?.runOnTransitionStart?.invoke(transition) if (Flags.enableMultipleDesktopsBackend()) { desksTransitionObserver.addPendingTransition( DeskTransition.ActiveDeskWithTask( token = transition, displayId = taskInfo.displayId, deskId = deskId, enterTaskId = taskInfo.taskId, ) ) } else { taskRepository.setActiveDesk(displayId = taskInfo.displayId, deskId = deskId) } } } Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +70 −0 Original line number Diff line number Diff line Loading @@ -4230,6 +4230,76 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() assertThat(findBoundsChange(wct, task)).isEqualTo(UNRESIZABLE_LANDSCAPE_BOUNDS) } @Test @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) fun dragToDesktop_movesTaskToDesk() { val spyController = spy(controller) whenever(spyController.getVisualIndicator()).thenReturn(desktopModeVisualIndicator) whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull())) .thenReturn(DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR) val task = setUpFullscreenTask(displayId = DEFAULT_DISPLAY) spyController.onDragPositioningEndThroughStatusBar(PointF(200f, 200f), task, mockSurface) val wct = getLatestDragToDesktopWct() verify(desksOrganizer).moveTaskToDesk(wct, deskId = 0, task) } @Test @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) fun dragToDesktop_activatesDesk() { val spyController = spy(controller) whenever(spyController.getVisualIndicator()).thenReturn(desktopModeVisualIndicator) whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull())) .thenReturn(DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR) val task = setUpFullscreenTask(displayId = DEFAULT_DISPLAY) spyController.onDragPositioningEndThroughStatusBar(PointF(200f, 200f), task, mockSurface) val wct = getLatestDragToDesktopWct() verify(desksOrganizer).activateDesk(wct, deskId = 0) } @Test @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) fun dragToDesktop_triggersEnterDesktopListener() { val spyController = spy(controller) whenever(spyController.getVisualIndicator()).thenReturn(desktopModeVisualIndicator) whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull())) .thenReturn(DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR) val task = setUpFullscreenTask(displayId = DEFAULT_DISPLAY) spyController.onDragPositioningEndThroughStatusBar(PointF(200f, 200f), task, mockSurface) verify(desktopModeEnterExitTransitionListener) .onEnterDesktopModeTransitionStarted(FREEFORM_ANIMATION_DURATION) } @Test @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) fun dragToDesktop_multipleDesks_addsPendingTransition() { val transition = Binder() val spyController = spy(controller) whenever(dragToDesktopTransitionHandler.finishDragToDesktopTransition(any())) .thenReturn(transition) whenever(spyController.getVisualIndicator()).thenReturn(desktopModeVisualIndicator) whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull())) .thenReturn(DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR) val task = setUpFullscreenTask(displayId = DEFAULT_DISPLAY) spyController.onDragPositioningEndThroughStatusBar(PointF(200f, 200f), task, mockSurface) verify(desksTransitionsObserver) .addPendingTransition( argThat { this is DeskTransition.ActiveDeskWithTask && this.token == transition && this.deskId == 0 && this.enterTaskId == task.taskId } ) } @Test fun onDesktopDragMove_endsOutsideValidDragArea_snapsToValidBounds() { val task = setUpFreeformTask() Loading