Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt +1 −1 Original line number Diff line number Diff line Loading @@ -821,7 +821,7 @@ class DesktopRepository( /** Removes the given task from the given desk. */ fun removeTaskFromDesk(deskId: Int, taskId: Int) { logD("removeTaskFromDesk: deskId=%d, taskId=%d", taskId, deskId) logD("removeTaskFromDesk: deskId=%d, taskId=%d", deskId, taskId) // TODO: b/362720497 - consider not clearing bounds on any removal, such as when moving // it between desks. It might be better to allow restoring to the previous bounds as long // as they're valid (probably valid if in the same display). Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +102 −38 Original line number Diff line number Diff line Loading @@ -153,6 +153,16 @@ import java.util.concurrent.TimeUnit import java.util.function.Consumer import kotlin.jvm.optionals.getOrNull /** * A callback to be invoked when a transition is started via |Transitions.startTransition| with the * transition binder token that it produces. * * Useful when multiple components are appending WCT operations to a single transition that is * started outside of their control, and each of them wants to track the transition lifecycle * independently by cross-referencing the transition token with future ready-transitions. */ typealias RunOnTransitStart = (IBinder) -> Unit /** Handles moving tasks in and out of desktop */ class DesktopTasksController( private val context: Context, Loading Loading @@ -481,7 +491,7 @@ class DesktopTasksController( ): Boolean { val runningTask = shellTaskOrganizer.getRunningTaskInfo(taskId) if (runningTask != null) { moveRunningTaskToDesk( return moveRunningTaskToDesk( task = runningTask, deskId = deskId, wct = wct, Loading Loading @@ -563,10 +573,10 @@ class DesktopTasksController( transitionSource: DesktopModeTransitionSource, remoteTransition: RemoteTransition? = null, callback: IMoveToDesktopCallback? = null, ) { ): Boolean { if (desktopModeCompatPolicy.isTopActivityExemptFromDesktopWindowing(task)) { logW("Cannot enter desktop for taskId %d, ineligible top activity found", task.taskId) return return false } val displayId = taskRepository.getDisplayForDesk(deskId) logV( Loading Loading @@ -621,6 +631,7 @@ class DesktopTasksController( } else { taskRepository.setActiveDesk(displayId = displayId, deskId = deskId) } return true } /** Loading Loading @@ -789,17 +800,33 @@ class DesktopTasksController( wct: WindowContainerTransaction, displayId: Int, taskInfo: RunningTaskInfo, ): ((IBinder) -> Unit)? { ): ((IBinder) -> Unit) { val taskId = taskInfo.taskId val deskId = taskRepository.getDeskIdForTask(taskInfo.taskId) snapEventHandler.removeTaskIfTiled(displayId, taskId) // TODO: b/394268248 - desk needs to be deactivated when closing the last task and going // home. performDesktopExitCleanupIfNeeded(taskId, displayId, wct, forceToFullscreen = false) val shouldExitDesktop = willExitDesktop( triggerTaskId = taskInfo.taskId, displayId = displayId, forceToFullscreen = false, ) taskRepository.setPipShouldKeepDesktopActive(displayId, keepActive = true) val desktopExitRunnable = performDesktopExitCleanUp( wct = wct, deskId = deskId, displayId = displayId, willExitDesktop = shouldExitDesktop, shouldEndUpAtHome = true, ) taskRepository.addClosingTask(displayId, taskId) taskbarDesktopTaskListener?.onTaskbarCornerRoundingUpdate( doesAnyTaskRequireTaskbarRounding(displayId, taskId) ) return desktopImmersiveController val immersiveRunnable = desktopImmersiveController .exitImmersiveIfApplicable( wct = wct, taskInfo = taskInfo, Loading @@ -807,6 +834,10 @@ class DesktopTasksController( ) .asExit() ?.runOnTransitionStart return { transitionToken -> immersiveRunnable?.invoke(transitionToken) desktopExitRunnable?.invoke(transitionToken) } } fun minimizeTask(taskInfo: RunningTaskInfo, minimizeReason: MinimizeReason) { Loading Loading @@ -840,12 +871,20 @@ class DesktopTasksController( private fun minimizeTaskInner(taskInfo: RunningTaskInfo, minimizeReason: MinimizeReason) { val taskId = taskInfo.taskId val deskId = taskRepository.getDeskIdForTask(taskInfo.taskId) val displayId = taskInfo.displayId val wct = WindowContainerTransaction() snapEventHandler.removeTaskIfTiled(displayId, taskId) // TODO: b/394268248 - desk needs to be deactivated when minimizing the last task and going // home. performDesktopExitCleanupIfNeeded(taskId, displayId, wct, forceToFullscreen = false) taskRepository.setPipShouldKeepDesktopActive(displayId, keepActive = true) val willExitDesktop = willExitDesktop(taskId, displayId, forceToFullscreen = false) val desktopExitRunnable = performDesktopExitCleanUp( wct = wct, deskId = deskId, displayId = displayId, willExitDesktop = willExitDesktop, ) // Notify immersive handler as it might need to exit immersive state. val exitResult = desktopImmersiveController.exitImmersiveIfApplicable( Loading @@ -867,6 +906,7 @@ class DesktopTasksController( ) } exitResult.asExit()?.runOnTransitionStart?.invoke(transition) desktopExitRunnable?.invoke(transition) } /** Move a task with given `taskId` to fullscreen */ Loading Loading @@ -915,7 +955,7 @@ class DesktopTasksController( logV("moveToFullscreenWithAnimation taskId=%d", task.taskId) val wct = WindowContainerTransaction() val willExitDesktop = willExitDesktop(task.taskId, task.displayId, forceToFullscreen = true) val deactivatingDeskId = addMoveToFullscreenChanges(wct, task, willExitDesktop) val deactivationRunnable = addMoveToFullscreenChanges(wct, task, willExitDesktop) // We are moving a freeform task to fullscreen, put the home task under the fullscreen task. if (!forceEnterDesktop(task.displayId)) { Loading @@ -930,11 +970,7 @@ class DesktopTasksController( position, mOnAnimationFinishedCallback, ) if (deactivatingDeskId != null) { desksTransitionObserver.addPendingTransition( DeskTransition.DeactivateDesk(token = transition, deskId = deactivatingDeskId) ) } deactivationRunnable?.invoke(transition) // handles case where we are moving to full screen without closing all DW tasks. if (!taskRepository.isOnlyVisibleNonClosingTask(task.taskId)) { Loading Loading @@ -1770,19 +1806,30 @@ class DesktopTasksController( wct: WindowContainerTransaction, forceToFullscreen: Boolean, shouldEndUpAtHome: Boolean = true, ) { ): RunOnTransitStart? { taskRepository.setPipShouldKeepDesktopActive(displayId, keepActive = !forceToFullscreen) if (!willExitDesktop(taskId, displayId, forceToFullscreen)) { return return null } performDesktopExitCleanUp(wct, displayId, shouldEndUpAtHome) // TODO: b/394268248 - update remaining callers to pass in a |deskId| and apply the // |RunOnTransitStart| when the transition is started. return performDesktopExitCleanUp( wct = wct, deskId = null, displayId = displayId, willExitDesktop = true, shouldEndUpAtHome = shouldEndUpAtHome, ) } private fun performDesktopExitCleanUp( wct: WindowContainerTransaction, deskId: Int?, displayId: Int, willExitDesktop: Boolean, shouldEndUpAtHome: Boolean = true, ) { ): RunOnTransitStart? { if (!willExitDesktop) return null desktopModeEnterExitTransitionListener?.onExitDesktopModeTransitionStarted( FULLSCREEN_ANIMATION_DURATION ) Loading @@ -1792,6 +1839,7 @@ class DesktopTasksController( // intent. addLaunchHomePendingIntent(wct, displayId) } return prepareDeskDeactivationIfNeeded(wct, deskId) } fun releaseVisualIndicator() { Loading Loading @@ -2473,7 +2521,7 @@ class DesktopTasksController( wct: WindowContainerTransaction, taskInfo: RunningTaskInfo, willExitDesktop: Boolean, ): Int? { ): RunOnTransitStart? { val tdaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(taskInfo.displayId)!! val tdaWindowingMode = tdaInfo.configuration.windowConfiguration.windowingMode val targetWindowingMode = Loading @@ -2492,15 +2540,14 @@ class DesktopTasksController( wct.reparent(taskInfo.token, tdaInfo.token, /* onTop= */ true) } taskRepository.setPipShouldKeepDesktopActive(taskInfo.displayId, keepActive = false) if (willExitDesktop) { performDesktopExitCleanUp(wct, taskInfo.displayId, shouldEndUpAtHome = false) val deskId = taskRepository.getDeskIdForTask(taskInfo.taskId) if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue && deskId != null) { desksOrganizer.deactivateDesk(wct, deskId) return deskId } } return null return performDesktopExitCleanUp( wct = wct, deskId = deskId, displayId = taskInfo.displayId, willExitDesktop = willExitDesktop, shouldEndUpAtHome = false, ) } private fun cascadeWindow(bounds: Rect, displayLayout: DisplayLayout, displayId: Int) { Loading Loading @@ -2661,6 +2708,23 @@ class DesktopTasksController( ) } /** * TODO: b/393978539 - Deactivation should not happen in desktop-first devices when going home. */ private fun prepareDeskDeactivationIfNeeded( wct: WindowContainerTransaction, deskId: Int?, ): RunOnTransitStart? { if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) return null if (deskId == null) return null desksOrganizer.deactivateDesk(wct, deskId) return { transition -> desksTransitionObserver.addPendingTransition( DeskTransition.DeactivateDesk(token = transition, deskId = deskId) ) } } /** Removes the default desk in the given display. */ @Deprecated("Deprecated with multi-desks.", ReplaceWith("removeDesk()")) fun removeDefaultDeskInDisplay(displayId: Int) { Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksTransitionObserver.kt +10 −1 Original line number Diff line number Diff line Loading @@ -92,10 +92,11 @@ class DesksTransitionObserver( } } is DeskTransition.DeactivateDesk -> { var visibleDeactivation = false for (change in info.changes) { val isDeskChange = desksOrganizer.isDeskChange(change, deskTransition.deskId) if (isDeskChange) { desktopRepository.setDeskInactive(deskId = deskTransition.deskId) visibleDeactivation = true continue } val taskId = change.taskInfo?.taskId ?: continue Loading @@ -109,6 +110,14 @@ class DesksTransitionObserver( ) } } // Always deactivate even if there's no change that confirms the desk was // deactivated. Some interactions, such as the desk deactivating because it's // occluded by a fullscreen task result in a transition change, but others, such // as transitioning from an empty desk to home may not. if (!visibleDeactivation) { logD("Deactivating desk without transition change") } desktopRepository.setDeskInactive(deskId = deskTransition.deskId) } } } Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java +1 −1 Original line number Diff line number Diff line Loading @@ -984,7 +984,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, mDesktopTasksController.onDesktopWindowClose( wct, mDisplayId, decoration.mTaskInfo); final IBinder transition = mTaskOperations.closeTask(mTaskToken, wct); if (transition != null && runOnTransitionStart != null) { if (transition != null) { runOnTransitionStart.invoke(transition); } } Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +68 −0 Original line number Diff line number Diff line Loading @@ -2921,6 +2921,32 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() } } @Test @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) fun onDesktopWindowClose_lastWindow_deactivatesDesk() { val task = setUpFreeformTask() val wct = WindowContainerTransaction() controller.onDesktopWindowClose(wct, displayId = DEFAULT_DISPLAY, task) verify(desksOrganizer).deactivateDesk(wct, deskId = 0) } @Test @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) fun onDesktopWindowClose_lastWindow_addsPendingDeactivateTransition() { val task = setUpFreeformTask() val wct = WindowContainerTransaction() val transition = Binder() val runOnTransitStart = controller.onDesktopWindowClose(wct, displayId = DEFAULT_DISPLAY, task) runOnTransitStart(transition) verify(desksTransitionsObserver) .addPendingTransition(DeskTransition.DeactivateDesk(transition, deskId = 0)) } @Test fun onDesktopWindowMinimize_noActiveTask_doesntRemoveWallpaper() { val task = setUpFreeformTask(active = false) Loading @@ -2944,6 +2970,48 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() } } @Test @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) fun onDesktopWindowMinimize_lastWindow_deactivatesDesk() { val task = setUpFreeformTask() val transition = Binder() whenever( freeformTaskTransitionStarter.startMinimizedModeTransition( any(), anyInt(), anyBoolean(), ) ) .thenReturn(transition) controller.minimizeTask(task, MinimizeReason.MINIMIZE_BUTTON) val captor = argumentCaptor<WindowContainerTransaction>() verify(freeformTaskTransitionStarter) .startMinimizedModeTransition(captor.capture(), eq(task.taskId), eq(true)) verify(desksOrganizer).deactivateDesk(captor.firstValue, deskId = 0) } @Test @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) fun onDesktopWindowMinimize_lastWindow_addsPendingDeactivateTransition() { val task = setUpFreeformTask() val transition = Binder() whenever( freeformTaskTransitionStarter.startMinimizedModeTransition( any(), anyInt(), anyBoolean(), ) ) .thenReturn(transition) controller.minimizeTask(task, MinimizeReason.MINIMIZE_BUTTON) verify(desksTransitionsObserver) .addPendingTransition(DeskTransition.DeactivateDesk(token = transition, deskId = 0)) } @Test fun onPipTaskMinimize_autoEnterEnabled_startPipTransition() { val task = setUpPipTask(autoEnterEnabled = true) Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt +1 −1 Original line number Diff line number Diff line Loading @@ -821,7 +821,7 @@ class DesktopRepository( /** Removes the given task from the given desk. */ fun removeTaskFromDesk(deskId: Int, taskId: Int) { logD("removeTaskFromDesk: deskId=%d, taskId=%d", taskId, deskId) logD("removeTaskFromDesk: deskId=%d, taskId=%d", deskId, taskId) // TODO: b/362720497 - consider not clearing bounds on any removal, such as when moving // it between desks. It might be better to allow restoring to the previous bounds as long // as they're valid (probably valid if in the same display). Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +102 −38 Original line number Diff line number Diff line Loading @@ -153,6 +153,16 @@ import java.util.concurrent.TimeUnit import java.util.function.Consumer import kotlin.jvm.optionals.getOrNull /** * A callback to be invoked when a transition is started via |Transitions.startTransition| with the * transition binder token that it produces. * * Useful when multiple components are appending WCT operations to a single transition that is * started outside of their control, and each of them wants to track the transition lifecycle * independently by cross-referencing the transition token with future ready-transitions. */ typealias RunOnTransitStart = (IBinder) -> Unit /** Handles moving tasks in and out of desktop */ class DesktopTasksController( private val context: Context, Loading Loading @@ -481,7 +491,7 @@ class DesktopTasksController( ): Boolean { val runningTask = shellTaskOrganizer.getRunningTaskInfo(taskId) if (runningTask != null) { moveRunningTaskToDesk( return moveRunningTaskToDesk( task = runningTask, deskId = deskId, wct = wct, Loading Loading @@ -563,10 +573,10 @@ class DesktopTasksController( transitionSource: DesktopModeTransitionSource, remoteTransition: RemoteTransition? = null, callback: IMoveToDesktopCallback? = null, ) { ): Boolean { if (desktopModeCompatPolicy.isTopActivityExemptFromDesktopWindowing(task)) { logW("Cannot enter desktop for taskId %d, ineligible top activity found", task.taskId) return return false } val displayId = taskRepository.getDisplayForDesk(deskId) logV( Loading Loading @@ -621,6 +631,7 @@ class DesktopTasksController( } else { taskRepository.setActiveDesk(displayId = displayId, deskId = deskId) } return true } /** Loading Loading @@ -789,17 +800,33 @@ class DesktopTasksController( wct: WindowContainerTransaction, displayId: Int, taskInfo: RunningTaskInfo, ): ((IBinder) -> Unit)? { ): ((IBinder) -> Unit) { val taskId = taskInfo.taskId val deskId = taskRepository.getDeskIdForTask(taskInfo.taskId) snapEventHandler.removeTaskIfTiled(displayId, taskId) // TODO: b/394268248 - desk needs to be deactivated when closing the last task and going // home. performDesktopExitCleanupIfNeeded(taskId, displayId, wct, forceToFullscreen = false) val shouldExitDesktop = willExitDesktop( triggerTaskId = taskInfo.taskId, displayId = displayId, forceToFullscreen = false, ) taskRepository.setPipShouldKeepDesktopActive(displayId, keepActive = true) val desktopExitRunnable = performDesktopExitCleanUp( wct = wct, deskId = deskId, displayId = displayId, willExitDesktop = shouldExitDesktop, shouldEndUpAtHome = true, ) taskRepository.addClosingTask(displayId, taskId) taskbarDesktopTaskListener?.onTaskbarCornerRoundingUpdate( doesAnyTaskRequireTaskbarRounding(displayId, taskId) ) return desktopImmersiveController val immersiveRunnable = desktopImmersiveController .exitImmersiveIfApplicable( wct = wct, taskInfo = taskInfo, Loading @@ -807,6 +834,10 @@ class DesktopTasksController( ) .asExit() ?.runOnTransitionStart return { transitionToken -> immersiveRunnable?.invoke(transitionToken) desktopExitRunnable?.invoke(transitionToken) } } fun minimizeTask(taskInfo: RunningTaskInfo, minimizeReason: MinimizeReason) { Loading Loading @@ -840,12 +871,20 @@ class DesktopTasksController( private fun minimizeTaskInner(taskInfo: RunningTaskInfo, minimizeReason: MinimizeReason) { val taskId = taskInfo.taskId val deskId = taskRepository.getDeskIdForTask(taskInfo.taskId) val displayId = taskInfo.displayId val wct = WindowContainerTransaction() snapEventHandler.removeTaskIfTiled(displayId, taskId) // TODO: b/394268248 - desk needs to be deactivated when minimizing the last task and going // home. performDesktopExitCleanupIfNeeded(taskId, displayId, wct, forceToFullscreen = false) taskRepository.setPipShouldKeepDesktopActive(displayId, keepActive = true) val willExitDesktop = willExitDesktop(taskId, displayId, forceToFullscreen = false) val desktopExitRunnable = performDesktopExitCleanUp( wct = wct, deskId = deskId, displayId = displayId, willExitDesktop = willExitDesktop, ) // Notify immersive handler as it might need to exit immersive state. val exitResult = desktopImmersiveController.exitImmersiveIfApplicable( Loading @@ -867,6 +906,7 @@ class DesktopTasksController( ) } exitResult.asExit()?.runOnTransitionStart?.invoke(transition) desktopExitRunnable?.invoke(transition) } /** Move a task with given `taskId` to fullscreen */ Loading Loading @@ -915,7 +955,7 @@ class DesktopTasksController( logV("moveToFullscreenWithAnimation taskId=%d", task.taskId) val wct = WindowContainerTransaction() val willExitDesktop = willExitDesktop(task.taskId, task.displayId, forceToFullscreen = true) val deactivatingDeskId = addMoveToFullscreenChanges(wct, task, willExitDesktop) val deactivationRunnable = addMoveToFullscreenChanges(wct, task, willExitDesktop) // We are moving a freeform task to fullscreen, put the home task under the fullscreen task. if (!forceEnterDesktop(task.displayId)) { Loading @@ -930,11 +970,7 @@ class DesktopTasksController( position, mOnAnimationFinishedCallback, ) if (deactivatingDeskId != null) { desksTransitionObserver.addPendingTransition( DeskTransition.DeactivateDesk(token = transition, deskId = deactivatingDeskId) ) } deactivationRunnable?.invoke(transition) // handles case where we are moving to full screen without closing all DW tasks. if (!taskRepository.isOnlyVisibleNonClosingTask(task.taskId)) { Loading Loading @@ -1770,19 +1806,30 @@ class DesktopTasksController( wct: WindowContainerTransaction, forceToFullscreen: Boolean, shouldEndUpAtHome: Boolean = true, ) { ): RunOnTransitStart? { taskRepository.setPipShouldKeepDesktopActive(displayId, keepActive = !forceToFullscreen) if (!willExitDesktop(taskId, displayId, forceToFullscreen)) { return return null } performDesktopExitCleanUp(wct, displayId, shouldEndUpAtHome) // TODO: b/394268248 - update remaining callers to pass in a |deskId| and apply the // |RunOnTransitStart| when the transition is started. return performDesktopExitCleanUp( wct = wct, deskId = null, displayId = displayId, willExitDesktop = true, shouldEndUpAtHome = shouldEndUpAtHome, ) } private fun performDesktopExitCleanUp( wct: WindowContainerTransaction, deskId: Int?, displayId: Int, willExitDesktop: Boolean, shouldEndUpAtHome: Boolean = true, ) { ): RunOnTransitStart? { if (!willExitDesktop) return null desktopModeEnterExitTransitionListener?.onExitDesktopModeTransitionStarted( FULLSCREEN_ANIMATION_DURATION ) Loading @@ -1792,6 +1839,7 @@ class DesktopTasksController( // intent. addLaunchHomePendingIntent(wct, displayId) } return prepareDeskDeactivationIfNeeded(wct, deskId) } fun releaseVisualIndicator() { Loading Loading @@ -2473,7 +2521,7 @@ class DesktopTasksController( wct: WindowContainerTransaction, taskInfo: RunningTaskInfo, willExitDesktop: Boolean, ): Int? { ): RunOnTransitStart? { val tdaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(taskInfo.displayId)!! val tdaWindowingMode = tdaInfo.configuration.windowConfiguration.windowingMode val targetWindowingMode = Loading @@ -2492,15 +2540,14 @@ class DesktopTasksController( wct.reparent(taskInfo.token, tdaInfo.token, /* onTop= */ true) } taskRepository.setPipShouldKeepDesktopActive(taskInfo.displayId, keepActive = false) if (willExitDesktop) { performDesktopExitCleanUp(wct, taskInfo.displayId, shouldEndUpAtHome = false) val deskId = taskRepository.getDeskIdForTask(taskInfo.taskId) if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue && deskId != null) { desksOrganizer.deactivateDesk(wct, deskId) return deskId } } return null return performDesktopExitCleanUp( wct = wct, deskId = deskId, displayId = taskInfo.displayId, willExitDesktop = willExitDesktop, shouldEndUpAtHome = false, ) } private fun cascadeWindow(bounds: Rect, displayLayout: DisplayLayout, displayId: Int) { Loading Loading @@ -2661,6 +2708,23 @@ class DesktopTasksController( ) } /** * TODO: b/393978539 - Deactivation should not happen in desktop-first devices when going home. */ private fun prepareDeskDeactivationIfNeeded( wct: WindowContainerTransaction, deskId: Int?, ): RunOnTransitStart? { if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) return null if (deskId == null) return null desksOrganizer.deactivateDesk(wct, deskId) return { transition -> desksTransitionObserver.addPendingTransition( DeskTransition.DeactivateDesk(token = transition, deskId = deskId) ) } } /** Removes the default desk in the given display. */ @Deprecated("Deprecated with multi-desks.", ReplaceWith("removeDesk()")) fun removeDefaultDeskInDisplay(displayId: Int) { Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksTransitionObserver.kt +10 −1 Original line number Diff line number Diff line Loading @@ -92,10 +92,11 @@ class DesksTransitionObserver( } } is DeskTransition.DeactivateDesk -> { var visibleDeactivation = false for (change in info.changes) { val isDeskChange = desksOrganizer.isDeskChange(change, deskTransition.deskId) if (isDeskChange) { desktopRepository.setDeskInactive(deskId = deskTransition.deskId) visibleDeactivation = true continue } val taskId = change.taskInfo?.taskId ?: continue Loading @@ -109,6 +110,14 @@ class DesksTransitionObserver( ) } } // Always deactivate even if there's no change that confirms the desk was // deactivated. Some interactions, such as the desk deactivating because it's // occluded by a fullscreen task result in a transition change, but others, such // as transitioning from an empty desk to home may not. if (!visibleDeactivation) { logD("Deactivating desk without transition change") } desktopRepository.setDeskInactive(deskId = deskTransition.deskId) } } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java +1 −1 Original line number Diff line number Diff line Loading @@ -984,7 +984,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, mDesktopTasksController.onDesktopWindowClose( wct, mDisplayId, decoration.mTaskInfo); final IBinder transition = mTaskOperations.closeTask(mTaskToken, wct); if (transition != null && runOnTransitionStart != null) { if (transition != null) { runOnTransitionStart.invoke(transition); } } Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +68 −0 Original line number Diff line number Diff line Loading @@ -2921,6 +2921,32 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() } } @Test @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) fun onDesktopWindowClose_lastWindow_deactivatesDesk() { val task = setUpFreeformTask() val wct = WindowContainerTransaction() controller.onDesktopWindowClose(wct, displayId = DEFAULT_DISPLAY, task) verify(desksOrganizer).deactivateDesk(wct, deskId = 0) } @Test @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) fun onDesktopWindowClose_lastWindow_addsPendingDeactivateTransition() { val task = setUpFreeformTask() val wct = WindowContainerTransaction() val transition = Binder() val runOnTransitStart = controller.onDesktopWindowClose(wct, displayId = DEFAULT_DISPLAY, task) runOnTransitStart(transition) verify(desksTransitionsObserver) .addPendingTransition(DeskTransition.DeactivateDesk(transition, deskId = 0)) } @Test fun onDesktopWindowMinimize_noActiveTask_doesntRemoveWallpaper() { val task = setUpFreeformTask(active = false) Loading @@ -2944,6 +2970,48 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase() } } @Test @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) fun onDesktopWindowMinimize_lastWindow_deactivatesDesk() { val task = setUpFreeformTask() val transition = Binder() whenever( freeformTaskTransitionStarter.startMinimizedModeTransition( any(), anyInt(), anyBoolean(), ) ) .thenReturn(transition) controller.minimizeTask(task, MinimizeReason.MINIMIZE_BUTTON) val captor = argumentCaptor<WindowContainerTransaction>() verify(freeformTaskTransitionStarter) .startMinimizedModeTransition(captor.capture(), eq(task.taskId), eq(true)) verify(desksOrganizer).deactivateDesk(captor.firstValue, deskId = 0) } @Test @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) fun onDesktopWindowMinimize_lastWindow_addsPendingDeactivateTransition() { val task = setUpFreeformTask() val transition = Binder() whenever( freeformTaskTransitionStarter.startMinimizedModeTransition( any(), anyInt(), anyBoolean(), ) ) .thenReturn(transition) controller.minimizeTask(task, MinimizeReason.MINIMIZE_BUTTON) verify(desksTransitionsObserver) .addPendingTransition(DeskTransition.DeactivateDesk(token = transition, deskId = 0)) } @Test fun onPipTaskMinimize_autoEnterEnabled_startPipTransition() { val task = setUpPipTask(autoEnterEnabled = true) Loading