diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 269a910a46bd3..5195edfb7c867 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -2422,12 +2422,27 @@ class RootWindowContainer extends WindowContainer } private RootTaskInfo getRootTaskInfo(Task task) { - final TaskDisplayArea taskDisplayArea = task.getDisplayArea(); RootTaskInfo info = new RootTaskInfo(); task.fillTaskInfo(info); - // A task might be not attached to a display. - info.position = taskDisplayArea != null ? taskDisplayArea.getTaskIndexOf(task) : 0; + final DisplayContent displayContent = task.getDisplayContent(); + if (displayContent == null) { + // A task might be not attached to a display. + info.position = -1; + } else { + // Find the task z-order among all root tasks on the display from bottom to top. + final int[] taskIndex = new int[1]; + final boolean[] hasFound = new boolean[1]; + displayContent.forAllRootTasks(rootTask -> { + if (task == rootTask) { + hasFound[0] = true; + return true; + } + taskIndex[0]++; + return false; + }, false /* traverseTopToBottom */); + info.position = hasFound[0] ? taskIndex[0] : -1; + } info.visible = task.shouldBeVisible(null); task.getBounds(info.bounds); diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 011500beac26a..2290c23be5137 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -6734,15 +6734,20 @@ class Task extends WindowContainer { if (taskDisplayArea == null) { return false; } - final int index = taskDisplayArea.getTaskIndexOf(this); - if (index == 0) { - return false; - } - final int[] indexCount = new int[1]; + final boolean[] hasFound = new boolean[1]; final Task rootTaskBehind = taskDisplayArea.getRootTask( - // From bottom to top, find the one behind this Task. - task -> ++indexCount[0] == index, false /* traverseTopToBottom */); - return rootTaskBehind.isActivityTypeStandard(); + // From top to bottom, find the one behind this Task. + task -> { + if (hasFound[0]) { + return true; + } + if (task == this) { + // The next one is our target. + hasFound[0] = true; + } + return false; + }); + return rootTaskBehind != null && rootTaskBehind.isActivityTypeStandard(); } boolean shouldUpRecreateTaskLocked(ActivityRecord srec, String destAffinity) { diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java index 866abbde16368..97383e3d1386c 100644 --- a/services/core/java/com/android/server/wm/TaskDisplayArea.java +++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java @@ -212,34 +212,6 @@ final class TaskDisplayArea extends DisplayArea { return getRootTask(t -> true); } - // TODO(b/175832855): Figure-out a way to remove since it might be a source of confusion. - /** - * Gets the order of the given {@link Task} as its z-order in the hierarchy below this TDA. - * The Task can be a direct child of a child TaskDisplayArea. {@code -1} if not found. - */ - int getTaskIndexOf(Task task) { - int index = 0; - final int childCount = getChildCount(); - for (int i = 0; i < childCount; i++) { - final WindowContainer wc = getChildAt(i); - if (wc.asTask() != null) { - if (wc.asTask() == task) { - return index; - } - index++; - } else { - final TaskDisplayArea tda = wc.asTaskDisplayArea(); - final int subIndex = tda.getTaskIndexOf(task); - if (subIndex > -1) { - return index + subIndex; - } else { - index += tda.getRootTaskCount(); - } - } - } - return -1; - } - @Nullable Task getRootHomeTask() { return mRootHomeTask; diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 6e0fec1c80fa5..576d22487437b 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -1677,13 +1677,13 @@ class WindowContainer extends ConfigurationContainer< int count = mChildren.size(); if (traverseTopToBottom) { for (int i = count - 1; i >= 0; --i) { - if (mChildren.get(i).forAllRootTasks(callback)) { + if (mChildren.get(i).forAllRootTasks(callback, traverseTopToBottom)) { return true; } } } else { for (int i = 0; i < count; i++) { - if (mChildren.get(i).forAllRootTasks(callback)) { + if (mChildren.get(i).forAllRootTasks(callback, traverseTopToBottom)) { return true; } // Root tasks may be removed from this display. Ensure each task will be processed diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java index ce0cd70a2f03d..1700707d98664 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java @@ -248,7 +248,7 @@ public class ActivityDisplayTests extends WindowTestsBase { int topPosition = taskDisplayArea.getRootTaskCount() - 1; // Ensure the new alwaysOnTop stack is put below the pinned stack, but on top of the // existing alwaysOnTop stack. - assertEquals(topPosition - 1, taskDisplayArea.getTaskIndexOf(anotherAlwaysOnTopStack)); + assertEquals(topPosition - 1, getTaskIndexOf(taskDisplayArea, anotherAlwaysOnTopStack)); final Task nonAlwaysOnTopStack = taskDisplayArea.createRootTask( WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, true /* onTop */); @@ -256,7 +256,7 @@ public class ActivityDisplayTests extends WindowTestsBase { topPosition = taskDisplayArea.getRootTaskCount() - 1; // Ensure the non-alwaysOnTop stack is put below the three alwaysOnTop stacks, but above the // existing other non-alwaysOnTop stacks. - assertEquals(topPosition - 3, taskDisplayArea.getTaskIndexOf(nonAlwaysOnTopStack)); + assertEquals(topPosition - 3, getTaskIndexOf(taskDisplayArea, nonAlwaysOnTopStack)); anotherAlwaysOnTopStack.setAlwaysOnTop(false); taskDisplayArea.positionChildAt(POSITION_TOP, anotherAlwaysOnTopStack, @@ -264,16 +264,16 @@ public class ActivityDisplayTests extends WindowTestsBase { assertFalse(anotherAlwaysOnTopStack.isAlwaysOnTop()); // Ensure, when always on top is turned off for a stack, the stack is put just below all // other always on top stacks. - assertEquals(topPosition - 2, taskDisplayArea.getTaskIndexOf(anotherAlwaysOnTopStack)); + assertEquals(topPosition - 2, getTaskIndexOf(taskDisplayArea, anotherAlwaysOnTopStack)); anotherAlwaysOnTopStack.setAlwaysOnTop(true); // Ensure always on top state changes properly when windowing mode changes. anotherAlwaysOnTopStack.setWindowingMode(WINDOWING_MODE_FULLSCREEN); assertFalse(anotherAlwaysOnTopStack.isAlwaysOnTop()); - assertEquals(topPosition - 2, taskDisplayArea.getTaskIndexOf(anotherAlwaysOnTopStack)); + assertEquals(topPosition - 2, getTaskIndexOf(taskDisplayArea, anotherAlwaysOnTopStack)); anotherAlwaysOnTopStack.setWindowingMode(WINDOWING_MODE_FREEFORM); assertTrue(anotherAlwaysOnTopStack.isAlwaysOnTop()); - assertEquals(topPosition - 1, taskDisplayArea.getTaskIndexOf(anotherAlwaysOnTopStack)); + assertEquals(topPosition - 1, getTaskIndexOf(taskDisplayArea, anotherAlwaysOnTopStack)); final Task dreamStack = taskDisplayArea.createRootTask( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_DREAM, true /* onTop */); @@ -282,7 +282,7 @@ public class ActivityDisplayTests extends WindowTestsBase { topPosition = taskDisplayArea.getRootTaskCount() - 1; // Ensure dream shows above all activities, including PiP assertEquals(dreamStack, taskDisplayArea.getTopRootTask()); - assertEquals(topPosition - 1, taskDisplayArea.getTaskIndexOf(pinnedStack)); + assertEquals(topPosition - 1, getTaskIndexOf(taskDisplayArea, pinnedStack)); final Task assistStack = taskDisplayArea.createRootTask( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */); @@ -295,7 +295,7 @@ public class ActivityDisplayTests extends WindowTestsBase { final boolean isAssistantOnTop = mContext.getResources() .getBoolean(com.android.internal.R.bool.config_assistantOnTopOfDream); assertEquals(isAssistantOnTop ? topPosition : topPosition - 4, - taskDisplayArea.getTaskIndexOf(assistStack)); + getTaskIndexOf(taskDisplayArea, assistStack)); } @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java index da70a5122f479..8b8617d8bf3a6 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java @@ -167,7 +167,7 @@ public class ActivityStackTests extends WindowTestsBase { null /* task */); // Assert that stack is at the bottom. - assertEquals(0, mDefaultTaskDisplayArea.getTaskIndexOf(primarySplitScreen)); + assertEquals(0, getTaskIndexOf(mDefaultTaskDisplayArea, primarySplitScreen)); // Ensure no longer in splitscreen. assertEquals(WINDOWING_MODE_FULLSCREEN, primarySplitScreen.getWindowingMode()); @@ -748,10 +748,10 @@ public class ActivityStackTests extends WindowTestsBase { doReturn(false).when(fullscreenStack).isTranslucent(any()); // Ensure that we don't move the home stack if it is already behind the top fullscreen stack - int homeStackIndex = mDefaultTaskDisplayArea.getTaskIndexOf(homeStack); + int homeStackIndex = getTaskIndexOf(mDefaultTaskDisplayArea, homeStack); assertEquals(fullscreenStack, getRootTaskAbove(homeStack)); mDefaultTaskDisplayArea.moveRootTaskBehindBottomMostVisibleRootTask(homeStack); - assertEquals(homeStackIndex, mDefaultTaskDisplayArea.getTaskIndexOf(homeStack)); + assertEquals(homeStackIndex, getTaskIndexOf(mDefaultTaskDisplayArea, homeStack)); } @Test @@ -766,10 +766,10 @@ public class ActivityStackTests extends WindowTestsBase { doReturn(true).when(fullscreenStack).isTranslucent(any()); // Ensure that we don't move the home stack if it is already behind the top fullscreen stack - int homeStackIndex = mDefaultTaskDisplayArea.getTaskIndexOf(homeStack); + int homeStackIndex = getTaskIndexOf(mDefaultTaskDisplayArea, homeStack); assertEquals(fullscreenStack, getRootTaskAbove(homeStack)); mDefaultTaskDisplayArea.moveRootTaskBehindBottomMostVisibleRootTask(homeStack); - assertEquals(homeStackIndex, mDefaultTaskDisplayArea.getTaskIndexOf(homeStack)); + assertEquals(homeStackIndex, getTaskIndexOf(mDefaultTaskDisplayArea, homeStack)); } @Test @@ -784,10 +784,10 @@ public class ActivityStackTests extends WindowTestsBase { doReturn(false).when(fullscreenStack).isTranslucent(any()); // Ensure we don't move the home stack if it is already on top - int homeStackIndex = mDefaultTaskDisplayArea.getTaskIndexOf(homeStack); + int homeStackIndex = getTaskIndexOf(mDefaultTaskDisplayArea, homeStack); assertNull(getRootTaskAbove(homeStack)); mDefaultTaskDisplayArea.moveRootTaskBehindBottomMostVisibleRootTask(homeStack); - assertEquals(homeStackIndex, mDefaultTaskDisplayArea.getTaskIndexOf(homeStack)); + assertEquals(homeStackIndex, getTaskIndexOf(mDefaultTaskDisplayArea, homeStack)); } @Test @@ -853,9 +853,9 @@ public class ActivityStackTests extends WindowTestsBase { doReturn(false).when(fullscreenStack2).isTranslucent(any()); // Ensure we don't move the home stack behind itself - int homeStackIndex = mDefaultTaskDisplayArea.getTaskIndexOf(homeStack); + int homeStackIndex = getTaskIndexOf(mDefaultTaskDisplayArea, homeStack); mDefaultTaskDisplayArea.moveRootTaskBehindRootTask(homeStack, homeStack); - assertEquals(homeStackIndex, mDefaultTaskDisplayArea.getTaskIndexOf(homeStack)); + assertEquals(homeStackIndex, getTaskIndexOf(mDefaultTaskDisplayArea, homeStack)); } @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java index 56c8bd12ac067..ba5ca2e250e83 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java @@ -363,6 +363,33 @@ class WindowTestsBase extends SystemServiceTestsBase { } } + /** + * Gets the order of the given {@link Task} as its z-order in the hierarchy below this TDA. + * The Task can be a direct child of a child TaskDisplayArea. {@code -1} if not found. + */ + static int getTaskIndexOf(TaskDisplayArea taskDisplayArea, Task task) { + int index = 0; + final int childCount = taskDisplayArea.getChildCount(); + for (int i = 0; i < childCount; i++) { + final WindowContainer wc = taskDisplayArea.getChildAt(i); + if (wc.asTask() != null) { + if (wc.asTask() == task) { + return index; + } + index++; + } else { + final TaskDisplayArea tda = wc.asTaskDisplayArea(); + final int subIndex = getTaskIndexOf(tda, task); + if (subIndex > -1) { + return index + subIndex; + } else { + index += tda.getRootTaskCount(); + } + } + } + return -1; + } + /** Creates a {@link TaskDisplayArea} right above the default one. */ static TaskDisplayArea createTaskDisplayArea(DisplayContent displayContent, WindowManagerService service, String name, int displayAreaFeature) {