Always bring desktop tasks to front
When showDesktop API is called, always bring desktop tasks to front. And ignore the visibility status of the tasks. Fixes an issue with launching desktop tasks from launcher when they are already visible. Skipping the reorder calls causes second invoke from launcher to hide all tasks. Bug: 263264985 Test: atest DesktopModeControllerTest DesktopTasksControllerTest Change-Id: Iaf5b77e24b75bf8dc8f1daeb749fa0e8e71fb232
This commit is contained in:
@@ -251,7 +251,8 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll
|
||||
* Show apps on desktop
|
||||
*/
|
||||
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) {
|
||||
mTransitions.startTransition(TRANSIT_TO_FRONT, wct, null /* handler */);
|
||||
@@ -261,7 +262,7 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private WindowContainerTransaction bringDesktopAppsToFront() {
|
||||
private WindowContainerTransaction bringDesktopAppsToFront(boolean force) {
|
||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
final ArraySet<Integer> activeTasks = mDesktopModeTaskRepository.getActiveTasks();
|
||||
ProtoLog.d(WM_SHELL_DESKTOP_MODE, "bringDesktopAppsToFront: tasks=%s", activeTasks.size());
|
||||
@@ -278,12 +279,14 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll
|
||||
return wct;
|
||||
}
|
||||
|
||||
final boolean allActiveTasksAreVisible = taskInfos.stream()
|
||||
.allMatch(info -> mDesktopModeTaskRepository.isVisibleTask(info.taskId));
|
||||
if (allActiveTasksAreVisible) {
|
||||
ProtoLog.d(WM_SHELL_DESKTOP_MODE,
|
||||
"bringDesktopAppsToFront: active tasks are already in front, skipping.");
|
||||
return wct;
|
||||
if (!force) {
|
||||
final boolean allActiveTasksAreVisible = taskInfos.stream()
|
||||
.allMatch(info -> mDesktopModeTaskRepository.isVisibleTask(info.taskId));
|
||||
if (allActiveTasksAreVisible) {
|
||||
ProtoLog.d(WM_SHELL_DESKTOP_MODE,
|
||||
"bringDesktopAppsToFront: active tasks are already in front, skipping.");
|
||||
return wct;
|
||||
}
|
||||
}
|
||||
ProtoLog.d(WM_SHELL_DESKTOP_MODE,
|
||||
"bringDesktopAppsToFront: reordering all active tasks to the front");
|
||||
@@ -354,7 +357,7 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll
|
||||
if (wct == null) {
|
||||
wct = new WindowContainerTransaction();
|
||||
}
|
||||
wct.merge(bringDesktopAppsToFront(), true /* transfer */);
|
||||
wct.merge(bringDesktopAppsToFront(false /* ignoreVisibility */), true /* transfer */);
|
||||
wct.reorder(request.getTriggerTask().token, true /* onTop */);
|
||||
|
||||
return wct;
|
||||
|
||||
@@ -84,8 +84,7 @@ class DesktopTasksController(
|
||||
fun showDesktopApps() {
|
||||
ProtoLog.v(WM_SHELL_DESKTOP_MODE, "showDesktopApps")
|
||||
val wct = WindowContainerTransaction()
|
||||
|
||||
bringDesktopAppsToFront(wct)
|
||||
bringDesktopAppsToFront(wct, force = true)
|
||||
|
||||
// Execute transaction if there are pending operations
|
||||
if (!wct.isEmpty) {
|
||||
@@ -150,11 +149,11 @@ class DesktopTasksController(
|
||||
?: WINDOWING_MODE_UNDEFINED
|
||||
}
|
||||
|
||||
private fun bringDesktopAppsToFront(wct: WindowContainerTransaction) {
|
||||
private fun bringDesktopAppsToFront(wct: WindowContainerTransaction, force: Boolean = false) {
|
||||
val activeTasks = desktopModeTaskRepository.getActiveTasks()
|
||||
|
||||
// Skip if all tasks are already visible
|
||||
if (activeTasks.isNotEmpty() && activeTasks.all(desktopModeTaskRepository::isVisibleTask)) {
|
||||
if (!force && activeTasks.all(desktopModeTaskRepository::isVisibleTask)) {
|
||||
ProtoLog.d(
|
||||
WM_SHELL_DESKTOP_MODE,
|
||||
"bringDesktopAppsToFront: active tasks are already in front, skipping."
|
||||
|
||||
@@ -279,7 +279,7 @@ public class DesktopModeControllerTest extends ShellTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowDesktopApps_appsAlreadyVisible_doesNothing() {
|
||||
public void testShowDesktopApps_appsAlreadyVisible_bringsToFront() {
|
||||
final RunningTaskInfo task1 = createFreeformTask();
|
||||
mDesktopModeTaskRepository.addActiveTask(task1.taskId);
|
||||
mDesktopModeTaskRepository.addOrMoveFreeformTaskToTop(task1.taskId);
|
||||
@@ -294,8 +294,17 @@ public class DesktopModeControllerTest extends ShellTestCase {
|
||||
mController.showDesktopApps();
|
||||
|
||||
final WindowContainerTransaction wct = getBringAppsToFrontTransaction();
|
||||
// No reordering needed.
|
||||
assertThat(wct.getHierarchyOps()).isEmpty();
|
||||
// Check wct has reorder calls
|
||||
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
|
||||
|
||||
@@ -150,8 +150,8 @@ class DesktopTasksControllerTest : ShellTestCase() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun showDesktopApps_appsAlreadyVisible_doesNothing() {
|
||||
setUpHomeTask()
|
||||
fun showDesktopApps_appsAlreadyVisible_bringsToFront() {
|
||||
val homeTask = setUpHomeTask()
|
||||
val task1 = setUpFreeformTask()
|
||||
val task2 = setUpFreeformTask()
|
||||
markTaskVisible(task1)
|
||||
@@ -159,7 +159,12 @@ class DesktopTasksControllerTest : ShellTestCase() {
|
||||
|
||||
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
|
||||
@@ -206,6 +211,23 @@ class DesktopTasksControllerTest : ShellTestCase() {
|
||||
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
|
||||
fun moveToFullscreen() {
|
||||
val task = setUpFreeformTask()
|
||||
@@ -406,3 +428,9 @@ private fun WindowContainerTransaction.assertReorderAt(index: Int, task: Running
|
||||
assertThat(op.type).isEqualTo(HIERARCHY_OP_TYPE_REORDER)
|
||||
assertThat(op.container).isEqualTo(task.token.asBinder())
|
||||
}
|
||||
|
||||
private fun WindowContainerTransaction.assertReorderSequence(vararg tasks: RunningTaskInfo) {
|
||||
for (i in tasks.indices) {
|
||||
assertReorderAt(i, tasks[i])
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user