Resume next activity if pausing app died
If the top activity is crashed before showing any window, when its
process reported dead, it will be regarded as no visible activity
and no need to resume next activity. That may lead to the next top
activity remains in paused state and may be unresponsive.
Bug: 159951007
Test: atest ActivityTaskManagerServiceTests# \
testResumeNextActivityOnCrashedAppDied
Change-Id: I635fceb9cf7b782f6ffbb9ebef7cb69053f64a0b
This commit is contained in:
@@ -7056,17 +7056,21 @@ class Task extends WindowContainer<WindowContainer> {
|
||||
/**
|
||||
* Reset local parameters because an app's activity died.
|
||||
* @param app The app of the activity that died.
|
||||
* @return {@code true} if the process of the pausing activity is died.
|
||||
*/
|
||||
void handleAppDied(WindowProcessController app) {
|
||||
boolean handleAppDied(WindowProcessController app) {
|
||||
boolean isPausingDied = false;
|
||||
if (mPausingActivity != null && mPausingActivity.app == app) {
|
||||
if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG_PAUSE,
|
||||
"App died while pausing: " + mPausingActivity);
|
||||
mPausingActivity = null;
|
||||
isPausingDied = true;
|
||||
}
|
||||
if (mLastPausedActivity != null && mLastPausedActivity.app == app) {
|
||||
mLastPausedActivity = null;
|
||||
mLastNoHistoryActivity = null;
|
||||
}
|
||||
return isPausingDied;
|
||||
}
|
||||
|
||||
boolean dump(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient,
|
||||
|
||||
@@ -1201,7 +1201,10 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
|
||||
|
||||
final Task rootTask = r.getRootTask();
|
||||
if (rootTask != null) {
|
||||
rootTask.handleAppDied(this);
|
||||
// There may be a pausing activity that hasn't shown any window and was requested
|
||||
// to be hidden. But pausing is also a visible state, it should be regarded as
|
||||
// visible, so the caller can know the next activity should be resumed.
|
||||
hasVisibleActivities |= rootTask.handleAppDied(this);
|
||||
}
|
||||
r.handleAppDied();
|
||||
}
|
||||
|
||||
@@ -225,5 +225,27 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase {
|
||||
|
||||
mockSession.finishMocking();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResumeNextActivityOnCrashedAppDied() {
|
||||
mSupervisor.beginDeferResume();
|
||||
final ActivityRecord homeActivity = new ActivityBuilder(mAtm)
|
||||
.setTask(mRootWindowContainer.getDefaultTaskDisplayArea().getOrCreateRootHomeTask())
|
||||
.build();
|
||||
final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true).build();
|
||||
mSupervisor.endDeferResume();
|
||||
// Assume the activity is finishing and hidden because it was crashed.
|
||||
activity.finishing = true;
|
||||
activity.mVisibleRequested = false;
|
||||
activity.setVisible(false);
|
||||
activity.getRootTask().mPausingActivity = activity;
|
||||
homeActivity.setState(Task.ActivityState.PAUSED, "test");
|
||||
|
||||
// Even the visibility states are invisible, the next activity should be resumed because
|
||||
// the crashed activity was pausing.
|
||||
mAtm.mInternal.handleAppDied(activity.app, false /* restarting */,
|
||||
null /* finishInstrumentationCallback */);
|
||||
assertEquals(Task.ActivityState.RESUMED, homeActivity.getState());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user