Loading services/core/java/com/android/server/am/ActivityRecord.java +21 −1 Original line number Diff line number Diff line Loading @@ -1614,16 +1614,36 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo void setState(ActivityState state, String reason) { if (DEBUG_STATES) Slog.v(TAG_STATES, "State movement: " + this + " from:" + getState() + " to:" + state + " reason:" + reason); final ActivityState prev = mState; final boolean stateChanged = prev != state; mState = state; if (mState != prev) { if (stateChanged) { if (mRecentTransitions.size() == MAX_STORED_STATE_TRANSITIONS) { mRecentTransitions.remove(0); } mRecentTransitions.add(new StateTransition(prev, state, reason)); } if (stateChanged && isState(DESTROYING, DESTROYED)) { makeFinishingLocked(); // When moving to the destroyed state, immediately destroy the activity in the // associated stack. Most paths for finishing an activity will handle an activity's path // to destroy through mechanisms such as ActivityStackSupervisor#mFinishingActivities. // However, moving to the destroyed state directly (as in the case of an app dying) and // marking it as finished will lead to cleanup steps that will prevent later handling // from happening. if (isState(DESTROYED)) { final ActivityStack stack = getStack(); if (stack != null) { stack.activityDestroyedLocked(this, reason); } } } } ActivityState getState() { Loading services/core/java/com/android/server/am/ActivityStack.java +18 −5 Original line number Diff line number Diff line Loading @@ -4000,16 +4000,26 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai * state to destroy so only the cleanup here is needed. * * Note: Call before #removeActivityFromHistoryLocked. * * @param r The {@link ActivityRecord} to cleanup. * @param cleanServices Whether services bound to the {@link ActivityRecord} should also be * cleaned up. * @param destroy Whether the {@link ActivityRecord} should be destroyed. * @param clearProcess Whether the client process should be cleared. */ private void cleanUpActivityLocked(ActivityRecord r, boolean cleanServices, boolean setState) { private void cleanUpActivityLocked(ActivityRecord r, boolean cleanServices, boolean destroy, boolean clearProcess) { onActivityRemovedFromStack(r); r.deferRelaunchUntilPaused = false; r.frozenBeforeDestroy = false; if (setState) { if (destroy) { if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to DESTROYED: " + r + " (cleaning up)"); r.setState(DESTROYED, "cleanupActivityLocked"); } if (clearProcess) { if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during cleanUp for activity " + r); r.app = null; } Loading Loading @@ -4228,7 +4238,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai boolean removedFromHistory = false; cleanUpActivityLocked(r, false, false); cleanUpActivityLocked(r, false /* cleanServices */, false /* destroy */, false /*clearProcess*/); final boolean hadApp = r.app != null; Loading Loading @@ -4334,7 +4345,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai if (isInStackLocked(record) != null) { if (record.isState(DESTROYING, DESTROYED)) { cleanUpActivityLocked(record, true, false); cleanUpActivityLocked(record, true /* cleanServices */, false /* destroy */, false /*clearProcess*/); removeActivityFromHistoryLocked(record, reason); } } Loading Loading @@ -4439,7 +4451,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai r.icicle = null; } } cleanUpActivityLocked(r, true, true); cleanUpActivityLocked(r, true /* cleanServices */, remove /* destroy */, true /*clearProcess*/); if (remove) { removeActivityFromHistoryLocked(r, "appDied"); } Loading services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java +16 −0 Original line number Diff line number Diff line Loading @@ -202,4 +202,20 @@ public class ActivityRecordTests extends ActivityTestsBase { verify(mService.mStackSupervisor, times(1)).canPlaceEntityOnDisplay(anyInt(), eq(expected), anyInt(), anyInt(), eq(record.info)); } @Test public void testFinishingAfterDestroying() throws Exception { assertFalse(mActivity.finishing); mActivity.setState(DESTROYING, "testFinishingAfterDestroying"); assertTrue(mActivity.isState(DESTROYING)); assertTrue(mActivity.finishing); } @Test public void testFinishingAfterDestroyed() throws Exception { assertFalse(mActivity.finishing); mActivity.setState(DESTROYED, "testFinishingAfterDestroyed"); assertTrue(mActivity.isState(DESTROYED)); assertTrue(mActivity.finishing); } } Loading
services/core/java/com/android/server/am/ActivityRecord.java +21 −1 Original line number Diff line number Diff line Loading @@ -1614,16 +1614,36 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo void setState(ActivityState state, String reason) { if (DEBUG_STATES) Slog.v(TAG_STATES, "State movement: " + this + " from:" + getState() + " to:" + state + " reason:" + reason); final ActivityState prev = mState; final boolean stateChanged = prev != state; mState = state; if (mState != prev) { if (stateChanged) { if (mRecentTransitions.size() == MAX_STORED_STATE_TRANSITIONS) { mRecentTransitions.remove(0); } mRecentTransitions.add(new StateTransition(prev, state, reason)); } if (stateChanged && isState(DESTROYING, DESTROYED)) { makeFinishingLocked(); // When moving to the destroyed state, immediately destroy the activity in the // associated stack. Most paths for finishing an activity will handle an activity's path // to destroy through mechanisms such as ActivityStackSupervisor#mFinishingActivities. // However, moving to the destroyed state directly (as in the case of an app dying) and // marking it as finished will lead to cleanup steps that will prevent later handling // from happening. if (isState(DESTROYED)) { final ActivityStack stack = getStack(); if (stack != null) { stack.activityDestroyedLocked(this, reason); } } } } ActivityState getState() { Loading
services/core/java/com/android/server/am/ActivityStack.java +18 −5 Original line number Diff line number Diff line Loading @@ -4000,16 +4000,26 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai * state to destroy so only the cleanup here is needed. * * Note: Call before #removeActivityFromHistoryLocked. * * @param r The {@link ActivityRecord} to cleanup. * @param cleanServices Whether services bound to the {@link ActivityRecord} should also be * cleaned up. * @param destroy Whether the {@link ActivityRecord} should be destroyed. * @param clearProcess Whether the client process should be cleared. */ private void cleanUpActivityLocked(ActivityRecord r, boolean cleanServices, boolean setState) { private void cleanUpActivityLocked(ActivityRecord r, boolean cleanServices, boolean destroy, boolean clearProcess) { onActivityRemovedFromStack(r); r.deferRelaunchUntilPaused = false; r.frozenBeforeDestroy = false; if (setState) { if (destroy) { if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to DESTROYED: " + r + " (cleaning up)"); r.setState(DESTROYED, "cleanupActivityLocked"); } if (clearProcess) { if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during cleanUp for activity " + r); r.app = null; } Loading Loading @@ -4228,7 +4238,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai boolean removedFromHistory = false; cleanUpActivityLocked(r, false, false); cleanUpActivityLocked(r, false /* cleanServices */, false /* destroy */, false /*clearProcess*/); final boolean hadApp = r.app != null; Loading Loading @@ -4334,7 +4345,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai if (isInStackLocked(record) != null) { if (record.isState(DESTROYING, DESTROYED)) { cleanUpActivityLocked(record, true, false); cleanUpActivityLocked(record, true /* cleanServices */, false /* destroy */, false /*clearProcess*/); removeActivityFromHistoryLocked(record, reason); } } Loading Loading @@ -4439,7 +4451,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai r.icicle = null; } } cleanUpActivityLocked(r, true, true); cleanUpActivityLocked(r, true /* cleanServices */, remove /* destroy */, true /*clearProcess*/); if (remove) { removeActivityFromHistoryLocked(r, "appDied"); } Loading
services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java +16 −0 Original line number Diff line number Diff line Loading @@ -202,4 +202,20 @@ public class ActivityRecordTests extends ActivityTestsBase { verify(mService.mStackSupervisor, times(1)).canPlaceEntityOnDisplay(anyInt(), eq(expected), anyInt(), anyInt(), eq(record.info)); } @Test public void testFinishingAfterDestroying() throws Exception { assertFalse(mActivity.finishing); mActivity.setState(DESTROYING, "testFinishingAfterDestroying"); assertTrue(mActivity.isState(DESTROYING)); assertTrue(mActivity.finishing); } @Test public void testFinishingAfterDestroyed() throws Exception { assertFalse(mActivity.finishing); mActivity.setState(DESTROYED, "testFinishingAfterDestroyed"); assertTrue(mActivity.isState(DESTROYED)); assertTrue(mActivity.finishing); } }