Don't ensure configuration for activity we are resuming.

Regression introduced in ag/865988 when ASS.ensureActivitiesVisibleLocked()
was added to the end of AS.completePauseLocked() without specifing the
starting/resuming activity. If the starting/resuming activity isn't specified
the resuming activity can be relaunched with the current configuration which
might be different from the configuration the activity will end up in if it has
fixed orientation.
We now pass in the starting/resuming activity to avoid this.

Bug: 30509213
Change-Id: Idd0be84745bad83a1924e850b9b4020b927a78d8
This commit is contained in:
Wale Ogunwale
2016-08-08 09:51:04 -07:00
parent 295d81c360
commit 950faffd02
2 changed files with 22 additions and 18 deletions

View File

@@ -988,7 +988,7 @@ final class ActivityStack {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep needs to pause " + mResumedActivity); if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep needs to pause " + mResumedActivity);
if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING, if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
"Sleep => pause with userLeaving=false"); "Sleep => pause with userLeaving=false");
startPausingLocked(false, true, false, false); startPausingLocked(false, true, null, false);
return true; return true;
} }
if (mPausingActivity != null) { if (mPausingActivity != null) {
@@ -1066,15 +1066,16 @@ final class ActivityStack {
* @param userLeaving True if this should result in an onUserLeaving to the current activity. * @param userLeaving True if this should result in an onUserLeaving to the current activity.
* @param uiSleeping True if this is happening with the user interface going to sleep (the * @param uiSleeping True if this is happening with the user interface going to sleep (the
* screen turning off). * screen turning off).
* @param resuming True if this is being called as part of resuming the top activity, so * @param resuming The activity we are currently trying to resume or null if this is not being
* we shouldn't try to instigate a resume here. * called as part of resuming the top activity, so we shouldn't try to instigate
* a resume here if not null.
* @param dontWait True if the caller does not want to wait for the pause to complete. If * @param dontWait True if the caller does not want to wait for the pause to complete. If
* set to true, we will immediately complete the pause here before returning. * set to true, we will immediately complete the pause here before returning.
* @return Returns true if an activity now is in the PAUSING state, and we are waiting for * @return Returns true if an activity now is in the PAUSING state, and we are waiting for
* it to tell us when it is done. * it to tell us when it is done.
*/ */
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming, final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
boolean dontWait) { ActivityRecord resuming, boolean dontWait) {
if (mPausingActivity != null) { if (mPausingActivity != null) {
Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity
+ " state=" + mPausingActivity.state); + " state=" + mPausingActivity.state);
@@ -1082,12 +1083,12 @@ final class ActivityStack {
// Avoid recursion among check for sleep and complete pause during sleeping. // Avoid recursion among check for sleep and complete pause during sleeping.
// Because activity will be paused immediately after resume, just let pause // Because activity will be paused immediately after resume, just let pause
// be completed by the order of activity paused from clients. // be completed by the order of activity paused from clients.
completePauseLocked(false); completePauseLocked(false, resuming);
} }
} }
ActivityRecord prev = mResumedActivity; ActivityRecord prev = mResumedActivity;
if (prev == null) { if (prev == null) {
if (!resuming) { if (resuming == null) {
Slog.wtf(TAG, "Trying to pause when nothing is resumed"); Slog.wtf(TAG, "Trying to pause when nothing is resumed");
mStackSupervisor.resumeFocusedStackTopActivityLocked(); mStackSupervisor.resumeFocusedStackTopActivityLocked();
} }
@@ -1160,7 +1161,7 @@ final class ActivityStack {
if (dontWait) { if (dontWait) {
// If the caller said they don't want to wait for the pause, then complete // If the caller said they don't want to wait for the pause, then complete
// the pause now. // the pause now.
completePauseLocked(false); completePauseLocked(false, resuming);
return false; return false;
} else { } else {
@@ -1179,7 +1180,7 @@ final class ActivityStack {
// This activity failed to schedule the // This activity failed to schedule the
// pause, so just treat it as being paused now. // pause, so just treat it as being paused now.
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Activity not running, resuming next."); if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Activity not running, resuming next.");
if (!resuming) { if (resuming == null) {
mStackSupervisor.resumeFocusedStackTopActivityLocked(); mStackSupervisor.resumeFocusedStackTopActivityLocked();
} }
return false; return false;
@@ -1196,7 +1197,7 @@ final class ActivityStack {
if (mPausingActivity == r) { if (mPausingActivity == r) {
if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r
+ (timeout ? " (due to timeout)" : " (pause complete)")); + (timeout ? " (due to timeout)" : " (pause complete)"));
completePauseLocked(true); completePauseLocked(true, null);
return; return;
} else { } else {
EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE, EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
@@ -1267,7 +1268,7 @@ final class ActivityStack {
} }
} }
private void completePauseLocked(boolean resumeNext) { private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
ActivityRecord prev = mPausingActivity; ActivityRecord prev = mPausingActivity;
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev); if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev);
@@ -1359,7 +1360,7 @@ final class ActivityStack {
mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = false; mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = false;
} }
mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); mStackSupervisor.ensureActivitiesVisibleLocked(resuming, 0, !PRESERVE_WINDOWS);
} }
private void addToStopping(ActivityRecord r, boolean immediate) { private void addToStopping(ActivityRecord r, boolean immediate) {
@@ -2256,11 +2257,11 @@ final class ActivityStack {
// We need to start pausing the current activity so the top one can be resumed... // We need to start pausing the current activity so the top one can be resumed...
final boolean dontWaitForPause = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0; final boolean dontWaitForPause = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0;
boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause); boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, dontWaitForPause);
if (mResumedActivity != null) { if (mResumedActivity != null) {
if (DEBUG_STATES) Slog.d(TAG_STATES, if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Pausing " + mResumedActivity); "resumeTopActivityLocked: Pausing " + mResumedActivity);
pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause); pausing |= startPausingLocked(userLeaving, false, next, dontWaitForPause);
} }
if (pausing) { if (pausing) {
if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG_STATES, if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG_STATES,
@@ -3497,7 +3498,7 @@ final class ActivityStack {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish needs to pause: " + r); if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish needs to pause: " + r);
if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING, if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
"finish() => pause with userLeaving=false"); "finish() => pause with userLeaving=false");
startPausingLocked(false, false, false, false); startPausingLocked(false, false, null, false);
} }
if (endTask) { if (endTask) {

View File

@@ -923,9 +923,12 @@ public final class ActivityStackSupervisor implements DisplayListener {
/** /**
* Pause all activities in either all of the stacks or just the back stacks. * Pause all activities in either all of the stacks or just the back stacks.
* @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving(). * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving().
* @param resuming The resuming activity.
* @param dontWait The resuming activity isn't going to wait for all activities to be paused
* before resuming.
* @return true if any activity was paused as a result of this call. * @return true if any activity was paused as a result of this call.
*/ */
boolean pauseBackStacks(boolean userLeaving, boolean resuming, boolean dontWait) { boolean pauseBackStacks(boolean userLeaving, ActivityRecord resuming, boolean dontWait) {
boolean someActivityPaused = false; boolean someActivityPaused = false;
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
@@ -964,7 +967,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
} }
void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping, void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping,
boolean resuming, boolean dontWait) { ActivityRecord resuming, boolean dontWait) {
// TODO: Put all stacks in supervisor and iterate through them instead. // TODO: Put all stacks in supervisor and iterate through them instead.
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
@@ -4200,7 +4203,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
mContainerState = CONTAINER_STATE_NO_SURFACE; mContainerState = CONTAINER_STATE_NO_SURFACE;
((VirtualActivityDisplay) mActivityDisplay).setSurface(null); ((VirtualActivityDisplay) mActivityDisplay).setSurface(null);
if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) { if (mStack.mPausingActivity == null && mStack.mResumedActivity != null) {
mStack.startPausingLocked(false, true, false, false); mStack.startPausingLocked(false, true, null, false);
} }
} }