[24/N] Desks: Fix deactivation when more than one task is open
When the user is explicitly exiting desktop, such as when usign the
to-fullscreen or to-split buttons, willExitDesktop should always return
true regardless of whether the task moving is the last one or not,
otherwise the exit "cleanup", which includes deactivation, won't be
added to the WCT and will leave the desktop in a bad state.
For multi-desks specifically, this meant that moving to fullscreen when
you only have 1 task did deactivate the desk, but doing so when you had
2 tasks open did not.
Flag: com.android.window.flags.enable_multiple_desktops_backend
Bug: 394268248
Test: enter desktop, have at least two tasks open in the desktop, then
move one to fullscreen and verify new task launches open in fullscreen
and the repository dump shows the source desk as deactivated.
Change-Id: I71e6cd5dd60b7b2c1aa5081ba8b17f4c1b9864f5
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 45397b0..bfad0b3 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
@@ -810,7 +810,7 @@
willExitDesktop(
triggerTaskId = taskInfo.taskId,
displayId = displayId,
- forceToFullscreen = false,
+ forceExitDesktop = false,
)
taskRepository.setPipShouldKeepDesktopActive(displayId, keepActive = true)
val desktopExitRunnable =
@@ -883,7 +883,7 @@
snapEventHandler.removeTaskIfTiled(displayId, taskId)
taskRepository.setPipShouldKeepDesktopActive(displayId, keepActive = true)
- val willExitDesktop = willExitDesktop(taskId, displayId, forceToFullscreen = false)
+ val willExitDesktop = willExitDesktop(taskId, displayId, forceExitDesktop = false)
val desktopExitRunnable =
performDesktopExitCleanUp(
wct = wct,
@@ -976,7 +976,7 @@
) {
logV("moveToFullscreenWithAnimation taskId=%d", task.taskId)
val wct = WindowContainerTransaction()
- val willExitDesktop = willExitDesktop(task.taskId, task.displayId, forceToFullscreen = true)
+ val willExitDesktop = willExitDesktop(task.taskId, task.displayId, forceExitDesktop = true)
val deactivationRunnable = addMoveToFullscreenChanges(wct, task, willExitDesktop)
// We are moving a freeform task to fullscreen, put the home task under the fullscreen task.
@@ -995,7 +995,14 @@
deactivationRunnable?.invoke(transition)
// handles case where we are moving to full screen without closing all DW tasks.
- if (!taskRepository.isOnlyVisibleNonClosingTask(task.taskId)) {
+ if (
+ !taskRepository.isOnlyVisibleNonClosingTask(task.taskId)
+ // This callback is already invoked by |addMoveToFullscreenChanges| when one of these
+ // flags is enabled.
+ &&
+ !DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue &&
+ !Flags.enableDesktopWindowingPip()
+ ) {
desktopModeEnterExitTransitionListener?.onExitDesktopModeTransitionStarted(
FULLSCREEN_ANIMATION_DURATION
)
@@ -1892,16 +1899,24 @@
private fun willExitDesktop(
triggerTaskId: Int,
displayId: Int,
- forceToFullscreen: Boolean,
+ forceExitDesktop: Boolean,
): Boolean {
+ if (
+ forceExitDesktop &&
+ (Flags.enableDesktopWindowingPip() ||
+ DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue)
+ ) {
+ // |forceExitDesktop| is true when the callers knows we'll exit desktop, such as when
+ // explicitly going fullscreen, so there's no point in checking the desktop state.
+ return true
+ }
if (Flags.enablePerDisplayDesktopWallpaperActivity()) {
if (!taskRepository.isOnlyVisibleNonClosingTask(triggerTaskId, displayId)) {
return false
}
} else if (
Flags.enableDesktopWindowingPip() &&
- taskRepository.isMinimizedPipPresentInDisplay(displayId) &&
- !forceToFullscreen
+ taskRepository.isMinimizedPipPresentInDisplay(displayId)
) {
return false
} else {
@@ -2294,7 +2309,7 @@
willExitDesktop(
triggerTaskId = task.taskId,
displayId = task.displayId,
- forceToFullscreen = true,
+ forceExitDesktop = true,
),
)
wct.reorder(task.token, true)
@@ -2327,7 +2342,7 @@
willExitDesktop(
triggerTaskId = task.taskId,
displayId = task.displayId,
- forceToFullscreen = true,
+ forceExitDesktop = true,
),
)
return wct
@@ -2432,7 +2447,7 @@
willExitDesktop(
triggerTaskId = task.taskId,
displayId = task.displayId,
- forceToFullscreen = true,
+ forceExitDesktop = true,
),
)
}
@@ -2470,7 +2485,7 @@
willExitDesktop(
triggerTaskId = task.taskId,
displayId = task.displayId,
- forceToFullscreen = true,
+ forceExitDesktop = true,
),
)
}
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 ac1deec..253740c 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
@@ -2069,6 +2069,21 @@
}
@Test
+ @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ fun moveToFullscreen_fromDeskWithMultipleTasks_deactivatesDesk() {
+ val deskId = 1
+ taskRepository.addDesk(displayId = DEFAULT_DISPLAY, deskId = deskId)
+ taskRepository.setActiveDesk(displayId = DEFAULT_DISPLAY, deskId = deskId)
+ val task1 = setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = deskId)
+ val task2 = setUpFreeformTask(displayId = DEFAULT_DISPLAY, deskId = deskId)
+
+ controller.moveToFullscreen(task1.taskId, transitionSource = UNKNOWN)
+
+ val wct = getLatestExitDesktopWct()
+ verify(desksOrganizer).deactivateDesk(wct, deskId = deskId)
+ }
+
+ @Test
fun moveToFullscreen_tdaFullscreen_windowingModeSetToUndefined() {
val task = setUpFreeformTask()
val tda = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)!!
@@ -2278,7 +2293,10 @@
}
@Test
- @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ @DisableFlags(
+ Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP,
+ )
fun moveToFullscreen_multipleVisibleNonMinimizedTasks_doesNotRemoveWallpaperActivity() {
val homeTask = setUpHomeTask()
val task1 = setUpFreeformTask()
@@ -2305,29 +2323,6 @@
}
@Test
- @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
- fun moveToFullscreen_multipleVisibleNonMinimizedTasks_doesNotRemoveWallpaperActivity_multiDesksEnabled() {
- val homeTask = setUpHomeTask()
- val task1 = setUpFreeformTask()
- // Setup task2
- setUpFreeformTask()
-
- val tdaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)
- assertNotNull(tdaInfo).configuration.windowConfiguration.windowingMode =
- WINDOWING_MODE_FULLSCREEN
-
- controller.moveToFullscreen(task1.taskId, transitionSource = UNKNOWN)
-
- val wct = getLatestExitDesktopWct()
- val task1Change = assertNotNull(wct.changes[task1.token.asBinder()])
- assertThat(task1Change.windowingMode).isEqualTo(WINDOWING_MODE_UNDEFINED)
- verify(desktopModeEnterExitTransitionListener)
- .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION)
- // Does not remove wallpaper activity, as desktop still has a visible desktop task
- wct.assertWithoutHop(ReorderPredicate(wallpaperToken, toTop = false))
- }
-
- @Test
fun moveToFullscreen_nonExistentTask_doesNothing() {
controller.moveToFullscreen(999, transitionSource = UNKNOWN)
verifyExitDesktopWCTNotExecuted()
@@ -4455,7 +4450,10 @@
}
@Test
- @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+ @DisableFlags(
+ Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP,
+ )
fun moveFocusedTaskToFullscreen_multipleVisibleTasks_doesNotRemoveWallpaperActivity() {
val homeTask = setUpHomeTask()
val task1 = setUpFreeformTask()
@@ -4480,27 +4478,6 @@
@Test
@EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
- fun moveFocusedTaskToFullscreen_multipleVisibleTasks_doesNotRemoveWallpaperActivity_multiDesksEnabled() {
- val homeTask = setUpHomeTask()
- val task1 = setUpFreeformTask()
- val task2 = setUpFreeformTask()
- val task3 = setUpFreeformTask()
-
- task1.isFocused = false
- task2.isFocused = true
- task3.isFocused = false
- controller.enterFullscreen(DEFAULT_DISPLAY, transitionSource = UNKNOWN)
-
- val wct = getLatestExitDesktopWct()
- val taskChange = assertNotNull(wct.changes[task2.token.asBinder()])
- assertThat(taskChange.windowingMode)
- .isEqualTo(WINDOWING_MODE_UNDEFINED) // inherited FULLSCREEN
- // Does not remove wallpaper activity
- wct.assertWithoutHop(ReorderPredicate(wallpaperToken, toTop = null))
- }
-
- @Test
- @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
fun moveFocusedTaskToFullscreen_multipleVisibleTasks_fullscreenOverHome_multiDesksEnabled() {
val homeTask = setUpHomeTask()
val task1 = setUpFreeformTask()
@@ -5225,6 +5202,10 @@
}
@Test
+ @DisableFlags(
+ Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+ Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP,
+ )
fun enterSplit_multipleVisibleNonMinimizedTasks_removesWallpaperActivity() {
val task1 = setUpFreeformTask()
val task2 = setUpFreeformTask()