diff options
6 files changed, 173 insertions, 165 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 3e8dc4e1ba18..8e64eeb39933 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -2743,9 +2743,9 @@ public final class ActivityManagerService extends ActivityManagerNative return mAppBindArgs; } - final void setFocusedActivityLocked(ActivityRecord r, String reason) { + boolean setFocusedActivityLocked(ActivityRecord r, String reason) { if (r == null || mFocusedActivity == r) { - return; + return false; } if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r); @@ -2783,7 +2783,7 @@ public final class ActivityManagerService extends ActivityManagerNative finishVoiceTask(last.task.voiceSession); } } - if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) { + if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) { mWindowManager.setFocusedApp(r.appToken, true); } applyUpdateLockStateLocked(r); @@ -2799,23 +2799,35 @@ public final class ActivityManagerService extends ActivityManagerNative mFocusedActivity == null ? -1 : mFocusedActivity.userId, mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName, reason); + return true; } - final void clearFocusedActivity(ActivityRecord r) { - if (mFocusedActivity == r) { - ActivityStack stack = mStackSupervisor.getFocusedStack(); - if (stack != null) { - ActivityRecord top = stack.topActivity(); - if (top != null && top.userId != mLastFocusedUserId) { - mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG); - mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, - top.userId, 0)); - mLastFocusedUserId = top.userId; - } + final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) { + if (mFocusedActivity != goingAway) { + return; + } + + final ActivityStack focusedStack = mStackSupervisor.getFocusedStack(); + if (focusedStack != null) { + final ActivityRecord top = focusedStack.topActivity(); + if (top != null && top.userId != mLastFocusedUserId) { + mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG); + mHandler.sendMessage( + mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0)); + mLastFocusedUserId = top.userId; } - mFocusedActivity = null; - EventLogTags.writeAmFocusedActivity(-1, "NULL", "clearFocusedActivity"); } + + // Try to move focus to another activity if possible. + if (setFocusedActivityLocked( + focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) { + return; + } + + if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL " + + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway); + mFocusedActivity = null; + EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded"); } @Override @@ -2827,7 +2839,7 @@ public final class ActivityManagerService extends ActivityManagerNative ActivityRecord r = stack.topRunningActivityLocked(); if (r != null) { setFocusedActivityLocked(r, "setFocusedStack"); - mStackSupervisor.resumeTopActivitiesLocked(stack, null, null); + mStackSupervisor.resumeFocusedStackTopActivityLocked(); } } } @@ -2844,7 +2856,7 @@ public final class ActivityManagerService extends ActivityManagerNative ActivityRecord r = task.topRunningActivityLocked(); if (r != null) { setFocusedActivityLocked(r, "setFocusedTask"); - mStackSupervisor.resumeTopActivitiesLocked(task.stack, null, null); + mStackSupervisor.resumeFocusedStackTopActivityLocked(); } } } @@ -4473,7 +4485,7 @@ public final class ActivityManagerService extends ActivityManagerNative if (config != null) { r.frozenBeforeDestroy = true; if (!updateConfigurationLocked(config, r, false)) { - mStackSupervisor.resumeTopActivitiesLocked(); + mStackSupervisor.resumeFocusedStackTopActivityLocked(); } } Binder.restoreCallingIdentity(origId); @@ -4811,12 +4823,11 @@ public final class ActivityManagerService extends ActivityManagerNative finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); } - if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) { - // If there was nothing to resume, and we are not already - // restarting this process, but there is a visible activity that - // is hosted by the process... then make sure all visible - // activities are running, taking care of restarting this - // process. + if (!restarting && hasVisibleActivities + && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) { + // If there was nothing to resume, and we are not already restarting this process, but + // there is a visible activity that is hosted by the process... then make sure all + // visible activities are running, taking care of restarting this process. mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); } } @@ -5873,7 +5884,7 @@ public final class ActivityManagerService extends ActivityManagerNative // Clean-up disabled activities. if (mStackSupervisor.finishDisabledPackageActivitiesLocked( packageName, disabledClasses, true, false, userId) && mBooted) { - mStackSupervisor.resumeTopActivitiesLocked(); + mStackSupervisor.resumeFocusedStackTopActivityLocked(); mStackSupervisor.scheduleIdleLocked(); } @@ -6061,7 +6072,7 @@ public final class ActivityManagerService extends ActivityManagerNative } } if (mBooted) { - mStackSupervisor.resumeTopActivitiesLocked(); + mStackSupervisor.resumeFocusedStackTopActivityLocked(); mStackSupervisor.scheduleIdleLocked(); } } @@ -8994,7 +9005,7 @@ public final class ActivityManagerService extends ActivityManagerNative task.mResizeable = resizeable; mWindowManager.setTaskResizeable(taskId, resizeable); mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); - mStackSupervisor.resumeTopActivitiesLocked(); + mStackSupervisor.resumeFocusedStackTopActivityLocked(); } } } @@ -12603,7 +12614,7 @@ public final class ActivityManagerService extends ActivityManagerNative } finally { Binder.restoreCallingIdentity(ident); } - mStackSupervisor.resumeTopActivitiesLocked(); + mStackSupervisor.resumeFocusedStackTopActivityLocked(); mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId); } } @@ -12714,10 +12725,10 @@ public final class ActivityManagerService extends ActivityManagerNative // annoy the user repeatedly. Unless it is persistent, since those // processes run critical code. removeProcessLocked(app, false, false, "crash"); - mStackSupervisor.resumeTopActivitiesLocked(); + mStackSupervisor.resumeFocusedStackTopActivityLocked(); return false; } - mStackSupervisor.resumeTopActivitiesLocked(); + mStackSupervisor.resumeFocusedStackTopActivityLocked(); } else { mStackSupervisor.finishTopRunningActivityLocked(app, reason); } diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 1492e23e37e4..b9ff32c5cf46 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -572,6 +572,10 @@ final class ActivityStack { } } + boolean isFocusable() { + return StackId.canReceiveKeys(mStackId); + } + final boolean isAttached() { return mStacks != null; } @@ -917,7 +921,7 @@ final class ActivityStack { if (prev == null) { if (!resuming) { Slog.wtf(TAG, "Trying to pause when nothing is resumed"); - mStackSupervisor.resumeTopActivitiesLocked(); + mStackSupervisor.resumeFocusedStackTopActivityLocked(); } return false; } @@ -1008,7 +1012,7 @@ final class ActivityStack { // pause, so just treat it as being paused now. if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Activity not running, resuming next."); if (!resuming) { - mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null); + mStackSupervisor.resumeFocusedStackTopActivityLocked(); } return false; } @@ -1075,7 +1079,7 @@ final class ActivityStack { } else { if (r.configDestroy) { destroyActivityLocked(r, true, "stop-config"); - mStackSupervisor.resumeTopActivitiesLocked(); + mStackSupervisor.resumeFocusedStackTopActivityLocked(); } else { mStackSupervisor.updatePreviousProcessLocked(r); } @@ -1131,17 +1135,16 @@ final class ActivityStack { if (resumeNext) { final ActivityStack topStack = mStackSupervisor.getFocusedStack(); if (!mService.isSleepingOrShuttingDown()) { - mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null); + mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null); } else { mStackSupervisor.checkReadyForSleepLocked(); ActivityRecord top = topStack.topRunningActivityLocked(); if (top == null || (prev != null && top != prev)) { - // If there are no more activities available to run, - // do resume anyway to start something. Also if the top - // activity on the stack is not the just paused activity, - // we need to go ahead and resume it to ensure we complete - // an in-flight app switch. - mStackSupervisor.resumeTopActivitiesLocked(topStack, null, null); + // If there are no more activities available to run, do resume anyway to start + // something. Also if the top activity on the stack is not the just paused + // activity, we need to go ahead and resume it to ensure we complete an + // in-flight app switch. + mStackSupervisor.resumeFocusedStackTopActivityLocked(); } } } @@ -1478,7 +1481,7 @@ final class ActivityStack { boolean aboveTop = top != null; final boolean stackInvisible = !isStackVisibleLocked(); boolean behindFullscreenActivity = stackInvisible; - boolean noStackActivityResumed = (isInStackLocked(starting) == null); + boolean resumeNextActivity = isFocusable() && (isInStackLocked(starting) == null); for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { final TaskRecord task = mTaskHistory.get(taskNdx); @@ -1509,18 +1512,18 @@ final class ActivityStack { if (r.app == null || r.app.thread == null) { if (makeVisibleAndRestartIfNeeded(starting, configChanges, isTop, - noStackActivityResumed, r)) { + resumeNextActivity, r)) { if (activityNdx >= activities.size()) { // Record may be removed if its process needs to restart. activityNdx = activities.size() - 1; } else { - noStackActivityResumed = false; + resumeNextActivity = false; } } } else if (r.visible) { // If this activity is already visible, then there is nothing to do here. if (handleAlreadyVisible(r)) { - noStackActivityResumed = false; + resumeNextActivity = false; } } else { makeVisible(starting, r); @@ -1561,7 +1564,7 @@ final class ActivityStack { } private boolean makeVisibleAndRestartIfNeeded(ActivityRecord starting, int configChanges, - boolean isTop, boolean noStackActivityResumed, ActivityRecord r) { + boolean isTop, boolean andResume, ActivityRecord r) { // We need to make sure the app is running if it's the top, or it is just made visible from // invisible. If the app is already visible, it must have died while it was visible. In this // case, we'll show the dead window but will not restart the app. Otherwise we could end up @@ -1578,7 +1581,7 @@ final class ActivityStack { setVisible(r, true); } if (r != starting) { - mStackSupervisor.startSpecificActivityLocked(r, noStackActivityResumed, false); + mStackSupervisor.startSpecificActivityLocked(r, andResume, false); return true; } } @@ -1772,15 +1775,17 @@ final class ActivityStack { * * @param prev The previously resumed activity, for when in the process * of pausing; can be null to call from elsewhere. + * @param options Activity options. * * @return Returns true if something is being resumed, or false if * nothing happened. + * + * NOTE: It is not safe to call this method directly as it can cause an activity in a + * non-focused stack to be resumed. + * Use {@link ActivityStackSupervisor#resumeFocusedStackTopActivityLocked} to resume the + * right activity for the current system state. */ - final boolean resumeTopActivityLocked(ActivityRecord prev) { - return resumeTopActivityLocked(prev, null); - } - - final boolean resumeTopActivityLocked(ActivityRecord prev, ActivityOptions options) { + boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) { if (mStackSupervisor.inResumeTopActivity) { // Don't even start recursing. return false; @@ -1836,7 +1841,7 @@ final class ActivityStack { // stack is not covering the entire screen. final ActivityStack stack = getNextVisibleStackLocked(); if (adjustFocusToNextVisibleStackLocked(stack, reason)) { - return mStackSupervisor.resumeTopActivitiesLocked(stack, prev, null); + return mStackSupervisor.resumeFocusedStackTopActivityLocked(stack, prev, null); } } // Let's just start up the Launcher... @@ -2897,10 +2902,7 @@ final class ActivityStack { } } - final ActivityRecord top = mStackSupervisor.topRunningActivityLocked(); - if (top != null) { - mService.setFocusedActivityLocked(top, myReason); - } + mService.setFocusedActivityLocked(mStackSupervisor.topRunningActivityLocked(), myReason); } private boolean adjustFocusToNextVisibleStackLocked(ActivityStack inStack, String reason) { @@ -2909,12 +2911,7 @@ final class ActivityStack { if (stack == null) { return false; } - final ActivityRecord top = stack.topRunningActivityLocked(); - if (top == null) { - return false; - } - mService.setFocusedActivityLocked(top, myReason); - return true; + return mService.setFocusedActivityLocked(stack.topRunningActivityLocked(), myReason); } final void stopActivityLocked(ActivityRecord r) { @@ -3224,7 +3221,7 @@ final class ActivityStack { r.makeFinishingLocked(); boolean activityRemoved = destroyActivityLocked(r, true, "finish-imm"); if (activityRemoved) { - mStackSupervisor.resumeTopActivitiesLocked(); + mStackSupervisor.resumeFocusedStackTopActivityLocked(); } if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS, "destroyActivityLocked: finishCurrentActivityLocked r=" + r + @@ -3237,7 +3234,7 @@ final class ActivityStack { if (DEBUG_ALL) Slog.v(TAG, "Enqueueing pending finish: " + r); mStackSupervisor.mFinishingActivities.add(r); r.resumeKeyDispatchingLocked(); - mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null); + mStackSupervisor.resumeFocusedStackTopActivityLocked(); return r; } @@ -3395,7 +3392,7 @@ final class ActivityStack { if (mPausingActivity == r) { mPausingActivity = null; } - mService.clearFocusedActivity(r); + mService.resetFocusedActivityIfNeededLocked(r); r.configDestroy = false; r.frozenBeforeDestroy = false; @@ -3526,7 +3523,7 @@ final class ActivityStack { } } if (activityRemoved) { - mStackSupervisor.resumeTopActivitiesLocked(); + mStackSupervisor.resumeFocusedStackTopActivityLocked(); } } @@ -3700,7 +3697,7 @@ final class ActivityStack { removeActivityFromHistoryLocked(r, reason); } } - mStackSupervisor.resumeTopActivitiesLocked(); + mStackSupervisor.resumeFocusedStackTopActivityLocked(); } finally { Binder.restoreCallingIdentity(origId); } @@ -3738,7 +3735,7 @@ final class ActivityStack { setVisibleBehindActivity(null); mStackSupervisor.scheduleIdleTimeoutLocked(null); } - mStackSupervisor.resumeTopActivitiesLocked(); + mStackSupervisor.resumeFocusedStackTopActivityLocked(); } boolean hasVisibleBehindActivity() { @@ -3953,7 +3950,7 @@ final class ActivityStack { updateTransitLocked(AppTransition.TRANSIT_TASK_TO_FRONT, options); } - mStackSupervisor.resumeTopActivitiesLocked(); + mStackSupervisor.resumeFocusedStackTopActivityLocked(); EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, tr.taskId); if (VALIDATE_TOKENS) { @@ -4016,7 +4013,7 @@ final class ActivityStack { if (fullscreenStack != null && fullscreenStack.hasVisibleBehindActivity()) { final ActivityRecord visibleBehind = fullscreenStack.getVisibleBehindActivity(); mService.setFocusedActivityLocked(visibleBehind, "moveTaskToBack"); - mStackSupervisor.resumeTopActivitiesLocked(fullscreenStack, null, null); + mStackSupervisor.resumeFocusedStackTopActivityLocked(); return true; } } @@ -4071,7 +4068,7 @@ final class ActivityStack { return mStackSupervisor.resumeHomeStackTask(taskToReturnTo, null, "moveTaskToBack"); } - mStackSupervisor.resumeTopActivitiesLocked(); + mStackSupervisor.resumeFocusedStackTopActivityLocked(); return true; } @@ -4734,10 +4731,7 @@ final class ActivityStack { private void postAddTask(TaskRecord task, ActivityStack prevStack) { if (prevStack != null) { - if (prevStack != this - && (prevStack.mStackId == PINNED_STACK_ID || mStackId == PINNED_STACK_ID)) { - task.reportPictureInPictureModeChange(); - } + task.reportPictureInPictureModeChangeIfNeeded(prevStack); } else if (task.voiceSession != null) { try { task.voiceSession.taskStarted(task.intent, task.taskId); @@ -4758,25 +4752,21 @@ final class ActivityStack { r.taskConfigOverride = task.mOverrideConfig; } - void setFocusAndResumeStateIfNeeded( - ActivityRecord r, boolean setFocus, boolean setResume, String reason) { - // If the activity had focus before move focus to this stack. - if (setFocus) { - // If the activity owns the last resumed activity, transfer that together, - // so that we don't resume the same activity again in the new stack. - // Apps may depend on onResume()/onPause() being called in pairs. - if (setResume) { - mResumedActivity = r; - // Move the stack in which we are placing the activity to the front. We don't use - // ActivityManagerService.setFocusedActivityLocked, because if the activity is - // already focused, the call will short-circuit and do nothing. - moveToFront(reason); - } else { - // We need to not only move the stack to the front, but also have the activity - // focused. This will achieve both goals. - mService.setFocusedActivityLocked(r, reason); - } + void moveToFrontAndResumeStateIfNeeded( + ActivityRecord r, boolean moveToFront, boolean setResume, String reason) { + if (!moveToFront) { + return; + } + + // If the activity owns the last resumed activity, transfer that together, + // so that we don't resume the same activity again in the new stack. + // Apps may depend on onResume()/onPause() being called in pairs. + if (setResume) { + mResumedActivity = r; } + // Move the stack in which we are placing the activity to the front. The call will also + // make sure the activity focus is set. + moveToFront(reason); } /** @@ -4800,8 +4790,11 @@ final class ActivityStack { r.setTask(task, null); task.addActivityToTop(r); setAppTask(r, task); - task.reportPictureInPictureModeChange(); - setFocusAndResumeStateIfNeeded(r, wasFocused, wasResumed, "moveActivityToStack"); + task.reportPictureInPictureModeChangeIfNeeded(prevStack); + moveToFrontAndResumeStateIfNeeded(r, wasFocused, wasResumed, "moveActivityToStack"); + if (wasResumed) { + prevStack.mResumedActivity = null; + } } private void setAppTask(ActivityRecord r, TaskRecord task) { diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 32671acfcc30..df1aa52ee68f 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -370,7 +370,7 @@ public final class ActivityStackSupervisor implements DisplayListener { */ private LockTaskNotify mLockTaskNotify; - /** Used to keep resumeTopActivityLocked() from being entered recursively */ + /** Used to keep resumeTopActivityUncheckedLocked() from being entered recursively */ boolean inResumeTopActivity; // temp. rects used during resize calculation so we don't need to create a new object each time. @@ -537,16 +537,25 @@ public final class ActivityStackSupervisor implements DisplayListener { return stack == mHomeStack.mStacks.get((mHomeStack.mStacks.size() - 1)); } + /** NOTE: Should only be called from {@link ActivityStack#moveToFront} */ void setFocusStack(String reason, ActivityStack focusedStack) { - mLastFocusedStack = mFocusedStack; - mFocusedStack = focusedStack; + if (focusedStack != mFocusedStack) { + mLastFocusedStack = mFocusedStack; + mFocusedStack = focusedStack; + + EventLogTags.writeAmFocusedStack( + mCurrentUser, mFocusedStack == null ? -1 : mFocusedStack.getStackId(), + mLastFocusedStack == null ? -1 : mLastFocusedStack.getStackId(), reason); + } - EventLogTags.writeAmFocusedStack( - mCurrentUser, mFocusedStack == null ? -1 : mFocusedStack.getStackId(), - mLastFocusedStack == null ? -1 : mLastFocusedStack.getStackId(), reason); + final ActivityRecord r = topRunningActivityLocked(); + if (mService.mFocusedActivity != r) { + // The focus activity should always be the top activity in the focused stack. + // There will be chaos and anarchy if it isn't... + mService.setFocusedActivityLocked(r, reason + " setFocusStack"); + } if (mService.mBooting || !mService.mBooted) { - final ActivityRecord r = topRunningActivityLocked(); if (r != null && r.idle) { checkFinishBootingLocked(); } @@ -591,12 +600,14 @@ public final class ActivityStackSupervisor implements DisplayListener { mHomeStack.moveHomeStackTaskToTop(homeStackTaskType); ActivityRecord r = getHomeActivity(); + final String myReason = reason + " resumeHomeStackTask"; + // Only resume home activity if isn't finishing. if (r != null && !r.finishing) { - mService.setFocusedActivityLocked(r, reason); - return resumeTopActivitiesLocked(mHomeStack, prev, null); + mService.setFocusedActivityLocked(r, myReason); + return resumeFocusedStackTopActivityLocked(mHomeStack, prev, null); } - return mService.startHomeActivityLocked(mCurrentUser, reason); + return mService.startHomeActivityLocked(mCurrentUser, myReason); } TaskRecord anyTaskForIdLocked(int id) { @@ -1148,14 +1159,12 @@ public final class ActivityStackSupervisor implements DisplayListener { // a resume. stack.minimalResumeActivityLocked(r); } else { - // This activity is not starting in the resumed state... which - // should look like we asked it to pause+stop (but remain visible), - // and it has done so and reported back the current icicle and - // other state. + // This activity is not starting in the resumed state... which should look like we asked + // it to pause+stop (but remain visible), and it has done so and reported back the + // current icicle and other state. if (DEBUG_STATES) Slog.v(TAG_STATES, - "Moving to STOPPED: " + r + " (starting in stopped state)"); - r.state = STOPPED; - r.stopped = true; + "Moving to PAUSED: " + r + " (starting in paused state)"); + r.state = PAUSED; } // Launch the new version setup screen if needed. We do this -after- @@ -1345,14 +1354,14 @@ public final class ActivityStackSupervisor implements DisplayListener { return ACTIVITY_RESTRICTION_NONE; } - boolean setFocusedStack(ActivityRecord r, String reason) { + boolean moveActivityStackToFront(ActivityRecord r, String reason) { if (r == null) { // Not sure what you are trying to do, but it is not going to work... return false; } final TaskRecord task = r.task; if (task == null || task.stack == null) { - Slog.w(TAG, "Can't set focus stack for r=" + r + " task=" + task); + Slog.w(TAG, "Can't move stack to front for r=" + r + " task=" + task); return false; } task.stack.moveToFront(reason, task); @@ -1518,7 +1527,7 @@ public final class ActivityStackSupervisor implements DisplayListener { //mWindowManager.dump(); if (activityRemoved) { - resumeTopActivitiesLocked(); + resumeFocusedStackTopActivityLocked(); } return r; @@ -1611,35 +1620,17 @@ public final class ActivityStackSupervisor implements DisplayListener { } } - boolean resumeTopActivitiesLocked() { - return resumeTopActivitiesLocked(null, null, null); + boolean resumeFocusedStackTopActivityLocked() { + return resumeFocusedStackTopActivityLocked(null, null, null); } - boolean resumeTopActivitiesLocked( + boolean resumeFocusedStackTopActivityLocked( ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) { - if (targetStack == null) { - targetStack = mFocusedStack; - } - // Do targetStack first. - boolean result = false; - if (isFocusedStack(targetStack)) { - result = targetStack.resumeTopActivityLocked(target, targetOptions); + if (targetStack != null && isFocusedStack(targetStack)) { + return targetStack.resumeTopActivityUncheckedLocked(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) { - final ActivityStack stack = stacks.get(stackNdx); - if (stack == targetStack) { - // Already started above. - continue; - } - if (isFocusedStack(stack)) { - stack.resumeTopActivityLocked(null); - } - } - } - return result; + mFocusedStack.resumeTopActivityUncheckedLocked(null, null); + return false; } void finishTopRunningActivityLocked(ProcessRecord app, String reason) { @@ -1905,7 +1896,7 @@ public final class ActivityStackSupervisor implements DisplayListener { // are made visible with the correct configuration. ensureActivitiesVisibleLocked(r, 0, preserveWindows); if (!updated) { - resumeTopActivitiesLocked(stack, null, null); + resumeFocusedStackTopActivityLocked(); } } } finally { @@ -1961,7 +1952,7 @@ public final class ActivityStackSupervisor implements DisplayListener { // All other activities must be made visible with their correct configuration. ensureActivitiesVisibleLocked(r, 0, !PRESERVE_WINDOWS); if (!kept) { - resumeTopActivitiesLocked(stack, null, null); + resumeFocusedStackTopActivityLocked(); } } } @@ -2083,8 +2074,14 @@ public final class ActivityStackSupervisor implements DisplayListener { ActivityStack moveTaskToStackUncheckedLocked( TaskRecord task, int stackId, boolean toTop, boolean forceFocus, String reason) { final ActivityRecord r = task.getTopActivity(); - final boolean wasFocused = isFocusedStack(task.stack) && (topRunningActivityLocked() == r); - final boolean wasResumed = wasFocused && (task.stack.mResumedActivity == r); + final ActivityStack prevStack = task.stack; + final boolean wasFocused = isFocusedStack(prevStack) && (topRunningActivityLocked() == r); + final boolean wasResumed = wasFocused && (prevStack.mResumedActivity == r); + // In some cases the focused stack isn't the front stack. E.g. pinned stack. + // Whenever we are moving the top activity from the front stack we want to make sure to move + // the stack to the front. + final boolean wasFront = isFrontStack(prevStack) + && (prevStack.topRunningActivityLocked() == r); final boolean resizeable = task.mResizeable; // Temporarily disable resizeablility of task we are moving. We don't want it to be resized @@ -2097,9 +2094,9 @@ public final class ActivityStackSupervisor implements DisplayListener { stack.addTask(task, toTop, reason); // If the task had focus before (or we're requested to move focus), - // move focus to the new stack. - stack.setFocusAndResumeStateIfNeeded( - r, forceFocus || wasFocused, wasResumed, reason); + // move focus to the new stack by moving the stack to the front. + stack.moveToFrontAndResumeStateIfNeeded( + r, forceFocus || wasFocused || wasFront, wasResumed, reason); return stack; } @@ -2149,7 +2146,7 @@ public final class ActivityStackSupervisor implements DisplayListener { // The task might have already been running and its visibility needs to be synchronized with // the visibility of the stack / windows. ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); - resumeTopActivitiesLocked(); + resumeFocusedStackTopActivityLocked(); if (!task.mResizeable && isStackDockedInEffect(stackId)) { showNonResizeableDockToast(taskId); @@ -2200,7 +2197,7 @@ public final class ActivityStackSupervisor implements DisplayListener { // The task might have already been running and its visibility needs to be synchronized with // the visibility of the stack / windows. ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); - resumeTopActivitiesLocked(); + resumeFocusedStackTopActivityLocked(); } void positionTaskInStackLocked(int taskId, int stackId, int position) { @@ -2219,7 +2216,7 @@ public final class ActivityStackSupervisor implements DisplayListener { // The task might have already been running and its visibility needs to be synchronized with // the visibility of the stack / windows. stack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); - resumeTopActivitiesLocked(); + resumeFocusedStackTopActivityLocked(); } ActivityRecord findTaskLocked(ActivityRecord r) { @@ -2329,7 +2326,7 @@ public final class ActivityStackSupervisor implements DisplayListener { final ActivityStack stack = stacks.get(stackNdx); stack.awakeFromSleepingLocked(); if (isFocusedStack(stack)) { - resumeTopActivitiesLocked(); + resumeFocusedStackTopActivityLocked(); } } } @@ -3124,7 +3121,7 @@ public final class ActivityStackSupervisor implements DisplayListener { if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "setLockTaskModeLocked: Tasks remaining, can't unlock"); lockedTask.performClearTaskLocked(); - resumeTopActivitiesLocked(); + resumeFocusedStackTopActivityLocked(); return; } } @@ -3165,7 +3162,7 @@ public final class ActivityStackSupervisor implements DisplayListener { if (andResume) { findTaskToMoveToFrontLocked(task, 0, null, reason); - resumeTopActivitiesLocked(); + resumeFocusedStackTopActivityLocked(); } } @@ -3233,7 +3230,7 @@ public final class ActivityStackSupervisor implements DisplayListener { didSomething = true; } if (didSomething) { - resumeTopActivitiesLocked(); + resumeFocusedStackTopActivityLocked(); } } @@ -3280,7 +3277,7 @@ public final class ActivityStackSupervisor implements DisplayListener { } break; case RESUME_TOP_ACTIVITY_MSG: { synchronized (mService) { - resumeTopActivitiesLocked(); + resumeFocusedStackTopActivityLocked(); } } break; case SLEEP_TIMEOUT_MSG: { @@ -3661,7 +3658,7 @@ public final class ActivityStackSupervisor implements DisplayListener { mSurface = surface; if (surface != null) { - mStack.resumeTopActivityLocked(null); + resumeFocusedStackTopActivityLocked(); } else { mContainerState = CONTAINER_STATE_NO_SURFACE; ((VirtualActivityDisplay) mActivityDisplay).setSurface(null); diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java index b16e160d9505..bcb22155dbad 100644 --- a/services/core/java/com/android/server/am/ActivityStarter.java +++ b/services/core/java/com/android/server/am/ActivityStarter.java @@ -916,7 +916,7 @@ public class ActivityStarter { // is the case, so this is it! And for paranoia, make // sure we have correctly resumed the top activity. if (doResume) { - mSupervisor.resumeTopActivitiesLocked(targetStack, null, options); + mSupervisor.resumeFocusedStackTopActivityLocked(targetStack, null, options); // Make sure to notify Keyguard as well if we are not running an app // transition later. @@ -1019,7 +1019,7 @@ public class ActivityStarter { // don't use that intent!) And for paranoia, make // sure we have correctly resumed the top activity. if (doResume) { - targetStack.resumeTopActivityLocked(null, options); + mSupervisor.resumeFocusedStackTopActivityLocked(targetStack, null, options); if (!movedToFront) { // Make sure to notify Keyguard as well if we are not running an app // transition later. @@ -1055,7 +1055,7 @@ public class ActivityStarter { // For paranoia, make sure we have correctly resumed the top activity. topStack.mLastPausedActivity = null; if (doResume) { - mSupervisor.resumeTopActivitiesLocked(); + mSupervisor.resumeFocusedStackTopActivityLocked(); } ActivityOptions.abort(options); if ((startFlags & ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) { @@ -1157,7 +1157,7 @@ public class ActivityStarter { // resumed the top activity. targetStack.mLastPausedActivity = null; if (doResume) { - targetStack.resumeTopActivityLocked(null); + mSupervisor.resumeFocusedStackTopActivityLocked(); } ActivityOptions.abort(options); return ActivityManager.START_DELIVERED_TO_TOP; @@ -1176,7 +1176,7 @@ public class ActivityStarter { top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage); targetStack.mLastPausedActivity = null; if (doResume) { - targetStack.resumeTopActivityLocked(null); + mSupervisor.resumeFocusedStackTopActivityLocked(); } return ActivityManager.START_DELIVERED_TO_TOP; } @@ -1266,9 +1266,11 @@ public class ActivityStarter { targetStack.startActivityLocked(r, newTask, keepCurTransition, options); if (doResume) { if (!launchTaskBehind) { + // TODO: Remove this code after verification that all the decision points above + // moved targetStack to the front which will also set the focus activity. mService.setFocusedActivityLocked(r, "startedActivity"); } - mSupervisor.resumeTopActivitiesLocked(targetStack, r, options); + mSupervisor.resumeFocusedStackTopActivityLocked(targetStack, r, options); } else { targetStack.addRecentActivityLocked(r); } diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java index 4647d77bef89..e77bb20f654f 100644 --- a/services/core/java/com/android/server/am/TaskRecord.java +++ b/services/core/java/com/android/server/am/TaskRecord.java @@ -1321,7 +1321,12 @@ final class TaskRecord { } } - void reportPictureInPictureModeChange() { + void reportPictureInPictureModeChangeIfNeeded(ActivityStack prevStack) { + if (prevStack == null || prevStack == stack + || (prevStack.mStackId != PINNED_STACK_ID && stack.mStackId != PINNED_STACK_ID)) { + return; + } + for (int i = mActivities.size() - 1; i >= 0; i--) { final ActivityRecord r = mActivities.get(i); if (r.app != null && r.app.thread != null) { diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index 20b1e6058224..4cdf6b8def47 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -931,7 +931,7 @@ final class UserController { if (homeInFront) { mService.startHomeActivityLocked(newUserId, "moveUserToForeground"); } else { - mService.mStackSupervisor.resumeTopActivitiesLocked(); + mService.mStackSupervisor.resumeFocusedStackTopActivityLocked(); } EventLogTags.writeAmSwitchUser(newUserId); getUserManager().onUserForeground(newUserId); |