Loading services/core/java/com/android/server/wm/ActivityRecord.java +69 −4 Original line number Diff line number Diff line Loading @@ -2865,7 +2865,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (hasProcess()) { if (removeFromApp) { app.removeActivity(this); app.removeActivity(this, true /* keepAssociation */); if (!app.hasActivities()) { mAtmService.clearHeavyWeightProcessIfEquals(app); // Update any services we are bound to that might care about whether Loading Loading @@ -2914,7 +2914,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A setState(DESTROYED, "destroyActivityLocked. not finishing or skipping destroy"); if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during destroy for activity " + this); app = null; detachFromProcess(); } } else { // Remove this record from the history. Loading Loading @@ -2963,13 +2963,20 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } setState(DESTROYED, "removeFromHistory"); if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during remove for activity " + this); app = null; detachFromProcess(); removeAppTokenFromDisplay(); cleanUpActivityServices(); removeUriPermissionsLocked(); } void detachFromProcess() { if (app != null) { app.removeActivity(this, false /* keepAssociation */); } app = null; } void makeFinishingLocked() { if (finishing) { return; Loading Loading @@ -3019,7 +3026,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (setState) { setState(DESTROYED, "cleanUp"); if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during cleanUp for activity " + this); app = null; detachFromProcess(); } // Inform supervisor the activity has been removed. Loading Loading @@ -3160,6 +3167,64 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mServiceConnectionsHolder = null; } /** * Detach this activity from process and clear the references to it. If the activity is * finishing or has no saved state or crashed many times, it will also be removed from history. */ void handleAppDied() { final boolean remove; if ((mRelaunchReason == RELAUNCH_REASON_WINDOWING_MODE_RESIZE || mRelaunchReason == RELAUNCH_REASON_FREE_RESIZE) && launchCount < 3 && !finishing) { // If the process crashed during a resize, always try to relaunch it, unless it has // failed more than twice. Skip activities that's already finishing cleanly by itself. remove = false; } else if ((!mHaveState && !stateNotNeeded && !isState(ActivityState.RESTARTING_PROCESS)) || finishing) { // Don't currently have state for the activity, or it is finishing -- always remove it. remove = true; } else if (!mVisibleRequested && launchCount > 2 && lastLaunchTime > (SystemClock.uptimeMillis() - 60000)) { // We have launched this activity too many times since it was able to run, so give up // and remove it. (Note if the activity is visible, we don't remove the record. We leave // the dead window on the screen but the process will not be restarted unless user // explicitly tap on it.) remove = true; } else { // The process may be gone, but the activity lives on! remove = false; } if (remove) { if (ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE || DEBUG_CLEANUP) { Slog.i(TAG_ADD_REMOVE, "Removing activity " + this + " hasSavedState=" + mHaveState + " stateNotNeeded=" + stateNotNeeded + " finishing=" + finishing + " state=" + mState + " callers=" + Debug.getCallers(5)); } if (!finishing || (app != null && app.isRemoved())) { Slog.w(TAG, "Force removing " + this + ": app died, no saved state"); EventLogTags.writeWmFinishActivity(mUserId, System.identityHashCode(this), task != null ? task.mTaskId : -1, shortComponentName, "proc died without state saved"); } } else { // We have the current state for this activity, so it can be restarted later // when needed. if (DEBUG_APP) { Slog.v(TAG_APP, "Keeping entry during removeHistory for activity " + this); } // Set nowVisible to previous visible state. If the app was visible while it died, we // leave the dead window on screen so it's basically visible. This is needed when user // later tap on the dead window, we need to stop other apps when user transfers focus // to the restarted activity. nowVisible = mVisibleRequested; } cleanUp(true /* cleanServices */, true /* setState */); if (remove) { removeFromHistory("appDied"); } } @Override void removeImmediately() { onRemovedFromDisplay(); Loading services/core/java/com/android/server/wm/ActivityStackSupervisor.java +1 −1 Original line number Diff line number Diff line Loading @@ -891,7 +891,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { // This is the first time we failed -- restart process and // retry. r.launchFailed = true; proc.removeActivity(r); proc.removeActivity(r, true /* keepAssociation */); throw e; } } finally { Loading services/core/java/com/android/server/wm/ActivityTaskManagerService.java +8 −5 Original line number Diff line number Diff line Loading @@ -6789,11 +6789,14 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { public void handleAppDied(WindowProcessController wpc, boolean restarting, Runnable finishInstrumentationCallback) { synchronized (mGlobalLockWithoutBoost) { mStackSupervisor.beginDeferResume(); final boolean hasVisibleActivities; try { // Remove this application's activities from active lists. boolean hasVisibleActivities = mRootWindowContainer.handleAppDied(wpc); wpc.clearRecentTasks(); wpc.clearActivities(); hasVisibleActivities = wpc.handleAppDied(); } finally { mStackSupervisor.endDeferResume(); } if (wpc.isInstrumenting()) { finishInstrumentationCallback.run(); Loading services/core/java/com/android/server/wm/RootWindowContainer.java +1 −17 Original line number Diff line number Diff line Loading @@ -2751,7 +2751,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> if (r.app != app) return; Slog.w(TAG, " Force finishing activity " + r.intent.getComponent().flattenToShortString()); r.app = null; r.detachFromProcess(); r.getDisplay().mDisplayContent.prepareAppTransition( TRANSIT_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */); r.destroyIfPossible("handleAppCrashed"); Loading Loading @@ -3104,22 +3104,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent> return null; } boolean handleAppDied(WindowProcessController app) { if (app.isRemoved()) { // The package of the died process should be force-stopped, so make its activities as // finishing to prevent the process from being started again if the next top (or being // visible) activity also resides in the same process. app.makeFinishingForProcessRemoved(); } return reduceOnAllTaskDisplayAreas((taskDisplayArea, result) -> { for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { final Task stack = taskDisplayArea.getStackAt(sNdx); result |= stack.handleAppDied(app); } return result; }, false /* initValue */); } void closeSystemDialogActivities(String reason) { forAllActivities((r) -> { if ((r.info.flags & ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0 Loading services/core/java/com/android/server/wm/Task.java +1 −114 Original line number Diff line number Diff line Loading @@ -86,8 +86,6 @@ import static com.android.server.wm.ActivityStackSupervisor.REMOVE_FROM_RECENTS; import static com.android.server.wm.ActivityStackSupervisor.dumpHistoryList; import static com.android.server.wm.ActivityStackSupervisor.printThisActivity; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_APP; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PAUSE; Loading Loading @@ -115,8 +113,6 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_VISIB import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.ActivityTaskManagerService.H.FIRST_ACTIVITY_STACK_MSG; import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE; import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE; import static com.android.server.wm.IdentifierProto.HASH_CODE; import static com.android.server.wm.IdentifierProto.TITLE; import static com.android.server.wm.IdentifierProto.USER_ID; Loading Loading @@ -746,111 +742,6 @@ class Task extends WindowContainer<WindowContainer> { } } // TODO: Can we just loop through WindowProcessController#mActivities instead of doing this? private final RemoveHistoryRecordsForApp mRemoveHistoryRecordsForApp = new RemoveHistoryRecordsForApp(); private class RemoveHistoryRecordsForApp { private boolean mHasVisibleActivities; private boolean mIsProcessRemoved; private WindowProcessController mApp; private ArrayList<ActivityRecord> mToRemove = new ArrayList<>(); boolean process(WindowProcessController app) { mToRemove.clear(); mHasVisibleActivities = false; mApp = app; mIsProcessRemoved = app.isRemoved(); final PooledConsumer c = PooledLambda.obtainConsumer( RemoveHistoryRecordsForApp::addActivityToRemove, this, PooledLambda.__(ActivityRecord.class)); forAllActivities(c); c.recycle(); while (!mToRemove.isEmpty()) { processActivity(mToRemove.remove(0)); } mApp = null; return mHasVisibleActivities; } private void addActivityToRemove(ActivityRecord r) { if (r.app == mApp) { mToRemove.add(r); } } private void processActivity(ActivityRecord r) { if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, "Record " + r + ": app=" + r.app); if (r.app != mApp) { return; } if (r.isVisible() || r.mVisibleRequested) { // While an activity launches a new activity, it's possible that the old // activity is already requested to be hidden (mVisibleRequested=false), but // this visibility is not yet committed, so isVisible()=true. mHasVisibleActivities = true; } final boolean remove; if ((r.mRelaunchReason == RELAUNCH_REASON_WINDOWING_MODE_RESIZE || r.mRelaunchReason == RELAUNCH_REASON_FREE_RESIZE) && r.launchCount < 3 && !r.finishing) { // If the process crashed during a resize, always try to relaunch it, unless // it has failed more than twice. Skip activities that's already finishing // cleanly by itself. remove = false; } else if ((!r.hasSavedState() && !r.stateNotNeeded && !r.isState(ActivityState.RESTARTING_PROCESS)) || r.finishing) { // Don't currently have state for the activity, or // it is finishing -- always remove it. remove = true; } else if (!r.mVisibleRequested && r.launchCount > 2 && r.lastLaunchTime > (SystemClock.uptimeMillis() - 60000)) { // We have launched this activity too many times since it was // able to run, so give up and remove it. // (Note if the activity is visible, we don't remove the record. // We leave the dead window on the screen but the process will // not be restarted unless user explicitly tap on it.) remove = true; } else { // The process may be gone, but the activity lives on! remove = false; } if (remove) { if (DEBUG_ADD_REMOVE || DEBUG_CLEANUP) Slog.i(TAG_ADD_REMOVE, "Removing activity " + r + " from stack " + ": hasSavedState=" + r.hasSavedState() + " stateNotNeeded=" + r.stateNotNeeded + " finishing=" + r.finishing + " state=" + r.getState() + " callers=" + Debug.getCallers(5)); if (!r.finishing || mIsProcessRemoved) { Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); EventLogTags.writeWmFinishActivity(r.mUserId, System.identityHashCode(r), r.getTask().mTaskId, r.shortComponentName, "proc died without state saved"); } } else { // We have the current state for this activity, so // it can be restarted later when needed. if (DEBUG_ALL) Slog.v(TAG, "Keeping entry, setting app to null"); if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during removeHistory for activity " + r); r.app = null; // Set nowVisible to previous visible state. If the app was visible while // it died, we leave the dead window on screen so it's basically visible. // This is needed when user later tap on the dead window, we need to stop // other apps when user transfers focus to the restarted activity. r.nowVisible = r.mVisibleRequested; } r.cleanUp(true /* cleanServices */, true /* setState */); if (remove) { r.removeFromHistory("appDied"); } } } private final FindRootHelper mFindRootHelper = new FindRootHelper(); private class FindRootHelper { private ActivityRecord mRoot; Loading Loading @@ -7167,9 +7058,8 @@ class Task extends WindowContainer<WindowContainer> { /** * Reset local parameters because an app's activity died. * @param app The app of the activity that died. * @return result from removeHistoryRecordsForAppLocked. */ boolean handleAppDied(WindowProcessController app) { void handleAppDied(WindowProcessController app) { if (mPausingActivity != null && mPausingActivity.app == app) { if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG_PAUSE, "App died while pausing: " + mPausingActivity); Loading @@ -7179,9 +7069,6 @@ class Task extends WindowContainer<WindowContainer> { mLastPausedActivity = null; mLastNoHistoryActivity = null; } mStackSupervisor.removeHistoryRecords(app); return mRemoveHistoryRecordsForApp.process(app); } boolean dump(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient, Loading Loading
services/core/java/com/android/server/wm/ActivityRecord.java +69 −4 Original line number Diff line number Diff line Loading @@ -2865,7 +2865,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (hasProcess()) { if (removeFromApp) { app.removeActivity(this); app.removeActivity(this, true /* keepAssociation */); if (!app.hasActivities()) { mAtmService.clearHeavyWeightProcessIfEquals(app); // Update any services we are bound to that might care about whether Loading Loading @@ -2914,7 +2914,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A setState(DESTROYED, "destroyActivityLocked. not finishing or skipping destroy"); if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during destroy for activity " + this); app = null; detachFromProcess(); } } else { // Remove this record from the history. Loading Loading @@ -2963,13 +2963,20 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } setState(DESTROYED, "removeFromHistory"); if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during remove for activity " + this); app = null; detachFromProcess(); removeAppTokenFromDisplay(); cleanUpActivityServices(); removeUriPermissionsLocked(); } void detachFromProcess() { if (app != null) { app.removeActivity(this, false /* keepAssociation */); } app = null; } void makeFinishingLocked() { if (finishing) { return; Loading Loading @@ -3019,7 +3026,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (setState) { setState(DESTROYED, "cleanUp"); if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during cleanUp for activity " + this); app = null; detachFromProcess(); } // Inform supervisor the activity has been removed. Loading Loading @@ -3160,6 +3167,64 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mServiceConnectionsHolder = null; } /** * Detach this activity from process and clear the references to it. If the activity is * finishing or has no saved state or crashed many times, it will also be removed from history. */ void handleAppDied() { final boolean remove; if ((mRelaunchReason == RELAUNCH_REASON_WINDOWING_MODE_RESIZE || mRelaunchReason == RELAUNCH_REASON_FREE_RESIZE) && launchCount < 3 && !finishing) { // If the process crashed during a resize, always try to relaunch it, unless it has // failed more than twice. Skip activities that's already finishing cleanly by itself. remove = false; } else if ((!mHaveState && !stateNotNeeded && !isState(ActivityState.RESTARTING_PROCESS)) || finishing) { // Don't currently have state for the activity, or it is finishing -- always remove it. remove = true; } else if (!mVisibleRequested && launchCount > 2 && lastLaunchTime > (SystemClock.uptimeMillis() - 60000)) { // We have launched this activity too many times since it was able to run, so give up // and remove it. (Note if the activity is visible, we don't remove the record. We leave // the dead window on the screen but the process will not be restarted unless user // explicitly tap on it.) remove = true; } else { // The process may be gone, but the activity lives on! remove = false; } if (remove) { if (ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE || DEBUG_CLEANUP) { Slog.i(TAG_ADD_REMOVE, "Removing activity " + this + " hasSavedState=" + mHaveState + " stateNotNeeded=" + stateNotNeeded + " finishing=" + finishing + " state=" + mState + " callers=" + Debug.getCallers(5)); } if (!finishing || (app != null && app.isRemoved())) { Slog.w(TAG, "Force removing " + this + ": app died, no saved state"); EventLogTags.writeWmFinishActivity(mUserId, System.identityHashCode(this), task != null ? task.mTaskId : -1, shortComponentName, "proc died without state saved"); } } else { // We have the current state for this activity, so it can be restarted later // when needed. if (DEBUG_APP) { Slog.v(TAG_APP, "Keeping entry during removeHistory for activity " + this); } // Set nowVisible to previous visible state. If the app was visible while it died, we // leave the dead window on screen so it's basically visible. This is needed when user // later tap on the dead window, we need to stop other apps when user transfers focus // to the restarted activity. nowVisible = mVisibleRequested; } cleanUp(true /* cleanServices */, true /* setState */); if (remove) { removeFromHistory("appDied"); } } @Override void removeImmediately() { onRemovedFromDisplay(); Loading
services/core/java/com/android/server/wm/ActivityStackSupervisor.java +1 −1 Original line number Diff line number Diff line Loading @@ -891,7 +891,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { // This is the first time we failed -- restart process and // retry. r.launchFailed = true; proc.removeActivity(r); proc.removeActivity(r, true /* keepAssociation */); throw e; } } finally { Loading
services/core/java/com/android/server/wm/ActivityTaskManagerService.java +8 −5 Original line number Diff line number Diff line Loading @@ -6789,11 +6789,14 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { public void handleAppDied(WindowProcessController wpc, boolean restarting, Runnable finishInstrumentationCallback) { synchronized (mGlobalLockWithoutBoost) { mStackSupervisor.beginDeferResume(); final boolean hasVisibleActivities; try { // Remove this application's activities from active lists. boolean hasVisibleActivities = mRootWindowContainer.handleAppDied(wpc); wpc.clearRecentTasks(); wpc.clearActivities(); hasVisibleActivities = wpc.handleAppDied(); } finally { mStackSupervisor.endDeferResume(); } if (wpc.isInstrumenting()) { finishInstrumentationCallback.run(); Loading
services/core/java/com/android/server/wm/RootWindowContainer.java +1 −17 Original line number Diff line number Diff line Loading @@ -2751,7 +2751,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> if (r.app != app) return; Slog.w(TAG, " Force finishing activity " + r.intent.getComponent().flattenToShortString()); r.app = null; r.detachFromProcess(); r.getDisplay().mDisplayContent.prepareAppTransition( TRANSIT_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */); r.destroyIfPossible("handleAppCrashed"); Loading Loading @@ -3104,22 +3104,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent> return null; } boolean handleAppDied(WindowProcessController app) { if (app.isRemoved()) { // The package of the died process should be force-stopped, so make its activities as // finishing to prevent the process from being started again if the next top (or being // visible) activity also resides in the same process. app.makeFinishingForProcessRemoved(); } return reduceOnAllTaskDisplayAreas((taskDisplayArea, result) -> { for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { final Task stack = taskDisplayArea.getStackAt(sNdx); result |= stack.handleAppDied(app); } return result; }, false /* initValue */); } void closeSystemDialogActivities(String reason) { forAllActivities((r) -> { if ((r.info.flags & ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0 Loading
services/core/java/com/android/server/wm/Task.java +1 −114 Original line number Diff line number Diff line Loading @@ -86,8 +86,6 @@ import static com.android.server.wm.ActivityStackSupervisor.REMOVE_FROM_RECENTS; import static com.android.server.wm.ActivityStackSupervisor.dumpHistoryList; import static com.android.server.wm.ActivityStackSupervisor.printThisActivity; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_APP; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PAUSE; Loading Loading @@ -115,8 +113,6 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_VISIB import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.ActivityTaskManagerService.H.FIRST_ACTIVITY_STACK_MSG; import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE; import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE; import static com.android.server.wm.IdentifierProto.HASH_CODE; import static com.android.server.wm.IdentifierProto.TITLE; import static com.android.server.wm.IdentifierProto.USER_ID; Loading Loading @@ -746,111 +742,6 @@ class Task extends WindowContainer<WindowContainer> { } } // TODO: Can we just loop through WindowProcessController#mActivities instead of doing this? private final RemoveHistoryRecordsForApp mRemoveHistoryRecordsForApp = new RemoveHistoryRecordsForApp(); private class RemoveHistoryRecordsForApp { private boolean mHasVisibleActivities; private boolean mIsProcessRemoved; private WindowProcessController mApp; private ArrayList<ActivityRecord> mToRemove = new ArrayList<>(); boolean process(WindowProcessController app) { mToRemove.clear(); mHasVisibleActivities = false; mApp = app; mIsProcessRemoved = app.isRemoved(); final PooledConsumer c = PooledLambda.obtainConsumer( RemoveHistoryRecordsForApp::addActivityToRemove, this, PooledLambda.__(ActivityRecord.class)); forAllActivities(c); c.recycle(); while (!mToRemove.isEmpty()) { processActivity(mToRemove.remove(0)); } mApp = null; return mHasVisibleActivities; } private void addActivityToRemove(ActivityRecord r) { if (r.app == mApp) { mToRemove.add(r); } } private void processActivity(ActivityRecord r) { if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, "Record " + r + ": app=" + r.app); if (r.app != mApp) { return; } if (r.isVisible() || r.mVisibleRequested) { // While an activity launches a new activity, it's possible that the old // activity is already requested to be hidden (mVisibleRequested=false), but // this visibility is not yet committed, so isVisible()=true. mHasVisibleActivities = true; } final boolean remove; if ((r.mRelaunchReason == RELAUNCH_REASON_WINDOWING_MODE_RESIZE || r.mRelaunchReason == RELAUNCH_REASON_FREE_RESIZE) && r.launchCount < 3 && !r.finishing) { // If the process crashed during a resize, always try to relaunch it, unless // it has failed more than twice. Skip activities that's already finishing // cleanly by itself. remove = false; } else if ((!r.hasSavedState() && !r.stateNotNeeded && !r.isState(ActivityState.RESTARTING_PROCESS)) || r.finishing) { // Don't currently have state for the activity, or // it is finishing -- always remove it. remove = true; } else if (!r.mVisibleRequested && r.launchCount > 2 && r.lastLaunchTime > (SystemClock.uptimeMillis() - 60000)) { // We have launched this activity too many times since it was // able to run, so give up and remove it. // (Note if the activity is visible, we don't remove the record. // We leave the dead window on the screen but the process will // not be restarted unless user explicitly tap on it.) remove = true; } else { // The process may be gone, but the activity lives on! remove = false; } if (remove) { if (DEBUG_ADD_REMOVE || DEBUG_CLEANUP) Slog.i(TAG_ADD_REMOVE, "Removing activity " + r + " from stack " + ": hasSavedState=" + r.hasSavedState() + " stateNotNeeded=" + r.stateNotNeeded + " finishing=" + r.finishing + " state=" + r.getState() + " callers=" + Debug.getCallers(5)); if (!r.finishing || mIsProcessRemoved) { Slog.w(TAG, "Force removing " + r + ": app died, no saved state"); EventLogTags.writeWmFinishActivity(r.mUserId, System.identityHashCode(r), r.getTask().mTaskId, r.shortComponentName, "proc died without state saved"); } } else { // We have the current state for this activity, so // it can be restarted later when needed. if (DEBUG_ALL) Slog.v(TAG, "Keeping entry, setting app to null"); if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during removeHistory for activity " + r); r.app = null; // Set nowVisible to previous visible state. If the app was visible while // it died, we leave the dead window on screen so it's basically visible. // This is needed when user later tap on the dead window, we need to stop // other apps when user transfers focus to the restarted activity. r.nowVisible = r.mVisibleRequested; } r.cleanUp(true /* cleanServices */, true /* setState */); if (remove) { r.removeFromHistory("appDied"); } } } private final FindRootHelper mFindRootHelper = new FindRootHelper(); private class FindRootHelper { private ActivityRecord mRoot; Loading Loading @@ -7167,9 +7058,8 @@ class Task extends WindowContainer<WindowContainer> { /** * Reset local parameters because an app's activity died. * @param app The app of the activity that died. * @return result from removeHistoryRecordsForAppLocked. */ boolean handleAppDied(WindowProcessController app) { void handleAppDied(WindowProcessController app) { if (mPausingActivity != null && mPausingActivity.app == app) { if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG_PAUSE, "App died while pausing: " + mPausingActivity); Loading @@ -7179,9 +7069,6 @@ class Task extends WindowContainer<WindowContainer> { mLastPausedActivity = null; mLastNoHistoryActivity = null; } mStackSupervisor.removeHistoryRecords(app); return mRemoveHistoryRecordsForApp.process(app); } boolean dump(FileDescriptor fd, PrintWriter pw, boolean dumpAll, boolean dumpClient, Loading