Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopFullImmersiveTransitionHandler.kt +6 −1 Original line number Diff line number Diff line Loading @@ -137,14 +137,19 @@ class DesktopFullImmersiveTransitionHandler( * * @param wct that will apply these changes * @param displayId of the display that should exit immersive mode * @param excludeTaskId of the task to ignore (not exit) if it is the immersive one * @return a function to apply once the transition that will apply these changes is started */ fun exitImmersiveIfApplicable( wct: WindowContainerTransaction, displayId: Int displayId: Int, excludeTaskId: Int? = null, ): ((IBinder) -> Unit)? { if (!Flags.enableFullyImmersiveInDesktop()) return null val immersiveTask = desktopRepository.getTaskInFullImmersiveState(displayId) ?: return null if (immersiveTask == excludeTaskId) { return null } val taskInfo = shellTaskOrganizer.getRunningTaskInfo(immersiveTask) ?: return null logV("Appending immersive exit for task: $immersiveTask in display: $displayId") wct.setBounds(taskInfo.token, getExitDestinationBounds(taskInfo)) Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +24 −8 Original line number Diff line number Diff line Loading @@ -372,8 +372,11 @@ class DesktopTasksController( // TODO(342378842): Instead of using default display, support multiple displays val taskToMinimize = bringDesktopAppsToFrontBeforeShowingNewTask( DEFAULT_DISPLAY, wct, taskId) val runOnTransit = immersiveTransitionHandler .exitImmersiveIfApplicable(wct, DEFAULT_DISPLAY) val runOnTransit = immersiveTransitionHandler.exitImmersiveIfApplicable( wct = wct, displayId = DEFAULT_DISPLAY, excludeTaskId = taskId, ) wct.startTask( taskId, ActivityOptions.makeBasic().apply { Loading @@ -400,7 +403,11 @@ class DesktopTasksController( } logV("moveRunningTaskToDesktop taskId=%d", task.taskId) exitSplitIfApplicable(wct, task) val runOnTransit = immersiveTransitionHandler.exitImmersiveIfApplicable(wct, task.displayId) val runOnTransit = immersiveTransitionHandler.exitImmersiveIfApplicable( wct = wct, displayId = task.displayId, excludeTaskId = task.taskId, ) // Bring other apps to front first val taskToMinimize = bringDesktopAppsToFrontBeforeShowingNewTask(task.displayId, wct, task.taskId) Loading Loading @@ -609,8 +616,11 @@ class DesktopTasksController( logV("moveBackgroundTaskToFront taskId=%s", taskId) val wct = WindowContainerTransaction() // TODO: b/342378842 - Instead of using default display, support multiple displays val runOnTransit = immersiveTransitionHandler .exitImmersiveIfApplicable(wct, DEFAULT_DISPLAY) val runOnTransit = immersiveTransitionHandler.exitImmersiveIfApplicable( wct = wct, displayId = DEFAULT_DISPLAY, excludeTaskId = taskId, ) wct.startTask( taskId, ActivityOptions.makeBasic().apply { Loading @@ -633,7 +643,10 @@ class DesktopTasksController( val wct = WindowContainerTransaction() wct.reorder(taskInfo.token, true /* onTop */, true /* includingParents */) val runOnTransit = immersiveTransitionHandler.exitImmersiveIfApplicable( wct, taskInfo.displayId) wct = wct, displayId = taskInfo.displayId, excludeTaskId = taskInfo.taskId, ) val transition = startLaunchTransition(TRANSIT_TO_FRONT, wct, taskInfo.taskId, remoteTransition) runOnTransit?.invoke(transition) Loading Loading @@ -1266,8 +1279,11 @@ class DesktopTasksController( wct.startTask(requestedTaskId, options.toBundle()) val taskToMinimize = bringDesktopAppsToFrontBeforeShowingNewTask( callingTask.displayId, wct, requestedTaskId) val runOnTransit = immersiveTransitionHandler .exitImmersiveIfApplicable(wct, callingTask.displayId) val runOnTransit = immersiveTransitionHandler.exitImmersiveIfApplicable( wct = wct, displayId = callingTask.displayId, excludeTaskId = requestedTaskId, ) val transition = transitions.startTransition(TRANSIT_OPEN, wct, null) addPendingMinimizeTransition(transition, taskToMinimize) runOnTransit?.invoke(transition) Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopFullImmersiveTransitionHandlerTest.kt +25 −0 Original line number Diff line number Diff line Loading @@ -338,6 +338,31 @@ class DesktopFullImmersiveTransitionHandlerTest : ShellTestCase() { assertThat(wct.hasBoundsChange(task.token)).isFalse() } @Test @EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP) fun exitImmersiveIfApplicable_byDisplay_withExcludeTask_doesNotExit() { val task = createFreeformTask() whenever(mockShellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task) val wct = WindowContainerTransaction() val transition = Binder() desktopRepository.setTaskInFullImmersiveState( displayId = DEFAULT_DISPLAY, taskId = task.taskId, immersive = true ) immersiveHandler.exitImmersiveIfApplicable( wct = wct, displayId = DEFAULT_DISPLAY, excludeTaskId = task.taskId )?.invoke(transition) assertThat(immersiveHandler.pendingExternalExitTransitions.any { exit -> exit.transition == transition && exit.displayId == DEFAULT_DISPLAY && exit.taskId == task.taskId }).isFalse() } @Test @EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP) fun exitImmersiveIfApplicable_byTask_inImmersive_changesTaskBounds() { Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +15 −10 Original line number Diff line number Diff line Loading @@ -3093,12 +3093,13 @@ class DesktopTasksControllerTest : ShellTestCase() { whenever(transitions.startTransition(eq(TRANSIT_OPEN), any(), anyOrNull())) .thenReturn(transition) whenever(mockDesktopFullImmersiveTransitionHandler .exitImmersiveIfApplicable(any(), eq(immersiveTask.displayId))).thenReturn(runOnStartTransit) .exitImmersiveIfApplicable(any(), eq(immersiveTask.displayId), eq(freeformTask.taskId))) .thenReturn(runOnStartTransit) runOpenInstance(immersiveTask, freeformTask.taskId) verify(mockDesktopFullImmersiveTransitionHandler) .exitImmersiveIfApplicable(any(), eq(immersiveTask.displayId)) .exitImmersiveIfApplicable(any(), eq(immersiveTask.displayId), eq(freeformTask.taskId)) runOnStartTransit.assertOnlyInvocation(transition) } Loading Loading @@ -3489,12 +3490,13 @@ class DesktopTasksControllerTest : ShellTestCase() { val runOnStartTransit = RunOnStartTransitionCallback() val transition = Binder() whenever(mockDesktopFullImmersiveTransitionHandler .exitImmersiveIfApplicable(wct, task.displayId)).thenReturn(runOnStartTransit) .exitImmersiveIfApplicable(wct, task.displayId, task.taskId)).thenReturn(runOnStartTransit) whenever(enterDesktopTransitionHandler.moveToDesktop(wct, UNKNOWN)).thenReturn(transition) controller.moveTaskToDesktop(taskId = task.taskId, wct = wct, transitionSource = UNKNOWN) verify(mockDesktopFullImmersiveTransitionHandler).exitImmersiveIfApplicable(wct, task.displayId) verify(mockDesktopFullImmersiveTransitionHandler) .exitImmersiveIfApplicable(wct, task.displayId, task.taskId) runOnStartTransit.assertOnlyInvocation(transition) } Loading @@ -3505,12 +3507,13 @@ class DesktopTasksControllerTest : ShellTestCase() { val runOnStartTransit = RunOnStartTransitionCallback() val transition = Binder() whenever(mockDesktopFullImmersiveTransitionHandler .exitImmersiveIfApplicable(wct, task.displayId)).thenReturn(runOnStartTransit) .exitImmersiveIfApplicable(wct, task.displayId, task.taskId)).thenReturn(runOnStartTransit) whenever(enterDesktopTransitionHandler.moveToDesktop(wct, UNKNOWN)).thenReturn(transition) controller.moveTaskToDesktop(taskId = task.taskId, wct = wct, transitionSource = UNKNOWN) verify(mockDesktopFullImmersiveTransitionHandler).exitImmersiveIfApplicable(wct, task.displayId) verify(mockDesktopFullImmersiveTransitionHandler) .exitImmersiveIfApplicable(wct, task.displayId, task.taskId) runOnStartTransit.assertOnlyInvocation(transition) } Loading @@ -3520,13 +3523,14 @@ class DesktopTasksControllerTest : ShellTestCase() { val runOnStartTransit = RunOnStartTransitionCallback() val transition = Binder() whenever(mockDesktopFullImmersiveTransitionHandler .exitImmersiveIfApplicable(any(), eq(task.displayId))).thenReturn(runOnStartTransit) .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId))) .thenReturn(runOnStartTransit) whenever(transitions.startTransition(any(), any(), anyOrNull())).thenReturn(transition) controller.moveTaskToFront(task.taskId, remoteTransition = null) verify(mockDesktopFullImmersiveTransitionHandler) .exitImmersiveIfApplicable(any(), eq(task.displayId)) .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId)) runOnStartTransit.assertOnlyInvocation(transition) } Loading @@ -3536,13 +3540,14 @@ class DesktopTasksControllerTest : ShellTestCase() { val runOnStartTransit = RunOnStartTransitionCallback() val transition = Binder() whenever(mockDesktopFullImmersiveTransitionHandler .exitImmersiveIfApplicable(any(), eq(task.displayId))).thenReturn(runOnStartTransit) .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId))) .thenReturn(runOnStartTransit) whenever(transitions.startTransition(any(), any(), anyOrNull())).thenReturn(transition) controller.moveTaskToFront(task.taskId, remoteTransition = null) verify(mockDesktopFullImmersiveTransitionHandler) .exitImmersiveIfApplicable(any(), eq(task.displayId)) .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId)) runOnStartTransit.assertOnlyInvocation(transition) } Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopFullImmersiveTransitionHandler.kt +6 −1 Original line number Diff line number Diff line Loading @@ -137,14 +137,19 @@ class DesktopFullImmersiveTransitionHandler( * * @param wct that will apply these changes * @param displayId of the display that should exit immersive mode * @param excludeTaskId of the task to ignore (not exit) if it is the immersive one * @return a function to apply once the transition that will apply these changes is started */ fun exitImmersiveIfApplicable( wct: WindowContainerTransaction, displayId: Int displayId: Int, excludeTaskId: Int? = null, ): ((IBinder) -> Unit)? { if (!Flags.enableFullyImmersiveInDesktop()) return null val immersiveTask = desktopRepository.getTaskInFullImmersiveState(displayId) ?: return null if (immersiveTask == excludeTaskId) { return null } val taskInfo = shellTaskOrganizer.getRunningTaskInfo(immersiveTask) ?: return null logV("Appending immersive exit for task: $immersiveTask in display: $displayId") wct.setBounds(taskInfo.token, getExitDestinationBounds(taskInfo)) Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +24 −8 Original line number Diff line number Diff line Loading @@ -372,8 +372,11 @@ class DesktopTasksController( // TODO(342378842): Instead of using default display, support multiple displays val taskToMinimize = bringDesktopAppsToFrontBeforeShowingNewTask( DEFAULT_DISPLAY, wct, taskId) val runOnTransit = immersiveTransitionHandler .exitImmersiveIfApplicable(wct, DEFAULT_DISPLAY) val runOnTransit = immersiveTransitionHandler.exitImmersiveIfApplicable( wct = wct, displayId = DEFAULT_DISPLAY, excludeTaskId = taskId, ) wct.startTask( taskId, ActivityOptions.makeBasic().apply { Loading @@ -400,7 +403,11 @@ class DesktopTasksController( } logV("moveRunningTaskToDesktop taskId=%d", task.taskId) exitSplitIfApplicable(wct, task) val runOnTransit = immersiveTransitionHandler.exitImmersiveIfApplicable(wct, task.displayId) val runOnTransit = immersiveTransitionHandler.exitImmersiveIfApplicable( wct = wct, displayId = task.displayId, excludeTaskId = task.taskId, ) // Bring other apps to front first val taskToMinimize = bringDesktopAppsToFrontBeforeShowingNewTask(task.displayId, wct, task.taskId) Loading Loading @@ -609,8 +616,11 @@ class DesktopTasksController( logV("moveBackgroundTaskToFront taskId=%s", taskId) val wct = WindowContainerTransaction() // TODO: b/342378842 - Instead of using default display, support multiple displays val runOnTransit = immersiveTransitionHandler .exitImmersiveIfApplicable(wct, DEFAULT_DISPLAY) val runOnTransit = immersiveTransitionHandler.exitImmersiveIfApplicable( wct = wct, displayId = DEFAULT_DISPLAY, excludeTaskId = taskId, ) wct.startTask( taskId, ActivityOptions.makeBasic().apply { Loading @@ -633,7 +643,10 @@ class DesktopTasksController( val wct = WindowContainerTransaction() wct.reorder(taskInfo.token, true /* onTop */, true /* includingParents */) val runOnTransit = immersiveTransitionHandler.exitImmersiveIfApplicable( wct, taskInfo.displayId) wct = wct, displayId = taskInfo.displayId, excludeTaskId = taskInfo.taskId, ) val transition = startLaunchTransition(TRANSIT_TO_FRONT, wct, taskInfo.taskId, remoteTransition) runOnTransit?.invoke(transition) Loading Loading @@ -1266,8 +1279,11 @@ class DesktopTasksController( wct.startTask(requestedTaskId, options.toBundle()) val taskToMinimize = bringDesktopAppsToFrontBeforeShowingNewTask( callingTask.displayId, wct, requestedTaskId) val runOnTransit = immersiveTransitionHandler .exitImmersiveIfApplicable(wct, callingTask.displayId) val runOnTransit = immersiveTransitionHandler.exitImmersiveIfApplicable( wct = wct, displayId = callingTask.displayId, excludeTaskId = requestedTaskId, ) val transition = transitions.startTransition(TRANSIT_OPEN, wct, null) addPendingMinimizeTransition(transition, taskToMinimize) runOnTransit?.invoke(transition) Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopFullImmersiveTransitionHandlerTest.kt +25 −0 Original line number Diff line number Diff line Loading @@ -338,6 +338,31 @@ class DesktopFullImmersiveTransitionHandlerTest : ShellTestCase() { assertThat(wct.hasBoundsChange(task.token)).isFalse() } @Test @EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP) fun exitImmersiveIfApplicable_byDisplay_withExcludeTask_doesNotExit() { val task = createFreeformTask() whenever(mockShellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task) val wct = WindowContainerTransaction() val transition = Binder() desktopRepository.setTaskInFullImmersiveState( displayId = DEFAULT_DISPLAY, taskId = task.taskId, immersive = true ) immersiveHandler.exitImmersiveIfApplicable( wct = wct, displayId = DEFAULT_DISPLAY, excludeTaskId = task.taskId )?.invoke(transition) assertThat(immersiveHandler.pendingExternalExitTransitions.any { exit -> exit.transition == transition && exit.displayId == DEFAULT_DISPLAY && exit.taskId == task.taskId }).isFalse() } @Test @EnableFlags(Flags.FLAG_ENABLE_FULLY_IMMERSIVE_IN_DESKTOP) fun exitImmersiveIfApplicable_byTask_inImmersive_changesTaskBounds() { Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +15 −10 Original line number Diff line number Diff line Loading @@ -3093,12 +3093,13 @@ class DesktopTasksControllerTest : ShellTestCase() { whenever(transitions.startTransition(eq(TRANSIT_OPEN), any(), anyOrNull())) .thenReturn(transition) whenever(mockDesktopFullImmersiveTransitionHandler .exitImmersiveIfApplicable(any(), eq(immersiveTask.displayId))).thenReturn(runOnStartTransit) .exitImmersiveIfApplicable(any(), eq(immersiveTask.displayId), eq(freeformTask.taskId))) .thenReturn(runOnStartTransit) runOpenInstance(immersiveTask, freeformTask.taskId) verify(mockDesktopFullImmersiveTransitionHandler) .exitImmersiveIfApplicable(any(), eq(immersiveTask.displayId)) .exitImmersiveIfApplicable(any(), eq(immersiveTask.displayId), eq(freeformTask.taskId)) runOnStartTransit.assertOnlyInvocation(transition) } Loading Loading @@ -3489,12 +3490,13 @@ class DesktopTasksControllerTest : ShellTestCase() { val runOnStartTransit = RunOnStartTransitionCallback() val transition = Binder() whenever(mockDesktopFullImmersiveTransitionHandler .exitImmersiveIfApplicable(wct, task.displayId)).thenReturn(runOnStartTransit) .exitImmersiveIfApplicable(wct, task.displayId, task.taskId)).thenReturn(runOnStartTransit) whenever(enterDesktopTransitionHandler.moveToDesktop(wct, UNKNOWN)).thenReturn(transition) controller.moveTaskToDesktop(taskId = task.taskId, wct = wct, transitionSource = UNKNOWN) verify(mockDesktopFullImmersiveTransitionHandler).exitImmersiveIfApplicable(wct, task.displayId) verify(mockDesktopFullImmersiveTransitionHandler) .exitImmersiveIfApplicable(wct, task.displayId, task.taskId) runOnStartTransit.assertOnlyInvocation(transition) } Loading @@ -3505,12 +3507,13 @@ class DesktopTasksControllerTest : ShellTestCase() { val runOnStartTransit = RunOnStartTransitionCallback() val transition = Binder() whenever(mockDesktopFullImmersiveTransitionHandler .exitImmersiveIfApplicable(wct, task.displayId)).thenReturn(runOnStartTransit) .exitImmersiveIfApplicable(wct, task.displayId, task.taskId)).thenReturn(runOnStartTransit) whenever(enterDesktopTransitionHandler.moveToDesktop(wct, UNKNOWN)).thenReturn(transition) controller.moveTaskToDesktop(taskId = task.taskId, wct = wct, transitionSource = UNKNOWN) verify(mockDesktopFullImmersiveTransitionHandler).exitImmersiveIfApplicable(wct, task.displayId) verify(mockDesktopFullImmersiveTransitionHandler) .exitImmersiveIfApplicable(wct, task.displayId, task.taskId) runOnStartTransit.assertOnlyInvocation(transition) } Loading @@ -3520,13 +3523,14 @@ class DesktopTasksControllerTest : ShellTestCase() { val runOnStartTransit = RunOnStartTransitionCallback() val transition = Binder() whenever(mockDesktopFullImmersiveTransitionHandler .exitImmersiveIfApplicable(any(), eq(task.displayId))).thenReturn(runOnStartTransit) .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId))) .thenReturn(runOnStartTransit) whenever(transitions.startTransition(any(), any(), anyOrNull())).thenReturn(transition) controller.moveTaskToFront(task.taskId, remoteTransition = null) verify(mockDesktopFullImmersiveTransitionHandler) .exitImmersiveIfApplicable(any(), eq(task.displayId)) .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId)) runOnStartTransit.assertOnlyInvocation(transition) } Loading @@ -3536,13 +3540,14 @@ class DesktopTasksControllerTest : ShellTestCase() { val runOnStartTransit = RunOnStartTransitionCallback() val transition = Binder() whenever(mockDesktopFullImmersiveTransitionHandler .exitImmersiveIfApplicable(any(), eq(task.displayId))).thenReturn(runOnStartTransit) .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId))) .thenReturn(runOnStartTransit) whenever(transitions.startTransition(any(), any(), anyOrNull())).thenReturn(transition) controller.moveTaskToFront(task.taskId, remoteTransition = null) verify(mockDesktopFullImmersiveTransitionHandler) .exitImmersiveIfApplicable(any(), eq(task.displayId)) .exitImmersiveIfApplicable(any(), eq(task.displayId), eq(task.taskId)) runOnStartTransit.assertOnlyInvocation(transition) } Loading