@@ -81,6 +81,7 @@ final class ActivityStack {
8181 static final boolean DEBUG_RESULTS = ActivityManagerService .DEBUG_RESULTS ;
8282 static final boolean DEBUG_CONFIGURATION = ActivityManagerService .DEBUG_CONFIGURATION ;
8383 static final boolean DEBUG_TASKS = ActivityManagerService .DEBUG_TASKS ;
84+ static final boolean DEBUG_CLEANUP = ActivityManagerService .DEBUG_CLEANUP ;
8485
8586 static final boolean DEBUG_STATES = false ;
8687 static final boolean DEBUG_ADD_REMOVE = false ;
@@ -1142,9 +1143,13 @@ private final void completePauseLocked() {
11421143 resumeTopActivityLocked (prev );
11431144 } else {
11441145 checkReadyForSleepLocked ();
1145- if (topRunningActivityLocked (null ) == null ) {
1146- // If there are no more activities available to run, then
1147- // do resume anyway to start something.
1146+ ActivityRecord top = topRunningActivityLocked (null );
1147+ if (top == null || (prev != null && top != prev )) {
1148+ // If there are no more activities available to run,
1149+ // do resume anyway to start something. Also if the top
1150+ // activity on the stack is not the just paused activity,
1151+ // we need to go ahead and resume it to ensure we complete
1152+ // an in-flight app switch.
11481153 resumeTopActivityLocked (null );
11491154 }
11501155 }
@@ -1461,7 +1466,8 @@ final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
14611466 // If we are currently pausing an activity, then don't do anything
14621467 // until that is done.
14631468 if (mPausingActivity != null ) {
1464- if (DEBUG_SWITCH ) Slog .v (TAG , "Skip resume: pausing=" + mPausingActivity );
1469+ if (DEBUG_SWITCH || DEBUG_PAUSE ) Slog .v (TAG ,
1470+ "Skip resume: pausing=" + mPausingActivity );
14651471 return false ;
14661472 }
14671473
@@ -3862,6 +3868,7 @@ final void cleanUpActivityLocked(ActivityRecord r, boolean cleanServices,
38623868 if (setState ) {
38633869 if (DEBUG_STATES ) Slog .v (TAG , "Moving to DESTROYED: " + r + " (cleaning up)" );
38643870 r .state = ActivityState .DESTROYED ;
3871+ r .app = null ;
38653872 }
38663873
38673874 // Make sure this record is no longer in the pending finishes list.
@@ -3905,26 +3912,26 @@ private void removeTimeoutsForActivityLocked(ActivityRecord r) {
39053912 }
39063913
39073914 final void removeActivityFromHistoryLocked (ActivityRecord r ) {
3908- if (r .state != ActivityState .DESTROYED ) {
3909- finishActivityResultsLocked (r , Activity .RESULT_CANCELED , null );
3910- r .makeFinishing ();
3911- if (DEBUG_ADD_REMOVE ) {
3912- RuntimeException here = new RuntimeException ("here" );
3913- here .fillInStackTrace ();
3914- Slog .i (TAG , "Removing activity " + r + " from stack" );
3915- }
3916- mHistory .remove (r );
3917- r .takeFromHistory ();
3918- if (DEBUG_STATES ) Slog .v (TAG , "Moving to DESTROYED: " + r
3919- + " (removed from history)" );
3920- r .state = ActivityState .DESTROYED ;
3921- mService .mWindowManager .removeAppToken (r .appToken );
3922- if (VALIDATE_TOKENS ) {
3923- validateAppTokensLocked ();
3924- }
3925- cleanUpActivityServicesLocked (r );
3926- r .removeUriPermissionsLocked ();
3915+ finishActivityResultsLocked (r , Activity .RESULT_CANCELED , null );
3916+ r .makeFinishing ();
3917+ if (DEBUG_ADD_REMOVE ) {
3918+ RuntimeException here = new RuntimeException ("here" );
3919+ here .fillInStackTrace ();
3920+ Slog .i (TAG , "Removing activity " + r + " from stack" );
3921+ }
3922+ mHistory .remove (r );
3923+ r .takeFromHistory ();
3924+ removeTimeoutsForActivityLocked (r );
3925+ if (DEBUG_STATES ) Slog .v (TAG , "Moving to DESTROYED: " + r
3926+ + " (removed from history)" );
3927+ r .state = ActivityState .DESTROYED ;
3928+ r .app = null ;
3929+ mService .mWindowManager .removeAppToken (r .appToken );
3930+ if (VALIDATE_TOKENS ) {
3931+ validateAppTokensLocked ();
39273932 }
3933+ cleanUpActivityServicesLocked (r );
3934+ r .removeUriPermissionsLocked ();
39283935 }
39293936
39303937 /**
@@ -3992,19 +3999,19 @@ final void destroyActivitiesLocked(ProcessRecord owner, boolean oomAdj, String r
39923999 */
39934000 final boolean destroyActivityLocked (ActivityRecord r ,
39944001 boolean removeFromApp , boolean oomAdj , String reason ) {
3995- if (DEBUG_SWITCH ) Slog .v (
4002+ if (DEBUG_SWITCH || DEBUG_CLEANUP ) Slog .v (
39964003 TAG , "Removing activity from " + reason + ": token=" + r
39974004 + ", app=" + (r .app != null ? r .app .processName : "(null)" ));
39984005 EventLog .writeEvent (EventLogTags .AM_DESTROY_ACTIVITY ,
39994006 r .userId , System .identityHashCode (r ),
40004007 r .task .taskId , r .shortComponentName , reason );
40014008
40024009 boolean removedFromHistory = false ;
4003-
4010+
40044011 cleanUpActivityLocked (r , false , false );
40054012
40064013 final boolean hadApp = r .app != null ;
4007-
4014+
40084015 if (hadApp ) {
40094016 if (removeFromApp ) {
40104017 int idx = r .app .activities .indexOf (r );
@@ -4040,7 +4047,6 @@ final boolean destroyActivityLocked(ActivityRecord r,
40404047 }
40414048 }
40424049
4043- r .app = null ;
40444050 r .nowVisible = false ;
40454051
40464052 // If the activity is finishing, we need to wait on removing it
@@ -4061,6 +4067,7 @@ final boolean destroyActivityLocked(ActivityRecord r,
40614067 if (DEBUG_STATES ) Slog .v (TAG , "Moving to DESTROYED: " + r
40624068 + " (destroy skipped)" );
40634069 r .state = ActivityState .DESTROYED ;
4070+ r .app = null ;
40644071 }
40654072 } else {
40664073 // remove this record from the history.
@@ -4071,6 +4078,7 @@ final boolean destroyActivityLocked(ActivityRecord r,
40714078 if (DEBUG_STATES ) Slog .v (TAG , "Moving to DESTROYED: " + r
40724079 + " (no app)" );
40734080 r .state = ActivityState .DESTROYED ;
4081+ r .app = null ;
40744082 }
40754083 }
40764084
@@ -4106,30 +4114,85 @@ final void activityDestroyed(IBinder token) {
41064114 }
41074115 }
41084116
4109- private void removeHistoryRecordsForAppLocked (ArrayList list , ProcessRecord app ) {
4117+ private void removeHistoryRecordsForAppLocked (ArrayList list , ProcessRecord app ,
4118+ String listName ) {
41104119 int i = list .size ();
4111- if (localLOGV ) Slog .v (
4112- TAG , "Removing app " + app + " from list " + list
4120+ if (DEBUG_CLEANUP ) Slog .v (
4121+ TAG , "Removing app " + app + " from list " + listName
41134122 + " with " + i + " entries" );
41144123 while (i > 0 ) {
41154124 i --;
41164125 ActivityRecord r = (ActivityRecord )list .get (i );
4117- if (localLOGV ) Slog .v (
4118- TAG , "Record #" + i + " " + r + ": app=" + r .app );
4126+ if (DEBUG_CLEANUP ) Slog .v (TAG , "Record #" + i + " " + r );
41194127 if (r .app == app ) {
4120- if (localLOGV ) Slog .v (TAG , "Removing this entry!" );
4128+ if (DEBUG_CLEANUP ) Slog .v (TAG , "---> REMOVING this entry!" );
41214129 list .remove (i );
41224130 removeTimeoutsForActivityLocked (r );
41234131 }
41244132 }
41254133 }
41264134
4127- void removeHistoryRecordsForAppLocked (ProcessRecord app ) {
4128- removeHistoryRecordsForAppLocked (mLRUActivities , app );
4129- removeHistoryRecordsForAppLocked (mStoppingActivities , app );
4130- removeHistoryRecordsForAppLocked (mGoingToSleepActivities , app );
4131- removeHistoryRecordsForAppLocked (mWaitingVisibleActivities , app );
4132- removeHistoryRecordsForAppLocked (mFinishingActivities , app );
4135+ boolean removeHistoryRecordsForAppLocked (ProcessRecord app ) {
4136+ removeHistoryRecordsForAppLocked (mLRUActivities , app , "mLRUActivities" );
4137+ removeHistoryRecordsForAppLocked (mStoppingActivities , app , "mStoppingActivities" );
4138+ removeHistoryRecordsForAppLocked (mGoingToSleepActivities , app , "mGoingToSleepActivities" );
4139+ removeHistoryRecordsForAppLocked (mWaitingVisibleActivities , app ,
4140+ "mWaitingVisibleActivities" );
4141+ removeHistoryRecordsForAppLocked (mFinishingActivities , app , "mFinishingActivities" );
4142+
4143+ boolean hasVisibleActivities = false ;
4144+
4145+ // Clean out the history list.
4146+ int i = mHistory .size ();
4147+ if (DEBUG_CLEANUP ) Slog .v (
4148+ TAG , "Removing app " + app + " from history with " + i + " entries" );
4149+ while (i > 0 ) {
4150+ i --;
4151+ ActivityRecord r = (ActivityRecord )mHistory .get (i );
4152+ if (DEBUG_CLEANUP ) Slog .v (
4153+ TAG , "Record #" + i + " " + r + ": app=" + r .app );
4154+ if (r .app == app ) {
4155+ if ((!r .haveState && !r .stateNotNeeded ) || r .finishing ) {
4156+ if (ActivityStack .DEBUG_ADD_REMOVE || DEBUG_CLEANUP ) {
4157+ RuntimeException here = new RuntimeException ("here" );
4158+ here .fillInStackTrace ();
4159+ Slog .i (TAG , "Removing activity " + r + " from stack at " + i
4160+ + ": haveState=" + r .haveState
4161+ + " stateNotNeeded=" + r .stateNotNeeded
4162+ + " finishing=" + r .finishing
4163+ + " state=" + r .state , here );
4164+ }
4165+ if (!r .finishing ) {
4166+ Slog .w (TAG , "Force removing " + r + ": app died, no saved state" );
4167+ EventLog .writeEvent (EventLogTags .AM_FINISH_ACTIVITY ,
4168+ r .userId , System .identityHashCode (r ),
4169+ r .task .taskId , r .shortComponentName ,
4170+ "proc died without state saved" );
4171+ }
4172+ removeActivityFromHistoryLocked (r );
4173+
4174+ } else {
4175+ // We have the current state for this activity, so
4176+ // it can be restarted later when needed.
4177+ if (localLOGV ) Slog .v (
4178+ TAG , "Keeping entry, setting app to null" );
4179+ if (r .visible ) {
4180+ hasVisibleActivities = true ;
4181+ }
4182+ r .app = null ;
4183+ r .nowVisible = false ;
4184+ if (!r .haveState ) {
4185+ if (ActivityStack .DEBUG_SAVED_STATE ) Slog .i (TAG ,
4186+ "App died, clearing saved state of " + r );
4187+ r .icicle = null ;
4188+ }
4189+ }
4190+
4191+ r .stack .cleanUpActivityLocked (r , true , true );
4192+ }
4193+ }
4194+
4195+ return hasVisibleActivities ;
41334196 }
41344197
41354198 /**
@@ -4375,7 +4438,7 @@ public ActivityRecord removeTaskActivitiesLocked(int taskId, int subTaskIndex,
43754438 return null ;
43764439 }
43774440
4378- // Remove all of this task's activies starting at the sub task.
4441+ // Remove all of this task's activities starting at the sub task.
43794442 TaskAccessInfo .SubTask subtask = info .subtasks .get (subTaskIndex );
43804443 performClearTaskAtIndexLocked (taskId , subtask .index );
43814444 return subtask .activity ;
0 commit comments