Loading services/core/java/com/android/server/wm/ActivityStack.java +5 −2 Original line number Diff line number Diff line Loading @@ -2723,13 +2723,15 @@ class ActivityStack extends Task { /** * Reset local parameters because an app's activity died. * @param app The app of the activity that died. * @return result from removeHistoryRecordsForAppLocked. * @return {@code true} if the process has any visible activity. */ 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; Loading @@ -2737,7 +2739,8 @@ class ActivityStack extends Task { } mStackSupervisor.removeHistoryRecords(app); return mRemoveHistoryRecordsForApp.process(app); final boolean hadVisibleActivities = mRemoveHistoryRecordsForApp.process(app); return hadVisibleActivities || isPausingDied; } boolean dump(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient, Loading services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java +22 −0 Original line number Diff line number Diff line Loading @@ -225,5 +225,27 @@ public class ActivityTaskManagerServiceTests extends ActivityTestsBase { mockSession.finishMocking(); } @Test public void testResumeNextActivityOnCrashedAppDied() { mSupervisor.beginDeferResume(); final ActivityRecord homeActivity = new ActivityBuilder(mService) .setTask(mRootWindowContainer.getDefaultTaskDisplayArea().getOrCreateRootHomeTask()) .build(); final ActivityRecord activity = new ActivityBuilder(mService).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(ActivityStack.ActivityState.PAUSED, "test"); // Even the visibility states are invisible, the next activity should be resumed because // the crashed activity was pausing. mService.mInternal.handleAppDied(activity.app, false /* restarting */, null /* finishInstrumentationCallback */); assertEquals(ActivityStack.ActivityState.RESUMED, homeActivity.getState()); } } Loading
services/core/java/com/android/server/wm/ActivityStack.java +5 −2 Original line number Diff line number Diff line Loading @@ -2723,13 +2723,15 @@ class ActivityStack extends Task { /** * Reset local parameters because an app's activity died. * @param app The app of the activity that died. * @return result from removeHistoryRecordsForAppLocked. * @return {@code true} if the process has any visible activity. */ 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; Loading @@ -2737,7 +2739,8 @@ class ActivityStack extends Task { } mStackSupervisor.removeHistoryRecords(app); return mRemoveHistoryRecordsForApp.process(app); final boolean hadVisibleActivities = mRemoveHistoryRecordsForApp.process(app); return hadVisibleActivities || isPausingDied; } boolean dump(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient, Loading
services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java +22 −0 Original line number Diff line number Diff line Loading @@ -225,5 +225,27 @@ public class ActivityTaskManagerServiceTests extends ActivityTestsBase { mockSession.finishMocking(); } @Test public void testResumeNextActivityOnCrashedAppDied() { mSupervisor.beginDeferResume(); final ActivityRecord homeActivity = new ActivityBuilder(mService) .setTask(mRootWindowContainer.getDefaultTaskDisplayArea().getOrCreateRootHomeTask()) .build(); final ActivityRecord activity = new ActivityBuilder(mService).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(ActivityStack.ActivityState.PAUSED, "test"); // Even the visibility states are invisible, the next activity should be resumed because // the crashed activity was pausing. mService.mInternal.handleAppDied(activity.app, false /* restarting */, null /* finishInstrumentationCallback */); assertEquals(ActivityStack.ActivityState.RESUMED, homeActivity.getState()); } }