diff options
-rw-r--r-- | services/core/java/com/android/server/am/ActivityStack.java | 74 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/ActivityStackSupervisor.java | 23 |
2 files changed, 76 insertions, 21 deletions
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 83a7b68..607af86 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -1154,6 +1154,23 @@ final class ActivityStack { return null; } + private ActivityStack getNextVisibleStackLocked() { + ArrayList<ActivityStack> stacks = mStacks; + final ActivityRecord parent = mActivityContainer.mParentActivity; + if (parent != null) { + stacks = parent.task.stack.mStacks; + } + if (stacks != null) { + for (int i = stacks.size() - 1; i >= 0; --i) { + ActivityStack stack = stacks.get(i); + if (stack != this && stack.isStackVisibleLocked()) { + return stack; + } + } + } + return null; + } + // Checks if any of the stacks above this one has a fullscreen activity behind it. // If so, this stack is hidden, otherwise it is visible. private boolean isStackVisibleLocked() { @@ -1482,7 +1499,7 @@ final class ActivityStack { return result; } - final boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) { + private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) { if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen(""); if (!mService.mBooting && !mService.mBooted) { @@ -1510,8 +1527,17 @@ final class ActivityStack { final TaskRecord prevTask = prev != null ? prev.task : null; if (next == null) { - // There are no more activities! Let's just start up the - // Launcher... + // There are no more activities! + final String reason = "noMoreActivities"; + if (!mFullscreen) { + // Try to move focus to the next visible stack with a running activity if this + // stack is not covering the entire screen. + final ActivityStack stack = getNextVisibleStackLocked(); + if (adjustFocusToNextVisibleStackLocked(stack, reason)) { + return mStackSupervisor.resumeTopActivitiesLocked(stack, prev, null); + } + } + // Let's just start up the Launcher... ActivityOptions.abort(options); if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: No more activities go home"); if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); @@ -1519,7 +1545,7 @@ final class ActivityStack { final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ? HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo(); return isOnHomeDisplay() && - mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, "noMoreActivities"); + mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, reason); } next.delayedResume = false; @@ -2516,20 +2542,45 @@ final class ActivityStack { private void adjustFocusedActivityLocked(ActivityRecord r, String reason) { if (mStackSupervisor.isFrontStack(this) && mService.mFocusedActivity == r) { ActivityRecord next = topRunningActivityLocked(null); + final String myReason = reason + " adjustFocus"; if (next != r) { final TaskRecord task = r.task; if (r.frontOfTask && task == topTask() && task.isOverHomeStack()) { - mStackSupervisor.moveHomeStackTaskToTop(task.getTaskToReturnTo(), - reason + " adjustFocus"); + // For non-fullscreen stack, we want to move the focus to the next visible + // stack to prevent the home screen from moving to the top and obscuring + // other visible stacks. + if (!mFullscreen + && adjustFocusToNextVisibleStackLocked(null, myReason)) { + return; + } + // Move the home stack to the top if this stack is fullscreen or there is no + // other visible stack. + mStackSupervisor.moveHomeStackTaskToTop(task.getTaskToReturnTo(), myReason); } } - ActivityRecord top = mStackSupervisor.topRunningActivityLocked(); + + final ActivityRecord top = mStackSupervisor.topRunningActivityLocked(); if (top != null) { - mService.setFocusedActivityLocked(top, reason + " adjustTopFocus"); + mService.setFocusedActivityLocked(top, myReason); } } } + private boolean adjustFocusToNextVisibleStackLocked(ActivityStack inStack, String reason) { + final ActivityStack stack = (inStack != null) ? inStack : getNextVisibleStackLocked(); + final String myReason = reason + " adjustFocusToNextVisibleStack"; + if (stack == null) { + return false; + } + final ActivityRecord top = stack.topRunningActivityLocked(null); + if (top == null) { + return false; + } + stack.moveToFront(myReason); + mService.setFocusedActivityLocked(top, myReason); + return true; + } + final void stopActivityLocked(ActivityRecord r) { if (DEBUG_SWITCH) Slog.d(TAG, "Stopping: " + r); if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0 @@ -4161,10 +4212,13 @@ final class ActivityStack { } if (mTaskHistory.isEmpty()) { - if (DEBUG_STACK) Slog.i(TAG, "removeTask: moving to back stack=" + this); + if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing stack=" + this); final boolean notHomeStack = !isHomeStack(); if (isOnHomeDisplay()) { - mStackSupervisor.moveHomeStack(notHomeStack, reason + " leftTaskHistoryEmpty"); + String myReason = reason + " leftTaskHistoryEmpty"; + if (mFullscreen || !adjustFocusToNextVisibleStackLocked(null, myReason)) { + mStackSupervisor.moveHomeStack(notHomeStack, myReason); + } } if (mStacks != null) { mStacks.remove(this); diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 9fe3c48..fb7a56c 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -386,8 +386,8 @@ public final class ActivityStackSupervisor implements DisplayListener { return mLastFocusedStack; } - // TODO: Split into two methods isFrontStack for any visible stack and isFrontmostStack for the - // top of all visible stacks. + /** Top of all visible stacks. Use {@link ActivityStack#isStackVisibleLocked} to determine if a + * specific stack is visible or not. */ boolean isFrontStack(ActivityStack stack) { final ActivityRecord parent = stack.mActivityContainer.mParentActivity; if (parent != null) { @@ -535,7 +535,7 @@ public final class ActivityStackSupervisor implements DisplayListener { } ActivityRecord resumedAppLocked() { - ActivityStack stack = getFocusedStack(); + ActivityStack stack = mFocusedStack; if (stack == null) { return null; } @@ -739,7 +739,7 @@ public final class ActivityStackSupervisor implements DisplayListener { } ActivityRecord topRunningActivityLocked() { - final ActivityStack focusedStack = getFocusedStack(); + final ActivityStack focusedStack = mFocusedStack; ActivityRecord r = focusedStack.topRunningActivityLocked(null); if (r != null) { return r; @@ -885,7 +885,7 @@ public final class ActivityStackSupervisor implements DisplayListener { final ActivityStack stack; if (container == null || container.mStack.isOnHomeDisplay()) { - stack = getFocusedStack(); + stack = mFocusedStack; } else { stack = container.mStack; } @@ -1502,7 +1502,7 @@ public final class ActivityStackSupervisor implements DisplayListener { outActivity[0] = r; } - final ActivityStack stack = getFocusedStack(); + final ActivityStack stack = mFocusedStack; if (voiceSession == null && (stack.mResumedActivity == null || stack.mResumedActivity.info.applicationInfo.uid != callingUid)) { if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, @@ -1706,7 +1706,7 @@ public final class ActivityStackSupervisor implements DisplayListener { if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { ActivityRecord checkedCaller = sourceRecord; if (checkedCaller == null) { - checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop); + checkedCaller = mFocusedStack.topRunningNonDelayedActivityLocked(notTop); } if (!checkedCaller.realActivity.equals(r.realActivity)) { // Caller is not the same as launcher, so always needed. @@ -2030,7 +2030,7 @@ public final class ActivityStackSupervisor implements DisplayListener { // If the activity being launched is the same as the one currently // at the top, then we need to check if it should only be launched // once. - ActivityStack topStack = getFocusedStack(); + ActivityStack topStack = mFocusedStack; ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop); if (top != null && r.resultTo == null) { if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) { @@ -2482,13 +2482,14 @@ public final class ActivityStackSupervisor implements DisplayListener { boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target, Bundle targetOptions) { if (targetStack == null) { - targetStack = getFocusedStack(); + targetStack = mFocusedStack; } // Do targetStack first. boolean result = false; if (isFrontStack(targetStack)) { result = targetStack.resumeTopActivityLocked(target, targetOptions); } + for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { @@ -3068,7 +3069,7 @@ public final class ActivityStackSupervisor implements DisplayListener { } boolean switchUserLocked(int userId, UserStartedState uss) { - mUserStackInFront.put(mCurrentUser, getFocusedStack().getStackId()); + mUserStackInFront.put(mCurrentUser, mFocusedStack.getStackId()); final int restoreStackId = mUserStackInFront.get(userId, HOME_STACK_ID); mCurrentUser = userId; @@ -3192,7 +3193,7 @@ public final class ActivityStackSupervisor implements DisplayListener { } ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) { - return getFocusedStack().getDumpActivitiesLocked(name); + return mFocusedStack.getDumpActivitiesLocked(name); } static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage, |