Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java +12 −9 Original line number Original line Diff line number Diff line Loading @@ -251,7 +251,8 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll * Show apps on desktop * Show apps on desktop */ */ void showDesktopApps() { void showDesktopApps() { WindowContainerTransaction wct = bringDesktopAppsToFront(); // Bring apps to front, ignoring their visibility status to always ensure they are on top. WindowContainerTransaction wct = bringDesktopAppsToFront(true /* ignoreVisibility */); if (Transitions.ENABLE_SHELL_TRANSITIONS) { if (Transitions.ENABLE_SHELL_TRANSITIONS) { mTransitions.startTransition(TRANSIT_TO_FRONT, wct, null /* handler */); mTransitions.startTransition(TRANSIT_TO_FRONT, wct, null /* handler */); Loading @@ -261,7 +262,7 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll } } @NonNull @NonNull private WindowContainerTransaction bringDesktopAppsToFront() { private WindowContainerTransaction bringDesktopAppsToFront(boolean force) { final WindowContainerTransaction wct = new WindowContainerTransaction(); final WindowContainerTransaction wct = new WindowContainerTransaction(); final ArraySet<Integer> activeTasks = mDesktopModeTaskRepository.getActiveTasks(); final ArraySet<Integer> activeTasks = mDesktopModeTaskRepository.getActiveTasks(); ProtoLog.d(WM_SHELL_DESKTOP_MODE, "bringDesktopAppsToFront: tasks=%s", activeTasks.size()); ProtoLog.d(WM_SHELL_DESKTOP_MODE, "bringDesktopAppsToFront: tasks=%s", activeTasks.size()); Loading @@ -278,6 +279,7 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll return wct; return wct; } } if (!force) { final boolean allActiveTasksAreVisible = taskInfos.stream() final boolean allActiveTasksAreVisible = taskInfos.stream() .allMatch(info -> mDesktopModeTaskRepository.isVisibleTask(info.taskId)); .allMatch(info -> mDesktopModeTaskRepository.isVisibleTask(info.taskId)); if (allActiveTasksAreVisible) { if (allActiveTasksAreVisible) { Loading @@ -285,6 +287,7 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll "bringDesktopAppsToFront: active tasks are already in front, skipping."); "bringDesktopAppsToFront: active tasks are already in front, skipping."); return wct; return wct; } } } ProtoLog.d(WM_SHELL_DESKTOP_MODE, ProtoLog.d(WM_SHELL_DESKTOP_MODE, "bringDesktopAppsToFront: reordering all active tasks to the front"); "bringDesktopAppsToFront: reordering all active tasks to the front"); final List<Integer> allTasksInZOrder = final List<Integer> allTasksInZOrder = Loading Loading @@ -354,7 +357,7 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll if (wct == null) { if (wct == null) { wct = new WindowContainerTransaction(); wct = new WindowContainerTransaction(); } } wct.merge(bringDesktopAppsToFront(), true /* transfer */); wct.merge(bringDesktopAppsToFront(false /* ignoreVisibility */), true /* transfer */); wct.reorder(request.getTriggerTask().token, true /* onTop */); wct.reorder(request.getTriggerTask().token, true /* onTop */); return wct; return wct; Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +3 −4 Original line number Original line Diff line number Diff line Loading @@ -84,8 +84,7 @@ class DesktopTasksController( fun showDesktopApps() { fun showDesktopApps() { ProtoLog.v(WM_SHELL_DESKTOP_MODE, "showDesktopApps") ProtoLog.v(WM_SHELL_DESKTOP_MODE, "showDesktopApps") val wct = WindowContainerTransaction() val wct = WindowContainerTransaction() bringDesktopAppsToFront(wct, force = true) bringDesktopAppsToFront(wct) // Execute transaction if there are pending operations // Execute transaction if there are pending operations if (!wct.isEmpty) { if (!wct.isEmpty) { Loading Loading @@ -150,11 +149,11 @@ class DesktopTasksController( ?: WINDOWING_MODE_UNDEFINED ?: WINDOWING_MODE_UNDEFINED } } private fun bringDesktopAppsToFront(wct: WindowContainerTransaction) { private fun bringDesktopAppsToFront(wct: WindowContainerTransaction, force: Boolean = false) { val activeTasks = desktopModeTaskRepository.getActiveTasks() val activeTasks = desktopModeTaskRepository.getActiveTasks() // Skip if all tasks are already visible // Skip if all tasks are already visible if (activeTasks.isNotEmpty() && activeTasks.all(desktopModeTaskRepository::isVisibleTask)) { if (!force && activeTasks.all(desktopModeTaskRepository::isVisibleTask)) { ProtoLog.d( ProtoLog.d( WM_SHELL_DESKTOP_MODE, WM_SHELL_DESKTOP_MODE, "bringDesktopAppsToFront: active tasks are already in front, skipping." "bringDesktopAppsToFront: active tasks are already in front, skipping." Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java +12 −3 Original line number Original line Diff line number Diff line Loading @@ -279,7 +279,7 @@ public class DesktopModeControllerTest extends ShellTestCase { } } @Test @Test public void testShowDesktopApps_appsAlreadyVisible_doesNothing() { public void testShowDesktopApps_appsAlreadyVisible_bringsToFront() { final RunningTaskInfo task1 = createFreeformTask(); final RunningTaskInfo task1 = createFreeformTask(); mDesktopModeTaskRepository.addActiveTask(task1.taskId); mDesktopModeTaskRepository.addActiveTask(task1.taskId); mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(task1.taskId); mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(task1.taskId); Loading @@ -294,8 +294,17 @@ public class DesktopModeControllerTest extends ShellTestCase { mController.showDesktopApps(); mController.showDesktopApps(); final WindowContainerTransaction wct = getBringAppsToFrontTransaction(); final WindowContainerTransaction wct = getBringAppsToFrontTransaction(); // No reordering needed. // Check wct has reorder calls assertThat(wct.getHierarchyOps()).isEmpty(); assertThat(wct.getHierarchyOps()).hasSize(2); // Task 1 appeared first, must be first reorder to top. HierarchyOp op1 = wct.getHierarchyOps().get(0); assertThat(op1.getType()).isEqualTo(HIERARCHY_OP_TYPE_REORDER); assertThat(op1.getContainer()).isEqualTo(task1.token.asBinder()); // Task 2 appeared last, must be last reorder to top. HierarchyOp op2 = wct.getHierarchyOps().get(1); assertThat(op2.getType()).isEqualTo(HIERARCHY_OP_TYPE_REORDER); assertThat(op2.getContainer()).isEqualTo(task2.token.asBinder()); } } @Test @Test Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +31 −3 Original line number Original line Diff line number Diff line Loading @@ -150,8 +150,8 @@ class DesktopTasksControllerTest : ShellTestCase() { } } @Test @Test fun showDesktopApps_appsAlreadyVisible_doesNothing() { fun showDesktopApps_appsAlreadyVisible_bringsToFront() { setUpHomeTask() val homeTask = setUpHomeTask() val task1 = setUpFreeformTask() val task1 = setUpFreeformTask() val task2 = setUpFreeformTask() val task2 = setUpFreeformTask() markTaskVisible(task1) markTaskVisible(task1) Loading @@ -159,7 +159,12 @@ class DesktopTasksControllerTest : ShellTestCase() { controller.showDesktopApps() controller.showDesktopApps() verifyWCTNotExecuted() val wct = getLatestWct() assertThat(wct.hierarchyOps).hasSize(3) // Expect order to be from bottom: home, task1, task2 wct.assertReorderAt(index = 0, homeTask) wct.assertReorderAt(index = 1, task1) wct.assertReorderAt(index = 2, task2) } } @Test @Test Loading Loading @@ -206,6 +211,23 @@ class DesktopTasksControllerTest : ShellTestCase() { verifyWCTNotExecuted() verifyWCTNotExecuted() } } @Test fun moveToDesktop_otherFreeformTasksBroughtToFront() { val homeTask = setUpHomeTask() val freeformTask = setUpFreeformTask() val fullscreenTask = setUpFullscreenTask() markTaskHidden(freeformTask) controller.moveToDesktop(fullscreenTask) with(getLatestWct()) { assertThat(hierarchyOps).hasSize(3) assertReorderSequence(homeTask, freeformTask, fullscreenTask) assertThat(changes[fullscreenTask.token.asBinder()]?.windowingMode) .isEqualTo(WINDOWING_MODE_FREEFORM) } } @Test @Test fun moveToFullscreen() { fun moveToFullscreen() { val task = setUpFreeformTask() val task = setUpFreeformTask() Loading Loading @@ -406,3 +428,9 @@ private fun WindowContainerTransaction.assertReorderAt(index: Int, task: Running assertThat(op.type).isEqualTo(HIERARCHY_OP_TYPE_REORDER) assertThat(op.type).isEqualTo(HIERARCHY_OP_TYPE_REORDER) assertThat(op.container).isEqualTo(task.token.asBinder()) assertThat(op.container).isEqualTo(task.token.asBinder()) } } private fun WindowContainerTransaction.assertReorderSequence(vararg tasks: RunningTaskInfo) { for (i in tasks.indices) { assertReorderAt(i, tasks[i]) } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java +12 −9 Original line number Original line Diff line number Diff line Loading @@ -251,7 +251,8 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll * Show apps on desktop * Show apps on desktop */ */ void showDesktopApps() { void showDesktopApps() { WindowContainerTransaction wct = bringDesktopAppsToFront(); // Bring apps to front, ignoring their visibility status to always ensure they are on top. WindowContainerTransaction wct = bringDesktopAppsToFront(true /* ignoreVisibility */); if (Transitions.ENABLE_SHELL_TRANSITIONS) { if (Transitions.ENABLE_SHELL_TRANSITIONS) { mTransitions.startTransition(TRANSIT_TO_FRONT, wct, null /* handler */); mTransitions.startTransition(TRANSIT_TO_FRONT, wct, null /* handler */); Loading @@ -261,7 +262,7 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll } } @NonNull @NonNull private WindowContainerTransaction bringDesktopAppsToFront() { private WindowContainerTransaction bringDesktopAppsToFront(boolean force) { final WindowContainerTransaction wct = new WindowContainerTransaction(); final WindowContainerTransaction wct = new WindowContainerTransaction(); final ArraySet<Integer> activeTasks = mDesktopModeTaskRepository.getActiveTasks(); final ArraySet<Integer> activeTasks = mDesktopModeTaskRepository.getActiveTasks(); ProtoLog.d(WM_SHELL_DESKTOP_MODE, "bringDesktopAppsToFront: tasks=%s", activeTasks.size()); ProtoLog.d(WM_SHELL_DESKTOP_MODE, "bringDesktopAppsToFront: tasks=%s", activeTasks.size()); Loading @@ -278,6 +279,7 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll return wct; return wct; } } if (!force) { final boolean allActiveTasksAreVisible = taskInfos.stream() final boolean allActiveTasksAreVisible = taskInfos.stream() .allMatch(info -> mDesktopModeTaskRepository.isVisibleTask(info.taskId)); .allMatch(info -> mDesktopModeTaskRepository.isVisibleTask(info.taskId)); if (allActiveTasksAreVisible) { if (allActiveTasksAreVisible) { Loading @@ -285,6 +287,7 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll "bringDesktopAppsToFront: active tasks are already in front, skipping."); "bringDesktopAppsToFront: active tasks are already in front, skipping."); return wct; return wct; } } } ProtoLog.d(WM_SHELL_DESKTOP_MODE, ProtoLog.d(WM_SHELL_DESKTOP_MODE, "bringDesktopAppsToFront: reordering all active tasks to the front"); "bringDesktopAppsToFront: reordering all active tasks to the front"); final List<Integer> allTasksInZOrder = final List<Integer> allTasksInZOrder = Loading Loading @@ -354,7 +357,7 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll if (wct == null) { if (wct == null) { wct = new WindowContainerTransaction(); wct = new WindowContainerTransaction(); } } wct.merge(bringDesktopAppsToFront(), true /* transfer */); wct.merge(bringDesktopAppsToFront(false /* ignoreVisibility */), true /* transfer */); wct.reorder(request.getTriggerTask().token, true /* onTop */); wct.reorder(request.getTriggerTask().token, true /* onTop */); return wct; return wct; Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +3 −4 Original line number Original line Diff line number Diff line Loading @@ -84,8 +84,7 @@ class DesktopTasksController( fun showDesktopApps() { fun showDesktopApps() { ProtoLog.v(WM_SHELL_DESKTOP_MODE, "showDesktopApps") ProtoLog.v(WM_SHELL_DESKTOP_MODE, "showDesktopApps") val wct = WindowContainerTransaction() val wct = WindowContainerTransaction() bringDesktopAppsToFront(wct, force = true) bringDesktopAppsToFront(wct) // Execute transaction if there are pending operations // Execute transaction if there are pending operations if (!wct.isEmpty) { if (!wct.isEmpty) { Loading Loading @@ -150,11 +149,11 @@ class DesktopTasksController( ?: WINDOWING_MODE_UNDEFINED ?: WINDOWING_MODE_UNDEFINED } } private fun bringDesktopAppsToFront(wct: WindowContainerTransaction) { private fun bringDesktopAppsToFront(wct: WindowContainerTransaction, force: Boolean = false) { val activeTasks = desktopModeTaskRepository.getActiveTasks() val activeTasks = desktopModeTaskRepository.getActiveTasks() // Skip if all tasks are already visible // Skip if all tasks are already visible if (activeTasks.isNotEmpty() && activeTasks.all(desktopModeTaskRepository::isVisibleTask)) { if (!force && activeTasks.all(desktopModeTaskRepository::isVisibleTask)) { ProtoLog.d( ProtoLog.d( WM_SHELL_DESKTOP_MODE, WM_SHELL_DESKTOP_MODE, "bringDesktopAppsToFront: active tasks are already in front, skipping." "bringDesktopAppsToFront: active tasks are already in front, skipping." Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java +12 −3 Original line number Original line Diff line number Diff line Loading @@ -279,7 +279,7 @@ public class DesktopModeControllerTest extends ShellTestCase { } } @Test @Test public void testShowDesktopApps_appsAlreadyVisible_doesNothing() { public void testShowDesktopApps_appsAlreadyVisible_bringsToFront() { final RunningTaskInfo task1 = createFreeformTask(); final RunningTaskInfo task1 = createFreeformTask(); mDesktopModeTaskRepository.addActiveTask(task1.taskId); mDesktopModeTaskRepository.addActiveTask(task1.taskId); mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(task1.taskId); mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(task1.taskId); Loading @@ -294,8 +294,17 @@ public class DesktopModeControllerTest extends ShellTestCase { mController.showDesktopApps(); mController.showDesktopApps(); final WindowContainerTransaction wct = getBringAppsToFrontTransaction(); final WindowContainerTransaction wct = getBringAppsToFrontTransaction(); // No reordering needed. // Check wct has reorder calls assertThat(wct.getHierarchyOps()).isEmpty(); assertThat(wct.getHierarchyOps()).hasSize(2); // Task 1 appeared first, must be first reorder to top. HierarchyOp op1 = wct.getHierarchyOps().get(0); assertThat(op1.getType()).isEqualTo(HIERARCHY_OP_TYPE_REORDER); assertThat(op1.getContainer()).isEqualTo(task1.token.asBinder()); // Task 2 appeared last, must be last reorder to top. HierarchyOp op2 = wct.getHierarchyOps().get(1); assertThat(op2.getType()).isEqualTo(HIERARCHY_OP_TYPE_REORDER); assertThat(op2.getContainer()).isEqualTo(task2.token.asBinder()); } } @Test @Test Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +31 −3 Original line number Original line Diff line number Diff line Loading @@ -150,8 +150,8 @@ class DesktopTasksControllerTest : ShellTestCase() { } } @Test @Test fun showDesktopApps_appsAlreadyVisible_doesNothing() { fun showDesktopApps_appsAlreadyVisible_bringsToFront() { setUpHomeTask() val homeTask = setUpHomeTask() val task1 = setUpFreeformTask() val task1 = setUpFreeformTask() val task2 = setUpFreeformTask() val task2 = setUpFreeformTask() markTaskVisible(task1) markTaskVisible(task1) Loading @@ -159,7 +159,12 @@ class DesktopTasksControllerTest : ShellTestCase() { controller.showDesktopApps() controller.showDesktopApps() verifyWCTNotExecuted() val wct = getLatestWct() assertThat(wct.hierarchyOps).hasSize(3) // Expect order to be from bottom: home, task1, task2 wct.assertReorderAt(index = 0, homeTask) wct.assertReorderAt(index = 1, task1) wct.assertReorderAt(index = 2, task2) } } @Test @Test Loading Loading @@ -206,6 +211,23 @@ class DesktopTasksControllerTest : ShellTestCase() { verifyWCTNotExecuted() verifyWCTNotExecuted() } } @Test fun moveToDesktop_otherFreeformTasksBroughtToFront() { val homeTask = setUpHomeTask() val freeformTask = setUpFreeformTask() val fullscreenTask = setUpFullscreenTask() markTaskHidden(freeformTask) controller.moveToDesktop(fullscreenTask) with(getLatestWct()) { assertThat(hierarchyOps).hasSize(3) assertReorderSequence(homeTask, freeformTask, fullscreenTask) assertThat(changes[fullscreenTask.token.asBinder()]?.windowingMode) .isEqualTo(WINDOWING_MODE_FREEFORM) } } @Test @Test fun moveToFullscreen() { fun moveToFullscreen() { val task = setUpFreeformTask() val task = setUpFreeformTask() Loading Loading @@ -406,3 +428,9 @@ private fun WindowContainerTransaction.assertReorderAt(index: Int, task: Running assertThat(op.type).isEqualTo(HIERARCHY_OP_TYPE_REORDER) assertThat(op.type).isEqualTo(HIERARCHY_OP_TYPE_REORDER) assertThat(op.container).isEqualTo(task.token.asBinder()) assertThat(op.container).isEqualTo(task.token.asBinder()) } } private fun WindowContainerTransaction.assertReorderSequence(vararg tasks: RunningTaskInfo) { for (i in tasks.indices) { assertReorderAt(i, tasks[i]) } }