Loading services/core/java/com/android/server/am/ActivityDisplay.java +34 −15 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; Loading Loading @@ -168,9 +169,9 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> { } else if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) { return (T) mSplitScreenPrimaryStack; } for (int i = mStacks.size() - 1; i >= 0; --i) { final ActivityStack stack = mStacks.get(i); // TODO: Should undefined windowing and activity type be compatible with standard type? if (stack.isCompatible(windowingMode, activityType)) { return (T) stack; } Loading @@ -178,16 +179,29 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> { return null; } private boolean alwaysCreateStack(int windowingMode, int activityType) { // Always create a stack for fullscreen, freeform, and split-screen-secondary windowing // modes so that we can manage visual ordering and return types correctly. return activityType == ACTIVITY_TYPE_STANDARD && (windowingMode == WINDOWING_MODE_FULLSCREEN || windowingMode == WINDOWING_MODE_FREEFORM || windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); } /** * Returns an existing stack compatible with the windowing mode and activity type or creates one * if a compatible stack doesn't exist. * @see #getStack(int, int) * @see #createStack(int, int, boolean) */ <T extends ActivityStack> T getOrCreateStack(int windowingMode, int activityType, boolean onTop) { if (!alwaysCreateStack(windowingMode, activityType)) { T stack = getStack(windowingMode, activityType); if (stack != null) { return stack; } } return createStack(windowingMode, activityType, onTop); } Loading Loading @@ -238,17 +252,7 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> { } } final boolean inSplitScreenMode = hasSplitScreenPrimaryStack(); if (!inSplitScreenMode && windowingMode == WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY) { // Switch to fullscreen windowing mode if we are not in split-screen mode and we are // trying to launch in split-screen secondary. windowingMode = WINDOWING_MODE_FULLSCREEN; } else if (inSplitScreenMode && windowingMode == WINDOWING_MODE_FULLSCREEN && WindowConfiguration.supportSplitScreenWindowingMode( windowingMode, activityType)) { windowingMode = WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; } windowingMode = updateWindowingModeForSplitScreenIfNeeded(windowingMode, activityType); final int stackId = mSupervisor.getNextStackId(); Loading Loading @@ -420,6 +424,21 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> { return mPinnedStack != null; } int updateWindowingModeForSplitScreenIfNeeded(int windowingMode, int activityType) { final boolean inSplitScreenMode = hasSplitScreenPrimaryStack(); if (!inSplitScreenMode && windowingMode == WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY) { // Switch to fullscreen windowing mode if we are not in split-screen mode and we are // trying to launch in split-screen secondary. return WINDOWING_MODE_FULLSCREEN; } else if (inSplitScreenMode && windowingMode == WINDOWING_MODE_FULLSCREEN && WindowConfiguration.supportSplitScreenWindowingMode( windowingMode, activityType)) { return WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; } return windowingMode; } @Override public String toString() { return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}"; Loading services/core/java/com/android/server/am/ActivityManagerService.java +21 −1 Original line number Diff line number Diff line Loading @@ -4877,7 +4877,7 @@ public class ActivityManagerService extends IActivityManager.Stub final long origId = Binder.clearCallingIdentity(); try { synchronized (this) { return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions); return mStackSupervisor.startActivityFromRecents(taskId, bOptions); } } finally { Binder.restoreCallingIdentity(origId); Loading Loading @@ -14890,6 +14890,10 @@ public class ActivityManagerService extends IActivityManager.Stub synchronized (this) { dumpActivityStarterLocked(pw, dumpPackage); } } else if ("containers".equals(cmd)) { synchronized (this) { dumpActivityContainersLocked(pw); } } else if ("recents".equals(cmd) || "r".equals(cmd)) { synchronized (this) { if (mRecentTasks != null) { Loading Loading @@ -15132,6 +15136,11 @@ public class ActivityManagerService extends IActivityManager.Stub if (dumpAll) { pw.println("-------------------------------------------------------------------------------"); } dumpActivityContainersLocked(pw); pw.println(); if (dumpAll) { pw.println("-------------------------------------------------------------------------------"); } dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); if (mAssociations.size() > 0) { pw.println(); Loading Loading @@ -15204,6 +15213,11 @@ public class ActivityManagerService extends IActivityManager.Stub if (dumpAll) { pw.println("-------------------------------------------------------------------------------"); } dumpActivityContainersLocked(pw); pw.println(); if (dumpAll) { pw.println("-------------------------------------------------------------------------------"); } dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); if (mAssociations.size() > 0) { pw.println(); Loading Loading @@ -15236,6 +15250,12 @@ public class ActivityManagerService extends IActivityManager.Stub } } private void dumpActivityContainersLocked(PrintWriter pw) { pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)"); mStackSupervisor.dumpChildrenNames(pw, " "); pw.println(" "); } private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) { pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)"); mActivityStarter.dump(pw, "", dumpPackage); services/core/java/com/android/server/am/ActivityStack.java +23 −0 Original line number Diff line number Diff line Loading @@ -480,6 +480,29 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } } @Override public boolean isCompatible(int windowingMode, int activityType) { // TODO: Should we just move this to ConfigurationContainer? if (activityType == ACTIVITY_TYPE_UNDEFINED) { // Undefined activity types end up in a standard stack once the stack is created on a // display, so they should be considered compatible. activityType = ACTIVITY_TYPE_STANDARD; } final ActivityDisplay display = getDisplay(); if (display != null) { if (activityType == ACTIVITY_TYPE_STANDARD && windowingMode == WINDOWING_MODE_UNDEFINED) { // Standard activity types will mostly take on the windowing mode of the display if // one isn't specified, so look-up a compatible stack based on the display's // windowing mode. windowingMode = display.getWindowingMode(); } windowingMode = display.updateWindowingModeForSplitScreenIfNeeded(windowingMode, activityType); } return super.isCompatible(windowingMode, activityType); } /** Adds the stack to specified display and calls WindowManager to do the same. */ void reparent(ActivityDisplay activityDisplay, boolean onTop) { removeFromDisplay(); Loading services/core/java/com/android/server/am/ActivityStackSupervisor.java +40 −46 Original line number Diff line number Diff line Loading @@ -706,7 +706,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D } TaskRecord anyTaskForIdLocked(int id, @AnyTaskForIdMatchTaskMode int matchMode) { return anyTaskForIdLocked(id, matchMode, null); return anyTaskForIdLocked(id, matchMode, null, !ON_TOP); } /** Loading @@ -714,11 +714,11 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D * @param id Id of the task we would like returned. * @param matchMode The mode to match the given task id in. * @param aOptions The activity options to use for restoration. Can be null. * @param onTop If the stack for the task should be the topmost on the display. */ TaskRecord anyTaskForIdLocked(int id, @AnyTaskForIdMatchTaskMode int matchMode, @Nullable ActivityOptions aOptions) { // If there is a stack id set, ensure that we are attempting to actually restore a task // TODO: Don't really know if this is needed... @Nullable ActivityOptions aOptions, boolean onTop) { // If options are set, ensure that we are attempting to actually restore a task if (matchMode != MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE && aOptions != null) { throw new IllegalArgumentException("Should not specify activity options for non-restore" + " lookup"); Loading @@ -730,9 +730,21 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = display.getChildAt(stackNdx); final TaskRecord task = stack.taskForIdLocked(id); if (task != null) { return task; if (task == null) { continue; } if (aOptions != null) { // Resolve the stack the task should be placed in now based on options // and reparent if needed. final ActivityStack launchStack = getLaunchStack(null, aOptions, task, onTop); if (launchStack != null && stack != launchStack) { final int reparentMode = onTop ? REPARENT_MOVE_STACK_TO_FRONT : REPARENT_LEAVE_STACK_IN_PLACE; task.reparent(launchStack, onTop, reparentMode, ANIMATE, DEFER_RESUME, "anyTaskForIdLocked"); } } return task; } } Loading @@ -759,7 +771,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D } // Implicitly, this case is MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE if (!restoreRecentTaskLocked(task, aOptions)) { if (!restoreRecentTaskLocked(task, aOptions, onTop)) { if (DEBUG_RECENTS) Slog.w(TAG_RECENTS, "Couldn't restore task id=" + id + " found in recents"); return null; Loading Loading @@ -2248,11 +2260,13 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D } } if (isWindowingModeSupported(windowingMode, supportsMultiWindow, supportsSplitScreen, if (windowingMode != WINDOWING_MODE_UNDEFINED && isWindowingModeSupported(windowingMode, supportsMultiWindow, supportsSplitScreen, supportsFreeform, supportsPip, activityType)) { return windowingMode; } return WINDOWING_MODE_FULLSCREEN; // Return root/systems windowing mode return getWindowingMode(); } int resolveActivityType(@Nullable ActivityRecord r, @Nullable ActivityOptions options, Loading @@ -2266,7 +2280,10 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D if (activityType != ACTIVITY_TYPE_UNDEFINED) { return activityType; } return options != null ? options.getLaunchActivityType() : ACTIVITY_TYPE_UNDEFINED; if (options != null) { activityType = options.getLaunchActivityType(); } return activityType != ACTIVITY_TYPE_UNDEFINED ? activityType : ACTIVITY_TYPE_STANDARD; } <T extends ActivityStack> T getLaunchStack(@Nullable ActivityRecord r, Loading Loading @@ -2304,7 +2321,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D // Temporarily set the task id to invalid in case in re-entry. options.setLaunchTaskId(INVALID_TASK_ID); final TaskRecord task = anyTaskForIdLocked(taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, options); MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, options, onTop); options.setLaunchTaskId(taskId); if (task != null) { return task.getStack(); Loading @@ -2330,14 +2347,11 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D } final ActivityDisplay display = getActivityDisplayOrCreateLocked(displayId); if (display != null) { for (int i = display.getChildCount() - 1; i >= 0; --i) { stack = (T) display.getChildAt(i); if (stack.isCompatible(windowingMode, activityType)) { stack = display.getOrCreateStack(windowingMode, activityType, onTop); if (stack != null) { return stack; } } // TODO: We should create the stack we want on the display at this point. } } // Give preference to the stack and display of the input task and activity if they match the Loading Loading @@ -2365,18 +2379,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D display = getDefaultDisplay(); } stack = display.getOrCreateStack(windowingMode, activityType, onTop); if (stack != null) { return stack; } // Whatever...return some default for now. if (candidateTask != null && candidateTask.mBounds != null && mService.mSupportsFreeformWindowManagement) { windowingMode = WINDOWING_MODE_FREEFORM; } else { windowingMode = WINDOWING_MODE_FULLSCREEN; } return display.getOrCreateStack(windowingMode, activityType, onTop); } Loading Loading @@ -2967,10 +2969,11 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D * * @param task The recent task to be restored. * @param aOptions The activity options to use for restoration. * @param onTop If the stack for the task should be the topmost on the display. * @return true if the task has been restored successfully. */ boolean restoreRecentTaskLocked(TaskRecord task, ActivityOptions aOptions) { final ActivityStack stack = getLaunchStack(null, aOptions, task, !ON_TOP); boolean restoreRecentTaskLocked(TaskRecord task, ActivityOptions aOptions, boolean onTop) { final ActivityStack stack = getLaunchStack(null, aOptions, task, onTop); final ActivityStack currentStack = task.getStack(); if (currentStack != null) { // Task has already been restored once. See if we need to do anything more Loading @@ -2983,9 +2986,9 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D currentStack.removeTask(task, "restoreRecentTaskLocked", REMOVE_TASK_MODE_MOVING); } stack.addTask(task, !ON_TOP, "restoreRecentTask"); stack.addTask(task, onTop, "restoreRecentTask"); // TODO: move call for creation here and other place into Stack.addTask() task.createWindowContainer(!ON_TOP, true /* showForAllUsers */); task.createWindowContainer(onTop, true /* showForAllUsers */); if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, "Added restored task=" + task + " to stack=" + stack); final ArrayList<ActivityRecord> activities = task.mActivities; Loading Loading @@ -4567,7 +4570,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D task.setTaskDockedResizing(true); } final int startActivityFromRecentsInner(int taskId, Bundle bOptions) { int startActivityFromRecents(int taskId, Bundle bOptions) { final TaskRecord task; final int callingUid; final String callingPackage; Loading @@ -4582,7 +4585,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D windowingMode = activityOptions.getLaunchWindowingMode(); } if (activityType == ACTIVITY_TYPE_HOME || activityType == ACTIVITY_TYPE_RECENTS) { throw new IllegalArgumentException("startActivityFromRecentsInner: Task " throw new IllegalArgumentException("startActivityFromRecents: Task " + taskId + " can't be launch in the home/recents stack."); } Loading @@ -4600,21 +4603,12 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D } task = anyTaskForIdLocked(taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, activityOptions); activityOptions, ON_TOP); if (task == null) { continueUpdateBounds(ACTIVITY_TYPE_RECENTS); mWindowManager.executeAppTransition(); throw new IllegalArgumentException( "startActivityFromRecentsInner: Task " + taskId + " not found."); } // Since we don't have an actual source record here, we assume that the currently // focused activity was the source. final ActivityStack stack = getLaunchStack(null, activityOptions, task, ON_TOP); if (stack != null && task.getStack() != stack) { task.reparent(stack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME, "startActivityFromRecents"); "startActivityFromRecents: Task " + taskId + " not found."); } // If the user must confirm credentials (e.g. when first launching a work app and the Loading services/core/java/com/android/server/am/AppTaskImpl.java +2 −2 Original line number Diff line number Diff line Loading @@ -94,7 +94,7 @@ class AppTaskImpl extends IAppTask.Stub { final long origId = Binder.clearCallingIdentity(); try { synchronized (this) { mService.mStackSupervisor.startActivityFromRecentsInner(mTaskId, null); mService.mStackSupervisor.startActivityFromRecents(mTaskId, null); } } finally { Binder.restoreCallingIdentity(origId); Loading Loading
services/core/java/com/android/server/am/ActivityDisplay.java +34 −15 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; Loading Loading @@ -168,9 +169,9 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> { } else if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) { return (T) mSplitScreenPrimaryStack; } for (int i = mStacks.size() - 1; i >= 0; --i) { final ActivityStack stack = mStacks.get(i); // TODO: Should undefined windowing and activity type be compatible with standard type? if (stack.isCompatible(windowingMode, activityType)) { return (T) stack; } Loading @@ -178,16 +179,29 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> { return null; } private boolean alwaysCreateStack(int windowingMode, int activityType) { // Always create a stack for fullscreen, freeform, and split-screen-secondary windowing // modes so that we can manage visual ordering and return types correctly. return activityType == ACTIVITY_TYPE_STANDARD && (windowingMode == WINDOWING_MODE_FULLSCREEN || windowingMode == WINDOWING_MODE_FREEFORM || windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); } /** * Returns an existing stack compatible with the windowing mode and activity type or creates one * if a compatible stack doesn't exist. * @see #getStack(int, int) * @see #createStack(int, int, boolean) */ <T extends ActivityStack> T getOrCreateStack(int windowingMode, int activityType, boolean onTop) { if (!alwaysCreateStack(windowingMode, activityType)) { T stack = getStack(windowingMode, activityType); if (stack != null) { return stack; } } return createStack(windowingMode, activityType, onTop); } Loading Loading @@ -238,17 +252,7 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> { } } final boolean inSplitScreenMode = hasSplitScreenPrimaryStack(); if (!inSplitScreenMode && windowingMode == WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY) { // Switch to fullscreen windowing mode if we are not in split-screen mode and we are // trying to launch in split-screen secondary. windowingMode = WINDOWING_MODE_FULLSCREEN; } else if (inSplitScreenMode && windowingMode == WINDOWING_MODE_FULLSCREEN && WindowConfiguration.supportSplitScreenWindowingMode( windowingMode, activityType)) { windowingMode = WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; } windowingMode = updateWindowingModeForSplitScreenIfNeeded(windowingMode, activityType); final int stackId = mSupervisor.getNextStackId(); Loading Loading @@ -420,6 +424,21 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> { return mPinnedStack != null; } int updateWindowingModeForSplitScreenIfNeeded(int windowingMode, int activityType) { final boolean inSplitScreenMode = hasSplitScreenPrimaryStack(); if (!inSplitScreenMode && windowingMode == WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY) { // Switch to fullscreen windowing mode if we are not in split-screen mode and we are // trying to launch in split-screen secondary. return WINDOWING_MODE_FULLSCREEN; } else if (inSplitScreenMode && windowingMode == WINDOWING_MODE_FULLSCREEN && WindowConfiguration.supportSplitScreenWindowingMode( windowingMode, activityType)) { return WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; } return windowingMode; } @Override public String toString() { return "ActivityDisplay={" + mDisplayId + " numStacks=" + mStacks.size() + "}"; Loading
services/core/java/com/android/server/am/ActivityManagerService.java +21 −1 Original line number Diff line number Diff line Loading @@ -4877,7 +4877,7 @@ public class ActivityManagerService extends IActivityManager.Stub final long origId = Binder.clearCallingIdentity(); try { synchronized (this) { return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions); return mStackSupervisor.startActivityFromRecents(taskId, bOptions); } } finally { Binder.restoreCallingIdentity(origId); Loading Loading @@ -14890,6 +14890,10 @@ public class ActivityManagerService extends IActivityManager.Stub synchronized (this) { dumpActivityStarterLocked(pw, dumpPackage); } } else if ("containers".equals(cmd)) { synchronized (this) { dumpActivityContainersLocked(pw); } } else if ("recents".equals(cmd) || "r".equals(cmd)) { synchronized (this) { if (mRecentTasks != null) { Loading Loading @@ -15132,6 +15136,11 @@ public class ActivityManagerService extends IActivityManager.Stub if (dumpAll) { pw.println("-------------------------------------------------------------------------------"); } dumpActivityContainersLocked(pw); pw.println(); if (dumpAll) { pw.println("-------------------------------------------------------------------------------"); } dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); if (mAssociations.size() > 0) { pw.println(); Loading Loading @@ -15204,6 +15213,11 @@ public class ActivityManagerService extends IActivityManager.Stub if (dumpAll) { pw.println("-------------------------------------------------------------------------------"); } dumpActivityContainersLocked(pw); pw.println(); if (dumpAll) { pw.println("-------------------------------------------------------------------------------"); } dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); if (mAssociations.size() > 0) { pw.println(); Loading Loading @@ -15236,6 +15250,12 @@ public class ActivityManagerService extends IActivityManager.Stub } } private void dumpActivityContainersLocked(PrintWriter pw) { pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)"); mStackSupervisor.dumpChildrenNames(pw, " "); pw.println(" "); } private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) { pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)"); mActivityStarter.dump(pw, "", dumpPackage);
services/core/java/com/android/server/am/ActivityStack.java +23 −0 Original line number Diff line number Diff line Loading @@ -480,6 +480,29 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } } @Override public boolean isCompatible(int windowingMode, int activityType) { // TODO: Should we just move this to ConfigurationContainer? if (activityType == ACTIVITY_TYPE_UNDEFINED) { // Undefined activity types end up in a standard stack once the stack is created on a // display, so they should be considered compatible. activityType = ACTIVITY_TYPE_STANDARD; } final ActivityDisplay display = getDisplay(); if (display != null) { if (activityType == ACTIVITY_TYPE_STANDARD && windowingMode == WINDOWING_MODE_UNDEFINED) { // Standard activity types will mostly take on the windowing mode of the display if // one isn't specified, so look-up a compatible stack based on the display's // windowing mode. windowingMode = display.getWindowingMode(); } windowingMode = display.updateWindowingModeForSplitScreenIfNeeded(windowingMode, activityType); } return super.isCompatible(windowingMode, activityType); } /** Adds the stack to specified display and calls WindowManager to do the same. */ void reparent(ActivityDisplay activityDisplay, boolean onTop) { removeFromDisplay(); Loading
services/core/java/com/android/server/am/ActivityStackSupervisor.java +40 −46 Original line number Diff line number Diff line Loading @@ -706,7 +706,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D } TaskRecord anyTaskForIdLocked(int id, @AnyTaskForIdMatchTaskMode int matchMode) { return anyTaskForIdLocked(id, matchMode, null); return anyTaskForIdLocked(id, matchMode, null, !ON_TOP); } /** Loading @@ -714,11 +714,11 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D * @param id Id of the task we would like returned. * @param matchMode The mode to match the given task id in. * @param aOptions The activity options to use for restoration. Can be null. * @param onTop If the stack for the task should be the topmost on the display. */ TaskRecord anyTaskForIdLocked(int id, @AnyTaskForIdMatchTaskMode int matchMode, @Nullable ActivityOptions aOptions) { // If there is a stack id set, ensure that we are attempting to actually restore a task // TODO: Don't really know if this is needed... @Nullable ActivityOptions aOptions, boolean onTop) { // If options are set, ensure that we are attempting to actually restore a task if (matchMode != MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE && aOptions != null) { throw new IllegalArgumentException("Should not specify activity options for non-restore" + " lookup"); Loading @@ -730,9 +730,21 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = display.getChildAt(stackNdx); final TaskRecord task = stack.taskForIdLocked(id); if (task != null) { return task; if (task == null) { continue; } if (aOptions != null) { // Resolve the stack the task should be placed in now based on options // and reparent if needed. final ActivityStack launchStack = getLaunchStack(null, aOptions, task, onTop); if (launchStack != null && stack != launchStack) { final int reparentMode = onTop ? REPARENT_MOVE_STACK_TO_FRONT : REPARENT_LEAVE_STACK_IN_PLACE; task.reparent(launchStack, onTop, reparentMode, ANIMATE, DEFER_RESUME, "anyTaskForIdLocked"); } } return task; } } Loading @@ -759,7 +771,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D } // Implicitly, this case is MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE if (!restoreRecentTaskLocked(task, aOptions)) { if (!restoreRecentTaskLocked(task, aOptions, onTop)) { if (DEBUG_RECENTS) Slog.w(TAG_RECENTS, "Couldn't restore task id=" + id + " found in recents"); return null; Loading Loading @@ -2248,11 +2260,13 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D } } if (isWindowingModeSupported(windowingMode, supportsMultiWindow, supportsSplitScreen, if (windowingMode != WINDOWING_MODE_UNDEFINED && isWindowingModeSupported(windowingMode, supportsMultiWindow, supportsSplitScreen, supportsFreeform, supportsPip, activityType)) { return windowingMode; } return WINDOWING_MODE_FULLSCREEN; // Return root/systems windowing mode return getWindowingMode(); } int resolveActivityType(@Nullable ActivityRecord r, @Nullable ActivityOptions options, Loading @@ -2266,7 +2280,10 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D if (activityType != ACTIVITY_TYPE_UNDEFINED) { return activityType; } return options != null ? options.getLaunchActivityType() : ACTIVITY_TYPE_UNDEFINED; if (options != null) { activityType = options.getLaunchActivityType(); } return activityType != ACTIVITY_TYPE_UNDEFINED ? activityType : ACTIVITY_TYPE_STANDARD; } <T extends ActivityStack> T getLaunchStack(@Nullable ActivityRecord r, Loading Loading @@ -2304,7 +2321,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D // Temporarily set the task id to invalid in case in re-entry. options.setLaunchTaskId(INVALID_TASK_ID); final TaskRecord task = anyTaskForIdLocked(taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, options); MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, options, onTop); options.setLaunchTaskId(taskId); if (task != null) { return task.getStack(); Loading @@ -2330,14 +2347,11 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D } final ActivityDisplay display = getActivityDisplayOrCreateLocked(displayId); if (display != null) { for (int i = display.getChildCount() - 1; i >= 0; --i) { stack = (T) display.getChildAt(i); if (stack.isCompatible(windowingMode, activityType)) { stack = display.getOrCreateStack(windowingMode, activityType, onTop); if (stack != null) { return stack; } } // TODO: We should create the stack we want on the display at this point. } } // Give preference to the stack and display of the input task and activity if they match the Loading Loading @@ -2365,18 +2379,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D display = getDefaultDisplay(); } stack = display.getOrCreateStack(windowingMode, activityType, onTop); if (stack != null) { return stack; } // Whatever...return some default for now. if (candidateTask != null && candidateTask.mBounds != null && mService.mSupportsFreeformWindowManagement) { windowingMode = WINDOWING_MODE_FREEFORM; } else { windowingMode = WINDOWING_MODE_FULLSCREEN; } return display.getOrCreateStack(windowingMode, activityType, onTop); } Loading Loading @@ -2967,10 +2969,11 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D * * @param task The recent task to be restored. * @param aOptions The activity options to use for restoration. * @param onTop If the stack for the task should be the topmost on the display. * @return true if the task has been restored successfully. */ boolean restoreRecentTaskLocked(TaskRecord task, ActivityOptions aOptions) { final ActivityStack stack = getLaunchStack(null, aOptions, task, !ON_TOP); boolean restoreRecentTaskLocked(TaskRecord task, ActivityOptions aOptions, boolean onTop) { final ActivityStack stack = getLaunchStack(null, aOptions, task, onTop); final ActivityStack currentStack = task.getStack(); if (currentStack != null) { // Task has already been restored once. See if we need to do anything more Loading @@ -2983,9 +2986,9 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D currentStack.removeTask(task, "restoreRecentTaskLocked", REMOVE_TASK_MODE_MOVING); } stack.addTask(task, !ON_TOP, "restoreRecentTask"); stack.addTask(task, onTop, "restoreRecentTask"); // TODO: move call for creation here and other place into Stack.addTask() task.createWindowContainer(!ON_TOP, true /* showForAllUsers */); task.createWindowContainer(onTop, true /* showForAllUsers */); if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, "Added restored task=" + task + " to stack=" + stack); final ArrayList<ActivityRecord> activities = task.mActivities; Loading Loading @@ -4567,7 +4570,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D task.setTaskDockedResizing(true); } final int startActivityFromRecentsInner(int taskId, Bundle bOptions) { int startActivityFromRecents(int taskId, Bundle bOptions) { final TaskRecord task; final int callingUid; final String callingPackage; Loading @@ -4582,7 +4585,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D windowingMode = activityOptions.getLaunchWindowingMode(); } if (activityType == ACTIVITY_TYPE_HOME || activityType == ACTIVITY_TYPE_RECENTS) { throw new IllegalArgumentException("startActivityFromRecentsInner: Task " throw new IllegalArgumentException("startActivityFromRecents: Task " + taskId + " can't be launch in the home/recents stack."); } Loading @@ -4600,21 +4603,12 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D } task = anyTaskForIdLocked(taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, activityOptions); activityOptions, ON_TOP); if (task == null) { continueUpdateBounds(ACTIVITY_TYPE_RECENTS); mWindowManager.executeAppTransition(); throw new IllegalArgumentException( "startActivityFromRecentsInner: Task " + taskId + " not found."); } // Since we don't have an actual source record here, we assume that the currently // focused activity was the source. final ActivityStack stack = getLaunchStack(null, activityOptions, task, ON_TOP); if (stack != null && task.getStack() != stack) { task.reparent(stack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, ANIMATE, DEFER_RESUME, "startActivityFromRecents"); "startActivityFromRecents: Task " + taskId + " not found."); } // If the user must confirm credentials (e.g. when first launching a work app and the Loading
services/core/java/com/android/server/am/AppTaskImpl.java +2 −2 Original line number Diff line number Diff line Loading @@ -94,7 +94,7 @@ class AppTaskImpl extends IAppTask.Stub { final long origId = Binder.clearCallingIdentity(); try { synchronized (this) { mService.mStackSupervisor.startActivityFromRecentsInner(mTaskId, null); mService.mStackSupervisor.startActivityFromRecents(mTaskId, null); } } finally { Binder.restoreCallingIdentity(origId); Loading