diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index edaa511128671..0a42aa9cce639 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -2312,7 +2312,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D if (displayId == INVALID_DISPLAY) { displayId = candidateDisplayId; } - if (displayId != INVALID_DISPLAY) { + if (displayId != INVALID_DISPLAY && canLaunchOnDisplay(r, displayId)) { if (r != null) { // TODO: This should also take in the windowing mode and activity type into account. stack = (T) getValidLaunchStackOnDisplay(displayId, r); @@ -2341,7 +2341,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D } if (stack != null) { display = stack.getDisplay(); - if (display != null) { + if (display != null && canLaunchOnDisplay(r, display.mDisplayId)) { final int windowingMode = display.resolveWindowingMode(r, options, candidateTask, activityType); if (stack.isCompatible(windowingMode, activityType)) { @@ -2351,6 +2351,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D } if (display == null + || !canLaunchOnDisplay(r, display.mDisplayId) // TODO: Can be removed once we figure-out how non-standard types should launch // outside the default display. || (activityType != ACTIVITY_TYPE_STANDARD @@ -2361,6 +2362,14 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D return display.getOrCreateStack(r, options, candidateTask, activityType, onTop); } + /** @return true if activity record is null or can be launched on provided display. */ + private boolean canLaunchOnDisplay(ActivityRecord r, int displayId) { + if (r == null) { + return true; + } + return r.canBeLaunchedOnDisplay(displayId); + } + /** * Get a topmost stack on the display, that is a valid launch stack for specified activity. * If there is no such stack, new dynamic stack can be created. @@ -4248,22 +4257,15 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D // Handle incorrect launch/move to secondary display if needed. if (isSecondaryDisplayPreferred) { - final boolean launchOnSecondaryDisplayFailed; final int actualDisplayId = task.getStack().mDisplayId; if (!task.canBeLaunchedOnDisplay(actualDisplayId)) { - // The task landed on an inappropriate display somehow, move it to the default - // display. - // TODO(multi-display): Find proper stack for the task on the default display. - mService.setTaskWindowingMode(task.taskId, - WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, true /* toTop */); - launchOnSecondaryDisplayFailed = true; - } else { - // The task might have landed on a display different from requested. - launchOnSecondaryDisplayFailed = actualDisplayId == DEFAULT_DISPLAY - || (preferredDisplayId != INVALID_DISPLAY - && preferredDisplayId != actualDisplayId); + throw new IllegalStateException("Task resolved to incompatible display"); } - if (launchOnSecondaryDisplayFailed) { + // The task might have landed on a display different from requested. + // TODO(multi-display): Find proper stack for the task on the default display. + mService.setTaskWindowingMode(task.taskId, + WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, true /* toTop */); + if (preferredDisplayId != actualDisplayId) { // Display a warning toast that we tried to put a non-resizeable task on a secondary // display with config different from global config. mService.mTaskChangeNotificationController diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java index 69cc3c7aacbcf..abdbfadf8d99e 100644 --- a/services/core/java/com/android/server/am/ActivityStarter.java +++ b/services/core/java/com/android/server/am/ActivityStarter.java @@ -1812,6 +1812,9 @@ class ActivityStarter { } } } + // Need to update mTargetStack because if task was moved out of it, the original stack may + // be destroyed. + mTargetStack = intentActivity.getStack(); if (!mMovedToFront && mDoResume) { if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Bring to front target: " + mTargetStack + " from " + intentActivity); diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java index dabcbcdcbb7cf..0ffc6b8e39ab4 100644 --- a/services/core/java/com/android/server/am/TaskRecord.java +++ b/services/core/java/com/android/server/am/TaskRecord.java @@ -623,6 +623,9 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi if (toStack == sourceStack) { return false; } + if (!canBeLaunchedOnDisplay(toStack.mDisplayId)) { + return false; + } final int toStackWindowingMode = toStack.getWindowingMode(); final ActivityRecord topActivity = getTopActivity(); diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 8c9948e1ee49e..92a0d702c65e7 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -4566,6 +4566,7 @@ public class WindowManagerService extends IWindowManager.Stub if (displayContent != null) { mAnimator.addDisplayLocked(displayId); displayContent.initializeDisplayBaseInfo(); + reconfigureDisplayLocked(displayContent); } } } @@ -6705,7 +6706,6 @@ public class WindowManagerService extends IWindowManager.Stub synchronized (mWindowMap) { final Display display = mDisplayManager.getDisplay(displayId); if (display != null) { - createDisplayContentLocked(display); displayReady(displayId); } mWindowPlacerLocked.requestTraversal();