Check that should resume activity directly while relaunch.

When running ActivityLifecycleSplitScreenTests test
testResumedWhenRecreatedFromInNonFocusedStack, we found that an activity
could have an extra paused lifecycle before resumed, this is because
one of the activity state in this stack is pausing, so the activity
behind it be relaunch to pause state.
To prevent another extra lifecycle, we can check that will the activity
goes to resume directly while relaunch.

Bug: 127741025
Test: run tests in android.server.am.lifecycle
Change-Id: I7f0520ec57250f0161741704d0f6ae79ced0139d
This commit is contained in:
wilsonshih
2019-10-23 13:01:40 +08:00
parent 66b1a264c5
commit b5d8f8b185
2 changed files with 23 additions and 23 deletions

View File

@@ -4620,16 +4620,25 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
/**
* Check if activity should be moved to RESUMED state. The activity:
* - should be eligible to be made active (see {@link #shouldMakeActive(ActivityRecord)})
* - should be focusable
* Check if activity should be moved to RESUMED state.
* See {@link #shouldBeResumed(ActivityRecord)}
* @param activeActivity the activity that is active or just completed pause action. We won't
* resume if this activity is active.
*/
@VisibleForTesting
boolean shouldResumeActivity(ActivityRecord activeActivity) {
return shouldMakeActive(activeActivity) && isFocusable() && !isState(RESUMED)
&& getActivityStack().getVisibility(activeActivity) == STACK_VISIBILITY_VISIBLE;
return shouldBeResumed(activeActivity) && !isState(RESUMED);
}
/**
* Check if activity should be RESUMED now. The activity:
* - should be eligible to be made active (see {@link #shouldMakeActive(ActivityRecord)})
* - should be focusable
*/
private boolean shouldBeResumed(ActivityRecord activeActivity) {
return shouldMakeActive(activeActivity) && isFocusable()
&& getActivityStack().getVisibility(activeActivity) == STACK_VISIBILITY_VISIBLE
&& canResumeByCompat();
}
/**
@@ -6905,23 +6914,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
deferRelaunchUntilPaused = true;
preserveWindowOnDeferredRelaunch = preserveWindow;
return true;
} else if (mState == RESUMED) {
// Try to optimize this case: the configuration is changing and we need to restart
// the top, resumed activity. Instead of doing the normal handshaking, just say
// "restart!".
if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
"Config is relaunching resumed " + this);
if (DEBUG_STATES && !visible) {
Slog.v(TAG_STATES, "Config is relaunching resumed invisible activity " + this
+ " called by " + Debug.getCallers(4));
}
relaunchActivityLocked(true /* andResume */, preserveWindow);
} else {
if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
"Config is relaunching non-resumed " + this);
relaunchActivityLocked(false /* andResume */, preserveWindow);
"Config is relaunching " + this);
if (DEBUG_STATES && !visible) {
Slog.v(TAG_STATES, "Config is relaunching invisible activity " + this
+ " called by " + Debug.getCallers(4));
}
relaunchActivityLocked(preserveWindow);
}
// All done... tell the caller we weren't able to keep this activity around.
@@ -7019,12 +7019,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
| CONFIG_SCREEN_LAYOUT)) != 0;
}
void relaunchActivityLocked(boolean andResume, boolean preserveWindow) {
void relaunchActivityLocked(boolean preserveWindow) {
if (mAtmService.mSuppressResizeConfigChanges && preserveWindow) {
configChangeFlags = 0;
return;
}
final boolean andResume = shouldBeResumed(null /*activeActivity*/);
List<ResultInfo> pendingResults = null;
List<ReferrerIntent> pendingNewIntents = null;
if (andResume) {

View File

@@ -1792,8 +1792,7 @@ class ActivityStack extends ConfigurationContainer {
if (prev.deferRelaunchUntilPaused) {
// Complete the deferred relaunch that was waiting for pause to complete.
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Re-launching after pause: " + prev);
prev.relaunchActivityLocked(false /* andResume */,
prev.preserveWindowOnDeferredRelaunch);
prev.relaunchActivityLocked(prev.preserveWindowOnDeferredRelaunch);
} else if (wasStopping) {
// We are also stopping, the stop request must have gone soon after the pause.
// We can't clobber it, because the stop confirmation will not be handled.