Loading services/core/java/com/android/server/wm/ActivityRecord.java +11 −1 Original line number Diff line number Diff line Loading @@ -7411,7 +7411,17 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A */ boolean isResumedActivityOnDisplay() { final DisplayContent display = getDisplay(); return display != null && this == display.mTaskContainers.getResumedActivity(); if (display == null) { return false; } for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx); final ActivityRecord resumedActivity = taskDisplayArea.getFocusedActivity(); if (resumedActivity != null) { return resumedActivity == this; } } return false; } Loading services/core/java/com/android/server/wm/ActivityStack.java +2 −2 Original line number Diff line number Diff line Loading @@ -1119,8 +1119,8 @@ class ActivityStack extends Task { @Override public boolean isAttached() { final DisplayContent display = getDisplay(); return display != null && !display.isRemoved(); final TaskDisplayArea taskDisplayArea = getDisplayArea(); return taskDisplayArea != null && !taskDisplayArea.isRemoved(); } // TODO: Should each user have there own stacks? Loading services/core/java/com/android/server/wm/ActivityStackSupervisor.java +24 −23 Original line number Diff line number Diff line Loading @@ -385,15 +385,15 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { private final MoveTaskToFullscreenHelper mMoveTaskToFullscreenHelper = new MoveTaskToFullscreenHelper(); private class MoveTaskToFullscreenHelper { private DisplayContent mToDisplay; private TaskDisplayArea mToDisplayArea; private boolean mOnTop; private Task mTopTask; private boolean mSchedulePictureInPictureModeChange; void process(ActivityStack fromStack, DisplayContent toDisplay, boolean onTop, void process(ActivityStack fromStack, TaskDisplayArea toDisplayArea, boolean onTop, boolean schedulePictureInPictureModeChange) { mSchedulePictureInPictureModeChange = schedulePictureInPictureModeChange; mToDisplay = toDisplay; mToDisplayArea = toDisplayArea; mOnTop = onTop; mTopTask = fromStack.getTopMostTask(); Loading @@ -401,7 +401,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { MoveTaskToFullscreenHelper::processLeafTask, this, PooledLambda.__(Task.class)); fromStack.forAllLeafTasks(c, false /* traverseTopToBottom */); c.recycle(); mToDisplay = null; mToDisplayArea = null; mTopTask = null; } Loading @@ -411,19 +411,18 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { task.getActivityType())) { final ActivityStack stack = (ActivityStack) task; stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN); if (mToDisplay.getDisplayId() != stack.getDisplayId()) { stack.reparent(mToDisplay.getDefaultTaskDisplayArea(), mOnTop); if (mToDisplayArea.getDisplayId() != stack.getDisplayId()) { stack.reparent(mToDisplayArea, mOnTop); } else if (mOnTop) { mToDisplay.mTaskContainers.positionStackAtTop(stack, false /* includingParents */); mToDisplayArea.positionStackAtTop(stack, false /* includingParents */); } else { mToDisplay.mTaskContainers.positionStackAtBottom(stack); mToDisplayArea.positionStackAtBottom(stack); } return; } final ActivityStack toStack = mToDisplay.mTaskContainers.getOrCreateStack( null, mTmpOptions, task, task.getActivityType(), mOnTop); final ActivityStack toStack = mToDisplayArea.getOrCreateStack(null, mTmpOptions, task, task.getActivityType(), mOnTop); if (task == toStack) { // The task was reused as the root task. return; Loading Loading @@ -1418,7 +1417,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { mRootWindowContainer.getLaunchStack(null, options, task, ON_TOP); if (stack != currentStack) { moveHomeStackToFrontIfNeeded(flags, stack.getDisplay(), reason); moveHomeStackToFrontIfNeeded(flags, stack.getDisplayArea(), reason); task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, !ANIMATE, DEFER_RESUME, reason); currentStack = stack; Loading @@ -1437,7 +1436,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { } if (!reparented) { moveHomeStackToFrontIfNeeded(flags, currentStack.getDisplay(), reason); moveHomeStackToFrontIfNeeded(flags, currentStack.getDisplayArea(), reason); } final ActivityRecord r = task.getTopNonFinishingActivity(); Loading @@ -1451,15 +1450,16 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { currentStack, forceNonResizeable); } private void moveHomeStackToFrontIfNeeded(int flags, DisplayContent display, String reason) { final ActivityStack focusedStack = display.getFocusedStack(); private void moveHomeStackToFrontIfNeeded(int flags, TaskDisplayArea taskDisplayArea, String reason) { final ActivityStack focusedStack = taskDisplayArea.getFocusedStack(); if ((display.getWindowingMode() == WINDOWING_MODE_FULLSCREEN if ((taskDisplayArea.getWindowingMode() == WINDOWING_MODE_FULLSCREEN && (flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) || (focusedStack != null && focusedStack.isActivityTypeRecents())) { // We move home stack to front when we are on a fullscreen display and caller has // We move home stack to front when we are on a fullscreen display area and caller has // requested the home activity to move with it. Or the previous stack is recents. display.mTaskContainers.moveHomeStackToFront(reason); taskDisplayArea.moveHomeStackToFront(reason); } } Loading Loading @@ -1511,15 +1511,15 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { mService.deferWindowLayout(); try { final int windowingMode = fromStack.getWindowingMode(); final DisplayContent toDisplay = mRootWindowContainer.getDisplayContent(toDisplayId); final TaskDisplayArea toDisplayArea = mRootWindowContainer .getDisplayContent(toDisplayId).getDefaultTaskDisplayArea(); if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) { // We are moving all tasks from the docked stack to the fullscreen stack, // which is dismissing the docked stack, so resize all other stacks to // fullscreen here already so we don't end up with resize trashing. for (int i = toDisplay.getStackCount() - 1; i >= 0; --i) { final ActivityStack otherStack = toDisplay.getStackAt(i); for (int i = toDisplayArea.getStackCount() - 1; i >= 0; --i) { final ActivityStack otherStack = toDisplayArea.getStackAt(i); if (!otherStack.inSplitScreenSecondaryWindowingMode()) { continue; } Loading @@ -1535,7 +1535,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { if (fromStack.hasChild()) { mTmpOptions.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN); mMoveTaskToFullscreenHelper.process( fromStack, toDisplay, onTop, schedulePictureInPictureModeChange); fromStack, toDisplayArea, onTop, schedulePictureInPictureModeChange); } mRootWindowContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS); Loading @@ -1546,6 +1546,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { } void moveTasksToFullscreenStackLocked(ActivityStack fromStack, boolean onTop) { // TODO(b/153089193): Support moving within the same task display area mWindowManager.inSurfaceTransaction(() -> moveTasksToFullscreenStackInSurfaceTransaction(fromStack, DEFAULT_DISPLAY, onTop)); } Loading services/core/java/com/android/server/wm/ActivityStartController.java +3 −2 Original line number Diff line number Diff line Loading @@ -189,9 +189,10 @@ public class ActivityStartController { mSupervisor.beginDeferResume(); final ActivityStack homeStack; try { // TODO(multi-display-area): Support starting home in a task display area // Make sure home stack exist on display. homeStack = display.mTaskContainers.getOrCreateStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP); homeStack = display.getDefaultTaskDisplayArea().getOrCreateStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP); } finally { mSupervisor.endDeferResume(); } Loading services/core/java/com/android/server/wm/DisplayContent.java +119 −80 Original line number Diff line number Diff line Loading @@ -2060,20 +2060,53 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo * activity type. Null is no compatible stack on the display. */ ActivityStack getStack(int windowingMode, int activityType) { return mTaskContainers.getStack(windowingMode, activityType); for (int tdaNdx = getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { final ActivityStack stack = getTaskDisplayAreaAt(tdaNdx) .getStack(windowingMode, activityType); if (stack != null) { return stack; } } return null; } protected int getStackCount() { return mTaskContainers.mChildren.size(); protected int getTaskDisplayAreaCount() { // TODO(multi-display-area): Report actual display area count return 1; } protected TaskDisplayArea getTaskDisplayAreaAt(int index) { // TODO(multi-display-area): Report actual display area values return mTaskContainers; } protected ActivityStack getStackAt(int index) { return mTaskContainers.mChildren.get(index); ActivityStack getStack(int rootTaskId) { for (int tdaNdx = getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { final ActivityStack stack = getTaskDisplayAreaAt(tdaNdx).getStack(rootTaskId); if (stack != null) { return stack; } } return null; } protected int getStackCount() { int totalStackCount = 0; for (int i = getTaskDisplayAreaCount() - 1; i >= 0; --i) { totalStackCount += getTaskDisplayAreaAt(i).getStackCount(); } return totalStackCount; } @VisibleForTesting ActivityStack getTopStack() { return mTaskContainers.getTopStack(); for (int i = getTaskDisplayAreaCount() - 1; i >= 0; --i) { final ActivityStack stack = getTaskDisplayAreaAt(i).getTopStack(); if (stack != null) { return stack; } } return null; } /** Loading Loading @@ -2449,7 +2482,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo final PooledConsumer c = PooledLambda.obtainConsumer( DisplayContent::processTaskForTouchExcludeRegion, this, PooledLambda.__(Task.class), focusedTask, delta); mTaskContainers.forAllTasks(c); forAllTasks(c); c.recycle(); // If we removed the focused task above, add it back and only leave its Loading Loading @@ -2630,9 +2663,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } void prepareFreezingTaskBounds() { for (int stackNdx = mTaskContainers.getChildCount() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = mTaskContainers.getChildAt(stackNdx); stack.prepareFreezingTaskBounds(); for (int tdaNdx = getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { getTaskDisplayAreaAt(tdaNdx).prepareFreezingTaskBounds(); } } Loading Loading @@ -2738,8 +2770,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo final ActivityStack focusedStack = getFocusedStack(); if (focusedStack != null) { proto.write(FOCUSED_ROOT_TASK_ID, focusedStack.getRootTaskId()); final ActivityRecord focusedActivity = focusedStack.getDisplay().mTaskContainers .getResumedActivity(); final ActivityRecord focusedActivity = focusedStack.getDisplayArea() .getFocusedActivity(); if (focusedActivity != null) { focusedActivity.writeIdentifierToProto(proto, RESUMED_ACTIVITY); } Loading Loading @@ -2797,13 +2829,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo if (mLastFocus != mCurrentFocus) { pw.print(" mLastFocus="); pw.println(mLastFocus); } if (mTaskContainers.mPreferredTopFocusableStack != null) { pw.println(prefix + "mPreferredTopFocusableStack=" + mTaskContainers.mPreferredTopFocusableStack); } if (mTaskContainers.mLastFocusedStack != null) { pw.println(prefix + "mLastFocusedStack=" + mTaskContainers.mLastFocusedStack); } if (mLosingFocus.size() > 0) { pw.println(); pw.println(" Windows losing focus:"); Loading Loading @@ -2837,10 +2862,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } pw.println(); pw.println(prefix + "Application tokens in top down Z order:"); for (int stackNdx = mTaskContainers.getChildCount() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = mTaskContainers.getChildAt(stackNdx); stack.dump(pw, prefix + " ", dumpAll); pw.println(prefix + "Task display areas in top down Z order:"); for (int tdaNdx = getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { getTaskDisplayAreaAt(tdaNdx).dump(pw, prefix + " ", dumpAll); } pw.println(); Loading Loading @@ -4002,7 +4026,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } // Initialize state of exiting applications. mTaskContainers.setExitingTokensHasVisible(hasVisible); for (int i = getTaskDisplayAreaCount() - 1; i >= 0; --i) { getTaskDisplayAreaAt(i).setExitingTokensHasVisible(hasVisible); } } void removeExistingTokensIfPossible() { Loading @@ -4014,7 +4040,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } // Time to remove any exiting applications? mTaskContainers.removeExistingAppTokensIfPossible(); for (int i = getTaskDisplayAreaCount() - 1; i >= 0; --i) { getTaskDisplayAreaAt(i).removeExistingAppTokensIfPossible(); } } @Override Loading Loading @@ -4475,7 +4503,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } void assignStackOrdering() { mTaskContainers.assignStackOrdering(getPendingTransaction()); for (int i = getTaskDisplayAreaCount() - 1; i >= 0; --i) { getTaskDisplayAreaAt(i).assignStackOrdering(getPendingTransaction()); } } /** Loading Loading @@ -5002,13 +5032,15 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo || windowingMode == WINDOWING_MODE_MULTI_WINDOW); } ActivityStack createStack(int windowingMode, int activityType, boolean onTop) { return mTaskContainers.createStack(windowingMode, activityType, onTop, null /* info */, null /* intent */, false /* createdByOrganizer */); } @Nullable ActivityStack getFocusedStack() { return mTaskContainers.getFocusedStack(); for (int i = getTaskDisplayAreaCount() - 1; i >= 0; --i) { final ActivityStack stack = getTaskDisplayAreaAt(i).getFocusedStack(); if (stack != null) { return stack; } } return null; } /** Loading @@ -5016,11 +5048,15 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED */ void removeStacksInWindowingModes(int... windowingModes) { mTaskContainers.removeStacksInWindowingModes(windowingModes); for (int i = getTaskDisplayAreaCount() - 1; i >= 0; --i) { getTaskDisplayAreaAt(i).removeStacksInWindowingModes(windowingModes); } } void removeStacksWithActivityTypes(int... activityTypes) { mTaskContainers.removeStacksWithActivityTypes(activityTypes); for (int i = getTaskDisplayAreaCount() - 1; i >= 0; --i) { getTaskDisplayAreaAt(i).removeStacksWithActivityTypes(activityTypes); } } ActivityRecord topRunningActivity() { Loading @@ -5037,7 +5073,14 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo * @return The top running activity. {@code null} if none is available. */ ActivityRecord topRunningActivity(boolean considerKeyguardState) { return mTaskContainers.topRunningActivity(considerKeyguardState); for (int i = getTaskDisplayAreaCount() - 1; i >= 0; --i) { final ActivityRecord activity = getTaskDisplayAreaAt(i) .topRunningActivity(considerKeyguardState); if (activity != null) { return activity; } } return null; } boolean updateDisplayOverrideConfigurationLocked() { Loading Loading @@ -5149,7 +5192,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo // The display may be about to rotate seamlessly, and the animation of closing apps may // still animate in old rotation. So make sure the outdated animation won't show on the // rotated display. mTaskContainers.forAllActivities(a -> { forAllActivities(a -> { if (a.nowVisible && a != mFixedRotationLaunchingApp && a.getWindowConfiguration().getRotation() != newRotation) { final WindowContainer<?> w = a.getAnimatingContainer(); Loading Loading @@ -5210,40 +5253,17 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo void remove() { mRemoving = true; final boolean destroyContentOnRemoval = shouldDestroyContentOnRemove(); ActivityStack lastReparentedStack = null; mTaskContainers.mPreferredTopFocusableStack = null; // Stacks could be reparented from the removed display to other display. While // reparenting the last stack of the removed display, the remove display is ready to be // released (no more ActivityStack). But, we cannot release it at that moment or the // related WindowContainer will also be removed. So, we set display as removed after // reparenting stack finished. final TaskDisplayArea toTaskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea(); mRootWindowContainer.mStackSupervisor.beginDeferResume(); try { int numStacks = getStackCount(); // Keep the order from bottom to top. for (int stackNdx = 0; stackNdx < numStacks; stackNdx++) { final ActivityStack stack = getStackAt(stackNdx); // Always finish non-standard type stacks. if (destroyContentOnRemoval || !stack.isActivityTypeStandardOrUndefined()) { stack.finishAllActivitiesImmediately(); } else { // If default display is in split-window mode, set windowing mode of the stack // to split-screen secondary. Otherwise, set the windowing mode to undefined by // default to let stack inherited the windowing mode from the new display. final int windowingMode = toTaskDisplayArea.isSplitScreenModeActivated() ? WINDOWING_MODE_SPLIT_SCREEN_SECONDARY : WINDOWING_MODE_UNDEFINED; stack.reparent(toTaskDisplayArea, true /* onTop */); stack.setWindowingMode(windowingMode); lastReparentedStack = stack; } // Stacks may be removed from this display. Ensure each stack will be processed and // the loop will end. stackNdx -= numStacks - getStackCount(); numStacks = getStackCount(); int numTaskContainers = getTaskDisplayAreaCount(); for (int tdaNdx = 0; tdaNdx < numTaskContainers; tdaNdx++) { final ActivityStack lastReparentedStackFromArea = getTaskDisplayAreaAt(tdaNdx) .remove(); if (lastReparentedStackFromArea != null) { lastReparentedStack = lastReparentedStackFromArea; } } } finally { mRootWindowContainer.mStackSupervisor.endDeferResume(); Loading @@ -5270,12 +5290,27 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo return; } final ActivityStack stack = getStackCount() == 1 ? getStackAt(0) : null; if (stack != null && stack.isActivityTypeHome() && !stack.hasChild()) { // Release this display if an empty home stack is the only thing left. // Since it is the last stack, this display will be released along with the stack // removal. stack.removeIfPossible(); // Check if all task display areas have only the empty home stacks left. boolean onlyEmptyHomeStacksLeft = true; for (int tdaNdx = getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { final TaskDisplayArea taskDisplayArea = getTaskDisplayAreaAt(tdaNdx); if (taskDisplayArea.getStackCount() != 1) { onlyEmptyHomeStacksLeft = false; break; } final ActivityStack stack = taskDisplayArea.getStackAt(0); if (!stack.isActivityTypeHome() || stack.hasChild()) { onlyEmptyHomeStacksLeft = false; break; } } if (onlyEmptyHomeStacksLeft) { // Release this display if only empty home stack(s) are left. This display will be // released along with the stack(s) removal. for (int tdaNdx = getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { final ActivityStack s = getTaskDisplayAreaAt(tdaNdx).getStackAt(0); s.removeIfPossible(); } } else if (getTopStack() == null) { removeIfPossible(); mRootWindowContainer.mStackSupervisor Loading Loading @@ -5334,10 +5369,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo void ensureActivitiesVisible(ActivityRecord starting, int configChanges, boolean preserveWindows, boolean notifyClients) { for (int stackNdx = getStackCount() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = getStackAt(stackNdx); stack.ensureActivitiesVisible(starting, configChanges, preserveWindows, notifyClients); for (int i = getTaskDisplayAreaCount() - 1; i >= 0; --i) { getTaskDisplayAreaAt(i).ensureActivitiesVisible(starting, configChanges, preserveWindows, notifyClients); } } Loading @@ -5350,13 +5384,18 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } void setDisplayToSingleTaskInstance() { final int childCount = getStackCount(); if (childCount > 1) { final int taskDisplayAreaCount = getTaskDisplayAreaCount(); if (taskDisplayAreaCount > 1) { throw new IllegalArgumentException( "Display already has multiple task display areas. display=" + this); } final int stackCount = getDefaultTaskDisplayArea().getStackCount(); if (stackCount > 1) { throw new IllegalArgumentException("Display already has multiple stacks. display=" + this); } if (childCount > 0) { final ActivityStack stack = getStackAt(0); if (stackCount > 0) { final ActivityStack stack = getDefaultTaskDisplayArea().getStackAt(0); if (stack.getChildCount() > 1) { throw new IllegalArgumentException("Display stack already has multiple tasks." + " display=" + this + " stack=" + stack); Loading Loading
services/core/java/com/android/server/wm/ActivityRecord.java +11 −1 Original line number Diff line number Diff line Loading @@ -7411,7 +7411,17 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A */ boolean isResumedActivityOnDisplay() { final DisplayContent display = getDisplay(); return display != null && this == display.mTaskContainers.getResumedActivity(); if (display == null) { return false; } for (int tdaNdx = display.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tdaNdx); final ActivityRecord resumedActivity = taskDisplayArea.getFocusedActivity(); if (resumedActivity != null) { return resumedActivity == this; } } return false; } Loading
services/core/java/com/android/server/wm/ActivityStack.java +2 −2 Original line number Diff line number Diff line Loading @@ -1119,8 +1119,8 @@ class ActivityStack extends Task { @Override public boolean isAttached() { final DisplayContent display = getDisplay(); return display != null && !display.isRemoved(); final TaskDisplayArea taskDisplayArea = getDisplayArea(); return taskDisplayArea != null && !taskDisplayArea.isRemoved(); } // TODO: Should each user have there own stacks? Loading
services/core/java/com/android/server/wm/ActivityStackSupervisor.java +24 −23 Original line number Diff line number Diff line Loading @@ -385,15 +385,15 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { private final MoveTaskToFullscreenHelper mMoveTaskToFullscreenHelper = new MoveTaskToFullscreenHelper(); private class MoveTaskToFullscreenHelper { private DisplayContent mToDisplay; private TaskDisplayArea mToDisplayArea; private boolean mOnTop; private Task mTopTask; private boolean mSchedulePictureInPictureModeChange; void process(ActivityStack fromStack, DisplayContent toDisplay, boolean onTop, void process(ActivityStack fromStack, TaskDisplayArea toDisplayArea, boolean onTop, boolean schedulePictureInPictureModeChange) { mSchedulePictureInPictureModeChange = schedulePictureInPictureModeChange; mToDisplay = toDisplay; mToDisplayArea = toDisplayArea; mOnTop = onTop; mTopTask = fromStack.getTopMostTask(); Loading @@ -401,7 +401,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { MoveTaskToFullscreenHelper::processLeafTask, this, PooledLambda.__(Task.class)); fromStack.forAllLeafTasks(c, false /* traverseTopToBottom */); c.recycle(); mToDisplay = null; mToDisplayArea = null; mTopTask = null; } Loading @@ -411,19 +411,18 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { task.getActivityType())) { final ActivityStack stack = (ActivityStack) task; stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN); if (mToDisplay.getDisplayId() != stack.getDisplayId()) { stack.reparent(mToDisplay.getDefaultTaskDisplayArea(), mOnTop); if (mToDisplayArea.getDisplayId() != stack.getDisplayId()) { stack.reparent(mToDisplayArea, mOnTop); } else if (mOnTop) { mToDisplay.mTaskContainers.positionStackAtTop(stack, false /* includingParents */); mToDisplayArea.positionStackAtTop(stack, false /* includingParents */); } else { mToDisplay.mTaskContainers.positionStackAtBottom(stack); mToDisplayArea.positionStackAtBottom(stack); } return; } final ActivityStack toStack = mToDisplay.mTaskContainers.getOrCreateStack( null, mTmpOptions, task, task.getActivityType(), mOnTop); final ActivityStack toStack = mToDisplayArea.getOrCreateStack(null, mTmpOptions, task, task.getActivityType(), mOnTop); if (task == toStack) { // The task was reused as the root task. return; Loading Loading @@ -1418,7 +1417,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { mRootWindowContainer.getLaunchStack(null, options, task, ON_TOP); if (stack != currentStack) { moveHomeStackToFrontIfNeeded(flags, stack.getDisplay(), reason); moveHomeStackToFrontIfNeeded(flags, stack.getDisplayArea(), reason); task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, !ANIMATE, DEFER_RESUME, reason); currentStack = stack; Loading @@ -1437,7 +1436,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { } if (!reparented) { moveHomeStackToFrontIfNeeded(flags, currentStack.getDisplay(), reason); moveHomeStackToFrontIfNeeded(flags, currentStack.getDisplayArea(), reason); } final ActivityRecord r = task.getTopNonFinishingActivity(); Loading @@ -1451,15 +1450,16 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { currentStack, forceNonResizeable); } private void moveHomeStackToFrontIfNeeded(int flags, DisplayContent display, String reason) { final ActivityStack focusedStack = display.getFocusedStack(); private void moveHomeStackToFrontIfNeeded(int flags, TaskDisplayArea taskDisplayArea, String reason) { final ActivityStack focusedStack = taskDisplayArea.getFocusedStack(); if ((display.getWindowingMode() == WINDOWING_MODE_FULLSCREEN if ((taskDisplayArea.getWindowingMode() == WINDOWING_MODE_FULLSCREEN && (flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) || (focusedStack != null && focusedStack.isActivityTypeRecents())) { // We move home stack to front when we are on a fullscreen display and caller has // We move home stack to front when we are on a fullscreen display area and caller has // requested the home activity to move with it. Or the previous stack is recents. display.mTaskContainers.moveHomeStackToFront(reason); taskDisplayArea.moveHomeStackToFront(reason); } } Loading Loading @@ -1511,15 +1511,15 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { mService.deferWindowLayout(); try { final int windowingMode = fromStack.getWindowingMode(); final DisplayContent toDisplay = mRootWindowContainer.getDisplayContent(toDisplayId); final TaskDisplayArea toDisplayArea = mRootWindowContainer .getDisplayContent(toDisplayId).getDefaultTaskDisplayArea(); if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) { // We are moving all tasks from the docked stack to the fullscreen stack, // which is dismissing the docked stack, so resize all other stacks to // fullscreen here already so we don't end up with resize trashing. for (int i = toDisplay.getStackCount() - 1; i >= 0; --i) { final ActivityStack otherStack = toDisplay.getStackAt(i); for (int i = toDisplayArea.getStackCount() - 1; i >= 0; --i) { final ActivityStack otherStack = toDisplayArea.getStackAt(i); if (!otherStack.inSplitScreenSecondaryWindowingMode()) { continue; } Loading @@ -1535,7 +1535,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { if (fromStack.hasChild()) { mTmpOptions.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN); mMoveTaskToFullscreenHelper.process( fromStack, toDisplay, onTop, schedulePictureInPictureModeChange); fromStack, toDisplayArea, onTop, schedulePictureInPictureModeChange); } mRootWindowContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS); Loading @@ -1546,6 +1546,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { } void moveTasksToFullscreenStackLocked(ActivityStack fromStack, boolean onTop) { // TODO(b/153089193): Support moving within the same task display area mWindowManager.inSurfaceTransaction(() -> moveTasksToFullscreenStackInSurfaceTransaction(fromStack, DEFAULT_DISPLAY, onTop)); } Loading
services/core/java/com/android/server/wm/ActivityStartController.java +3 −2 Original line number Diff line number Diff line Loading @@ -189,9 +189,10 @@ public class ActivityStartController { mSupervisor.beginDeferResume(); final ActivityStack homeStack; try { // TODO(multi-display-area): Support starting home in a task display area // Make sure home stack exist on display. homeStack = display.mTaskContainers.getOrCreateStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP); homeStack = display.getDefaultTaskDisplayArea().getOrCreateStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP); } finally { mSupervisor.endDeferResume(); } Loading
services/core/java/com/android/server/wm/DisplayContent.java +119 −80 Original line number Diff line number Diff line Loading @@ -2060,20 +2060,53 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo * activity type. Null is no compatible stack on the display. */ ActivityStack getStack(int windowingMode, int activityType) { return mTaskContainers.getStack(windowingMode, activityType); for (int tdaNdx = getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { final ActivityStack stack = getTaskDisplayAreaAt(tdaNdx) .getStack(windowingMode, activityType); if (stack != null) { return stack; } } return null; } protected int getStackCount() { return mTaskContainers.mChildren.size(); protected int getTaskDisplayAreaCount() { // TODO(multi-display-area): Report actual display area count return 1; } protected TaskDisplayArea getTaskDisplayAreaAt(int index) { // TODO(multi-display-area): Report actual display area values return mTaskContainers; } protected ActivityStack getStackAt(int index) { return mTaskContainers.mChildren.get(index); ActivityStack getStack(int rootTaskId) { for (int tdaNdx = getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { final ActivityStack stack = getTaskDisplayAreaAt(tdaNdx).getStack(rootTaskId); if (stack != null) { return stack; } } return null; } protected int getStackCount() { int totalStackCount = 0; for (int i = getTaskDisplayAreaCount() - 1; i >= 0; --i) { totalStackCount += getTaskDisplayAreaAt(i).getStackCount(); } return totalStackCount; } @VisibleForTesting ActivityStack getTopStack() { return mTaskContainers.getTopStack(); for (int i = getTaskDisplayAreaCount() - 1; i >= 0; --i) { final ActivityStack stack = getTaskDisplayAreaAt(i).getTopStack(); if (stack != null) { return stack; } } return null; } /** Loading Loading @@ -2449,7 +2482,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo final PooledConsumer c = PooledLambda.obtainConsumer( DisplayContent::processTaskForTouchExcludeRegion, this, PooledLambda.__(Task.class), focusedTask, delta); mTaskContainers.forAllTasks(c); forAllTasks(c); c.recycle(); // If we removed the focused task above, add it back and only leave its Loading Loading @@ -2630,9 +2663,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } void prepareFreezingTaskBounds() { for (int stackNdx = mTaskContainers.getChildCount() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = mTaskContainers.getChildAt(stackNdx); stack.prepareFreezingTaskBounds(); for (int tdaNdx = getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { getTaskDisplayAreaAt(tdaNdx).prepareFreezingTaskBounds(); } } Loading Loading @@ -2738,8 +2770,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo final ActivityStack focusedStack = getFocusedStack(); if (focusedStack != null) { proto.write(FOCUSED_ROOT_TASK_ID, focusedStack.getRootTaskId()); final ActivityRecord focusedActivity = focusedStack.getDisplay().mTaskContainers .getResumedActivity(); final ActivityRecord focusedActivity = focusedStack.getDisplayArea() .getFocusedActivity(); if (focusedActivity != null) { focusedActivity.writeIdentifierToProto(proto, RESUMED_ACTIVITY); } Loading Loading @@ -2797,13 +2829,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo if (mLastFocus != mCurrentFocus) { pw.print(" mLastFocus="); pw.println(mLastFocus); } if (mTaskContainers.mPreferredTopFocusableStack != null) { pw.println(prefix + "mPreferredTopFocusableStack=" + mTaskContainers.mPreferredTopFocusableStack); } if (mTaskContainers.mLastFocusedStack != null) { pw.println(prefix + "mLastFocusedStack=" + mTaskContainers.mLastFocusedStack); } if (mLosingFocus.size() > 0) { pw.println(); pw.println(" Windows losing focus:"); Loading Loading @@ -2837,10 +2862,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } pw.println(); pw.println(prefix + "Application tokens in top down Z order:"); for (int stackNdx = mTaskContainers.getChildCount() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = mTaskContainers.getChildAt(stackNdx); stack.dump(pw, prefix + " ", dumpAll); pw.println(prefix + "Task display areas in top down Z order:"); for (int tdaNdx = getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { getTaskDisplayAreaAt(tdaNdx).dump(pw, prefix + " ", dumpAll); } pw.println(); Loading Loading @@ -4002,7 +4026,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } // Initialize state of exiting applications. mTaskContainers.setExitingTokensHasVisible(hasVisible); for (int i = getTaskDisplayAreaCount() - 1; i >= 0; --i) { getTaskDisplayAreaAt(i).setExitingTokensHasVisible(hasVisible); } } void removeExistingTokensIfPossible() { Loading @@ -4014,7 +4040,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } // Time to remove any exiting applications? mTaskContainers.removeExistingAppTokensIfPossible(); for (int i = getTaskDisplayAreaCount() - 1; i >= 0; --i) { getTaskDisplayAreaAt(i).removeExistingAppTokensIfPossible(); } } @Override Loading Loading @@ -4475,7 +4503,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } void assignStackOrdering() { mTaskContainers.assignStackOrdering(getPendingTransaction()); for (int i = getTaskDisplayAreaCount() - 1; i >= 0; --i) { getTaskDisplayAreaAt(i).assignStackOrdering(getPendingTransaction()); } } /** Loading Loading @@ -5002,13 +5032,15 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo || windowingMode == WINDOWING_MODE_MULTI_WINDOW); } ActivityStack createStack(int windowingMode, int activityType, boolean onTop) { return mTaskContainers.createStack(windowingMode, activityType, onTop, null /* info */, null /* intent */, false /* createdByOrganizer */); } @Nullable ActivityStack getFocusedStack() { return mTaskContainers.getFocusedStack(); for (int i = getTaskDisplayAreaCount() - 1; i >= 0; --i) { final ActivityStack stack = getTaskDisplayAreaAt(i).getFocusedStack(); if (stack != null) { return stack; } } return null; } /** Loading @@ -5016,11 +5048,15 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED */ void removeStacksInWindowingModes(int... windowingModes) { mTaskContainers.removeStacksInWindowingModes(windowingModes); for (int i = getTaskDisplayAreaCount() - 1; i >= 0; --i) { getTaskDisplayAreaAt(i).removeStacksInWindowingModes(windowingModes); } } void removeStacksWithActivityTypes(int... activityTypes) { mTaskContainers.removeStacksWithActivityTypes(activityTypes); for (int i = getTaskDisplayAreaCount() - 1; i >= 0; --i) { getTaskDisplayAreaAt(i).removeStacksWithActivityTypes(activityTypes); } } ActivityRecord topRunningActivity() { Loading @@ -5037,7 +5073,14 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo * @return The top running activity. {@code null} if none is available. */ ActivityRecord topRunningActivity(boolean considerKeyguardState) { return mTaskContainers.topRunningActivity(considerKeyguardState); for (int i = getTaskDisplayAreaCount() - 1; i >= 0; --i) { final ActivityRecord activity = getTaskDisplayAreaAt(i) .topRunningActivity(considerKeyguardState); if (activity != null) { return activity; } } return null; } boolean updateDisplayOverrideConfigurationLocked() { Loading Loading @@ -5149,7 +5192,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo // The display may be about to rotate seamlessly, and the animation of closing apps may // still animate in old rotation. So make sure the outdated animation won't show on the // rotated display. mTaskContainers.forAllActivities(a -> { forAllActivities(a -> { if (a.nowVisible && a != mFixedRotationLaunchingApp && a.getWindowConfiguration().getRotation() != newRotation) { final WindowContainer<?> w = a.getAnimatingContainer(); Loading Loading @@ -5210,40 +5253,17 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo void remove() { mRemoving = true; final boolean destroyContentOnRemoval = shouldDestroyContentOnRemove(); ActivityStack lastReparentedStack = null; mTaskContainers.mPreferredTopFocusableStack = null; // Stacks could be reparented from the removed display to other display. While // reparenting the last stack of the removed display, the remove display is ready to be // released (no more ActivityStack). But, we cannot release it at that moment or the // related WindowContainer will also be removed. So, we set display as removed after // reparenting stack finished. final TaskDisplayArea toTaskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea(); mRootWindowContainer.mStackSupervisor.beginDeferResume(); try { int numStacks = getStackCount(); // Keep the order from bottom to top. for (int stackNdx = 0; stackNdx < numStacks; stackNdx++) { final ActivityStack stack = getStackAt(stackNdx); // Always finish non-standard type stacks. if (destroyContentOnRemoval || !stack.isActivityTypeStandardOrUndefined()) { stack.finishAllActivitiesImmediately(); } else { // If default display is in split-window mode, set windowing mode of the stack // to split-screen secondary. Otherwise, set the windowing mode to undefined by // default to let stack inherited the windowing mode from the new display. final int windowingMode = toTaskDisplayArea.isSplitScreenModeActivated() ? WINDOWING_MODE_SPLIT_SCREEN_SECONDARY : WINDOWING_MODE_UNDEFINED; stack.reparent(toTaskDisplayArea, true /* onTop */); stack.setWindowingMode(windowingMode); lastReparentedStack = stack; } // Stacks may be removed from this display. Ensure each stack will be processed and // the loop will end. stackNdx -= numStacks - getStackCount(); numStacks = getStackCount(); int numTaskContainers = getTaskDisplayAreaCount(); for (int tdaNdx = 0; tdaNdx < numTaskContainers; tdaNdx++) { final ActivityStack lastReparentedStackFromArea = getTaskDisplayAreaAt(tdaNdx) .remove(); if (lastReparentedStackFromArea != null) { lastReparentedStack = lastReparentedStackFromArea; } } } finally { mRootWindowContainer.mStackSupervisor.endDeferResume(); Loading @@ -5270,12 +5290,27 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo return; } final ActivityStack stack = getStackCount() == 1 ? getStackAt(0) : null; if (stack != null && stack.isActivityTypeHome() && !stack.hasChild()) { // Release this display if an empty home stack is the only thing left. // Since it is the last stack, this display will be released along with the stack // removal. stack.removeIfPossible(); // Check if all task display areas have only the empty home stacks left. boolean onlyEmptyHomeStacksLeft = true; for (int tdaNdx = getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { final TaskDisplayArea taskDisplayArea = getTaskDisplayAreaAt(tdaNdx); if (taskDisplayArea.getStackCount() != 1) { onlyEmptyHomeStacksLeft = false; break; } final ActivityStack stack = taskDisplayArea.getStackAt(0); if (!stack.isActivityTypeHome() || stack.hasChild()) { onlyEmptyHomeStacksLeft = false; break; } } if (onlyEmptyHomeStacksLeft) { // Release this display if only empty home stack(s) are left. This display will be // released along with the stack(s) removal. for (int tdaNdx = getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { final ActivityStack s = getTaskDisplayAreaAt(tdaNdx).getStackAt(0); s.removeIfPossible(); } } else if (getTopStack() == null) { removeIfPossible(); mRootWindowContainer.mStackSupervisor Loading Loading @@ -5334,10 +5369,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo void ensureActivitiesVisible(ActivityRecord starting, int configChanges, boolean preserveWindows, boolean notifyClients) { for (int stackNdx = getStackCount() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = getStackAt(stackNdx); stack.ensureActivitiesVisible(starting, configChanges, preserveWindows, notifyClients); for (int i = getTaskDisplayAreaCount() - 1; i >= 0; --i) { getTaskDisplayAreaAt(i).ensureActivitiesVisible(starting, configChanges, preserveWindows, notifyClients); } } Loading @@ -5350,13 +5384,18 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } void setDisplayToSingleTaskInstance() { final int childCount = getStackCount(); if (childCount > 1) { final int taskDisplayAreaCount = getTaskDisplayAreaCount(); if (taskDisplayAreaCount > 1) { throw new IllegalArgumentException( "Display already has multiple task display areas. display=" + this); } final int stackCount = getDefaultTaskDisplayArea().getStackCount(); if (stackCount > 1) { throw new IllegalArgumentException("Display already has multiple stacks. display=" + this); } if (childCount > 0) { final ActivityStack stack = getStackAt(0); if (stackCount > 0) { final ActivityStack stack = getDefaultTaskDisplayArea().getStackAt(0); if (stack.getChildCount() > 1) { throw new IllegalArgumentException("Display stack already has multiple tasks." + " display=" + this + " stack=" + stack); Loading