From 4a85741bd0b1f86f24b56d6fd35d725904dc2909 Mon Sep 17 00:00:00 2001 From: Chris Li Date: Sun, 13 Dec 2020 16:55:34 -0800 Subject: [PATCH] Allow TaskDisplayArea to have TaskDisplayArea children (3/n) - Have TaskDisplayArea extends DisplayArea Bug: 175136051 Test: Passed existing tests Change-Id: I33474acfb0fdb665823a6dcb63635f1e7702a1e2 --- data/etc/services.core.protolog.json | 36 +- .../com/android/server/wm/DisplayContent.java | 23 +- .../android/server/wm/RecentsAnimation.java | 7 +- .../server/wm/RootWindowContainer.java | 140 ++-- .../core/java/com/android/server/wm/Task.java | 38 +- .../android/server/wm/TaskDisplayArea.java | 642 ++++++++++++------ .../server/wm/ActivityDisplayTests.java | 14 +- .../android/server/wm/ActivityStackTests.java | 18 +- .../server/wm/ActivityStarterTests.java | 4 +- .../wm/DisplayAreaPolicyBuilderTest.java | 4 +- .../android/server/wm/WindowTestsBase.java | 6 +- 11 files changed, 584 insertions(+), 348 deletions(-) diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json index d8a735c78ca33..faf49733050ad 100644 --- a/data/etc/services.core.protolog.json +++ b/data/etc/services.core.protolog.json @@ -901,6 +901,12 @@ "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, + "-1069336896": { + "message": "onRootTaskOrderChanged(): rootTask=%s", + "level": "DEBUG", + "group": "WM_DEBUG_RECENTS_ANIMATIONS", + "at": "com\/android\/server\/wm\/RecentsAnimation.java" + }, "-1066383762": { "message": "Sleep still waiting to pause %s", "level": "VERBOSE", @@ -1303,6 +1309,12 @@ "group": "WM_DEBUG_CONFIGURATION", "at": "com\/android\/server\/am\/ActivityManagerService.java" }, + "-592371899": { + "message": "Skipping rootTask: (mismatch activity\/rootTask) %s", + "level": "DEBUG", + "group": "WM_DEBUG_TASKS", + "at": "com\/android\/server\/wm\/TaskDisplayArea.java" + }, "-583031528": { "message": "%s", "level": "INFO", @@ -2119,12 +2131,6 @@ "group": "WM_DEBUG_APP_TRANSITIONS", "at": "com\/android\/server\/wm\/AppTransition.java" }, - "349443311": { - "message": "pauseBackStacks: task=%s mResumedActivity=%s", - "level": "DEBUG", - "group": "WM_DEBUG_STATES", - "at": "com\/android\/server\/wm\/TaskDisplayArea.java" - }, "355720268": { "message": "stopFreezingDisplayLocked: Unfreezing now", "level": "DEBUG", @@ -2161,6 +2167,12 @@ "group": "WM_DEBUG_BOOT", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, + "391189028": { + "message": "pauseBackTasks: task=%s mResumedActivity=%s", + "level": "DEBUG", + "group": "WM_DEBUG_STATES", + "at": "com\/android\/server\/wm\/TaskDisplayArea.java" + }, "397105698": { "message": "grantEmbeddedWindowFocus remove request for win=%s dropped since no candidate was found", "level": "VERBOSE", @@ -2245,12 +2257,6 @@ "group": "WM_DEBUG_WINDOW_ORGANIZER", "at": "com\/android\/server\/wm\/DisplayAreaOrganizerController.java" }, - "490877640": { - "message": "onStackOrderChanged(): stack=%s", - "level": "DEBUG", - "group": "WM_DEBUG_RECENTS_ANIMATIONS", - "at": "com\/android\/server\/wm\/RecentsAnimation.java" - }, "495032901": { "message": "Expected target stack=%s to restored behind stack=%s but it is behind stack=%s", "level": "WARN", @@ -2575,12 +2581,6 @@ "group": "WM_DEBUG_REMOTE_ANIMATIONS", "at": "com\/android\/server\/wm\/RemoteAnimationController.java" }, - "875196661": { - "message": "Skipping stack: (mismatch activity\/stack) %s", - "level": "DEBUG", - "group": "WM_DEBUG_TASKS", - "at": "com\/android\/server\/wm\/TaskDisplayArea.java" - }, "883475718": { "message": "Report configuration: %s %s %s", "level": "VERBOSE", diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 8d6d981be2b80..69085fdb9c70c 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -2300,10 +2300,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp return count[0]; } - @VisibleForTesting @Nullable Task getTopRootTask() { - return getItemFromTaskDisplayAreas(TaskDisplayArea::getTopRootTask); + return getRootTask(t -> true); } /** @@ -5479,12 +5478,12 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp return; } - // Check if all task display areas have only the empty home stacks left. - boolean hasNonEmptyHomeStack = forAllRootTasks(stack -> - !stack.isActivityTypeHome() || stack.hasChild()); - if (!hasNonEmptyHomeStack && getRootTaskCount() > 0) { - // Release this display if only empty home stack(s) are left. This display will be - // released along with the stack(s) removal. + // Check if all task display areas have only the empty home root tasks left. + boolean hasNonEmptyHomeRootTask = forAllRootTasks(rootTask -> + !rootTask.isActivityTypeHome() || rootTask.hasChild()); + if (!hasNonEmptyHomeRootTask && getRootTaskCount() > 0) { + // Release this display if only empty home root task(s) are left. This display will be + // released along with the root task(s) removal. forAllRootTasks(Task::removeIfPossible); } else if (getTopRootTask() == null) { removeIfPossible(); @@ -5525,12 +5524,14 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp return; } mInEnsureActivitiesVisible = true; + mAtmService.mTaskSupervisor.beginActivityVisibilityUpdate(); try { - forAllTaskDisplayAreas(taskDisplayArea -> { - taskDisplayArea.ensureActivitiesVisible(starting, configChanges, - preserveWindows, notifyClients, userLeaving); + forAllRootTasks(rootTask -> { + rootTask.ensureActivitiesVisible(starting, configChanges, preserveWindows, + notifyClients, userLeaving); }); } finally { + mAtmService.mTaskSupervisor.endActivityVisibilityUpdate(); mInEnsureActivitiesVisible = false; } } diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java index 05dcd366dbac1..5bcb28753d188 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimation.java +++ b/services/core/java/com/android/server/wm/RecentsAnimation.java @@ -413,9 +413,10 @@ class RecentsAnimation implements RecentsAnimationCallbacks, OnRootTaskOrderChan @Override public void onRootTaskOrderChanged(Task rootTask) { - ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "onStackOrderChanged(): stack=%s", rootTask); - if (mDefaultTaskDisplayArea.getIndexOf(rootTask) == -1 || !rootTask.shouldBeVisible(null)) { - // The stack is not visible, so ignore this change + ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "onRootTaskOrderChanged(): rootTask=%s", rootTask); + if (mDefaultTaskDisplayArea.getRootTask(t -> t == rootTask) == null + || !rootTask.shouldBeVisible(null)) { + // The root task is not visible, so ignore this change return; } final RecentsAnimationController controller = diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index d652393dbdc15..d926a36c1dab0 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -1828,19 +1828,19 @@ class RootWindowContainer extends WindowContainer } /** - * @return a list of activities which are the top ones in each visible stack. The first + * @return a list of activities which are the top ones in each visible root task. The first * entry will be the focused activity. */ List getTopVisibleActivities() { final ArrayList topActivityTokens = new ArrayList<>(); - final Task topFocusedStack = getTopDisplayFocusedRootTask(); + final Task topFocusedRootTask = getTopDisplayFocusedRootTask(); // Traverse all displays. - forAllRootTasks(stack -> { - // Get top activity from a visible stack and add it to the list. - if (stack.shouldBeVisible(null /* starting */)) { - final ActivityRecord top = stack.getTopNonFinishingActivity(); + forAllRootTasks(rootTask -> { + // Get top activity from a visible root task and add it to the list. + if (rootTask.shouldBeVisible(null /* starting */)) { + final ActivityRecord top = rootTask.getTopNonFinishingActivity(); if (top != null) { - if (stack == topFocusedStack) { + if (rootTask == topFocusedRootTask) { topActivityTokens.add(0, top.appToken); } else { topActivityTokens.add(top.appToken); @@ -1854,9 +1854,9 @@ class RootWindowContainer extends WindowContainer @Nullable Task getTopDisplayFocusedRootTask() { for (int i = getChildCount() - 1; i >= 0; --i) { - final Task focusedStack = getChildAt(i).getFocusedRootTask(); - if (focusedStack != null) { - return focusedStack; + final Task focusedRootTask = getChildAt(i).getFocusedRootTask(); + if (focusedRootTask != null) { + return focusedRootTask; } } return null; @@ -1864,15 +1864,15 @@ class RootWindowContainer extends WindowContainer @Nullable ActivityRecord getTopResumedActivity() { - final Task focusedStack = getTopDisplayFocusedRootTask(); - if (focusedStack == null) { + final Task focusedRootTask = getTopDisplayFocusedRootTask(); + if (focusedRootTask == null) { return null; } - final ActivityRecord resumedActivity = focusedStack.getResumedActivity(); + final ActivityRecord resumedActivity = focusedRootTask.getResumedActivity(); if (resumedActivity != null && resumedActivity.app != null) { return resumedActivity; } - // The top focused stack might not have a resumed activity yet - look on all displays in + // The top focused root task might not have a resumed activity yet - look on all displays in // focus order. return getItemFromTaskDisplayAreas(TaskDisplayArea::getFocusedActivity); } @@ -1997,36 +1997,36 @@ class RootWindowContainer extends WindowContainer } boolean switchUser(int userId, UserState uss) { - final Task topFocusedStack = getTopDisplayFocusedRootTask(); - final int focusStackId = topFocusedStack != null - ? topFocusedStack.getRootTaskId() : INVALID_TASK_ID; - // We dismiss the docked stack whenever we switch users. + final Task topFocusedRootTask = getTopDisplayFocusedRootTask(); + final int focusRootTaskId = topFocusedRootTask != null + ? topFocusedRootTask.getRootTaskId() : INVALID_TASK_ID; + // We dismiss the docked root task whenever we switch users. if (getDefaultTaskDisplayArea().isSplitScreenModeActivated()) { getDefaultTaskDisplayArea().onSplitScreenModeDismissed(); } - // Also dismiss the pinned stack whenever we switch users. Removing the pinned stack will - // also cause all tasks to be moved to the fullscreen stack at a position that is + // Also dismiss the pinned root task whenever we switch users. Removing the pinned root task + // will also cause all tasks to be moved to the fullscreen root task at a position that is // appropriate. removeRootTasksInWindowingModes(WINDOWING_MODE_PINNED); - mUserRootTaskInFront.put(mCurrentUser, focusStackId); + mUserRootTaskInFront.put(mCurrentUser, focusRootTaskId); mCurrentUser = userId; mTaskSupervisor.mStartingUsers.add(uss); - forAllRootTasks(stack -> { - stack.switchUser(userId); + forAllRootTasks(rootTask -> { + rootTask.switchUser(userId); }); - final int restoreStackId = mUserRootTaskInFront.get(userId); - Task stack = getRootTask(restoreStackId); - if (stack == null) { - stack = getDefaultTaskDisplayArea().getOrCreateRootHomeTask(); + final int restoreRootTaskId = mUserRootTaskInFront.get(userId); + Task rootTask = getRootTask(restoreRootTaskId); + if (rootTask == null) { + rootTask = getDefaultTaskDisplayArea().getOrCreateRootHomeTask(); } - final boolean homeInFront = stack.isActivityTypeHome(); - if (stack.isOnHomeDisplay()) { - stack.moveToFront("switchUserOnHomeDisplay"); + final boolean homeInFront = rootTask.isActivityTypeHome(); + if (rootTask.isOnHomeDisplay()) { + rootTask.moveToFront("switchUserOnHomeDisplay"); } else { - // Stack was moved to another display while user was swapped out. + // Root task was moved to another display while user was swapped out. resumeHomeActivity(null, "switchUserOnOtherDisplay", getDefaultTaskDisplayArea()); } return homeInFront; @@ -2350,7 +2350,7 @@ class RootWindowContainer extends WindowContainer return result; } - void applySleepTokens(boolean applyToStacks) { + void applySleepTokens(boolean applyToRootTasks) { for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { // Set the sleeping state of the display. final DisplayContent display = getChildAt(displayNdx); @@ -2360,17 +2360,17 @@ class RootWindowContainer extends WindowContainer } display.setIsSleeping(displayShouldSleep); - if (!applyToStacks) { + if (!applyToRootTasks) { continue; } - // Set the sleeping state of the stacks on the display. - display.forAllRootTasks(stack -> { + // Set the sleeping state of the root tasks on the display. + display.forAllRootTasks(rootTask -> { if (displayShouldSleep) { - stack.goToSleepIfPossible(false /* shuttingDown */); + rootTask.goToSleepIfPossible(false /* shuttingDown */); } else { - stack.awakeFromSleepingLocked(); - if (stack.isFocusedStackOnDisplay() + rootTask.awakeFromSleepingLocked(); + if (rootTask.isFocusedStackOnDisplay() && !mTaskSupervisor.getKeyguardController() .isKeyguardOrAodShowing(display.mDisplayId)) { // If the keyguard is unlocked - resume immediately. @@ -2378,13 +2378,13 @@ class RootWindowContainer extends WindowContainer // process the keyguard going away, which can happen before the sleep // token is released. As a result, it is important we resume the // activity here. - stack.resumeTopActivityUncheckedLocked(null, null); + rootTask.resumeTopActivityUncheckedLocked(null, null); } // The visibility update must not be called before resuming the top, so the // display orientation can be updated first if needed. Otherwise there may // have redundant configuration changes due to apply outdated display // orientation (from keyguard) to activity. - stack.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, + rootTask.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, false /* preserveWindows */); } }); @@ -2427,7 +2427,7 @@ class RootWindowContainer extends WindowContainer task.fillTaskInfo(info); // A task might be not attached to a display. - info.position = taskDisplayArea != null ? taskDisplayArea.getIndexOf(task) : 0; + info.position = taskDisplayArea != null ? taskDisplayArea.getTaskIndexOf(task) : 0; info.visible = task.shouldBeVisible(null); task.getBounds(info.bounds); @@ -2471,21 +2471,21 @@ class RootWindowContainer extends WindowContainer } RootTaskInfo getRootTaskInfo(int windowingMode, int activityType) { - final Task stack = getRootTask(windowingMode, activityType); - return (stack != null) ? getRootTaskInfo(stack) : null; + final Task rootTask = getRootTask(windowingMode, activityType); + return (rootTask != null) ? getRootTaskInfo(rootTask) : null; } RootTaskInfo getRootTaskInfo(int windowingMode, int activityType, int displayId) { - final Task stack = getRootTask(windowingMode, activityType, displayId); - return (stack != null) ? getRootTaskInfo(stack) : null; + final Task rootTask = getRootTask(windowingMode, activityType, displayId); + return (rootTask != null) ? getRootTaskInfo(rootTask) : null; } /** If displayId == INVALID_DISPLAY, this will get root task infos on all displays */ ArrayList getAllRootTaskInfos(int displayId) { final ArrayList list = new ArrayList<>(); if (displayId == INVALID_DISPLAY) { - forAllRootTasks(stack -> { - list.add(getRootTaskInfo(stack)); + forAllRootTasks(rootTask -> { + list.add(getRootTaskInfo(rootTask)); }); return list; } @@ -2493,8 +2493,8 @@ class RootWindowContainer extends WindowContainer if (display == null) { return list; } - display.forAllRootTasks(stack -> { - list.add(getRootTaskInfo(stack)); + display.forAllRootTasks(rootTask -> { + list.add(getRootTaskInfo(rootTask)); }); return list; } @@ -2955,8 +2955,8 @@ class RootWindowContainer extends WindowContainer } // If {@code r} is already in target display area and its task is the same as the candidate - // task, the intention should be getting a launch stack for the reusable activity, so we can - // use the existing stack. + // task, the intention should be getting a launch root task for the reusable activity, so we + // can use the existing root task. if (candidateTask != null) { final TaskDisplayArea attachedTaskDisplayArea = candidateTask.getDisplayArea(); if (attachedTaskDisplayArea == null || attachedTaskDisplayArea == taskDisplayArea) { @@ -2965,9 +2965,9 @@ class RootWindowContainer extends WindowContainer // Or the candidate task is already a root task that can be reused by reparenting // it to the target display. if (candidateTask.isRootTask()) { - final Task stack = candidateTask.getRootTask(); - stack.reparent(taskDisplayArea, true /* onTop */); - return stack; + final Task rootTask = candidateTask.getRootTask(); + rootTask.reparent(taskDisplayArea, true /* onTop */); + return rootTask; } } @@ -2984,16 +2984,16 @@ class RootWindowContainer extends WindowContainer windowingMode = taskDisplayArea.validateWindowingMode(windowingMode, r, candidateTask, r.getActivityType()); - // Return the topmost valid stack on the display. + // Return the topmost valid root task on the display. final int targetWindowingMode = windowingMode; - final Task topmostValidStack = taskDisplayArea.getRootTask(stack -> - isValidLaunchRootTask(stack, r, targetWindowingMode)); - if (topmostValidStack != null) { - return topmostValidStack; + final Task topmostValidRootTask = taskDisplayArea.getRootTask(rootTask -> + isValidLaunchRootTask(rootTask, r, targetWindowingMode)); + if (topmostValidRootTask != null) { + return topmostValidRootTask; } - // If there is no valid stack on the secondary display area - check if new dynamic stack - // will do. + // If there is no valid root task on the secondary display area - check if new dynamic root + // task will do. if (taskDisplayArea != getDisplayContent(taskDisplayArea.getDisplayId()) .getDefaultTaskDisplayArea()) { final int activityType = @@ -3224,8 +3224,8 @@ class RootWindowContainer extends WindowContainer } void finishVoiceTask(IVoiceInteractionSession session) { - forAllRootTasks(stack -> { - stack.finishVoiceTask(session); + forAllRootTasks(rootTask -> { + rootTask.finishVoiceTask(session); }); } @@ -3284,8 +3284,8 @@ class RootWindowContainer extends WindowContainer boolean allResumedActivitiesVisible() { boolean[] foundResumed = {false}; - final boolean foundInvisibleResumedActivity = forAllRootTasks(stack -> { - final ActivityRecord r = stack.getResumedActivity(); + final boolean foundInvisibleResumedActivity = forAllRootTasks(rootTask -> { + final ActivityRecord r = rootTask.getResumedActivity(); if (r != null) { if (!r.nowVisible) { return true; @@ -3529,9 +3529,9 @@ class RootWindowContainer extends WindowContainer } } else { final ArrayList activities = new ArrayList<>(); - forAllRootTasks(stack -> { - if (!dumpVisibleStacksOnly || stack.shouldBeVisible(null)) { - activities.addAll(stack.getDumpActivitiesLocked(name)); + forAllRootTasks(rootTask -> { + if (!dumpVisibleStacksOnly || rootTask.shouldBeVisible(null)) { + activities.addAll(rootTask.getDumpActivitiesLocked(name)); } }); return activities; @@ -3581,11 +3581,11 @@ class RootWindowContainer extends WindowContainer pw.print("Display #"); pw.print(displayContent.mDisplayId); pw.println(" (activities from top to bottom):"); - displayContent.forAllRootTasks(stack -> { + displayContent.forAllRootTasks(rootTask -> { if (needSep[0]) { pw.println(); } - needSep[0] = stack.dump(fd, pw, dumpAll, dumpClient, dumpPackage, false); + needSep[0] = rootTask.dump(fd, pw, dumpAll, dumpClient, dumpPackage, false); printed[0] |= needSep[0]; }); displayContent.forAllTaskDisplayAreas(taskDisplayArea -> { diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 69723ff99d062..e676d5b9d064d 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -5320,20 +5320,19 @@ class Task extends WindowContainer { final TaskDisplayArea taskDisplayArea = getDisplayArea(); if (inSplitScreenSecondaryWindowingMode()) { - // If the stack is in split-screen secondary mode, we need to make sure we move the - // primary split-screen stack forward in the case it is currently behind a fullscreen - // stack so both halves of the split-screen appear on-top and the fullscreen stack isn't - // cutting between them. + // If the root task is in split-screen secondary mode, we need to make sure we move the + // primary split-screen root task forward in the case it is currently behind a + // fullscreen root task so both halves of the split-screen appear on-top and the + // fullscreen root task isn't cutting between them. // TODO(b/70677280): This is a workaround until we can fix as part of b/70677280. - final Task topFullScreenStack = + final Task topFullScreenRootTask = taskDisplayArea.getTopRootTaskInWindowingMode(WINDOWING_MODE_FULLSCREEN); - if (topFullScreenStack != null) { - final Task primarySplitScreenStack = + if (topFullScreenRootTask != null) { + final Task primarySplitScreenRootTask = taskDisplayArea.getRootSplitScreenPrimaryTask(); - if (primarySplitScreenStack != null - && taskDisplayArea.getIndexOf(topFullScreenStack) - > taskDisplayArea.getIndexOf(primarySplitScreenStack)) { - primarySplitScreenStack.moveToFront(reason + " splitScreenToTop"); + if (primarySplitScreenRootTask != null + && topFullScreenRootTask.compareTo(primarySplitScreenRootTask) > 0) { + primarySplitScreenRootTask.moveToFront(reason + " splitScreenToTop"); } } } @@ -5748,7 +5747,7 @@ class Task extends WindowContainer { } /** - * @return {@code true} if this is the focused stack on its current display, {@code false} + * @return {@code true} if this is the focused root task on its current display, {@code false} * otherwise. */ boolean isFocusedStackOnDisplay() { @@ -6700,18 +6699,21 @@ class Task extends WindowContainer { }); } - /** @return true if the stack behind this one is a standard activity type. */ - private boolean inFrontOfStandardStack() { + /** @return true if the root task behind this one is a standard activity type. */ + private boolean inFrontOfStandardRootTask() { final TaskDisplayArea taskDisplayArea = getDisplayArea(); if (taskDisplayArea == null) { return false; } - final int index = taskDisplayArea.getIndexOf(this); + final int index = taskDisplayArea.getTaskIndexOf(this); if (index == 0) { return false; } - final Task stackBehind = taskDisplayArea.getChildAt(index - 1); - return stackBehind.isActivityTypeStandard(); + final int[] indexCount = new int[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(); } boolean shouldUpRecreateTaskLocked(ActivityRecord srec, String destAffinity) { @@ -6732,7 +6734,7 @@ class Task extends WindowContainer { if (srec.isRootOfTask() && task.getBaseIntent() != null && task.getBaseIntent().isDocument()) { // Okay, this activity is at the root of its task. What to do, what to do... - if (!inFrontOfStandardStack()) { + if (!inFrontOfStandardRootTask()) { // Finishing won't return to an application, so we need to recreate. return true; } diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java index 7fed84015e8b0..866abbde16368 100644 --- a/services/core/java/com/android/server/wm/TaskDisplayArea.java +++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java @@ -71,8 +71,10 @@ import java.util.function.Function; /** * {@link DisplayArea} that represents a section of a screen that contains app window containers. + * + * The children can be either {@link Task} or {@link TaskDisplayArea}. */ -final class TaskDisplayArea extends DisplayArea { +final class TaskDisplayArea extends DisplayArea { DisplayContent mDisplayContent; @@ -106,9 +108,9 @@ final class TaskDisplayArea extends DisplayArea { // TODO(b/159029784): Remove when getStack() behavior is cleaned-up private Task mRootRecentsTask; - private final ArrayList mTmpAlwaysOnTopRootTasks = new ArrayList<>(); - private final ArrayList mTmpNormalRootTasks = new ArrayList<>(); - private final ArrayList mTmpHomeRootTasks = new ArrayList<>(); + private final ArrayList mTmpAlwaysOnTopChildren = new ArrayList<>(); + private final ArrayList mTmpNormalChildren = new ArrayList<>(); + private final ArrayList mTmpHomeChildren = new ArrayList<>(); private final IntArray mTmpNeedsZBoostIndexes = new IntArray(); private int mTmpLayerForSplitScreenDividerAnchor; private int mTmpLayerForAnimationLayer; @@ -179,9 +181,10 @@ final class TaskDisplayArea extends DisplayArea { } /** - * Returns the topmost stack on the display that is compatible with the input windowing mode - * and activity type. Null is no compatible stack on the display. + * Returns the topmost root task on the display that is compatible with the input windowing mode + * and activity type. Null is no compatible root task on the display. */ + @Nullable Task getRootTask(int windowingMode, int activityType) { if (activityType == ACTIVITY_TYPE_HOME) { return mRootHomeTask; @@ -193,30 +196,48 @@ final class TaskDisplayArea extends DisplayArea { } else if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) { return mRootSplitScreenPrimaryTask; } - for (int i = getChildCount() - 1; i >= 0; --i) { - final Task stack = getChildAt(i); + return getRootTask(rootTask -> { if (activityType == ACTIVITY_TYPE_UNDEFINED - && windowingMode == stack.getWindowingMode()) { - // Passing in undefined type means we want to match the topmost stack with the + && windowingMode == rootTask.getWindowingMode()) { + // Passing in undefined type means we want to match the topmost root task with the // windowing mode. - return stack; + return true; } - if (stack.isCompatible(windowingMode, activityType)) { - return stack; - } - } - return null; + return rootTask.isCompatible(windowingMode, activityType); + }); } @VisibleForTesting Task getTopRootTask() { - final int count = getChildCount(); - return count > 0 ? getChildAt(count - 1) : null; + return getRootTask(t -> true); } - // TODO: Figure-out a way to remove since it might be a source of confusion. - int getIndexOf(Task task) { - return mChildren.indexOf(task); + // 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 @@ -238,9 +259,11 @@ final class TaskDisplayArea extends DisplayArea { } Task getRootSplitScreenSecondaryTask() { + // Only check the direct child Task for now, since the primary is also a direct child Task. for (int i = mChildren.size() - 1; i >= 0; --i) { - if (mChildren.get(i).inSplitScreenSecondaryWindowingMode()) { - return mChildren.get(i); + final Task task = mChildren.get(i).asTask(); + if (task != null && task.inSplitScreenSecondaryWindowingMode()) { + return task; } } return null; @@ -323,7 +346,22 @@ final class TaskDisplayArea extends DisplayArea { } @Override - void addChild(Task task, int position) { + void addChild(WindowContainer child, int position) { + if (child.asTaskDisplayArea() != null) { + if (DEBUG_ROOT_TASK) { + Slog.d(TAG_WM, "Set TaskDisplayArea=" + child + " on taskDisplayArea=" + this); + } + super.addChild(child, position); + } else if (child.asTask() != null) { + addChildTask(child.asTask(), position); + } else { + throw new IllegalArgumentException( + "TaskDisplayArea can only add Task and TaskDisplayArea, but found " + + child); + } + } + + private void addChildTask(Task task, int position) { if (DEBUG_ROOT_TASK) Slog.d(TAG_WM, "Set task=" + task + " on taskDisplayArea=" + this); addRootTaskReferenceIfNeeded(task); @@ -335,11 +373,23 @@ final class TaskDisplayArea extends DisplayArea { } @Override - protected void removeChild(Task stack) { - super.removeChild(stack); - onRootTaskRemoved(stack); + protected void removeChild(WindowContainer child) { + if (child.asTaskDisplayArea() != null) { + super.removeChild(child); + } else if (child.asTask() != null) { + removeChildTask(child.asTask()); + } else { + throw new IllegalArgumentException( + "TaskDisplayArea can only remove Task and TaskDisplayArea, but found " + + child); + } + } + + private void removeChildTask(Task task) { + super.removeChild(task); + onRootTaskRemoved(task); mAtmService.updateSleepIfNeededLocked(); - removeRootTaskReferenceIfNeeded(stack); + removeRootTaskReferenceIfNeeded(task); } @Override @@ -349,21 +399,33 @@ final class TaskDisplayArea extends DisplayArea { } @Override - void positionChildAt(int position, Task child, boolean includingParents) { + void positionChildAt(int position, WindowContainer child, boolean includingParents) { + if (child.asTaskDisplayArea() != null) { + super.positionChildAt(position, child, includingParents); + } else if (child.asTask() != null) { + positionChildTaskAt(position, child.asTask(), includingParents); + } else { + throw new IllegalArgumentException( + "TaskDisplayArea can only position Task and TaskDisplayArea, but found " + + child); + } + } + + private void positionChildTaskAt(int position, Task child, boolean includingParents) { final boolean moveToTop = position >= getChildCount() - 1; final boolean moveToBottom = position <= 0; final int oldPosition = mChildren.indexOf(child); if (child.getWindowConfiguration().isAlwaysOnTop() && !moveToTop) { - // This stack is always-on-top, override the default behavior. - Slog.w(TAG_WM, "Ignoring move of always-on-top stack=" + this + " to bottom"); + // This root task is always-on-top, override the default behavior. + Slog.w(TAG_WM, "Ignoring move of always-on-top root task=" + this + " to bottom"); // Moving to its current position, as we must call super but we don't want to // perform any meaningful action. super.positionChildAt(oldPosition, child, false /* includingParents */); return; } - // We don't allow untrusted display to top when task stack moves to top, + // We don't allow untrusted display to top when root task moves to top, // until user tapping this display to change display position as top intentionally. if (!mDisplayContent.isTrusted() && !getParent().isOnTop()) { includingParents = false; @@ -432,41 +494,78 @@ final class TaskDisplayArea extends DisplayArea { @Override boolean forAllTaskDisplayAreas(Function callback, boolean traverseTopToBottom) { - return callback.apply(this); + // Apply the callback to all TDAs at or below this container. If the callback returns true, + // stop early. + if (traverseTopToBottom) { + // When it is top to bottom, run on child TDA first as they are on top of the parent. + return super.forAllTaskDisplayAreas(callback, traverseTopToBottom) + || callback.apply(this); + } + return callback.apply(this) || super.forAllTaskDisplayAreas(callback, traverseTopToBottom); } @Override void forAllTaskDisplayAreas(Consumer callback, boolean traverseTopToBottom) { - callback.accept(this); + if (traverseTopToBottom) { + super.forAllTaskDisplayAreas(callback, traverseTopToBottom); + callback.accept(this); + } else { + callback.accept(this); + super.forAllTaskDisplayAreas(callback, traverseTopToBottom); + } } @Nullable @Override R reduceOnAllTaskDisplayAreas(BiFunction accumulator, @Nullable R initValue, boolean traverseTopToBottom) { - return accumulator.apply(this, initValue); + if (traverseTopToBottom) { + final R result = + super.reduceOnAllTaskDisplayAreas(accumulator, initValue, traverseTopToBottom); + return accumulator.apply(this, result); + } else { + final R result = accumulator.apply(this, initValue); + return super.reduceOnAllTaskDisplayAreas(accumulator, result, traverseTopToBottom); + + } } @Nullable @Override R getItemFromTaskDisplayAreas(Function callback, boolean traverseTopToBottom) { - return callback.apply(this); + if (traverseTopToBottom) { + final R item = super.getItemFromTaskDisplayAreas(callback, traverseTopToBottom); + return item != null ? item : callback.apply(this); + } else { + final R item = callback.apply(this); + return item != null + ? item + : super.getItemFromTaskDisplayAreas(callback, traverseTopToBottom); + } } /** - * Assigns a priority number to stack types. This priority defines an order between the types - * of stacks that are added to the task display area. + * Assigns a priority number to root task types. This priority defines an order between the + * types of root task that are added to the task display area. * - * Higher priority number indicates that the stack should have a higher z-order. + * Higher priority number indicates that the root task should have a higher z-order. * - * @return the priority of the stack + * For child {@link TaskDisplayArea}, it will be the priority of its top child. + * + * @return the priority of the root task */ - private int getPriority(Task stack) { - if (mWmService.mAssistantOnTopOfDream && stack.isActivityTypeAssistant()) return 4; - if (stack.isActivityTypeDream()) return 3; - if (stack.inPinnedWindowingMode()) return 2; - if (stack.isAlwaysOnTop()) return 1; + private int getPriority(WindowContainer child) { + final TaskDisplayArea tda = child.asTaskDisplayArea(); + if (tda != null) { + // Use the top child priority as the TaskDisplayArea priority. + return tda.getPriority(tda.getTopChild()); + } + final Task rootTask = child.asTask(); + if (mWmService.mAssistantOnTopOfDream && rootTask.isActivityTypeAssistant()) return 4; + if (rootTask.isActivityTypeDream()) return 3; + if (rootTask.inPinnedWindowingMode()) return 2; + if (rootTask.isAlwaysOnTop()) return 1; return 0; } @@ -481,10 +580,12 @@ final class TaskDisplayArea extends DisplayArea { } if (rootTask.isAlwaysOnTop()) { - // Since a stack could be repositioned while still being one of the children, we check - // if this always-on-top stack already exists and if so, set the minPosition to its - // previous position. - final int currentIndex = getIndexOf(rootTask); + // Since a root task could be repositioned while still being one of the children, we + // check if this always-on-top root task already exists and if so, set the minPosition + // to its previous position. + // Use mChildren.indexOf instead of getTaskIndexOf because we need to place the rootTask + // as a direct child. + final int currentIndex = mChildren.indexOf(rootTask); if (currentIndex > minPosition) { minPosition = currentIndex; } @@ -494,9 +595,9 @@ final class TaskDisplayArea extends DisplayArea { private int findMaxPositionForRootTask(Task rootTask) { for (int i = mChildren.size() - 1; i >= 0; --i) { - final Task curr = mChildren.get(i); - // Since a stack could be repositioned while still being one of the children, we check - // if 'curr' is the same stack and skip it if so + final WindowContainer curr = mChildren.get(i); + // Since a root task could be repositioned while still being one of the children, we + // check if 'curr' is the same root task and skip it if so final boolean sameRootTask = curr == rootTask; if (getPriority(curr) <= getPriority(rootTask) && !sameRootTask) { return i; @@ -506,29 +607,29 @@ final class TaskDisplayArea extends DisplayArea { } /** - * When stack is added or repositioned, find a proper position for it. + * When root task is added or repositioned, find a proper position for it. * * The order is defined as: * - Dream is on top of everything * - PiP is directly below the Dream - * - always-on-top stacks are directly below PiP; new always-on-top stacks are added above - * existing ones - * - other non-always-on-top stacks come directly below always-on-top stacks; new - * non-always-on-top stacks are added directly below always-on-top stacks and above existing - * non-always-on-top stacks + * - always-on-top root tasks are directly below PiP; new always-on-top root tasks are added + * above existing ones + * - other non-always-on-top root tasks come directly below always-on-top root tasks; new + * non-always-on-top root tasks are added directly below always-on-top root tasks and above + * existing non-always-on-top root tasks * - if {@link #mAssistantOnTopOfDream} is enabled, then Assistant is on top of everything - * (including the Dream); otherwise, it is a normal non-always-on-top stack + * (including the Dream); otherwise, it is a normal non-always-on-top root task * * @param requestedPosition Position requested by caller. * @param rootTask Root task to be added or positioned. - * @param adding Flag indicates whether we're adding a new stack or positioning an - * existing. - * @return The proper position for the stack. + * @param adding Flag indicates whether we're adding a new root task or positioning + * an existing. + * @return The proper position for the root task. */ private int findPositionForRootTask(int requestedPosition, Task rootTask, boolean adding) { - // The max possible position we can insert the stack at. + // The max possible position we can insert the root task at. int maxPosition = findMaxPositionForRootTask(rootTask); - // The min possible position we can insert the stack at. + // The min possible position we can insert the root task at. int minPosition = findMinPositionForRootTask(rootTask); // Cap the requested position to something reasonable for the previous position check @@ -547,8 +648,8 @@ final class TaskDisplayArea extends DisplayArea { // The positions we calculated above (maxPosition, minPosition) do not take into // consideration the following edge cases. // 1) We need to adjust the position depending on the value "adding". - // 2) When we are moving a stack to another position, we also need to adjust the - // position depending on whether the stack is moving to a higher or lower position. + // 2) When we are moving a root task to another position, we also need to adjust the + // position depending on whether the root task is moving to a higher or lower position. if ((targetPosition != requestedPosition) && (adding || targetPosition < prevPosition)) { targetPosition++; } @@ -579,13 +680,19 @@ final class TaskDisplayArea extends DisplayArea { private boolean forAllExitingAppTokenWindows(ToBooleanFunction callback, boolean traverseTopToBottom) { - // For legacy reasons we process the TaskStack.mExitingActivities first here before the + // For legacy reasons we process the RootTask.mExitingActivities first here before the // app tokens. // TODO: Investigate if we need to continue to do this or if we can just process them // in-order. if (traverseTopToBottom) { for (int i = mChildren.size() - 1; i >= 0; --i) { - final List activities = mChildren.get(i).mExitingActivities; + // Only run on those of direct Task child, because child TaskDisplayArea has run on + // its child in #forAllWindows() + if (mChildren.get(i).asTask() == null) { + continue; + } + final List activities = + mChildren.get(i).asTask().mExitingActivities; for (int j = activities.size() - 1; j >= 0; --j) { if (activities.get(j).forAllWindowsUnchecked(callback, traverseTopToBottom)) { @@ -596,7 +703,13 @@ final class TaskDisplayArea extends DisplayArea { } else { final int count = mChildren.size(); for (int i = 0; i < count; ++i) { - final List activities = mChildren.get(i).mExitingActivities; + // Only run on those of direct Task child, because child TaskDisplayArea has run on + // its child in #forAllWindows() + if (mChildren.get(i).asTask() == null) { + continue; + } + final List activities = + mChildren.get(i).asTask().mExitingActivities; final int appTokensCount = activities.size(); for (int j = 0; j < appTokensCount; j++) { if (activities.get(j).forAllWindowsUnchecked(callback, @@ -612,9 +725,18 @@ final class TaskDisplayArea extends DisplayArea { @Override int getOrientation(int candidate) { mLastOrientationSource = null; - if (!canSpecifyOrientation()) { + if (mIgnoreOrientationRequest) { return SCREEN_ORIENTATION_UNSET; } + if (!canSpecifyOrientation()) { + // We only respect orientation of the focused TDA, which can be a child of this TDA. + return reduceOnAllTaskDisplayAreas((taskDisplayArea, orientation) -> { + if (taskDisplayArea == this || orientation != SCREEN_ORIENTATION_UNSET) { + return orientation; + } + return taskDisplayArea.getOrientation(candidate); + }, SCREEN_ORIENTATION_UNSET); + } if (isRootTaskVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY)) { // Apps and their containers are not allowed to specify an orientation while using @@ -671,8 +793,7 @@ final class TaskDisplayArea extends DisplayArea { assignRootTaskOrdering(t); for (int i = 0; i < mChildren.size(); i++) { - final Task s = mChildren.get(i); - s.assignChildLayers(t); + mChildren.get(i).assignChildLayers(t); } } @@ -680,33 +801,49 @@ final class TaskDisplayArea extends DisplayArea { if (getParent() == null) { return; } - mTmpAlwaysOnTopRootTasks.clear(); - mTmpHomeRootTasks.clear(); - mTmpNormalRootTasks.clear(); + mTmpAlwaysOnTopChildren.clear(); + mTmpHomeChildren.clear(); + mTmpNormalChildren.clear(); for (int i = 0; i < mChildren.size(); ++i) { - final Task s = mChildren.get(i); - if (s.isAlwaysOnTop()) { - mTmpAlwaysOnTopRootTasks.add(s); - } else if (s.isActivityTypeHome()) { - mTmpHomeRootTasks.add(s); + final WindowContainer child = mChildren.get(i); + final TaskDisplayArea childTda = child.asTaskDisplayArea(); + if (childTda != null) { + final Task childTdaTopRootTask = childTda.getTopRootTask(); + if (childTdaTopRootTask == null) { + mTmpNormalChildren.add(childTda); + } else if (childTdaTopRootTask.isAlwaysOnTop()) { + mTmpAlwaysOnTopChildren.add(childTda); + } else if (childTdaTopRootTask.isActivityTypeHome()) { + mTmpHomeChildren.add(childTda); + } else { + mTmpNormalChildren.add(childTda); + } + continue; + } + + final Task childTask = child.asTask(); + if (childTask.isAlwaysOnTop()) { + mTmpAlwaysOnTopChildren.add(childTask); + } else if (childTask.isActivityTypeHome()) { + mTmpHomeChildren.add(childTask); } else { - mTmpNormalRootTasks.add(s); + mTmpNormalChildren.add(childTask); } } int layer = 0; // Place home stacks to the bottom. - layer = adjustRootTaskLayer(t, mTmpHomeRootTasks, layer, false /* normalStacks */); + layer = adjustRootTaskLayer(t, mTmpHomeChildren, layer, false /* normalRootTasks */); // The home animation layer is between the home stacks and the normal stacks. final int layerForHomeAnimationLayer = layer++; mTmpLayerForSplitScreenDividerAnchor = layer++; mTmpLayerForAnimationLayer = layer++; - layer = adjustRootTaskLayer(t, mTmpNormalRootTasks, layer, true /* normalStacks */); + layer = adjustRootTaskLayer(t, mTmpNormalChildren, layer, true /* normalRootTasks */); // The boosted animation layer is between the normal stacks and the always on top // stacks. final int layerForBoostedAnimationLayer = layer++; - adjustRootTaskLayer(t, mTmpAlwaysOnTopRootTasks, layer, false /* normalStacks */); + adjustRootTaskLayer(t, mTmpAlwaysOnTopChildren, layer, false /* normalRootTasks */); t.setLayer(mHomeAppAnimationLayer, layerForHomeAnimationLayer); t.setLayer(mAppAnimationLayer, mTmpLayerForAnimationLayer); @@ -714,13 +851,14 @@ final class TaskDisplayArea extends DisplayArea { t.setLayer(mBoostedAppAnimationLayer, layerForBoostedAnimationLayer); } - private int adjustNormalRootTaskLayer(Task s, int layer) { - if (s.inSplitScreenWindowingMode()) { + private int adjustNormalRootTaskLayer(WindowContainer child, int layer) { + if (child.asTask() != null && child.inSplitScreenWindowingMode()) { // The split screen divider anchor is located above the split screen window. mTmpLayerForSplitScreenDividerAnchor = layer++; } - if (s.isAnimatingByRecents() || s.isAppTransitioning()) { - // The animation layer is located above the highest animating stack and no + if ((child.asTask() != null && child.asTask().isAnimatingByRecents()) + || child.isAppTransitioning()) { + // The animation layer is located above the highest animating root task and no // higher. mTmpLayerForAnimationLayer = layer++; } @@ -728,23 +866,30 @@ final class TaskDisplayArea extends DisplayArea { } /** - * Adjusts the layer of the stack which belongs to the same group. - * Note that there are three stack groups: home stacks, always on top stacks, and normal stacks. + * Adjusts the layer of the root task which belongs to the same group. + * Note that there are three root task groups: home rootTasks, always on top rootTasks, and + * normal rootTasks. * - * @param startLayer The beginning layer of this group of stacks. - * @param normalStacks Set {@code true} if this group is neither home nor always on top. + * @param startLayer The beginning layer of this group of rootTasks. + * @param normalRootTasks Set {@code true} if this group is neither home nor always on top. * @return The adjusted layer value. */ - private int adjustRootTaskLayer(SurfaceControl.Transaction t, ArrayList stacks, - int startLayer, boolean normalStacks) { + private int adjustRootTaskLayer(SurfaceControl.Transaction t, + ArrayList children, int startLayer, boolean normalRootTasks) { mTmpNeedsZBoostIndexes.clear(); - final int stackSize = stacks.size(); - for (int i = 0; i < stackSize; i++) { - final Task stack = stacks.get(i); - if (!stack.needsZBoost()) { - stack.assignLayer(t, startLayer++); - if (normalStacks) { - startLayer = adjustNormalRootTaskLayer(stack, startLayer); + final int childCount = children.size(); + for (int i = 0; i < childCount; i++) { + final WindowContainer child = children.get(i); + final TaskDisplayArea childTda = child.asTaskDisplayArea(); + + boolean childNeedsZBoost = childTda != null + ? childTda.childrenNeedZBoost() + : child.needsZBoost(); + + if (!childNeedsZBoost) { + child.assignLayer(t, startLayer++); + if (normalRootTasks) { + startLayer = adjustNormalRootTaskLayer(child, startLayer); } } else { mTmpNeedsZBoostIndexes.add(i); @@ -753,15 +898,23 @@ final class TaskDisplayArea extends DisplayArea { final int zBoostSize = mTmpNeedsZBoostIndexes.size(); for (int i = 0; i < zBoostSize; i++) { - final Task stack = stacks.get(mTmpNeedsZBoostIndexes.get(i)); - stack.assignLayer(t, startLayer++); - if (normalStacks) { - startLayer = adjustNormalRootTaskLayer(stack, startLayer); + final WindowContainer child = children.get(mTmpNeedsZBoostIndexes.get(i)); + child.assignLayer(t, startLayer++); + if (normalRootTasks) { + startLayer = adjustNormalRootTaskLayer(child, startLayer); } } return startLayer; } + private boolean childrenNeedZBoost() { + final boolean[] needsZBoost = new boolean[1]; + forAllRootTasks(task -> { + needsZBoost[0] |= task.needsZBoost(); + }); + return needsZBoost[0]; + } + @Override SurfaceControl getAppAnimationLayer(@AnimationLayer int animationLayer) { switch (animationLayer) { @@ -1027,15 +1180,25 @@ final class TaskDisplayArea extends DisplayArea { return null; } for (int i = mChildren.size() - 1; i >= 0; --i) { - final Task t = mChildren.get(i); - if (!t.mCreatedByOrganizer || t.getRequestedOverrideWindowingMode() != windowingMode) { + final WindowContainer child = mChildren.get(i); + if (child.asTaskDisplayArea() != null) { + final Task t = child.asTaskDisplayArea().updateLaunchRootTask(windowingMode); + if (t != null) { + return t; + } + continue; + } + + final Task t = mChildren.get(i).asTask(); + if (t == null || !t.mCreatedByOrganizer + || t.getRequestedOverrideWindowingMode() != windowingMode) { continue; } // If not already set, pick a launch root which is not the one we are launching into. if (mLaunchRootTask == null) { for (int j = 0, n = mChildren.size(); j < n; ++j) { - final Task tt = mChildren.get(j); - if (tt.mCreatedByOrganizer && tt != t) { + final Task tt = mChildren.get(j).asTask(); + if (tt != null && tt.mCreatedByOrganizer && tt != t) { mLaunchRootTask = tt; break; } @@ -1081,8 +1244,8 @@ final class TaskDisplayArea extends DisplayArea { } /** - * Get the preferred focusable stack in priority. If the preferred stack does not exist, find a - * focusable and visible stack from the top of stacks in this display. + * Get the preferred focusable root task in priority. If the preferred root task does not exist, + * find a focusable and visible root task from the top of root tasks in this display. */ Task getFocusedRootTask() { if (mPreferredTopFocusableRootTask != null) { @@ -1090,9 +1253,18 @@ final class TaskDisplayArea extends DisplayArea { } for (int i = mChildren.size() - 1; i >= 0; --i) { - final Task stack = mChildren.get(i); - if (stack.isFocusableAndVisible()) { - return stack; + final WindowContainer child = mChildren.get(i); + if (child.asTaskDisplayArea() != null) { + final Task rootTask = child.asTaskDisplayArea().getFocusedRootTask(); + if (rootTask != null) { + return rootTask; + } + continue; + } + + final Task rootTask = mChildren.get(i).asTask(); + if (rootTask.isFocusableAndVisible()) { + return rootTask; } } @@ -1105,7 +1277,17 @@ final class TaskDisplayArea extends DisplayArea { Task candidate = null; for (int i = mChildren.size() - 1; i >= 0; --i) { - final Task rootTask = mChildren.get(i); + final WindowContainer child = mChildren.get(i); + if (child.asTaskDisplayArea() != null) { + final Task rootTask = child.asTaskDisplayArea() + .getNextFocusableRootTask(currentFocus, ignoreCurrent); + if (rootTask != null) { + return rootTask; + } + continue; + } + + final Task rootTask = mChildren.get(i).asTask(); if (ignoreCurrent && rootTask == currentFocus) { continue; } @@ -1115,18 +1297,19 @@ final class TaskDisplayArea extends DisplayArea { if (currentWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY && candidate == null && rootTask.inSplitScreenPrimaryWindowingMode()) { - // If the currently focused stack is in split-screen secondary we save off the - // top primary split-screen stack as a candidate for focus because we might - // prefer focus to move to an other stack to avoid primary split-screen stack - // overlapping with a fullscreen stack when a fullscreen stack is higher in z - // than the next split-screen stack. Assistant stack, I am looking at you... - // We only move the focus to the primary-split screen stack if there isn't a + // If the currently focused root task is in split-screen secondary we save off the + // top primary split-screen root task as a candidate for focus because we might + // prefer focus to move to an other root task to avoid primary split-screen root + // task overlapping with a fullscreen root task when a fullscreen root task is + // higher in z than the next split-screen root task. Assistant root task, I am + // looking at you... + // We only move the focus to the primary-split screen root task if there isn't a // better alternative. candidate = rootTask; continue; } if (candidate != null && rootTask.inSplitScreenSecondaryWindowingMode()) { - // Use the candidate stack since we are now at the secondary split-screen. + // Use the candidate root task since we are now at the secondary split-screen. return candidate; } return rootTask; @@ -1135,21 +1318,21 @@ final class TaskDisplayArea extends DisplayArea { } ActivityRecord getFocusedActivity() { - final Task focusedStack = getFocusedRootTask(); - if (focusedStack == null) { + final Task focusedRootTask = getFocusedRootTask(); + if (focusedRootTask == null) { return null; } // TODO(b/111541062): Move this into ActivityStack#getResumedActivity() - // Check if the focused stack has the resumed activity - ActivityRecord resumedActivity = focusedStack.getResumedActivity(); + // Check if the focused root task has the resumed activity + ActivityRecord resumedActivity = focusedRootTask.getResumedActivity(); if (resumedActivity == null || resumedActivity.app == null) { - // If there is no registered resumed activity in the stack or it is not running - + // If there is no registered resumed activity in the root task or it is not running - // try to use previously resumed one. - resumedActivity = focusedStack.getPausingActivity(); + resumedActivity = focusedRootTask.getPausingActivity(); if (resumedActivity == null || resumedActivity.app == null) { // If previously resumed activity doesn't work either - find the topmost running // activity that can be focused. - resumedActivity = focusedStack.topRunningActivity(true /* focusableOnly */); + resumedActivity = focusedRootTask.topRunningActivity(true /* focusableOnly */); } } return resumedActivity; @@ -1184,27 +1367,35 @@ final class TaskDisplayArea extends DisplayArea { } boolean allResumedActivitiesComplete() { - for (int stackNdx = mChildren.size() - 1; stackNdx >= 0; --stackNdx) { - final ActivityRecord r = mChildren.get(stackNdx).getResumedActivity(); + for (int i = mChildren.size() - 1; i >= 0; --i) { + final WindowContainer child = mChildren.get(i); + if (child.asTaskDisplayArea() != null) { + if (!child.asTaskDisplayArea().allResumedActivitiesComplete()) { + return false; + } + continue; + } + + final ActivityRecord r = mChildren.get(i).asTask().getResumedActivity(); if (r != null && !r.isState(RESUMED)) { return false; } } - final Task currentFocusedStack = getFocusedRootTask(); + final Task currentFocusedRootTask = getFocusedRootTask(); if (ActivityTaskManagerDebugConfig.DEBUG_ROOT_TASK) { - Slog.d(TAG_ROOT_TASK, "allResumedActivitiesComplete: mLastFocusedStack changing from=" - + mLastFocusedRootTask + " to=" + currentFocusedStack); + Slog.d(TAG_ROOT_TASK, "allResumedActivitiesComplete: currentFocusedRootTask " + + "changing from=" + mLastFocusedRootTask + " to=" + currentFocusedRootTask); } - mLastFocusedRootTask = currentFocusedStack; + mLastFocusedRootTask = currentFocusedRootTask; return true; } /** - * Pause all activities in either all of the stacks or just the back stacks. This is done before - * resuming a new activity and to make sure that previously active activities are - * paused in stacks that are no longer visible or in pinned windowing mode. This does not - * pause activities in visible stacks, so if an activity is launched within the same stack/task, - * then we should explicitly pause that stack's top activity. + * Pause all activities in either all of the root tasks or just the back root tasks. This is + * done before resuming a new activity and to make sure that previously active activities are + * paused in root tasks that are no longer visible or in pinned windowing mode. This does not + * pause activities in visible root tasks, so if an activity is launched within the same root + * task, hen we should explicitly pause that root task's top activity. * * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving(). * @param resuming The resuming activity. @@ -1217,10 +1408,10 @@ final class TaskDisplayArea extends DisplayArea { if (resumedActivity != null && (task.getVisibility(resuming) != TASK_VISIBILITY_VISIBLE || !task.isTopActivityFocusable())) { - ProtoLog.d(WM_DEBUG_STATES, "pauseBackStacks: task=%s " + ProtoLog.d(WM_DEBUG_STATES, "pauseBackTasks: task=%s " + "mResumedActivity=%s", task, resumedActivity); if (task.startPausingLocked(userLeaving, false /* uiSleeping*/, - resuming, "pauseBackStacks")) { + resuming, "pauseBackTasks")) { someActivityPaused[0]++; } } @@ -1234,18 +1425,21 @@ final class TaskDisplayArea extends DisplayArea { void findTaskLocked(final ActivityRecord r, final boolean isPreferredDisplayArea, RootWindowContainer.FindTaskResult result) { mTmpFindTaskResult.clear(); - for (int stackNdx = mChildren.size() - 1; stackNdx >= 0; --stackNdx) { - final Task stack = mChildren.get(stackNdx); - if (!r.hasCompatibleActivityType(stack) && stack.isLeafTask()) { - ProtoLog.d(WM_DEBUG_TASKS, "Skipping stack: (mismatch activity/stack) " - + "%s", stack); + for (int i = mChildren.size() - 1; i >= 0; --i) { + final Task rootTask = mChildren.get(i).asTask(); + if (rootTask == null) { + continue; + } + if (!r.hasCompatibleActivityType(rootTask) && rootTask.isLeafTask()) { + ProtoLog.d(WM_DEBUG_TASKS, "Skipping rootTask: (mismatch activity/rootTask) " + + "%s", rootTask); continue; } - mTmpFindTaskResult.process(r, stack); - // It is possible to have tasks in multiple stacks with the same root affinity, so + mTmpFindTaskResult.process(r, rootTask); + // It is possible to have tasks in multiple root tasks with the same root affinity, so // we should keep looking after finding an affinity match to see if there is a - // better match in another stack. Also, task affinity isn't a good enough reason + // better match in another root task. Also, task affinity isn't a good enough reason // to target a display which isn't the source of the intent, so skip any affinity // matches not on the specified display. if (mTmpFindTaskResult.mRecord != null) { @@ -1253,9 +1447,9 @@ final class TaskDisplayArea extends DisplayArea { result.setTo(mTmpFindTaskResult); return; } else if (isPreferredDisplayArea) { - // Note: since the traversing through the stacks is top down, the floating + // Note: since the traversing through the root tasks is top down, the floating // tasks should always have lower priority than any affinity-matching tasks - // in the fullscreen stacks + // in the fullscreen root tasks result.setTo(mTmpFindTaskResult); } } @@ -1474,20 +1668,29 @@ final class TaskDisplayArea extends DisplayArea { */ ActivityRecord topRunningActivity(boolean considerKeyguardState) { ActivityRecord topRunning = null; - final Task focusedStack = getFocusedRootTask(); - if (focusedStack != null) { - topRunning = focusedStack.topRunningActivity(); + final Task focusedRootTask = getFocusedRootTask(); + if (focusedRootTask != null) { + topRunning = focusedRootTask.topRunningActivity(); } - // Look in other focusable stacks. + // Look in other focusable root tasks. if (topRunning == null) { for (int i = mChildren.size() - 1; i >= 0; --i) { - final Task stack = mChildren.get(i); - // Only consider focusable stacks other than the current focused one. - if (stack == focusedStack || !stack.isTopActivityFocusable()) { + final WindowContainer child = mChildren.get(i); + if (child.asTaskDisplayArea() != null) { + topRunning = + child.asTaskDisplayArea().topRunningActivity(considerKeyguardState); + if (topRunning != null) { + break; + } continue; } - topRunning = stack.topRunningActivity(); + final Task rootTask = mChildren.get(i).asTask(); + // Only consider focusable root tasks other than the current focused one. + if (rootTask == focusedRootTask || !rootTask.isTopActivityFocusable()) { + continue; + } + topRunning = rootTask.topRunningActivity(); if (topRunning != null) { break; } @@ -1593,35 +1796,44 @@ final class TaskDisplayArea extends DisplayArea { } /** - * Adjusts the {@param stack} behind the last visible stack in the display if necessary. + * Adjusts the {@param rootTask} behind the last visible rootTask in the display if necessary. * Generally used in conjunction with {@link #moveRootTaskBehindRootTask}. */ // TODO(b/151575894): Remove special stack movement methods. void moveRootTaskBehindBottomMostVisibleRootTask(Task rootTask) { if (rootTask.shouldBeVisible(null)) { - // Skip if the stack is already visible + // Skip if the root task is already visible return; } - // Move the stack to the bottom to not affect the following visibility checks + // Move the root task to the bottom to not affect the following visibility checks rootTask.getParent().positionChildAt(POSITION_BOTTOM, rootTask, false /* includingParents */); - // Find the next position where the stack should be placed + // Find the next position where the root task should be placed final boolean isRootTask = rootTask.isRootTask(); final int numRootTasks = isRootTask ? mChildren.size() : rootTask.getParent().getChildCount(); for (int rootTaskNdx = 0; rootTaskNdx < numRootTasks; rootTaskNdx++) { - final Task s = isRootTask ? mChildren.get(rootTaskNdx) - : (Task) rootTask.getParent().getChildAt(rootTaskNdx); - if (s == rootTask) { + Task s; + if (isRootTask) { + final WindowContainer child = mChildren.get(rootTaskNdx); + if (child.asTaskDisplayArea() != null) { + s = child.asTaskDisplayArea().getBottomMostVisibleRootTask(rootTask); + } else { + s = child.asTask(); + } + } else { + s = rootTask.getParent().getChildAt(rootTaskNdx).asTask(); + } + if (s == rootTask || s == null) { continue; } final int winMode = s.getWindowingMode(); final boolean isValidWindowingMode = winMode == WINDOWING_MODE_FULLSCREEN || winMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; if (s.shouldBeVisible(null) && isValidWindowingMode) { - // Move the provided stack to behind this stack + // Move the provided root task to behind this root task final int position = Math.max(0, rootTaskNdx - 1); rootTask.getParent().positionChildAt(position, rootTask, false /*includingParents */); @@ -1630,6 +1842,16 @@ final class TaskDisplayArea extends DisplayArea { } } + @Nullable + private Task getBottomMostVisibleRootTask(Task excludeRootTask) { + return getRootTask(task -> { + final int winMode = task.getWindowingMode(); + final boolean isValidWindowingMode = winMode == WINDOWING_MODE_FULLSCREEN + || winMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; + return task.shouldBeVisible(null) && isValidWindowingMode; + }, false /* traverseTopToBottom */); + } + /** * Moves the {@param stack} behind the given {@param behindStack} if possible. If * {@param behindStack} is not currently in the display, then then the stack is moved to the @@ -1735,77 +1957,82 @@ final class TaskDisplayArea extends DisplayArea { boolean preserveWindows, boolean notifyClients, boolean userLeaving) { mAtmService.mTaskSupervisor.beginActivityVisibilityUpdate(); try { - for (int stackNdx = mChildren.size() - 1; stackNdx >= 0; --stackNdx) { - final Task stack = mChildren.get(stackNdx); - stack.ensureActivitiesVisible(starting, configChanges, preserveWindows, + forAllRootTasks(rootTask -> { + rootTask.ensureActivitiesVisible(starting, configChanges, preserveWindows, notifyClients, userLeaving); - } + }); } finally { mAtmService.mTaskSupervisor.endActivityVisibilityUpdate(); } } /** - * Removes the stacks in the node applying the content removal node from the display. + * Removes the root tasks in the node applying the content removal node from the display. * - * @return last reparented stack, or {@code null} if the stacks had to be destroyed. + * @return last reparented root task, or {@code null} if the root tasks had to be destroyed. */ Task remove() { mPreferredTopFocusableRootTask = null; // TODO(b/153090332): Allow setting content removal mode per task display area final boolean destroyContentOnRemoval = mDisplayContent.shouldDestroyContentOnRemove(); final TaskDisplayArea toDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea(); - Task lastReparentedStack = null; + Task lastReparentedRootTask = null; - // Stacks could be reparented from the removed display area to other display area. After - // reparenting the last stack of the removed display area, the display area becomes ready to - // be released (no more ActivityStack-s). But, we cannot release it at that moment or the - // related WindowContainer will also be removed. So, we set display area as removed after - // reparenting stack finished. + // Root tasks could be reparented from the removed display area to other display area. After + // reparenting the last root task of the removed display area, the display area becomes + // ready to be released (no more ActivityStack-s). But, we cannot release it at that moment + // or the related WindowContainer will also be removed. So, we set display area as removed + // after reparenting root task finished. // Keep the order from bottom to top. - int numStacks = mChildren.size(); + int numRootTasks = mChildren.size(); final boolean splitScreenActivated = toDisplayArea.isSplitScreenModeActivated(); - final Task rootStack = splitScreenActivated ? toDisplayArea + final Task splitScreenRoot = splitScreenActivated ? toDisplayArea .getTopRootTaskInWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) : null; - for (int stackNdx = 0; stackNdx < numStacks; stackNdx++) { - final Task stack = mChildren.get(stackNdx); - // Always finish non-standard type stacks and stacks created by a organizer. + for (int i = 0; i < numRootTasks; i++) { + final WindowContainer child = mChildren.get(i); + if (child.asTaskDisplayArea() != null) { + lastReparentedRootTask = child.asTaskDisplayArea().remove(); + continue; + } + final Task task = mChildren.get(i).asTask(); + // Always finish non-standard type root tasks and root tasks created by a organizer. // TODO: For stacks created by organizer, consider reparenting children tasks if the use // case arises in the future. if (destroyContentOnRemoval - || !stack.isActivityTypeStandardOrUndefined() - || stack.mCreatedByOrganizer) { - stack.finishAllActivitiesImmediately(); + || !task.isActivityTypeStandardOrUndefined() + || task.mCreatedByOrganizer) { + task.finishAllActivitiesImmediately(); } else { - // Reparent the stack to the root task of secondary-split-screen or display area. - stack.reparent(stack.supportsSplitScreenWindowingMode() && rootStack != null - ? rootStack : toDisplayArea, POSITION_TOP); + // Reparent the root task to the root task of secondary-split-screen or display + // area. + task.reparent(task.supportsSplitScreenWindowingMode() && splitScreenRoot != null + ? splitScreenRoot : toDisplayArea, POSITION_TOP); - // Set the windowing mode to undefined by default to let the stack inherited the + // Set the windowing mode to undefined by default to let the root task inherited the // windowing mode. - stack.setWindowingMode(WINDOWING_MODE_UNDEFINED); - lastReparentedStack = stack; + task.setWindowingMode(WINDOWING_MODE_UNDEFINED); + lastReparentedRootTask = task; } - // Stacks may be removed from this display. Ensure each stack will be processed + // Root task may be removed from this display. Ensure each root task will be processed // and the loop will end. - stackNdx -= numStacks - mChildren.size(); - numStacks = mChildren.size(); + i -= numRootTasks - mChildren.size(); + numRootTasks = mChildren.size(); } - if (lastReparentedStack != null && splitScreenActivated) { - if (!lastReparentedStack.supportsSplitScreenWindowingMode()) { + if (lastReparentedRootTask != null && splitScreenActivated) { + if (!lastReparentedRootTask.supportsSplitScreenWindowingMode()) { mAtmService.getTaskChangeNotificationController() .notifyActivityDismissingDockedStack(); - toDisplayArea.onSplitScreenModeDismissed(lastReparentedStack); - } else if (rootStack != null) { + toDisplayArea.onSplitScreenModeDismissed(lastReparentedRootTask); + } else if (splitScreenRoot != null) { // update focus - rootStack.moveToFront("display-removed"); + splitScreenRoot.moveToFront("display-removed"); } } mRemoved = true; - return lastReparentedStack; + return lastReparentedRootTask; } /** Whether this task display area can request orientation. */ @@ -1842,8 +2069,13 @@ final class TaskDisplayArea extends DisplayArea { } final String triplePrefix = doublePrefix + " "; pw.println(doublePrefix + "Application tokens in top down Z order:"); - for (int rootTaskNdx = getChildCount() - 1; rootTaskNdx >= 0; --rootTaskNdx) { - final Task rootTask = getChildAt(rootTaskNdx); + for (int index = getChildCount() - 1; index >= 0; --index) { + final WindowContainer child = getChildAt(index); + if (child.asTaskDisplayArea() != null) { + child.dump(pw, doublePrefix, dumpAll); + continue; + } + final Task rootTask = child.asTask(); pw.println(doublePrefix + "* " + rootTask); rootTask.dump(pw, triplePrefix, dumpAll); } 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 466b86117fdcd..801a27d09e120 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.getIndexOf(anotherAlwaysOnTopStack)); + assertEquals(topPosition - 1, taskDisplayArea.getTaskIndexOf(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.getIndexOf(nonAlwaysOnTopStack)); + assertEquals(topPosition - 3, taskDisplayArea.getTaskIndexOf(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.getIndexOf(anotherAlwaysOnTopStack)); + assertEquals(topPosition - 2, taskDisplayArea.getTaskIndexOf(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.getIndexOf(anotherAlwaysOnTopStack)); + assertEquals(topPosition - 2, taskDisplayArea.getTaskIndexOf(anotherAlwaysOnTopStack)); anotherAlwaysOnTopStack.setWindowingMode(WINDOWING_MODE_FREEFORM); assertTrue(anotherAlwaysOnTopStack.isAlwaysOnTop()); - assertEquals(topPosition - 1, taskDisplayArea.getIndexOf(anotherAlwaysOnTopStack)); + assertEquals(topPosition - 1, taskDisplayArea.getTaskIndexOf(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.getIndexOf(pinnedStack)); + assertEquals(topPosition - 1, taskDisplayArea.getTaskIndexOf(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.getIndexOf(assistStack)); + taskDisplayArea.getTaskIndexOf(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 5504460f1036e..8ea95ae212f03 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.getIndexOf(primarySplitScreen)); + assertEquals(0, mDefaultTaskDisplayArea.getTaskIndexOf(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.getIndexOf(homeStack); + int homeStackIndex = mDefaultTaskDisplayArea.getTaskIndexOf(homeStack); assertEquals(fullscreenStack, getRootTaskAbove(homeStack)); mDefaultTaskDisplayArea.moveRootTaskBehindBottomMostVisibleRootTask(homeStack); - assertEquals(homeStackIndex, mDefaultTaskDisplayArea.getIndexOf(homeStack)); + assertEquals(homeStackIndex, mDefaultTaskDisplayArea.getTaskIndexOf(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.getIndexOf(homeStack); + int homeStackIndex = mDefaultTaskDisplayArea.getTaskIndexOf(homeStack); assertEquals(fullscreenStack, getRootTaskAbove(homeStack)); mDefaultTaskDisplayArea.moveRootTaskBehindBottomMostVisibleRootTask(homeStack); - assertEquals(homeStackIndex, mDefaultTaskDisplayArea.getIndexOf(homeStack)); + assertEquals(homeStackIndex, mDefaultTaskDisplayArea.getTaskIndexOf(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.getIndexOf(homeStack); + int homeStackIndex = mDefaultTaskDisplayArea.getTaskIndexOf(homeStack); assertNull(getRootTaskAbove(homeStack)); mDefaultTaskDisplayArea.moveRootTaskBehindBottomMostVisibleRootTask(homeStack); - assertEquals(homeStackIndex, mDefaultTaskDisplayArea.getIndexOf(homeStack)); + assertEquals(homeStackIndex, mDefaultTaskDisplayArea.getTaskIndexOf(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.getIndexOf(homeStack); + int homeStackIndex = mDefaultTaskDisplayArea.getTaskIndexOf(homeStack); mDefaultTaskDisplayArea.moveRootTaskBehindRootTask(homeStack, homeStack); - assertEquals(homeStackIndex, mDefaultTaskDisplayArea.getIndexOf(homeStack)); + assertEquals(homeStackIndex, mDefaultTaskDisplayArea.getTaskIndexOf(homeStack)); } @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java index 5695412394ce7..f3031847839c3 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java @@ -512,8 +512,8 @@ public class ActivityStarterTests extends WindowTestsBase { } private void assertNoTasks(DisplayContent display) { - display.forAllRootTasks(stack -> { - assertFalse(stack.hasChild()); + display.forAllRootTasks(rootTask -> { + assertFalse(rootTask.hasChild()); }); } diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java index 8e78dce39ac7f..0aa618b80092b 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java @@ -692,7 +692,7 @@ public class DisplayAreaPolicyBuilderTest { private Map, Set> calculateZSets( DisplayAreaPolicyBuilder.Result policy, DisplayArea.Tokens ime, - DisplayArea tasks) { + TaskDisplayArea taskDisplayArea) { Map, Set> zSets = new HashMap<>(); int[] types = {TYPE_STATUS_BAR, TYPE_NAVIGATION_BAR, TYPE_PRESENTATION, TYPE_APPLICATION_OVERLAY}; @@ -700,7 +700,7 @@ public class DisplayAreaPolicyBuilderTest { WindowToken token = tokenOfType(type); recordLayer(policy.findAreaForToken(token), token.getWindowLayerFromType(), zSets); } - recordLayer(tasks, APPLICATION_LAYER, zSets); + recordLayer(taskDisplayArea, APPLICATION_LAYER, zSets); recordLayer(ime, mPolicy.getWindowLayerFromTypeLw(TYPE_INPUT_METHOD), zSets); return zSets; } 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 e13a5952ccacf..421c13005550e 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java @@ -1121,9 +1121,9 @@ class WindowTestsBase extends SystemServiceTestsBase { mService.mTaskOrganizerController.setLaunchRoot(mDisplayId, mSecondary.mRemoteToken.toWindowContainerToken()); DisplayContent dc = mService.mRootWindowContainer.getDisplayContent(mDisplayId); - dc.forAllRootTasks(stack -> { - if (!WindowConfiguration.isSplitScreenWindowingMode(stack.getWindowingMode())) { - stack.reparent(mSecondary, POSITION_BOTTOM); + dc.forAllRootTasks(rootTask -> { + if (!WindowConfiguration.isSplitScreenWindowingMode(rootTask.getWindowingMode())) { + rootTask.reparent(mSecondary, POSITION_BOTTOM); } }); }