diff options
9 files changed, 369 insertions, 3 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt index 6cb26b54e802..e77acfb805a6 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt @@ -68,6 +68,8 @@ class DesktopRepository( * @property topTransparentFullscreenTaskId the task id of any current top transparent * fullscreen task launched on top of the desk. Cleared when the transparent task is closed or * sent to back. (top is at index 0). + * @property leftTiledTaskId task id of the task tiled on the left. + * @property rightTiledTaskId task id of the task tiled on the right. */ private data class Desk( val deskId: Int, @@ -80,6 +82,8 @@ class DesktopRepository( val freeformTasksInZOrder: ArrayList<Int> = ArrayList(), var fullImmersiveTaskId: Int? = null, var topTransparentFullscreenTaskId: Int? = null, + var leftTiledTaskId: Int? = null, + var rightTiledTaskId: Int? = null, ) { fun deepCopy(): Desk = Desk( @@ -92,6 +96,8 @@ class DesktopRepository( freeformTasksInZOrder = ArrayList(freeformTasksInZOrder), fullImmersiveTaskId = fullImmersiveTaskId, topTransparentFullscreenTaskId = topTransparentFullscreenTaskId, + leftTiledTaskId = leftTiledTaskId, + rightTiledTaskId = rightTiledTaskId, ) // TODO: b/362720497 - remove when multi-desktops is enabled where instances aren't @@ -104,6 +110,8 @@ class DesktopRepository( freeformTasksInZOrder.clear() fullImmersiveTaskId = null topTransparentFullscreenTaskId = null + leftTiledTaskId = null + rightTiledTaskId = null } } @@ -268,6 +276,106 @@ class DesktopRepository( } } + /** Register a left tiled task to desktop state. */ + fun addLeftTiledTask(displayId: Int, taskId: Int) { + logD("addLeftTiledTask for displayId=%d, taskId=%d", displayId, taskId) + val activeDesk = + checkNotNull(desktopData.getDefaultDesk(displayId)) { + "Expected desk in display: $displayId" + } + addLeftTiledTaskToDesk(displayId, taskId, activeDesk.deskId) + } + + private fun addLeftTiledTaskToDesk(displayId: Int, taskId: Int, deskId: Int) { + logD("addLeftTiledTaskToDesk for displayId=%d, taskId=%d", displayId, taskId) + val desk = checkNotNull(desktopData.getDesk(deskId)) { "Did not find desk: $deskId" } + desk.leftTiledTaskId = taskId + if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) { + updatePersistentRepository(displayId) + } + } + + /** Register a right tiled task to desktop state. */ + fun addRightTiledTask(displayId: Int, taskId: Int) { + logD("addRightTiledTask for displayId=%d, taskId=%d", displayId, taskId) + val activeDesk = + checkNotNull(desktopData.getDefaultDesk(displayId)) { + "Expected desk in display: $displayId" + } + addRightTiledTaskToDesk(displayId, taskId, activeDesk.deskId) + } + + private fun addRightTiledTaskToDesk(displayId: Int, taskId: Int, deskId: Int) { + logD("addRightTiledTaskToDesk for displayId=%d, taskId=%d", displayId, taskId) + val desk = checkNotNull(desktopData.getDesk(deskId)) { "Did not find desk: $deskId" } + desk.rightTiledTaskId = taskId + if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) { + updatePersistentRepository(displayId) + } + } + + /** Gets a registered left tiled task to desktop state or returns null. */ + fun getLeftTiledTask(displayId: Int): Int? { + logD("getLeftTiledTask for displayId=%d", displayId) + val activeDesk = + checkNotNull(desktopData.getDefaultDesk(displayId)) { + "Expected desk in display: $displayId" + } + val deskId = activeDesk.deskId + val desk = checkNotNull(desktopData.getDesk(deskId)) { "Did not find desk: $deskId" } + return desk.leftTiledTaskId + } + + /** gets a registered right tiled task to desktop state or returns null. */ + fun getRightTiledTask(displayId: Int): Int? { + logD("getRightTiledTask for displayId=%d", displayId) + val activeDesk = + checkNotNull(desktopData.getDefaultDesk(displayId)) { + "Expected desk in display: $displayId" + } + val deskId = activeDesk.deskId + val desk = checkNotNull(desktopData.getDesk(deskId)) { "Did not find desk: $deskId" } + return desk.rightTiledTaskId + } + + /* Unregisters a left tiled task from desktop state. */ + fun removeLeftTiledTask(displayId: Int) { + logD("removeLeftTiledTask for displayId=%d", displayId) + val activeDesk = + checkNotNull(desktopData.getDefaultDesk(displayId)) { + "Expected desk in display: $displayId" + } + removeLeftTiledTaskFromDesk(displayId, activeDesk.deskId) + } + + private fun removeLeftTiledTaskFromDesk(displayId: Int, deskId: Int) { + logD("removeLeftTiledTaskToDesk for displayId=%d", displayId) + val desk = checkNotNull(desktopData.getDesk(deskId)) { "Did not find desk: $deskId" } + desk.leftTiledTaskId = null + if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) { + updatePersistentRepository(displayId) + } + } + + /* Unregisters a right tiled task from desktop state. */ + fun removeRightTiledTask(displayId: Int) { + logD("removeRightTiledTask for displayId=%d", displayId) + val activeDesk = + checkNotNull(desktopData.getDefaultDesk(displayId)) { + "Expected desk in display: $displayId" + } + removeRightTiledTaskFromDesk(displayId, activeDesk.deskId) + } + + private fun removeRightTiledTaskFromDesk(displayId: Int, deskId: Int) { + logD("removeRightTiledTaskFromDesk for displayId=%d", displayId) + val desk = checkNotNull(desktopData.getDesk(deskId)) { "Did not find desk: $deskId" } + desk.rightTiledTaskId = null + if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) { + updatePersistentRepository(displayId) + } + } + /** Returns the id of the active desk in the given display, if any. */ fun getActiveDeskId(displayId: Int): Int? = desktopData.getActiveDesk(displayId)?.deskId @@ -972,6 +1080,8 @@ class DesktopRepository( visibleTasks = desk.visibleTasks, minimizedTasks = desk.minimizedTasks, freeformTasksInZOrder = desk.freeformTasksInZOrder, + leftTiledTask = desk.leftTiledTaskId, + rightTiledTask = desk.rightTiledTaskId, ) } catch (exception: Exception) { logE( diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepository.kt index f71eacab518d..e04a5cdb8a38 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepository.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepository.kt @@ -113,6 +113,8 @@ class DesktopPersistentRepository(private val dataStore: DataStore<DesktopPersis visibleTasks: ArraySet<Int> = ArraySet(), minimizedTasks: ArraySet<Int> = ArraySet(), freeformTasksInZOrder: ArrayList<Int> = ArrayList(), + leftTiledTask: Int? = null, + rightTiledTask: Int? = null, ) { // TODO: b/367609270 - Improve the API to support multi-user try { @@ -125,7 +127,13 @@ class DesktopPersistentRepository(private val dataStore: DataStore<DesktopPersis val desktop = getDesktop(currentRepository, desktopId) .toBuilder() - .updateTaskStates(visibleTasks, minimizedTasks, freeformTasksInZOrder) + .updateTaskStates( + visibleTasks, + minimizedTasks, + freeformTasksInZOrder, + leftTiledTask, + rightTiledTask, + ) .updateZOrder(freeformTasksInZOrder) persistentRepositories @@ -222,6 +230,8 @@ class DesktopPersistentRepository(private val dataStore: DataStore<DesktopPersis visibleTasks: ArraySet<Int>, minimizedTasks: ArraySet<Int>, freeformTasksInZOrder: ArrayList<Int>, + leftTiledTask: Int?, + rightTiledTask: Int?, ): Desktop.Builder { clearTasksByTaskId() @@ -238,7 +248,11 @@ class DesktopPersistentRepository(private val dataStore: DataStore<DesktopPersis } putAllTasksByTaskId( visibleTasks.associateWith { - createDesktopTask(it, state = DesktopTaskState.VISIBLE) + createDesktopTask( + it, + state = DesktopTaskState.VISIBLE, + getTilingStateForTask(it, leftTiledTask, rightTiledTask), + ) } ) putAllTasksByTaskId( @@ -249,6 +263,17 @@ class DesktopPersistentRepository(private val dataStore: DataStore<DesktopPersis return this } + private fun getTilingStateForTask( + taskId: Int, + leftTiledTask: Int?, + rightTiledTask: Int?, + ): DesktopTaskTilingState = + when (taskId) { + leftTiledTask -> DesktopTaskTilingState.LEFT + rightTiledTask -> DesktopTaskTilingState.RIGHT + else -> DesktopTaskTilingState.NONE + } + private fun Desktop.Builder.updateZOrder( freeformTasksInZOrder: ArrayList<Int> ): Desktop.Builder { @@ -260,7 +285,12 @@ class DesktopPersistentRepository(private val dataStore: DataStore<DesktopPersis private fun createDesktopTask( taskId: Int, state: DesktopTaskState = DesktopTaskState.VISIBLE, + tiling_state: DesktopTaskTilingState = DesktopTaskTilingState.NONE, ): DesktopTask = - DesktopTask.newBuilder().setTaskId(taskId).setDesktopTaskState(state).build() + DesktopTask.newBuilder() + .setTaskId(taskId) + .setDesktopTaskState(state) + .setDesktopTaskTilingState(tiling_state) + .build() } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerImpl.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerImpl.kt index 49cb7391fe97..5ed0b1d1616f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerImpl.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerImpl.kt @@ -126,6 +126,20 @@ class DesktopRepositoryInitializerImpl( taskId = task.taskId, ) } + + if (task.desktopTaskTilingState == DesktopTaskTilingState.LEFT) { + repository.addLeftTiledTask( + persistentDesktop.displayId, + task.taskId, + ) + } else if ( + task.desktopTaskTilingState == DesktopTaskTilingState.RIGHT + ) { + repository.addRightTiledTask( + persistentDesktop.displayId, + task.taskId, + ) + } } } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/persistent_desktop_repositories.proto b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/persistent_desktop_repositories.proto index 010523162cec..86dcee8f8515 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/persistent_desktop_repositories.proto +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/persistent_desktop_repositories.proto @@ -9,9 +9,16 @@ enum DesktopTaskState { MINIMIZED = 1; } +enum DesktopTaskTilingState { + NONE = 1; + LEFT = 2; + RIGHT = 3; +} + message DesktopTask { optional int32 task_id = 1; optional DesktopTaskState desktop_task_state= 2; + optional DesktopTaskTilingState desktop_task_tiling_state = 3; } message Desktop { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt index 7c5f34f979cd..854d9e1deef1 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt @@ -137,6 +137,7 @@ class DesktopTilingWindowDecoration( // Observe drag resizing to break tiling if a task is drag resized. desktopModeWindowDecoration.addDragResizeListener(this) val callback = { initTilingForDisplayIfNeeded(taskInfo.configuration, isFirstTiledApp) } + updateDesktopRepository(taskInfo.taskId, snapPosition = position) if (isTiled) { val wct = WindowContainerTransaction().setBounds(taskInfo.token, destinationBounds) toggleResizeDesktopTaskTransitionHandler.startTransition(wct, currentBounds, callback) @@ -159,6 +160,14 @@ class DesktopTilingWindowDecoration( return isTiled } + private fun updateDesktopRepository(taskId: Int, snapPosition: SnapPosition) { + when (snapPosition) { + SnapPosition.LEFT -> desktopUserRepositories.current.addLeftTiledTask(displayId, taskId) + SnapPosition.RIGHT -> + desktopUserRepositories.current.addRightTiledTask(displayId, taskId) + } + } + // If a task is already tiled on the same position, release this task, otherwise if the same // task is tiled on the opposite side, remove it from the opposite side so it's tiled correctly. private fun initTilingApps( @@ -580,6 +589,7 @@ class DesktopTilingWindowDecoration( ) { val taskRepository = desktopUserRepositories.current if (taskId == leftTaskResizingHelper?.taskInfo?.taskId) { + desktopUserRepositories.current.removeLeftTiledTask(displayId) removeTask(leftTaskResizingHelper, taskVanished, shouldDelayUpdate) leftTaskResizingHelper = null val taskId = rightTaskResizingHelper?.taskInfo?.taskId @@ -593,6 +603,7 @@ class DesktopTilingWindowDecoration( } if (taskId == rightTaskResizingHelper?.taskInfo?.taskId) { + desktopUserRepositories.current.removeRightTiledTask(displayId) removeTask(rightTaskResizingHelper, taskVanished, shouldDelayUpdate) rightTaskResizingHelper = null val taskId = leftTaskResizingHelper?.taskInfo?.taskId diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt index a10aeca95bce..3fb008377d6e 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt @@ -58,6 +58,7 @@ import org.mockito.Mockito.spy import org.mockito.kotlin.any import org.mockito.kotlin.clearInvocations import org.mockito.kotlin.eq +import org.mockito.kotlin.isNull import org.mockito.kotlin.never import org.mockito.kotlin.times import org.mockito.kotlin.verify @@ -331,6 +332,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = ArraySet(arrayOf(1)), minimizedTasks = ArraySet(), freeformTasksInZOrder = arrayListOf(), + leftTiledTask = null, + rightTiledTask = null, ) verify(persistentRepository) .addOrUpdateDesktop( @@ -339,6 +342,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = ArraySet(arrayOf(1, 2)), minimizedTasks = ArraySet(), freeformTasksInZOrder = arrayListOf(), + leftTiledTask = null, + rightTiledTask = null, ) } } @@ -358,6 +363,52 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { } @Test + @EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_PERSISTENCE) + fun leftTiledTask_updatedInRepoAndPersisted() { + runTest(StandardTestDispatcher()) { + repo.addLeftTiledTask(displayId = DEFAULT_DISPLAY, taskId = 1) + + assertThat(repo.getLeftTiledTask(displayId = DEFAULT_DISPLAY)).isEqualTo(1) + verify(persistentRepository) + .addOrUpdateDesktop( + DEFAULT_USER_ID, + DEFAULT_DESKTOP_ID, + visibleTasks = ArraySet(), + minimizedTasks = ArraySet(), + freeformTasksInZOrder = arrayListOf(), + leftTiledTask = 1, + rightTiledTask = null, + ) + + repo.removeRightTiledTask(displayId = DEFAULT_DISPLAY) + assertThat(repo.getRightTiledTask(displayId = DEFAULT_DISPLAY)).isNull() + } + } + + @Test + @EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_PERSISTENCE) + fun rightTiledTask_updatedInRepoAndPersisted() { + runTest(StandardTestDispatcher()) { + repo.addRightTiledTask(displayId = DEFAULT_DISPLAY, taskId = 1) + + assertThat(repo.getRightTiledTask(displayId = DEFAULT_DISPLAY)).isEqualTo(1) + verify(persistentRepository) + .addOrUpdateDesktop( + DEFAULT_USER_ID, + DEFAULT_DESKTOP_ID, + visibleTasks = ArraySet(), + minimizedTasks = ArraySet(), + freeformTasksInZOrder = arrayListOf(), + leftTiledTask = null, + rightTiledTask = 1, + ) + + repo.removeLeftTiledTask(displayId = DEFAULT_DISPLAY) + assertThat(repo.getLeftTiledTask(displayId = DEFAULT_DISPLAY)).isNull() + } + } + + @Test fun isOnlyVisibleNonClosingTask_singleVisibleMinimizedTask() { val taskId = 1 repo.addTask(DEFAULT_DISPLAY, taskId, isVisible = true) @@ -663,6 +714,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = ArraySet(), minimizedTasks = ArraySet(), freeformTasksInZOrder = arrayListOf(5), + leftTiledTask = null, + rightTiledTask = null, ) verify(persistentRepository) .addOrUpdateDesktop( @@ -671,6 +724,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = ArraySet(arrayOf(5)), minimizedTasks = ArraySet(), freeformTasksInZOrder = arrayListOf(6, 5), + leftTiledTask = null, + rightTiledTask = null, ) verify(persistentRepository) .addOrUpdateDesktop( @@ -679,6 +734,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = ArraySet(arrayOf(5, 6)), minimizedTasks = ArraySet(), freeformTasksInZOrder = arrayListOf(7, 6, 5), + leftTiledTask = null, + rightTiledTask = null, ) } } @@ -729,6 +786,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = ArraySet(), minimizedTasks = ArraySet(), freeformTasksInZOrder = arrayListOf(5), + leftTiledTask = null, + rightTiledTask = null, ) verify(persistentRepository) .addOrUpdateDesktop( @@ -737,6 +796,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = ArraySet(arrayOf(5)), minimizedTasks = ArraySet(), freeformTasksInZOrder = arrayListOf(6, 5), + leftTiledTask = null, + rightTiledTask = null, ) verify(persistentRepository) .addOrUpdateDesktop( @@ -745,6 +806,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = ArraySet(arrayOf(5, 6)), minimizedTasks = ArraySet(), freeformTasksInZOrder = arrayListOf(7, 6, 5), + leftTiledTask = null, + rightTiledTask = null, ) verify(persistentRepository, times(2)) .addOrUpdateDesktop( @@ -753,6 +816,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = ArraySet(arrayOf(5, 7)), minimizedTasks = ArraySet(arrayOf(6)), freeformTasksInZOrder = arrayListOf(7, 6, 5), + leftTiledTask = null, + rightTiledTask = null, ) } } @@ -793,6 +858,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = ArraySet(), minimizedTasks = ArraySet(), freeformTasksInZOrder = arrayListOf(1), + leftTiledTask = null, + rightTiledTask = null, ) verify(persistentRepository) .addOrUpdateDesktop( @@ -801,6 +868,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = ArraySet(), minimizedTasks = ArraySet(), freeformTasksInZOrder = ArrayList(), + leftTiledTask = null, + rightTiledTask = null, ) } } @@ -830,6 +899,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = ArraySet(), minimizedTasks = ArraySet(), freeformTasksInZOrder = arrayListOf(1), + leftTiledTask = null, + rightTiledTask = null, ) verify(persistentRepository) .addOrUpdateDesktop( @@ -838,6 +909,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = ArraySet(), minimizedTasks = ArraySet(), freeformTasksInZOrder = ArrayList(), + leftTiledTask = null, + rightTiledTask = null, ) } } @@ -869,6 +942,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = ArraySet(), minimizedTasks = ArraySet(), freeformTasksInZOrder = arrayListOf(1), + leftTiledTask = null, + rightTiledTask = null, ) verify(persistentRepository, never()) .addOrUpdateDesktop( @@ -877,6 +952,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = ArraySet(), minimizedTasks = ArraySet(), freeformTasksInZOrder = ArrayList(), + leftTiledTask = null, + rightTiledTask = null, ) } } @@ -1391,6 +1468,8 @@ class DesktopRepositoryTest(flags: FlagsParameterization) : ShellTestCase() { visibleTasks = any(), minimizedTasks = any(), freeformTasksInZOrder = any(), + leftTiledTask = isNull(), + rightTiledTask = isNull(), ) } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepositoryTest.kt index 5f92326b5e5e..6039b8f0edc5 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepositoryTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepositoryTest.kt @@ -115,6 +115,8 @@ class DesktopPersistentRepositoryTest : ShellTestCase() { minimizedTasks = minimizedTasks, freeformTasksInZOrder = freeformTasksInZOrder, userId = DEFAULT_USER_ID, + leftTiledTask = null, + rightTiledTask = null, ) val actualDesktop = datastoreRepository.readDesktop(DEFAULT_USER_ID, DEFAULT_DESKTOP_ID) @@ -124,6 +126,50 @@ class DesktopPersistentRepositoryTest : ShellTestCase() { } @Test + fun addTiledTasks_addsTiledTasksToDesktop() { + runTest(StandardTestDispatcher()) { + // Create a basic repository state + val task = createDesktopTask(1) + val desktopPersistentRepositories = createRepositoryWithOneDesk(task) + testDatastore.updateData { desktopPersistentRepositories } + // Create a new state to be initialized + val visibleTasks = ArraySet(listOf(1, 2)) + + // Update with new state + datastoreRepository.addOrUpdateDesktop( + visibleTasks = visibleTasks, + minimizedTasks = ArraySet(), + freeformTasksInZOrder = ArrayList(), + userId = DEFAULT_USER_ID, + leftTiledTask = 1, + rightTiledTask = null, + ) + + var actualDesktop = datastoreRepository.readDesktop(DEFAULT_USER_ID, DEFAULT_DESKTOP_ID) + assertThat(actualDesktop?.tasksByTaskIdMap?.get(1)?.desktopTaskTilingState) + .isEqualTo(DesktopTaskTilingState.LEFT) + assertThat(actualDesktop?.tasksByTaskIdMap?.get(2)?.desktopTaskTilingState) + .isEqualTo(DesktopTaskTilingState.NONE) + + // Update with new state + datastoreRepository.addOrUpdateDesktop( + visibleTasks = visibleTasks, + minimizedTasks = ArraySet(), + freeformTasksInZOrder = ArrayList(), + userId = DEFAULT_USER_ID, + leftTiledTask = null, + rightTiledTask = 2, + ) + + actualDesktop = datastoreRepository.readDesktop(DEFAULT_USER_ID, DEFAULT_DESKTOP_ID) + assertThat(actualDesktop?.tasksByTaskIdMap?.get(1)?.desktopTaskTilingState) + .isEqualTo(DesktopTaskTilingState.NONE) + assertThat(actualDesktop?.tasksByTaskIdMap?.get(2)?.desktopTaskTilingState) + .isEqualTo(DesktopTaskTilingState.RIGHT) + } + } + + @Test fun removeUsers_removesUsersData() { runTest(StandardTestDispatcher()) { val task = createDesktopTask(1) @@ -138,12 +184,16 @@ class DesktopPersistentRepositoryTest : ShellTestCase() { minimizedTasks = minimizedTasks, freeformTasksInZOrder = freeformTasksInZOrder, userId = DEFAULT_USER_ID, + leftTiledTask = null, + rightTiledTask = null, ) datastoreRepository.addOrUpdateDesktop( visibleTasks = visibleTasks, minimizedTasks = minimizedTasks, freeformTasksInZOrder = freeformTasksInZOrder, userId = USER_ID_2, + leftTiledTask = null, + rightTiledTask = null, ) datastoreRepository.removeUsers(mutableListOf(USER_ID_2)) @@ -175,6 +225,8 @@ class DesktopPersistentRepositoryTest : ShellTestCase() { minimizedTasks = minimizedTasks, freeformTasksInZOrder = freeformTasksInZOrder, userId = DEFAULT_USER_ID, + leftTiledTask = null, + rightTiledTask = null, ) val actualDesktop = datastoreRepository.readDesktop(DEFAULT_USER_ID, DEFAULT_DESKTOP_ID) @@ -200,6 +252,8 @@ class DesktopPersistentRepositoryTest : ShellTestCase() { minimizedTasks = minimizedTasks, freeformTasksInZOrder = freeformTasksInZOrder, userId = DEFAULT_USER_ID, + leftTiledTask = null, + rightTiledTask = null, ) val actualDesktop = datastoreRepository.readDesktop(DEFAULT_USER_ID, DEFAULT_DESKTOP_ID) diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt index 646ec21cab9b..9e148e57260b 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt @@ -28,6 +28,7 @@ import com.android.wm.shell.common.DisplayLayout import com.android.wm.shell.common.ShellExecutor import com.android.wm.shell.common.SyncTransactionQueue import com.android.wm.shell.desktopmode.DesktopModeEventLogger +import com.android.wm.shell.desktopmode.DesktopRepository import com.android.wm.shell.desktopmode.DesktopTasksController import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask import com.android.wm.shell.desktopmode.DesktopUserRepositories @@ -63,6 +64,7 @@ class DesktopTilingDecorViewModelTest : ShellTestCase() { private val transitionsMock: Transitions = mock() private val shellTaskOrganizerMock: ShellTaskOrganizer = mock() private val userRepositories: DesktopUserRepositories = mock() + private val desktopRepository: DesktopRepository = mock() private val desktopModeEventLogger: DesktopModeEventLogger = mock() private val toggleResizeDesktopTaskTransitionHandlerMock: ToggleResizeDesktopTaskTransitionHandler = @@ -105,6 +107,7 @@ class DesktopTilingDecorViewModelTest : ShellTestCase() { whenever(contextMock.createContextAsUser(any(), any())).thenReturn(context) whenever(contextMock.resources).thenReturn(resourcesMock) whenever(resourcesMock.getDimensionPixelSize(any())).thenReturn(10) + whenever(userRepositories.current).thenReturn(desktopRepository) } @Test diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt index e4424f3c57f2..e5f8d7d34a47 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt @@ -653,6 +653,64 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() { verify(context, never()).getApplicationContext() } + @Test + fun addLeftTiledTask_updatesTaskRepository_whenLeftTileInitializedOrBroken() { + val task1 = createVisibleTask() + val stableBounds = STABLE_BOUNDS_MOCK + whenever(displayController.getDisplayLayout(any())).thenReturn(displayLayout) + whenever(displayLayout.getStableBounds(any())).thenAnswer { i -> + (i.arguments.first() as Rect).set(stableBounds) + } + whenever(context.resources).thenReturn(resources) + whenever(resources.getDimensionPixelSize(any())).thenReturn(split_divider_width) + whenever(tiledTaskHelper.taskInfo).thenReturn(task1) + whenever(tiledTaskHelper.desktopModeWindowDecoration).thenReturn(desktopWindowDecoration) + + tilingDecoration.onAppTiled( + task1, + desktopWindowDecoration, + DesktopTasksController.SnapPosition.LEFT, + BOUNDS, + ) + + verify(desktopRepository, times(1)).addLeftTiledTask(displayId, task1.taskId) + verify(desktopRepository, never()).addRightTiledTask(displayId, task1.taskId) + + tilingDecoration.removeTaskIfTiled(task1.taskId) + + verify(desktopRepository, times(1)).removeLeftTiledTask(displayId) + verify(desktopRepository, never()).removeRightTiledTask(displayId) + } + + @Test + fun addRightTiledTask_updatesTaskRepository_whenRightTileInitializedOrBroken() { + val task1 = createVisibleTask() + val stableBounds = STABLE_BOUNDS_MOCK + whenever(displayController.getDisplayLayout(any())).thenReturn(displayLayout) + whenever(displayLayout.getStableBounds(any())).thenAnswer { i -> + (i.arguments.first() as Rect).set(stableBounds) + } + whenever(context.resources).thenReturn(resources) + whenever(resources.getDimensionPixelSize(any())).thenReturn(split_divider_width) + whenever(tiledTaskHelper.taskInfo).thenReturn(task1) + whenever(tiledTaskHelper.desktopModeWindowDecoration).thenReturn(desktopWindowDecoration) + + tilingDecoration.onAppTiled( + task1, + desktopWindowDecoration, + DesktopTasksController.SnapPosition.RIGHT, + BOUNDS, + ) + + verify(desktopRepository, times(1)).addRightTiledTask(displayId, task1.taskId) + verify(desktopRepository, never()).addLeftTiledTask(displayId, task1.taskId) + + tilingDecoration.removeTaskIfTiled(task1.taskId) + + verify(desktopRepository, times(1)).removeRightTiledTask(displayId) + verify(desktopRepository, never()).removeLeftTiledTask(displayId) + } + private fun initTiledTaskHelperMock(taskInfo: ActivityManager.RunningTaskInfo) { whenever(tiledTaskHelper.bounds).thenReturn(BOUNDS) whenever(tiledTaskHelper.taskInfo).thenReturn(taskInfo) |