diff options
author | 2025-02-25 20:16:15 +0000 | |
---|---|---|
committer | 2025-02-26 04:58:05 +0000 | |
commit | dd0112e1d8392ea33de59ae1932a669fe20d0796 (patch) | |
tree | 1cd2ef8b859131fabbad57d81f56912d2f107d9d | |
parent | 45dc6eaa853ec1ab4ba92a0d83b681a75dcf666b (diff) |
[26/N] Desks: Apply desk activation logic when moving task to next display
Consolidates activation logic regardless of multi-desks being enabled
when moving a task to the desktop of another display. Prior to this
change, the target desk only got desk activation changes with the flag
enabled. Activation in this context means:
- Home/Wallpaper go to front to cover existing non-desktop windows (e.g.
if something was fullscreen in the target display)
- Existing inactive desktop tasks are brought to front to join the task
moving to the desktop in the new display
- The task moving to the new desktop/display may put the # of desktop
tasks over the task-limit, so minimization logic needs to be applied.
So with this change all that is applied even with multi-desks disabled
(which fixes pre-existing bugs), and allows the activation logic in the
moveToDisplay() function to be simplified to calling
addDeskActivationChanges(), which already internally handles multi-desk
flag differences.
Bug: 362720497
Flag: com.android.window.flags.enable_desktop_windowing_mode
Flag: com.android.window.flags.enable_move_to_next_display_shortcut
Flag: com.android.window.flags.enable_multiple_desktops_backend
Test: open a couple of freeform apps in an external display, move one to
fullscreen. Then, move a task from the internal display to the external
display and verify:
1) The fullscreen task is no longer visible
2) Wallpaper is visible in the background
3) Existing desktop tasks are visible
4) Going over the limit minimizes some of the existing tasks from (3)
Change-Id: I5c9ddf8c3de52ddc948c847036feed195e639c80
2 files changed, 114 insertions, 14 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 a6f8ebd0717a..bedea2f8741c 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 @@ -1317,25 +1317,23 @@ class DesktopTasksController( applyFreeformDisplayChange(wct, task, displayId) } - val activationRunnable: RunOnTransitStart? if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) { desksOrganizer.moveTaskToDesk(wct, destinationDeskId, task) - prepareForDeskActivation(displayId, wct) - desksOrganizer.activateDesk(wct, destinationDeskId) - activationRunnable = { transition -> - desksTransitionObserver.addPendingTransition( - DeskTransition.ActiveDeskWithTask( - token = transition, - displayId = displayId, - deskId = destinationDeskId, - enterTaskId = task.taskId, - ) - ) - } } else { wct.reparent(task.token, displayAreaInfo.token, /* onTop= */ true) - activationRunnable = null } + addDeskActivationChanges(destinationDeskId, wct) + val activationRunnable: RunOnTransitStart = { transition -> + desksTransitionObserver.addPendingTransition( + DeskTransition.ActiveDeskWithTask( + token = transition, + displayId = displayId, + deskId = destinationDeskId, + enterTaskId = task.taskId, + ) + ) + } + if (Flags.enableDisplayFocusInShellTransitions()) { // Bring the destination display to top with includingParents=true, so that the // destination display gains the display focus, which makes the top task in the display 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 1e2fc5768289..8ce31a5b8bed 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 @@ -2781,6 +2781,73 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() } @Test + @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) + fun moveToNextDisplay_toDesktopInOtherDisplay_bringsExistingTasksToFront() { + val transition = Binder() + val sourceDeskId = 0 + val targetDeskId = 2 + taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = targetDeskId) + taskRepository.setDeskInactive(deskId = targetDeskId) + // Set up two display ids + whenever(rootTaskDisplayAreaOrganizer.displayIds) + .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) + // Create a mock for the target display area: second display + val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) + whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) + .thenReturn(secondDisplayArea) + whenever(transitions.startTransition(eq(TRANSIT_CHANGE), any(), anyOrNull())) + .thenReturn(transition) + val task1 = setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = sourceDeskId) + val task2 = setUpFreeformTask(displayId = SECOND_DISPLAY, deskId = targetDeskId) + + controller.moveToNextDisplay(task1.taskId) + + // Existing desktop task in the target display is moved to front. + val wct = getLatestTransition() + wct.assertReorder(task2.token, /* toTop= */ true) + } + + @Test + @EnableFlags( + Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY, + 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)) + .thenReturn(wallpaperToken) + val transition = Binder() + val sourceDeskId = 0 + val targetDeskId = 2 + taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = targetDeskId) + taskRepository.setDeskInactive(deskId = targetDeskId) + // Set up two display ids + whenever(rootTaskDisplayAreaOrganizer.displayIds) + .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) + // Create a mock for the target display area: second display + val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) + whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) + .thenReturn(secondDisplayArea) + whenever(transitions.startTransition(eq(TRANSIT_CHANGE), any(), anyOrNull())) + .thenReturn(transition) + val task1 = setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = sourceDeskId) + + controller.moveToNextDisplay(task1.taskId) + + // Home / Wallpaper should be moved to front as the background of desktop tasks, otherwise + // fullscreen (non-desktop) tasks could remain visible. + val wct = getLatestTransition() + val homeReorderIndex = wct.indexOfReorder(homeTask, toTop = true) + val wallpaperReorderIndex = wct.indexOfReorder(wallpaperToken, toTop = true) + assertThat(homeReorderIndex).isNotEqualTo(-1) + assertThat(wallpaperReorderIndex).isNotEqualTo(-1) + // Wallpaper last, to be in front of Home. + assertThat(wallpaperReorderIndex).isGreaterThan(homeReorderIndex) + } + + @Test @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) fun moveToNextDisplay_toDeskInOtherDisplay_movesToDeskAndActivates() { val transition = Binder() @@ -2854,6 +2921,35 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() } @Test + fun moveToNextDisplay_movingToDesktop_sendsTaskbarRoundingUpdate() { + val transition = Binder() + val sourceDeskId = 1 + val targetDeskId = 2 + taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = targetDeskId) + taskRepository.setDeskInactive(deskId = targetDeskId) + // Set up two display ids + whenever(rootTaskDisplayAreaOrganizer.displayIds) + .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) + // Create a mock for the target display area: second display + val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) + whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) + .thenReturn(secondDisplayArea) + whenever(transitions.startTransition(eq(TRANSIT_CHANGE), any(), anyOrNull())) + .thenReturn(transition) + + val task = setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = sourceDeskId) + taskRepository.addTaskToDesk( + displayId = DEFAULT_DISPLAY, + deskId = sourceDeskId, + taskId = task.taskId, + isVisible = true, + ) + controller.moveToNextDisplay(task.taskId) + + verify(taskbarDesktopTaskListener).onTaskbarCornerRoundingUpdate(anyBoolean()) + } + + @Test fun getTaskWindowingMode() { val fullscreenTask = setUpFullscreenTask() val freeformTask = setUpFreeformTask() @@ -6786,6 +6882,12 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() return arg.lastValue } + private fun getLatestTransition(): WindowContainerTransaction { + val arg = argumentCaptor<WindowContainerTransaction>() + verify(transitions).startTransition(any(), arg.capture(), anyOrNull()) + return arg.lastValue + } + private fun getLatestEnterDesktopWct(): WindowContainerTransaction { val arg = argumentCaptor<WindowContainerTransaction>() verify(enterDesktopTransitionHandler).moveToDesktop(arg.capture(), any()) |