Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayEventHandler.kt +22 −2 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import com.android.wm.shell.desktopmode.desktopfirst.isDisplayDesktopFirst import com.android.wm.shell.desktopmode.multidesks.DesksOrganizer import com.android.wm.shell.desktopmode.multidesks.DesksTransitionObserver import com.android.wm.shell.desktopmode.multidesks.OnDeskRemovedListener import com.android.wm.shell.desktopmode.multidesks.PreserveDisplayRequestHandler import com.android.wm.shell.desktopmode.persistence.DesktopRepositoryInitializer import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE import com.android.wm.shell.shared.desktopmode.DesktopState Loading @@ -59,13 +60,17 @@ class DesktopDisplayEventHandler( private val desktopDisplayModeController: DesktopDisplayModeController, private val desksTransitionObserver: DesksTransitionObserver, private val desktopState: DesktopState, ) : OnDisplaysChangedListener, OnDeskRemovedListener { ) : OnDisplaysChangedListener, OnDeskRemovedListener, PreserveDisplayRequestHandler { private val onDisplayAreaChangeListener = OnDisplayAreaChangeListener { displayId -> logV("displayAreaChanged in displayId=%d", displayId) createDefaultDesksIfNeeded(displayIds = listOf(displayId), userId = null) } // Mapping of display uniqueIds to displayId. Used to match a disconnected // displayId to its uniqueId since we will not be able to fetch it after disconnect. private val uniqueIdByDisplayId = mutableMapOf<Int, String>() init { shellInit.addInitCallback({ onInit() }, this) } Loading @@ -84,6 +89,7 @@ class DesktopDisplayEventHandler( } } ) desktopTasksController.preserveDisplayRequestHandler = this } } Loading @@ -97,6 +103,13 @@ class DesktopDisplayEventHandler( // display. So updating the default display's windowing mode here. desktopDisplayModeController.updateDefaultDisplayWindowingMode() } if (DesktopExperienceFlags.ENABLE_DISPLAY_RECONNECT_INTERACTION.isTrue) { // TODO - b/365873835: Restore a display if a uniqueId match is found in // the desktop repository. displayController.getDisplay(displayId)?.uniqueId?.let { uniqueId -> uniqueIdByDisplayId[displayId] = uniqueId } } } override fun onDisplayRemoved(displayId: Int) { Loading @@ -106,7 +119,14 @@ class DesktopDisplayEventHandler( if (displayId != DEFAULT_DISPLAY) { desktopDisplayModeController.updateDefaultDisplayWindowingMode() } // TODO(b/391652399): store a persisted DesktopDisplay in DesktopRepository uniqueIdByDisplayId.remove(displayId) } override fun requestPreserveDisplay(displayId: Int) { logV("requestPreserveDisplay displayId=%d", displayId) val uniqueId = uniqueIdByDisplayId.remove(displayId) ?: return // TODO: b/365873835 - Preserve/restore bounds for other repositories. desktopUserRepositories.current.preserveDisplay(displayId, uniqueId) } override fun onDesktopModeEligibleChanged(displayId: Int) { Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt +101 −24 Original line number Diff line number Diff line Loading @@ -81,6 +81,7 @@ class DesktopRepository( private data class Desk( val deskId: Int, var displayId: Int, // TODO: b/421928445 - Refactor these and boundsByTaskId into a new data class. val activeTasks: ArraySet<Int> = ArraySet(), val visibleTasks: ArraySet<Int> = ArraySet(), val minimizedTasks: ArraySet<Int> = ArraySet(), Loading @@ -92,6 +93,12 @@ class DesktopRepository( var leftTiledTaskId: Int? = null, var rightTiledTaskId: Int? = null, ) { // TODO: b/417907552 - Add these variables to persistent repository. // The display's unique id that will remain the same across reboots. var uniqueDisplayId: String? = null // Bounds of tasks in this desk mapped to their respective task ids. Used for reconnect. var boundsByTaskId: MutableMap<Int, Rect> = mutableMapOf() fun deepCopy(): Desk = Desk( deskId = deskId, Loading @@ -106,6 +113,10 @@ class DesktopRepository( leftTiledTaskId = leftTiledTaskId, rightTiledTaskId = rightTiledTaskId, ) .also { it.uniqueDisplayId = uniqueDisplayId it.boundsByTaskId = boundsByTaskId.toMutableMap() } // TODO: b/362720497 - remove when multi-desktops is enabled where instances aren't // reusable. Loading @@ -119,6 +130,7 @@ class DesktopRepository( topTransparentFullscreenTaskData = null leftTiledTaskId = null rightTiledTaskId = null boundsByTaskId.clear() } } Loading @@ -141,6 +153,9 @@ class DesktopRepository( private var desktopGestureExclusionListener: Consumer<Region>? = null private var desktopGestureExclusionExecutor: Executor? = null // TODO - b/365873835: Add this to persistent repository. private val preservedDisplaysByUniqueId = ArrayMap<String, DesktopDisplay>() private val desktopData: DesktopData = if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) { MultiDesktopData() Loading Loading @@ -178,6 +193,33 @@ class DesktopRepository( activeTasksListeners.onEach { it.onActiveTasksChanged(displayId) } } /** Stores the last state of the given display, along with the bounds of the tasks on it. */ fun preserveDisplay(displayId: Int, uniqueId: String) { val orderedDesks = desktopData.getOrderedDesks(displayId) // Do not preserve the display if there are no active tasks on it. if (!orderedDesks.any { it.activeTasks.isNotEmpty() }) return val preservedDisplay = DesktopDisplay(displayId) orderedDesks.mapTo(preservedDisplay.orderedDesks) { it.deepCopy() } preservedDisplay.activeDeskId = desktopData.getActiveDesk(displayId)?.deskId preservedDisplaysByUniqueId[uniqueId] = preservedDisplay } /** Returns the bounds of all tasks in all desks of the preserved display. */ @VisibleForTesting fun getPreservedTaskBounds(uniqueDisplayId: String): Map<Int, Rect> { val combinedBoundsMap = mutableMapOf<Int, Rect>() val orderedDesks = preservedDisplaysByUniqueId[uniqueDisplayId]?.orderedDesks ?: return emptyMap() for (desk in orderedDesks) { combinedBoundsMap.putAll(desk.boundsByTaskId) } return combinedBoundsMap } @VisibleForTesting fun getPreservedDeskIds(uniqueDisplayId: String): List<Int> = preservedDisplaysByUniqueId[uniqueDisplayId]?.orderedDesks?.map { it.deskId } ?: emptyList() /** Returns a list of all [Desk]s in the repository. */ private fun desksSequence(): Sequence<Desk> = desktopData.desksSequence() Loading Loading @@ -411,22 +453,41 @@ class DesktopRepository( * * TODO: b/389960283 - add explicit [deskId] argument. */ fun addTask(displayId: Int, taskId: Int, isVisible: Boolean) { logD("addTask for displayId=%d, taskId=%d, isVisible=%b", displayId, taskId, isVisible) fun addTask(displayId: Int, taskId: Int, isVisible: Boolean, taskBounds: Rect) { logD( "addTask for displayId=%d, taskId=%d, isVisible=%b," + "taskBounds=%s", displayId, taskId, isVisible, taskBounds, ) val activeDesk = checkNotNull(desktopData.getDefaultDesk(displayId)) { "Expected desk in display: $displayId" } addTaskToDesk(displayId = displayId, deskId = activeDesk.deskId, taskId = taskId, isVisible) addTaskToDesk( displayId = displayId, deskId = activeDesk.deskId, taskId = taskId, isVisible = isVisible, taskBounds = taskBounds, ) } fun addTaskToDesk(displayId: Int, deskId: Int, taskId: Int, isVisible: Boolean) { fun addTaskToDesk( displayId: Int, deskId: Int, taskId: Int, isVisible: Boolean, taskBounds: Rect?, ) { logD( "addTaskToDesk for displayId=%d, deskId=%d, taskId=%d, isVisible=%b", "addTaskToDesk for displayId=%d, deskId=%d, taskId=%d, isVisible=%b, taskBounds=%s", displayId, deskId, taskId, isVisible, taskBounds, ) if (deskId == taskId) { Slog.e(TAG, "Adding desk to itself: deskId=$deskId", Exception()) Loading @@ -438,6 +499,7 @@ class DesktopRepository( deskId = deskId, taskId = taskId, isVisible = isVisible, taskBounds = taskBounds, ) } Loading Loading @@ -674,7 +736,7 @@ class DesktopRepository( * * TODO: b/389960283 - add explicit [deskId] argument. */ fun updateTask(displayId: Int, taskId: Int, isVisible: Boolean) { fun updateTask(displayId: Int, taskId: Int, isVisible: Boolean, taskBounds: Rect?) { val validDisplayId = if (displayId == INVALID_DISPLAY) { // When a task vanishes it doesn't have a displayId. Find the display of the task. Loading @@ -694,18 +756,26 @@ class DesktopRepository( displayId = validDisplayId, deskId = desk.deskId, taskId = taskId, isVisible, isVisible = isVisible, taskBounds = taskBounds, ) } private fun updateTaskInDesk(displayId: Int, deskId: Int, taskId: Int, isVisible: Boolean) { private fun updateTaskInDesk( displayId: Int, deskId: Int, taskId: Int, isVisible: Boolean, taskBounds: Rect?, ) { check(displayId != INVALID_DISPLAY) { "Display must be valid" } logD( "updateTaskInDesk taskId=%d, deskId=%d, displayId=%d, isVisible=%b", "updateTaskInDesk taskId=%d, deskId=%d, displayId=%d, isVisible=%b, taskBounds=%s", taskId, deskId, displayId, isVisible, taskBounds, ) if (isVisible) { Loading @@ -720,6 +790,7 @@ class DesktopRepository( } else { desk.visibleTasks.remove(taskId) } taskBounds?.let { desk.boundsByTaskId[taskId] = it } val newCount = getVisibleTaskCountInDesk(deskId) if (prevCount != newCount) { logD( Loading Loading @@ -855,8 +926,13 @@ class DesktopRepository( */ private fun addOrMoveTaskToTopOfDesk(displayId: Int, deskId: Int, taskId: Int) { val desk = desktopData.getDesk(deskId) ?: error("Could not find desk: $deskId") desktopData.forAllDesks { _, desk1 -> desk1.freeformTasksInZOrder.remove(taskId) } val bounds = Rect() desktopData.forAllDesks { _, desk1 -> desk1.freeformTasksInZOrder.remove(taskId) desk1.boundsByTaskId[taskId]?.let { bounds.set(it) } } desk.freeformTasksInZOrder.add(0, taskId) if (!bounds.isEmpty) desk.boundsByTaskId[taskId] = bounds if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) { // TODO: can probably just update the desk. updatePersistentRepository(displayId) Loading Loading @@ -890,7 +966,7 @@ class DesktopRepository( logD("MinimizeTaskInDesk: displayId=%d deskId=%d, task=%d", displayId, deskId, taskId) desktopData.getDesk(deskId)?.minimizedTasks?.add(taskId) ?: logD("Minimize task: No active desk found for task: taskId=%d", taskId) updateTaskInDesk(displayId, deskId, taskId, isVisible = false) updateTaskInDesk(displayId, deskId, taskId, isVisible = false, taskBounds = null) if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) { updatePersistentRepositoryForDesk(deskId) } Loading Loading @@ -955,6 +1031,7 @@ class DesktopRepository( boundsBeforeFullImmersiveByTaskId.remove(taskId) val desk = desktopData.getDesk(deskId) ?: return if (desk.freeformTasksInZOrder.remove(taskId)) { desk.boundsByTaskId.remove(taskId) logD( "Remaining freeform tasks in desk: %d, tasks: %s", desk.deskId, Loading Loading @@ -1420,7 +1497,7 @@ class DesktopRepository( } override fun getOrderedDesks(displayId: Int): List<Desk> = desktopDisplays[displayId].orderedDesks.toList() desktopDisplays[displayId]?.orderedDesks?.toList() ?: emptyList() override fun getAllActiveDesks(): Set<Desk> { return desktopDisplays Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListener.kt +30 −5 Original line number Diff line number Diff line Loading @@ -54,7 +54,12 @@ class DesktopTaskChangeListener( ) return } desktopRepository.addTask(taskInfo.displayId, taskInfo.taskId, taskInfo.isVisible) desktopRepository.addTask( taskInfo.displayId, taskInfo.taskId, taskInfo.isVisible, taskInfo.configuration.windowConfiguration.bounds, ) } } Loading Loading @@ -90,7 +95,12 @@ class DesktopTaskChangeListener( } // If the task is already active in the repository, then moves task to the front, // else adds the task. desktopRepository.addTask(taskInfo.displayId, taskInfo.taskId, taskInfo.isVisible) desktopRepository.addTask( taskInfo.displayId, taskInfo.taskId, taskInfo.isVisible, taskInfo.configuration.windowConfiguration.bounds, ) } } Loading Loading @@ -134,7 +144,12 @@ class DesktopTaskChangeListener( } // If the task is already active in the repository, then it only moves the task to the // front. desktopRepository.addTask(taskInfo.displayId, taskInfo.taskId, taskInfo.isVisible) desktopRepository.addTask( taskInfo.displayId, taskInfo.taskId, taskInfo.isVisible, taskInfo.configuration.windowConfiguration.bounds, ) } } Loading @@ -149,7 +164,12 @@ class DesktopTaskChangeListener( val desktopRepository: DesktopRepository = desktopUserRepositories.getProfile(taskInfo.userId) if (!desktopRepository.isActiveTask(taskInfo.taskId)) return desktopRepository.updateTask(taskInfo.displayId, taskInfo.taskId, /* isVisible= */ false) desktopRepository.updateTask( taskInfo.displayId, taskInfo.taskId, isVisible = false, taskInfo.configuration.windowConfiguration.bounds, ) } override fun onTaskClosing(taskInfo: RunningTaskInfo) { Loading @@ -172,7 +192,12 @@ class DesktopTaskChangeListener( // the repo. desktopRepository.removeClosingTask(taskInfo.taskId) if (isMinimized) { desktopRepository.updateTask(taskInfo.displayId, taskInfo.taskId, isVisible = false) desktopRepository.updateTask( taskInfo.displayId, taskInfo.taskId, isVisible = false, taskInfo.configuration.windowConfiguration.bounds, ) } else { desktopRepository.removeTask(taskInfo.taskId) } Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +5 −0 Original line number Diff line number Diff line Loading @@ -128,6 +128,7 @@ import com.android.wm.shell.desktopmode.multidesks.DeskTransition import com.android.wm.shell.desktopmode.multidesks.DesksOrganizer import com.android.wm.shell.desktopmode.multidesks.DesksTransitionObserver import com.android.wm.shell.desktopmode.multidesks.OnDeskRemovedListener import com.android.wm.shell.desktopmode.multidesks.PreserveDisplayRequestHandler import com.android.wm.shell.desktopmode.persistence.DesktopRepositoryInitializer import com.android.wm.shell.desktopmode.persistence.DesktopRepositoryInitializer.DeskRecreationFactory import com.android.wm.shell.draganddrop.DragAndDropController Loading Loading @@ -295,6 +296,9 @@ class DesktopTasksController( // A listener that is invoked after a desk has been remove from the system. */ var onDeskRemovedListener: OnDeskRemovedListener? = null // A handler for requests to preserve a disconnected display to potentially restore later. var preserveDisplayRequestHandler: PreserveDisplayRequestHandler? = null private val toDesktopAnimationDurationMs = context.resources.getInteger(SharedR.integer.to_desktop_animation_duration_ms) Loading Loading @@ -680,6 +684,7 @@ class DesktopTasksController( destinationDisplayId: Int, transition: IBinder, ): WindowContainerTransaction { preserveDisplayRequestHandler?.requestPreserveDisplay(disconnectedDisplayId) // TODO: b/406320371 - Verify this works with non-system users once the underlying bug is // resolved. val wct = WindowContainerTransaction() Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksTransitionObserver.kt +1 −0 Original line number Diff line number Diff line Loading @@ -187,6 +187,7 @@ class DesksTransitionObserver( deskId = deskTransition.deskId, taskId = deskTransition.enterTaskId, isVisible = true, taskBounds = taskChange.taskInfo?.configuration?.windowConfiguration?.bounds, ) } else { // This is possible in cases where the task that was originally launched is a Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayEventHandler.kt +22 −2 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import com.android.wm.shell.desktopmode.desktopfirst.isDisplayDesktopFirst import com.android.wm.shell.desktopmode.multidesks.DesksOrganizer import com.android.wm.shell.desktopmode.multidesks.DesksTransitionObserver import com.android.wm.shell.desktopmode.multidesks.OnDeskRemovedListener import com.android.wm.shell.desktopmode.multidesks.PreserveDisplayRequestHandler import com.android.wm.shell.desktopmode.persistence.DesktopRepositoryInitializer import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE import com.android.wm.shell.shared.desktopmode.DesktopState Loading @@ -59,13 +60,17 @@ class DesktopDisplayEventHandler( private val desktopDisplayModeController: DesktopDisplayModeController, private val desksTransitionObserver: DesksTransitionObserver, private val desktopState: DesktopState, ) : OnDisplaysChangedListener, OnDeskRemovedListener { ) : OnDisplaysChangedListener, OnDeskRemovedListener, PreserveDisplayRequestHandler { private val onDisplayAreaChangeListener = OnDisplayAreaChangeListener { displayId -> logV("displayAreaChanged in displayId=%d", displayId) createDefaultDesksIfNeeded(displayIds = listOf(displayId), userId = null) } // Mapping of display uniqueIds to displayId. Used to match a disconnected // displayId to its uniqueId since we will not be able to fetch it after disconnect. private val uniqueIdByDisplayId = mutableMapOf<Int, String>() init { shellInit.addInitCallback({ onInit() }, this) } Loading @@ -84,6 +89,7 @@ class DesktopDisplayEventHandler( } } ) desktopTasksController.preserveDisplayRequestHandler = this } } Loading @@ -97,6 +103,13 @@ class DesktopDisplayEventHandler( // display. So updating the default display's windowing mode here. desktopDisplayModeController.updateDefaultDisplayWindowingMode() } if (DesktopExperienceFlags.ENABLE_DISPLAY_RECONNECT_INTERACTION.isTrue) { // TODO - b/365873835: Restore a display if a uniqueId match is found in // the desktop repository. displayController.getDisplay(displayId)?.uniqueId?.let { uniqueId -> uniqueIdByDisplayId[displayId] = uniqueId } } } override fun onDisplayRemoved(displayId: Int) { Loading @@ -106,7 +119,14 @@ class DesktopDisplayEventHandler( if (displayId != DEFAULT_DISPLAY) { desktopDisplayModeController.updateDefaultDisplayWindowingMode() } // TODO(b/391652399): store a persisted DesktopDisplay in DesktopRepository uniqueIdByDisplayId.remove(displayId) } override fun requestPreserveDisplay(displayId: Int) { logV("requestPreserveDisplay displayId=%d", displayId) val uniqueId = uniqueIdByDisplayId.remove(displayId) ?: return // TODO: b/365873835 - Preserve/restore bounds for other repositories. desktopUserRepositories.current.preserveDisplay(displayId, uniqueId) } override fun onDesktopModeEligibleChanged(displayId: Int) { Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt +101 −24 Original line number Diff line number Diff line Loading @@ -81,6 +81,7 @@ class DesktopRepository( private data class Desk( val deskId: Int, var displayId: Int, // TODO: b/421928445 - Refactor these and boundsByTaskId into a new data class. val activeTasks: ArraySet<Int> = ArraySet(), val visibleTasks: ArraySet<Int> = ArraySet(), val minimizedTasks: ArraySet<Int> = ArraySet(), Loading @@ -92,6 +93,12 @@ class DesktopRepository( var leftTiledTaskId: Int? = null, var rightTiledTaskId: Int? = null, ) { // TODO: b/417907552 - Add these variables to persistent repository. // The display's unique id that will remain the same across reboots. var uniqueDisplayId: String? = null // Bounds of tasks in this desk mapped to their respective task ids. Used for reconnect. var boundsByTaskId: MutableMap<Int, Rect> = mutableMapOf() fun deepCopy(): Desk = Desk( deskId = deskId, Loading @@ -106,6 +113,10 @@ class DesktopRepository( leftTiledTaskId = leftTiledTaskId, rightTiledTaskId = rightTiledTaskId, ) .also { it.uniqueDisplayId = uniqueDisplayId it.boundsByTaskId = boundsByTaskId.toMutableMap() } // TODO: b/362720497 - remove when multi-desktops is enabled where instances aren't // reusable. Loading @@ -119,6 +130,7 @@ class DesktopRepository( topTransparentFullscreenTaskData = null leftTiledTaskId = null rightTiledTaskId = null boundsByTaskId.clear() } } Loading @@ -141,6 +153,9 @@ class DesktopRepository( private var desktopGestureExclusionListener: Consumer<Region>? = null private var desktopGestureExclusionExecutor: Executor? = null // TODO - b/365873835: Add this to persistent repository. private val preservedDisplaysByUniqueId = ArrayMap<String, DesktopDisplay>() private val desktopData: DesktopData = if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) { MultiDesktopData() Loading Loading @@ -178,6 +193,33 @@ class DesktopRepository( activeTasksListeners.onEach { it.onActiveTasksChanged(displayId) } } /** Stores the last state of the given display, along with the bounds of the tasks on it. */ fun preserveDisplay(displayId: Int, uniqueId: String) { val orderedDesks = desktopData.getOrderedDesks(displayId) // Do not preserve the display if there are no active tasks on it. if (!orderedDesks.any { it.activeTasks.isNotEmpty() }) return val preservedDisplay = DesktopDisplay(displayId) orderedDesks.mapTo(preservedDisplay.orderedDesks) { it.deepCopy() } preservedDisplay.activeDeskId = desktopData.getActiveDesk(displayId)?.deskId preservedDisplaysByUniqueId[uniqueId] = preservedDisplay } /** Returns the bounds of all tasks in all desks of the preserved display. */ @VisibleForTesting fun getPreservedTaskBounds(uniqueDisplayId: String): Map<Int, Rect> { val combinedBoundsMap = mutableMapOf<Int, Rect>() val orderedDesks = preservedDisplaysByUniqueId[uniqueDisplayId]?.orderedDesks ?: return emptyMap() for (desk in orderedDesks) { combinedBoundsMap.putAll(desk.boundsByTaskId) } return combinedBoundsMap } @VisibleForTesting fun getPreservedDeskIds(uniqueDisplayId: String): List<Int> = preservedDisplaysByUniqueId[uniqueDisplayId]?.orderedDesks?.map { it.deskId } ?: emptyList() /** Returns a list of all [Desk]s in the repository. */ private fun desksSequence(): Sequence<Desk> = desktopData.desksSequence() Loading Loading @@ -411,22 +453,41 @@ class DesktopRepository( * * TODO: b/389960283 - add explicit [deskId] argument. */ fun addTask(displayId: Int, taskId: Int, isVisible: Boolean) { logD("addTask for displayId=%d, taskId=%d, isVisible=%b", displayId, taskId, isVisible) fun addTask(displayId: Int, taskId: Int, isVisible: Boolean, taskBounds: Rect) { logD( "addTask for displayId=%d, taskId=%d, isVisible=%b," + "taskBounds=%s", displayId, taskId, isVisible, taskBounds, ) val activeDesk = checkNotNull(desktopData.getDefaultDesk(displayId)) { "Expected desk in display: $displayId" } addTaskToDesk(displayId = displayId, deskId = activeDesk.deskId, taskId = taskId, isVisible) addTaskToDesk( displayId = displayId, deskId = activeDesk.deskId, taskId = taskId, isVisible = isVisible, taskBounds = taskBounds, ) } fun addTaskToDesk(displayId: Int, deskId: Int, taskId: Int, isVisible: Boolean) { fun addTaskToDesk( displayId: Int, deskId: Int, taskId: Int, isVisible: Boolean, taskBounds: Rect?, ) { logD( "addTaskToDesk for displayId=%d, deskId=%d, taskId=%d, isVisible=%b", "addTaskToDesk for displayId=%d, deskId=%d, taskId=%d, isVisible=%b, taskBounds=%s", displayId, deskId, taskId, isVisible, taskBounds, ) if (deskId == taskId) { Slog.e(TAG, "Adding desk to itself: deskId=$deskId", Exception()) Loading @@ -438,6 +499,7 @@ class DesktopRepository( deskId = deskId, taskId = taskId, isVisible = isVisible, taskBounds = taskBounds, ) } Loading Loading @@ -674,7 +736,7 @@ class DesktopRepository( * * TODO: b/389960283 - add explicit [deskId] argument. */ fun updateTask(displayId: Int, taskId: Int, isVisible: Boolean) { fun updateTask(displayId: Int, taskId: Int, isVisible: Boolean, taskBounds: Rect?) { val validDisplayId = if (displayId == INVALID_DISPLAY) { // When a task vanishes it doesn't have a displayId. Find the display of the task. Loading @@ -694,18 +756,26 @@ class DesktopRepository( displayId = validDisplayId, deskId = desk.deskId, taskId = taskId, isVisible, isVisible = isVisible, taskBounds = taskBounds, ) } private fun updateTaskInDesk(displayId: Int, deskId: Int, taskId: Int, isVisible: Boolean) { private fun updateTaskInDesk( displayId: Int, deskId: Int, taskId: Int, isVisible: Boolean, taskBounds: Rect?, ) { check(displayId != INVALID_DISPLAY) { "Display must be valid" } logD( "updateTaskInDesk taskId=%d, deskId=%d, displayId=%d, isVisible=%b", "updateTaskInDesk taskId=%d, deskId=%d, displayId=%d, isVisible=%b, taskBounds=%s", taskId, deskId, displayId, isVisible, taskBounds, ) if (isVisible) { Loading @@ -720,6 +790,7 @@ class DesktopRepository( } else { desk.visibleTasks.remove(taskId) } taskBounds?.let { desk.boundsByTaskId[taskId] = it } val newCount = getVisibleTaskCountInDesk(deskId) if (prevCount != newCount) { logD( Loading Loading @@ -855,8 +926,13 @@ class DesktopRepository( */ private fun addOrMoveTaskToTopOfDesk(displayId: Int, deskId: Int, taskId: Int) { val desk = desktopData.getDesk(deskId) ?: error("Could not find desk: $deskId") desktopData.forAllDesks { _, desk1 -> desk1.freeformTasksInZOrder.remove(taskId) } val bounds = Rect() desktopData.forAllDesks { _, desk1 -> desk1.freeformTasksInZOrder.remove(taskId) desk1.boundsByTaskId[taskId]?.let { bounds.set(it) } } desk.freeformTasksInZOrder.add(0, taskId) if (!bounds.isEmpty) desk.boundsByTaskId[taskId] = bounds if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) { // TODO: can probably just update the desk. updatePersistentRepository(displayId) Loading Loading @@ -890,7 +966,7 @@ class DesktopRepository( logD("MinimizeTaskInDesk: displayId=%d deskId=%d, task=%d", displayId, deskId, taskId) desktopData.getDesk(deskId)?.minimizedTasks?.add(taskId) ?: logD("Minimize task: No active desk found for task: taskId=%d", taskId) updateTaskInDesk(displayId, deskId, taskId, isVisible = false) updateTaskInDesk(displayId, deskId, taskId, isVisible = false, taskBounds = null) if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) { updatePersistentRepositoryForDesk(deskId) } Loading Loading @@ -955,6 +1031,7 @@ class DesktopRepository( boundsBeforeFullImmersiveByTaskId.remove(taskId) val desk = desktopData.getDesk(deskId) ?: return if (desk.freeformTasksInZOrder.remove(taskId)) { desk.boundsByTaskId.remove(taskId) logD( "Remaining freeform tasks in desk: %d, tasks: %s", desk.deskId, Loading Loading @@ -1420,7 +1497,7 @@ class DesktopRepository( } override fun getOrderedDesks(displayId: Int): List<Desk> = desktopDisplays[displayId].orderedDesks.toList() desktopDisplays[displayId]?.orderedDesks?.toList() ?: emptyList() override fun getAllActiveDesks(): Set<Desk> { return desktopDisplays Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListener.kt +30 −5 Original line number Diff line number Diff line Loading @@ -54,7 +54,12 @@ class DesktopTaskChangeListener( ) return } desktopRepository.addTask(taskInfo.displayId, taskInfo.taskId, taskInfo.isVisible) desktopRepository.addTask( taskInfo.displayId, taskInfo.taskId, taskInfo.isVisible, taskInfo.configuration.windowConfiguration.bounds, ) } } Loading Loading @@ -90,7 +95,12 @@ class DesktopTaskChangeListener( } // If the task is already active in the repository, then moves task to the front, // else adds the task. desktopRepository.addTask(taskInfo.displayId, taskInfo.taskId, taskInfo.isVisible) desktopRepository.addTask( taskInfo.displayId, taskInfo.taskId, taskInfo.isVisible, taskInfo.configuration.windowConfiguration.bounds, ) } } Loading Loading @@ -134,7 +144,12 @@ class DesktopTaskChangeListener( } // If the task is already active in the repository, then it only moves the task to the // front. desktopRepository.addTask(taskInfo.displayId, taskInfo.taskId, taskInfo.isVisible) desktopRepository.addTask( taskInfo.displayId, taskInfo.taskId, taskInfo.isVisible, taskInfo.configuration.windowConfiguration.bounds, ) } } Loading @@ -149,7 +164,12 @@ class DesktopTaskChangeListener( val desktopRepository: DesktopRepository = desktopUserRepositories.getProfile(taskInfo.userId) if (!desktopRepository.isActiveTask(taskInfo.taskId)) return desktopRepository.updateTask(taskInfo.displayId, taskInfo.taskId, /* isVisible= */ false) desktopRepository.updateTask( taskInfo.displayId, taskInfo.taskId, isVisible = false, taskInfo.configuration.windowConfiguration.bounds, ) } override fun onTaskClosing(taskInfo: RunningTaskInfo) { Loading @@ -172,7 +192,12 @@ class DesktopTaskChangeListener( // the repo. desktopRepository.removeClosingTask(taskInfo.taskId) if (isMinimized) { desktopRepository.updateTask(taskInfo.displayId, taskInfo.taskId, isVisible = false) desktopRepository.updateTask( taskInfo.displayId, taskInfo.taskId, isVisible = false, taskInfo.configuration.windowConfiguration.bounds, ) } else { desktopRepository.removeTask(taskInfo.taskId) } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +5 −0 Original line number Diff line number Diff line Loading @@ -128,6 +128,7 @@ import com.android.wm.shell.desktopmode.multidesks.DeskTransition import com.android.wm.shell.desktopmode.multidesks.DesksOrganizer import com.android.wm.shell.desktopmode.multidesks.DesksTransitionObserver import com.android.wm.shell.desktopmode.multidesks.OnDeskRemovedListener import com.android.wm.shell.desktopmode.multidesks.PreserveDisplayRequestHandler import com.android.wm.shell.desktopmode.persistence.DesktopRepositoryInitializer import com.android.wm.shell.desktopmode.persistence.DesktopRepositoryInitializer.DeskRecreationFactory import com.android.wm.shell.draganddrop.DragAndDropController Loading Loading @@ -295,6 +296,9 @@ class DesktopTasksController( // A listener that is invoked after a desk has been remove from the system. */ var onDeskRemovedListener: OnDeskRemovedListener? = null // A handler for requests to preserve a disconnected display to potentially restore later. var preserveDisplayRequestHandler: PreserveDisplayRequestHandler? = null private val toDesktopAnimationDurationMs = context.resources.getInteger(SharedR.integer.to_desktop_animation_duration_ms) Loading Loading @@ -680,6 +684,7 @@ class DesktopTasksController( destinationDisplayId: Int, transition: IBinder, ): WindowContainerTransaction { preserveDisplayRequestHandler?.requestPreserveDisplay(disconnectedDisplayId) // TODO: b/406320371 - Verify this works with non-system users once the underlying bug is // resolved. val wct = WindowContainerTransaction() Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksTransitionObserver.kt +1 −0 Original line number Diff line number Diff line Loading @@ -187,6 +187,7 @@ class DesksTransitionObserver( deskId = deskTransition.deskId, taskId = deskTransition.enterTaskId, isVisible = true, taskBounds = taskChange.taskInfo?.configuration?.windowConfiguration?.bounds, ) } else { // This is possible in cases where the task that was originally launched is a Loading