Resuming the restarting activities only if they were on stack top

While starting multiple activities via Activity.startActivities(),
more than one activities were launched within the same task.
If the top activity is not fullscreen, the activities below were
visible and stayed in RESUMED states.

Only resume the top-most activity while restarting it.

Bug: 136126538
Test: atest ActivityStackTests
Change-Id: I63d69609d9ebc31899c22b9d913a587348725826
This commit is contained in:
Louis Chang
2019-07-30 10:34:18 +08:00
parent a3662b912d
commit cfe46219cf
3 changed files with 22 additions and 16 deletions

View File

@@ -2918,7 +2918,7 @@ final class ActivityRecord extends ConfigurationContainer {
return false;
}
boolean handleAlreadyVisible() {
void handleAlreadyVisible() {
stopFreezingScreenLocked(false);
try {
if (returningOptions != null) {
@@ -2926,7 +2926,6 @@ final class ActivityRecord extends ConfigurationContainer {
}
} catch(RemoteException e) {
}
return mState == RESUMED;
}
static void activityResumedLocked(IBinder token) {

View File

@@ -2088,7 +2088,7 @@ class ActivityStack extends ConfigurationContainer {
boolean aboveTop = top != null;
final boolean stackShouldBeVisible = shouldBeVisible(starting);
boolean behindFullscreenActivity = !stackShouldBeVisible;
boolean resumeNextActivity = isFocusable() && isInStackLocked(starting) == null;
final boolean resumeTopActivity = isFocusable() && isInStackLocked(starting) == null;
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
final TaskRecord task = mTaskHistory.get(taskNdx);
final ArrayList<ActivityRecord> activities = task.mActivities;
@@ -2122,15 +2122,8 @@ class ActivityStack extends ConfigurationContainer {
}
if (!r.attachedToProcess()) {
if (makeVisibleAndRestartIfNeeded(starting, configChanges, isTop,
resumeNextActivity, r)) {
if (activityNdx >= activities.size()) {
// Record may be removed if its process needs to restart.
activityNdx = activities.size() - 1;
} else {
resumeNextActivity = false;
}
}
makeVisibleAndRestartIfNeeded(starting, configChanges, isTop,
resumeTopActivity && isTop, r);
} else if (r.visible) {
// If this activity is already visible, then there is nothing to do here.
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
@@ -2140,10 +2133,7 @@ class ActivityStack extends ConfigurationContainer {
r.makeClientVisible();
}
if (r.handleAlreadyVisible()) {
resumeNextActivity = false;
}
r.handleAlreadyVisible();
if (notifyClients) {
r.makeActiveIfNeeded(starting);
}

View File

@@ -26,6 +26,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMAR
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
@@ -1122,6 +1123,22 @@ public class ActivityStackTests extends ActivityTestsBase {
assertThat(result).isEqualTo(taskTop);
}
@Test
public void testNonTopVisibleActivityNotResume() {
final ActivityRecord nonTopVisibleActivity =
new ActivityBuilder(mService).setTask(mTask).build();
new ActivityBuilder(mService).setTask(mTask).build();
doReturn(false).when(nonTopVisibleActivity).attachedToProcess();
doReturn(true).when(nonTopVisibleActivity).shouldBeVisibleIgnoringKeyguard(anyBoolean());
doNothing().when(mSupervisor).startSpecificActivityLocked(any(), anyBoolean(),
anyBoolean());
mStack.ensureActivitiesVisibleLocked(null /* starting */, 0 /* configChanges */,
false /* preserveWindows */);
verify(mSupervisor).startSpecificActivityLocked(any(), eq(false) /* andResume */,
anyBoolean());
}
private void verifyShouldSleepActivities(boolean focusedStack,
boolean keyguardGoingAway, boolean displaySleeping, boolean expected) {
final ActivityDisplay display = mock(ActivityDisplay.class);