Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt +18 −0 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.wm.shell.desktopmode package com.android.wm.shell.desktopmode import android.graphics.Rect import android.graphics.Region import android.graphics.Region import android.util.ArrayMap import android.util.ArrayMap import android.util.ArraySet import android.util.ArraySet Loading Loading @@ -55,6 +56,8 @@ class DesktopModeTaskRepository { private val visibleTasksListeners = ArrayMap<VisibleTasksListener, Executor>() private val visibleTasksListeners = ArrayMap<VisibleTasksListener, Executor>() // Track corner/caption regions of desktop tasks, used to determine gesture exclusion // Track corner/caption regions of desktop tasks, used to determine gesture exclusion private val desktopExclusionRegions = SparseArray<Region>() private val desktopExclusionRegions = SparseArray<Region>() // Track last bounds of task before toggled to stable bounds private val boundsBeforeMaximizeByTaskId = SparseArray<Rect>() private var desktopGestureExclusionListener: Consumer<Region>? = null private var desktopGestureExclusionListener: Consumer<Region>? = null private var desktopGestureExclusionExecutor: Executor? = null private var desktopGestureExclusionExecutor: Executor? = null Loading Loading @@ -307,6 +310,7 @@ class DesktopModeTaskRepository { taskId taskId ) ) freeformTasksInZOrder.remove(taskId) freeformTasksInZOrder.remove(taskId) boundsBeforeMaximizeByTaskId.remove(taskId) KtProtoLog.d( KtProtoLog.d( WM_SHELL_DESKTOP_MODE, WM_SHELL_DESKTOP_MODE, "DesktopTaskRepo: remaining freeform tasks: " + freeformTasksInZOrder.toDumpString() "DesktopTaskRepo: remaining freeform tasks: " + freeformTasksInZOrder.toDumpString() Loading Loading @@ -357,6 +361,20 @@ class DesktopModeTaskRepository { } } } } /** * Removes and returns the bounds saved before maximizing the given task. */ fun removeBoundsBeforeMaximize(taskId: Int): Rect? { return boundsBeforeMaximizeByTaskId.removeReturnOld(taskId) } /** * Saves the bounds of the given task before maximizing. */ fun saveBoundsBeforeMaximize(taskId: Int, bounds: Rect) { boundsBeforeMaximizeByTaskId.set(taskId, Rect(bounds)) } /** /** * Check if display with id [displayId] has desktop tasks stashed * Check if display with id [displayId] has desktop tasks stashed */ */ Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +18 −6 Original line number Original line Diff line number Diff line Loading @@ -120,7 +120,6 @@ class DesktopTasksController( private var visualIndicator: DesktopModeVisualIndicator? = null private var visualIndicator: DesktopModeVisualIndicator? = null private val desktopModeShellCommandHandler: DesktopModeShellCommandHandler = private val desktopModeShellCommandHandler: DesktopModeShellCommandHandler = DesktopModeShellCommandHandler(this) DesktopModeShellCommandHandler(this) private val mOnAnimationFinishedCallback = Consumer<SurfaceControl.Transaction> { private val mOnAnimationFinishedCallback = Consumer<SurfaceControl.Transaction> { t: SurfaceControl.Transaction -> t: SurfaceControl.Transaction -> visualIndicator?.releaseVisualIndicator(t) visualIndicator?.releaseVisualIndicator(t) Loading Loading @@ -570,7 +569,10 @@ class DesktopTasksController( } } } } /** Quick-resizes a desktop task, toggling between the stable bounds and the default bounds. */ /** * Quick-resizes a desktop task, toggling between the stable bounds and the last saved bounds * if available or the default bounds otherwise. */ fun toggleDesktopTaskSize(taskInfo: RunningTaskInfo) { fun toggleDesktopTaskSize(taskInfo: RunningTaskInfo) { val displayLayout = displayController.getDisplayLayout(taskInfo.displayId) ?: return val displayLayout = displayController.getDisplayLayout(taskInfo.displayId) ?: return Loading @@ -578,11 +580,21 @@ class DesktopTasksController( displayLayout.getStableBounds(stableBounds) displayLayout.getStableBounds(stableBounds) val destinationBounds = Rect() val destinationBounds = Rect() if (taskInfo.configuration.windowConfiguration.bounds == stableBounds) { if (taskInfo.configuration.windowConfiguration.bounds == stableBounds) { // The desktop task is currently occupying the whole stable bounds, toggle to the // The desktop task is currently occupying the whole stable bounds. If the bounds // default bounds. // before the task was toggled to stable bounds were saved, toggle the task to those // bounds. Otherwise, toggle to the default bounds. val taskBoundsBeforeMaximize = desktopModeTaskRepository.removeBoundsBeforeMaximize(taskInfo.taskId) if (taskBoundsBeforeMaximize != null) { destinationBounds.set(taskBoundsBeforeMaximize) } else { getDefaultDesktopTaskBounds(displayLayout, destinationBounds) getDefaultDesktopTaskBounds(displayLayout, destinationBounds) } } else { } else { // Toggle to the stable bounds. // Save current bounds so that task can be restored back to original bounds if necessary // and toggle to the stable bounds. val taskBounds = taskInfo.configuration.windowConfiguration.bounds desktopModeTaskRepository.saveBoundsBeforeMaximize(taskInfo.taskId, taskBounds) destinationBounds.set(stableBounds) destinationBounds.set(stableBounds) } } Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepositoryTest.kt +26 −0 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.wm.shell.desktopmode package com.android.wm.shell.desktopmode import android.graphics.Rect import android.testing.AndroidTestingRunner import android.testing.AndroidTestingRunner import android.view.Display.DEFAULT_DISPLAY import android.view.Display.DEFAULT_DISPLAY import android.view.Display.INVALID_DISPLAY import android.view.Display.INVALID_DISPLAY Loading Loading @@ -406,6 +407,31 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() { assertThat(listener.stashedOnSecondaryDisplay).isTrue() assertThat(listener.stashedOnSecondaryDisplay).isTrue() } } @Test fun removeFreeformTask_removesTaskBoundsBeforeMaximize() { val taskId = 1 repo.saveBoundsBeforeMaximize(taskId, Rect(0, 0, 200, 200)) repo.removeFreeformTask(taskId) assertThat(repo.removeBoundsBeforeMaximize(taskId)).isNull() } @Test fun saveBoundsBeforeMaximize_boundsSavedByTaskId() { val taskId = 1 val bounds = Rect(0, 0, 200, 200) repo.saveBoundsBeforeMaximize(taskId, bounds) assertThat(repo.removeBoundsBeforeMaximize(taskId)).isEqualTo(bounds) } @Test fun removeBoundsBeforeMaximize_returnsNullAfterBoundsRemoved() { val taskId = 1 val bounds = Rect(0, 0, 200, 200) repo.saveBoundsBeforeMaximize(taskId, bounds) repo.removeBoundsBeforeMaximize(taskId) assertThat(repo.removeBoundsBeforeMaximize(taskId)).isNull() } class TestListener : DesktopModeTaskRepository.ActiveTasksListener { class TestListener : DesktopModeTaskRepository.ActiveTasksListener { var activeChangesOnDefaultDisplay = 0 var activeChangesOnDefaultDisplay = 0 var activeChangesOnSecondaryDisplay = 0 var activeChangesOnSecondaryDisplay = 0 Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +88 −10 Original line number Original line Diff line number Diff line Loading @@ -95,9 +95,10 @@ import org.mockito.Mockito.anyInt import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.mock import org.mockito.Mockito.mock import org.mockito.Mockito.verify import org.mockito.Mockito.verify import org.mockito.kotlin.times import org.mockito.kotlin.atLeastOnce import org.mockito.Mockito.`when` as whenever import org.mockito.kotlin.capture import org.mockito.quality.Strictness import org.mockito.quality.Strictness import org.mockito.Mockito.`when` as whenever /** /** * Test class for {@link DesktopTasksController} * Test class for {@link DesktopTasksController} Loading @@ -116,13 +117,14 @@ class DesktopTasksControllerTest : ShellTestCase() { @Mock lateinit var shellCommandHandler: ShellCommandHandler @Mock lateinit var shellCommandHandler: ShellCommandHandler @Mock lateinit var shellController: ShellController @Mock lateinit var shellController: ShellController @Mock lateinit var displayController: DisplayController @Mock lateinit var displayController: DisplayController @Mock lateinit var displayLayout: DisplayLayout @Mock lateinit var shellTaskOrganizer: ShellTaskOrganizer @Mock lateinit var shellTaskOrganizer: ShellTaskOrganizer @Mock lateinit var syncQueue: SyncTransactionQueue @Mock lateinit var syncQueue: SyncTransactionQueue @Mock lateinit var rootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer @Mock lateinit var rootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer @Mock lateinit var transitions: Transitions @Mock lateinit var transitions: Transitions @Mock lateinit var exitDesktopTransitionHandler: ExitDesktopTaskTransitionHandler @Mock lateinit var exitDesktopTransitionHandler: ExitDesktopTaskTransitionHandler @Mock lateinit var enterDesktopTransitionHandler: EnterDesktopTaskTransitionHandler @Mock lateinit var enterDesktopTransitionHandler: EnterDesktopTaskTransitionHandler @Mock lateinit var mToggleResizeDesktopTaskTransitionHandler: @Mock lateinit var toggleResizeDesktopTaskTransitionHandler: ToggleResizeDesktopTaskTransitionHandler ToggleResizeDesktopTaskTransitionHandler @Mock lateinit var dragToDesktopTransitionHandler: DragToDesktopTransitionHandler @Mock lateinit var dragToDesktopTransitionHandler: DragToDesktopTransitionHandler @Mock lateinit var launchAdjacentController: LaunchAdjacentController @Mock lateinit var launchAdjacentController: LaunchAdjacentController Loading Loading @@ -154,6 +156,10 @@ class DesktopTasksControllerTest : ShellTestCase() { whenever(shellTaskOrganizer.getRunningTasks(anyInt())).thenAnswer { runningTasks } whenever(shellTaskOrganizer.getRunningTasks(anyInt())).thenAnswer { runningTasks } whenever(transitions.startTransition(anyInt(), any(), isNull())).thenAnswer { Binder() } whenever(transitions.startTransition(anyInt(), any(), isNull())).thenAnswer { Binder() } whenever(displayController.getDisplayLayout(anyInt())).thenReturn(displayLayout) whenever(displayLayout.getStableBounds(any())).thenAnswer { i -> (i.arguments.first() as Rect).set(STABLE_BOUNDS) } controller = createController() controller = createController() controller.setSplitScreenController(splitScreenController) controller.setSplitScreenController(splitScreenController) Loading @@ -179,7 +185,7 @@ class DesktopTasksControllerTest : ShellTestCase() { transitions, transitions, enterDesktopTransitionHandler, enterDesktopTransitionHandler, exitDesktopTransitionHandler, exitDesktopTransitionHandler, mToggleResizeDesktopTaskTransitionHandler, toggleResizeDesktopTaskTransitionHandler, dragToDesktopTransitionHandler, dragToDesktopTransitionHandler, desktopModeTaskRepository, desktopModeTaskRepository, desktopModeLoggerTransitionObserver, desktopModeLoggerTransitionObserver, Loading Loading @@ -936,8 +942,67 @@ class DesktopTasksControllerTest : ShellTestCase() { ) ) } } private fun setUpFreeformTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo { @Test val task = createFreeformTask(displayId) fun toggleBounds_togglesToStableBounds() { val bounds = Rect(0, 0, 100, 100) val task = setUpFreeformTask(DEFAULT_DISPLAY, bounds) controller.toggleDesktopTaskSize(task) // Assert bounds set to stable bounds val wct = getLatestToggleResizeDesktopTaskWct() assertThat(wct.changes[task.token.asBinder()]?.configuration?.windowConfiguration?.bounds) .isEqualTo(STABLE_BOUNDS) } @Test fun toggleBounds_lastBoundsBeforeMaximizeSaved() { val bounds = Rect(0, 0, 100, 100) val task = setUpFreeformTask(DEFAULT_DISPLAY, bounds) controller.toggleDesktopTaskSize(task) assertThat(desktopModeTaskRepository.removeBoundsBeforeMaximize(task.taskId)) .isEqualTo(bounds) } @Test fun toggleBounds_togglesFromStableBoundsToLastBoundsBeforeMaximize() { val boundsBeforeMaximize = Rect(0, 0, 100, 100) val task = setUpFreeformTask(DEFAULT_DISPLAY, boundsBeforeMaximize) // Maximize controller.toggleDesktopTaskSize(task) task.configuration.windowConfiguration.bounds.set(STABLE_BOUNDS) // Restore controller.toggleDesktopTaskSize(task) // Assert bounds set to last bounds before maximize val wct = getLatestToggleResizeDesktopTaskWct() assertThat(wct.changes[task.token.asBinder()]?.configuration?.windowConfiguration?.bounds) .isEqualTo(boundsBeforeMaximize) } @Test fun toggleBounds_removesLastBoundsBeforeMaximizeAfterRestoringBounds() { val boundsBeforeMaximize = Rect(0, 0, 100, 100) val task = setUpFreeformTask(DEFAULT_DISPLAY, boundsBeforeMaximize) // Maximize controller.toggleDesktopTaskSize(task) task.configuration.windowConfiguration.bounds.set(STABLE_BOUNDS) // Restore controller.toggleDesktopTaskSize(task) // Assert last bounds before maximize removed after use assertThat(desktopModeTaskRepository.removeBoundsBeforeMaximize(task.taskId)).isNull() } private fun setUpFreeformTask( displayId: Int = DEFAULT_DISPLAY, bounds: Rect? = null ): RunningTaskInfo { val task = createFreeformTask(displayId, bounds) whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task) whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task) desktopModeTaskRepository.addActiveTask(displayId, task.taskId) desktopModeTaskRepository.addActiveTask(displayId, task.taskId) desktopModeTaskRepository.addOrMoveFreeformTaskToTop(task.taskId) desktopModeTaskRepository.addOrMoveFreeformTaskToTop(task.taskId) Loading Loading @@ -1004,6 +1069,18 @@ class DesktopTasksControllerTest : ShellTestCase() { return arg.value return arg.value } } private fun getLatestToggleResizeDesktopTaskWct(): WindowContainerTransaction { val arg: ArgumentCaptor<WindowContainerTransaction> = ArgumentCaptor.forClass(WindowContainerTransaction::class.java) if (ENABLE_SHELL_TRANSITIONS) { verify(toggleResizeDesktopTaskTransitionHandler, atLeastOnce()) .startTransition(capture(arg)) } else { verify(shellTaskOrganizer).applyTransaction(capture(arg)) } return arg.value } private fun getLatestMoveToDesktopWct(): WindowContainerTransaction { private fun getLatestMoveToDesktopWct(): WindowContainerTransaction { val arg = ArgumentCaptor.forClass(WindowContainerTransaction::class.java) val arg = ArgumentCaptor.forClass(WindowContainerTransaction::class.java) if (ENABLE_SHELL_TRANSITIONS) { if (ENABLE_SHELL_TRANSITIONS) { Loading Loading @@ -1042,6 +1119,7 @@ class DesktopTasksControllerTest : ShellTestCase() { companion object { companion object { const val SECOND_DISPLAY = 2 const val SECOND_DISPLAY = 2 private val STABLE_BOUNDS = Rect(0, 0, 1000, 1000) } } } } Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt +6 −1 Original line number Original line Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN import android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW import android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW import android.graphics.Rect import android.view.Display.DEFAULT_DISPLAY import android.view.Display.DEFAULT_DISPLAY import com.android.wm.shell.MockToken import com.android.wm.shell.MockToken import com.android.wm.shell.TestRunningTaskInfoBuilder import com.android.wm.shell.TestRunningTaskInfoBuilder Loading @@ -31,13 +32,17 @@ class DesktopTestHelpers { /** Create a task that has windowing mode set to [WINDOWING_MODE_FREEFORM] */ /** Create a task that has windowing mode set to [WINDOWING_MODE_FREEFORM] */ @JvmStatic @JvmStatic @JvmOverloads @JvmOverloads fun createFreeformTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo { fun createFreeformTask( displayId: Int = DEFAULT_DISPLAY, bounds: Rect? = null ): RunningTaskInfo { return TestRunningTaskInfoBuilder() return TestRunningTaskInfoBuilder() .setDisplayId(displayId) .setDisplayId(displayId) .setToken(MockToken().token()) .setToken(MockToken().token()) .setActivityType(ACTIVITY_TYPE_STANDARD) .setActivityType(ACTIVITY_TYPE_STANDARD) .setWindowingMode(WINDOWING_MODE_FREEFORM) .setWindowingMode(WINDOWING_MODE_FREEFORM) .setLastActiveTime(100) .setLastActiveTime(100) .apply { bounds?.let { setBounds(it) }} .build() .build() } } Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt +18 −0 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.wm.shell.desktopmode package com.android.wm.shell.desktopmode import android.graphics.Rect import android.graphics.Region import android.graphics.Region import android.util.ArrayMap import android.util.ArrayMap import android.util.ArraySet import android.util.ArraySet Loading Loading @@ -55,6 +56,8 @@ class DesktopModeTaskRepository { private val visibleTasksListeners = ArrayMap<VisibleTasksListener, Executor>() private val visibleTasksListeners = ArrayMap<VisibleTasksListener, Executor>() // Track corner/caption regions of desktop tasks, used to determine gesture exclusion // Track corner/caption regions of desktop tasks, used to determine gesture exclusion private val desktopExclusionRegions = SparseArray<Region>() private val desktopExclusionRegions = SparseArray<Region>() // Track last bounds of task before toggled to stable bounds private val boundsBeforeMaximizeByTaskId = SparseArray<Rect>() private var desktopGestureExclusionListener: Consumer<Region>? = null private var desktopGestureExclusionListener: Consumer<Region>? = null private var desktopGestureExclusionExecutor: Executor? = null private var desktopGestureExclusionExecutor: Executor? = null Loading Loading @@ -307,6 +310,7 @@ class DesktopModeTaskRepository { taskId taskId ) ) freeformTasksInZOrder.remove(taskId) freeformTasksInZOrder.remove(taskId) boundsBeforeMaximizeByTaskId.remove(taskId) KtProtoLog.d( KtProtoLog.d( WM_SHELL_DESKTOP_MODE, WM_SHELL_DESKTOP_MODE, "DesktopTaskRepo: remaining freeform tasks: " + freeformTasksInZOrder.toDumpString() "DesktopTaskRepo: remaining freeform tasks: " + freeformTasksInZOrder.toDumpString() Loading Loading @@ -357,6 +361,20 @@ class DesktopModeTaskRepository { } } } } /** * Removes and returns the bounds saved before maximizing the given task. */ fun removeBoundsBeforeMaximize(taskId: Int): Rect? { return boundsBeforeMaximizeByTaskId.removeReturnOld(taskId) } /** * Saves the bounds of the given task before maximizing. */ fun saveBoundsBeforeMaximize(taskId: Int, bounds: Rect) { boundsBeforeMaximizeByTaskId.set(taskId, Rect(bounds)) } /** /** * Check if display with id [displayId] has desktop tasks stashed * Check if display with id [displayId] has desktop tasks stashed */ */ Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +18 −6 Original line number Original line Diff line number Diff line Loading @@ -120,7 +120,6 @@ class DesktopTasksController( private var visualIndicator: DesktopModeVisualIndicator? = null private var visualIndicator: DesktopModeVisualIndicator? = null private val desktopModeShellCommandHandler: DesktopModeShellCommandHandler = private val desktopModeShellCommandHandler: DesktopModeShellCommandHandler = DesktopModeShellCommandHandler(this) DesktopModeShellCommandHandler(this) private val mOnAnimationFinishedCallback = Consumer<SurfaceControl.Transaction> { private val mOnAnimationFinishedCallback = Consumer<SurfaceControl.Transaction> { t: SurfaceControl.Transaction -> t: SurfaceControl.Transaction -> visualIndicator?.releaseVisualIndicator(t) visualIndicator?.releaseVisualIndicator(t) Loading Loading @@ -570,7 +569,10 @@ class DesktopTasksController( } } } } /** Quick-resizes a desktop task, toggling between the stable bounds and the default bounds. */ /** * Quick-resizes a desktop task, toggling between the stable bounds and the last saved bounds * if available or the default bounds otherwise. */ fun toggleDesktopTaskSize(taskInfo: RunningTaskInfo) { fun toggleDesktopTaskSize(taskInfo: RunningTaskInfo) { val displayLayout = displayController.getDisplayLayout(taskInfo.displayId) ?: return val displayLayout = displayController.getDisplayLayout(taskInfo.displayId) ?: return Loading @@ -578,11 +580,21 @@ class DesktopTasksController( displayLayout.getStableBounds(stableBounds) displayLayout.getStableBounds(stableBounds) val destinationBounds = Rect() val destinationBounds = Rect() if (taskInfo.configuration.windowConfiguration.bounds == stableBounds) { if (taskInfo.configuration.windowConfiguration.bounds == stableBounds) { // The desktop task is currently occupying the whole stable bounds, toggle to the // The desktop task is currently occupying the whole stable bounds. If the bounds // default bounds. // before the task was toggled to stable bounds were saved, toggle the task to those // bounds. Otherwise, toggle to the default bounds. val taskBoundsBeforeMaximize = desktopModeTaskRepository.removeBoundsBeforeMaximize(taskInfo.taskId) if (taskBoundsBeforeMaximize != null) { destinationBounds.set(taskBoundsBeforeMaximize) } else { getDefaultDesktopTaskBounds(displayLayout, destinationBounds) getDefaultDesktopTaskBounds(displayLayout, destinationBounds) } } else { } else { // Toggle to the stable bounds. // Save current bounds so that task can be restored back to original bounds if necessary // and toggle to the stable bounds. val taskBounds = taskInfo.configuration.windowConfiguration.bounds desktopModeTaskRepository.saveBoundsBeforeMaximize(taskInfo.taskId, taskBounds) destinationBounds.set(stableBounds) destinationBounds.set(stableBounds) } } Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepositoryTest.kt +26 −0 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.wm.shell.desktopmode package com.android.wm.shell.desktopmode import android.graphics.Rect import android.testing.AndroidTestingRunner import android.testing.AndroidTestingRunner import android.view.Display.DEFAULT_DISPLAY import android.view.Display.DEFAULT_DISPLAY import android.view.Display.INVALID_DISPLAY import android.view.Display.INVALID_DISPLAY Loading Loading @@ -406,6 +407,31 @@ class DesktopModeTaskRepositoryTest : ShellTestCase() { assertThat(listener.stashedOnSecondaryDisplay).isTrue() assertThat(listener.stashedOnSecondaryDisplay).isTrue() } } @Test fun removeFreeformTask_removesTaskBoundsBeforeMaximize() { val taskId = 1 repo.saveBoundsBeforeMaximize(taskId, Rect(0, 0, 200, 200)) repo.removeFreeformTask(taskId) assertThat(repo.removeBoundsBeforeMaximize(taskId)).isNull() } @Test fun saveBoundsBeforeMaximize_boundsSavedByTaskId() { val taskId = 1 val bounds = Rect(0, 0, 200, 200) repo.saveBoundsBeforeMaximize(taskId, bounds) assertThat(repo.removeBoundsBeforeMaximize(taskId)).isEqualTo(bounds) } @Test fun removeBoundsBeforeMaximize_returnsNullAfterBoundsRemoved() { val taskId = 1 val bounds = Rect(0, 0, 200, 200) repo.saveBoundsBeforeMaximize(taskId, bounds) repo.removeBoundsBeforeMaximize(taskId) assertThat(repo.removeBoundsBeforeMaximize(taskId)).isNull() } class TestListener : DesktopModeTaskRepository.ActiveTasksListener { class TestListener : DesktopModeTaskRepository.ActiveTasksListener { var activeChangesOnDefaultDisplay = 0 var activeChangesOnDefaultDisplay = 0 var activeChangesOnSecondaryDisplay = 0 var activeChangesOnSecondaryDisplay = 0 Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +88 −10 Original line number Original line Diff line number Diff line Loading @@ -95,9 +95,10 @@ import org.mockito.Mockito.anyInt import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.mock import org.mockito.Mockito.mock import org.mockito.Mockito.verify import org.mockito.Mockito.verify import org.mockito.kotlin.times import org.mockito.kotlin.atLeastOnce import org.mockito.Mockito.`when` as whenever import org.mockito.kotlin.capture import org.mockito.quality.Strictness import org.mockito.quality.Strictness import org.mockito.Mockito.`when` as whenever /** /** * Test class for {@link DesktopTasksController} * Test class for {@link DesktopTasksController} Loading @@ -116,13 +117,14 @@ class DesktopTasksControllerTest : ShellTestCase() { @Mock lateinit var shellCommandHandler: ShellCommandHandler @Mock lateinit var shellCommandHandler: ShellCommandHandler @Mock lateinit var shellController: ShellController @Mock lateinit var shellController: ShellController @Mock lateinit var displayController: DisplayController @Mock lateinit var displayController: DisplayController @Mock lateinit var displayLayout: DisplayLayout @Mock lateinit var shellTaskOrganizer: ShellTaskOrganizer @Mock lateinit var shellTaskOrganizer: ShellTaskOrganizer @Mock lateinit var syncQueue: SyncTransactionQueue @Mock lateinit var syncQueue: SyncTransactionQueue @Mock lateinit var rootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer @Mock lateinit var rootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer @Mock lateinit var transitions: Transitions @Mock lateinit var transitions: Transitions @Mock lateinit var exitDesktopTransitionHandler: ExitDesktopTaskTransitionHandler @Mock lateinit var exitDesktopTransitionHandler: ExitDesktopTaskTransitionHandler @Mock lateinit var enterDesktopTransitionHandler: EnterDesktopTaskTransitionHandler @Mock lateinit var enterDesktopTransitionHandler: EnterDesktopTaskTransitionHandler @Mock lateinit var mToggleResizeDesktopTaskTransitionHandler: @Mock lateinit var toggleResizeDesktopTaskTransitionHandler: ToggleResizeDesktopTaskTransitionHandler ToggleResizeDesktopTaskTransitionHandler @Mock lateinit var dragToDesktopTransitionHandler: DragToDesktopTransitionHandler @Mock lateinit var dragToDesktopTransitionHandler: DragToDesktopTransitionHandler @Mock lateinit var launchAdjacentController: LaunchAdjacentController @Mock lateinit var launchAdjacentController: LaunchAdjacentController Loading Loading @@ -154,6 +156,10 @@ class DesktopTasksControllerTest : ShellTestCase() { whenever(shellTaskOrganizer.getRunningTasks(anyInt())).thenAnswer { runningTasks } whenever(shellTaskOrganizer.getRunningTasks(anyInt())).thenAnswer { runningTasks } whenever(transitions.startTransition(anyInt(), any(), isNull())).thenAnswer { Binder() } whenever(transitions.startTransition(anyInt(), any(), isNull())).thenAnswer { Binder() } whenever(displayController.getDisplayLayout(anyInt())).thenReturn(displayLayout) whenever(displayLayout.getStableBounds(any())).thenAnswer { i -> (i.arguments.first() as Rect).set(STABLE_BOUNDS) } controller = createController() controller = createController() controller.setSplitScreenController(splitScreenController) controller.setSplitScreenController(splitScreenController) Loading @@ -179,7 +185,7 @@ class DesktopTasksControllerTest : ShellTestCase() { transitions, transitions, enterDesktopTransitionHandler, enterDesktopTransitionHandler, exitDesktopTransitionHandler, exitDesktopTransitionHandler, mToggleResizeDesktopTaskTransitionHandler, toggleResizeDesktopTaskTransitionHandler, dragToDesktopTransitionHandler, dragToDesktopTransitionHandler, desktopModeTaskRepository, desktopModeTaskRepository, desktopModeLoggerTransitionObserver, desktopModeLoggerTransitionObserver, Loading Loading @@ -936,8 +942,67 @@ class DesktopTasksControllerTest : ShellTestCase() { ) ) } } private fun setUpFreeformTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo { @Test val task = createFreeformTask(displayId) fun toggleBounds_togglesToStableBounds() { val bounds = Rect(0, 0, 100, 100) val task = setUpFreeformTask(DEFAULT_DISPLAY, bounds) controller.toggleDesktopTaskSize(task) // Assert bounds set to stable bounds val wct = getLatestToggleResizeDesktopTaskWct() assertThat(wct.changes[task.token.asBinder()]?.configuration?.windowConfiguration?.bounds) .isEqualTo(STABLE_BOUNDS) } @Test fun toggleBounds_lastBoundsBeforeMaximizeSaved() { val bounds = Rect(0, 0, 100, 100) val task = setUpFreeformTask(DEFAULT_DISPLAY, bounds) controller.toggleDesktopTaskSize(task) assertThat(desktopModeTaskRepository.removeBoundsBeforeMaximize(task.taskId)) .isEqualTo(bounds) } @Test fun toggleBounds_togglesFromStableBoundsToLastBoundsBeforeMaximize() { val boundsBeforeMaximize = Rect(0, 0, 100, 100) val task = setUpFreeformTask(DEFAULT_DISPLAY, boundsBeforeMaximize) // Maximize controller.toggleDesktopTaskSize(task) task.configuration.windowConfiguration.bounds.set(STABLE_BOUNDS) // Restore controller.toggleDesktopTaskSize(task) // Assert bounds set to last bounds before maximize val wct = getLatestToggleResizeDesktopTaskWct() assertThat(wct.changes[task.token.asBinder()]?.configuration?.windowConfiguration?.bounds) .isEqualTo(boundsBeforeMaximize) } @Test fun toggleBounds_removesLastBoundsBeforeMaximizeAfterRestoringBounds() { val boundsBeforeMaximize = Rect(0, 0, 100, 100) val task = setUpFreeformTask(DEFAULT_DISPLAY, boundsBeforeMaximize) // Maximize controller.toggleDesktopTaskSize(task) task.configuration.windowConfiguration.bounds.set(STABLE_BOUNDS) // Restore controller.toggleDesktopTaskSize(task) // Assert last bounds before maximize removed after use assertThat(desktopModeTaskRepository.removeBoundsBeforeMaximize(task.taskId)).isNull() } private fun setUpFreeformTask( displayId: Int = DEFAULT_DISPLAY, bounds: Rect? = null ): RunningTaskInfo { val task = createFreeformTask(displayId, bounds) whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task) whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task) desktopModeTaskRepository.addActiveTask(displayId, task.taskId) desktopModeTaskRepository.addActiveTask(displayId, task.taskId) desktopModeTaskRepository.addOrMoveFreeformTaskToTop(task.taskId) desktopModeTaskRepository.addOrMoveFreeformTaskToTop(task.taskId) Loading Loading @@ -1004,6 +1069,18 @@ class DesktopTasksControllerTest : ShellTestCase() { return arg.value return arg.value } } private fun getLatestToggleResizeDesktopTaskWct(): WindowContainerTransaction { val arg: ArgumentCaptor<WindowContainerTransaction> = ArgumentCaptor.forClass(WindowContainerTransaction::class.java) if (ENABLE_SHELL_TRANSITIONS) { verify(toggleResizeDesktopTaskTransitionHandler, atLeastOnce()) .startTransition(capture(arg)) } else { verify(shellTaskOrganizer).applyTransaction(capture(arg)) } return arg.value } private fun getLatestMoveToDesktopWct(): WindowContainerTransaction { private fun getLatestMoveToDesktopWct(): WindowContainerTransaction { val arg = ArgumentCaptor.forClass(WindowContainerTransaction::class.java) val arg = ArgumentCaptor.forClass(WindowContainerTransaction::class.java) if (ENABLE_SHELL_TRANSITIONS) { if (ENABLE_SHELL_TRANSITIONS) { Loading Loading @@ -1042,6 +1119,7 @@ class DesktopTasksControllerTest : ShellTestCase() { companion object { companion object { const val SECOND_DISPLAY = 2 const val SECOND_DISPLAY = 2 private val STABLE_BOUNDS = Rect(0, 0, 1000, 1000) } } } } Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt +6 −1 Original line number Original line Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN import android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW import android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW import android.graphics.Rect import android.view.Display.DEFAULT_DISPLAY import android.view.Display.DEFAULT_DISPLAY import com.android.wm.shell.MockToken import com.android.wm.shell.MockToken import com.android.wm.shell.TestRunningTaskInfoBuilder import com.android.wm.shell.TestRunningTaskInfoBuilder Loading @@ -31,13 +32,17 @@ class DesktopTestHelpers { /** Create a task that has windowing mode set to [WINDOWING_MODE_FREEFORM] */ /** Create a task that has windowing mode set to [WINDOWING_MODE_FREEFORM] */ @JvmStatic @JvmStatic @JvmOverloads @JvmOverloads fun createFreeformTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo { fun createFreeformTask( displayId: Int = DEFAULT_DISPLAY, bounds: Rect? = null ): RunningTaskInfo { return TestRunningTaskInfoBuilder() return TestRunningTaskInfoBuilder() .setDisplayId(displayId) .setDisplayId(displayId) .setToken(MockToken().token()) .setToken(MockToken().token()) .setActivityType(ACTIVITY_TYPE_STANDARD) .setActivityType(ACTIVITY_TYPE_STANDARD) .setWindowingMode(WINDOWING_MODE_FREEFORM) .setWindowingMode(WINDOWING_MODE_FREEFORM) .setLastActiveTime(100) .setLastActiveTime(100) .apply { bounds?.let { setBounds(it) }} .build() .build() } } Loading