Loading core/java/android/app/servertransaction/TransactionExecutor.java +4 −1 Original line number Diff line number Diff line Loading @@ -147,7 +147,10 @@ public class TransactionExecutor { pw.println("Executor:"); dump(pw, prefix); Slog.wtf(TAG, stringWriter.toString()); Slog.w(TAG, stringWriter.toString()); // Ignore requests for non-existent client records for now. return; } // Cycle to the state right before the final requested state. Loading services/core/java/com/android/server/am/ActivityRecord.java +0 −23 Original line number Diff line number Diff line Loading @@ -1621,12 +1621,6 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo return; } if (isState(DESTROYED) || (state != DESTROYED && isState(DESTROYING))) { // We cannot move backwards from destroyed and destroying states. throw new IllegalArgumentException("cannot move back states once destroying" + "current:" + mState + " requested:" + state); } final ActivityState prev = mState; mState = state; Loading @@ -1641,23 +1635,6 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo if (parent != null) { parent.onActivityStateChanged(this, state, reason); } if (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 +10 −27 Original line number Diff line number Diff line Loading @@ -3811,14 +3811,6 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai final ActivityState prevState = r.getState(); if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to FINISHING: " + r); // We are already destroying / have already destroyed the activity. Do not continue to // modify it. Note that we do not use ActivityRecord#finishing here as finishing is not // indicative of destruction (though destruction is indicative of finishing) as finishing // can be delayed below. if (r.isState(DESTROYING, DESTROYED)) { return null; } r.setState(FINISHING, "finishCurrentActivityLocked"); final boolean finishingActivityInNonFocusedStack = r.getStack() != mStackSupervisor.getFocusedStack() Loading Loading @@ -4037,26 +4029,16 @@ 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 destroy, boolean clearProcess) { private void cleanUpActivityLocked(ActivityRecord r, boolean cleanServices, boolean setState) { onActivityRemovedFromStack(r); r.deferRelaunchUntilPaused = false; r.frozenBeforeDestroy = false; if (destroy) { if (setState) { 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 @@ -4271,7 +4253,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai + ", app=" + (r.app != null ? r.app.processName : "(null)")); if (r.isState(DESTROYING, DESTROYED)) { if (DEBUG_STATES) Slog.v(TAG_STATES, "activity " + r + " already finishing." if (DEBUG_STATES) Slog.v(TAG_STATES, "activity " + r + " already destroying." + "skipping request with reason:" + reason); return false; } Loading @@ -4282,8 +4264,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai boolean removedFromHistory = false; cleanUpActivityLocked(r, false /* cleanServices */, false /* destroy */, false /*clearProcess*/); cleanUpActivityLocked(r, false, false); final boolean hadApp = r.app != null; Loading Loading @@ -4380,6 +4361,10 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } } /** * This method is to only be called from the client via binder when the activity is destroyed * AND finished. */ final void activityDestroyedLocked(ActivityRecord record, String reason) { if (record != null) { mHandler.removeMessages(DESTROY_TIMEOUT_MSG, record); Loading @@ -4389,8 +4374,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai if (isInStackLocked(record) != null) { if (record.isState(DESTROYING, DESTROYED)) { cleanUpActivityLocked(record, true /* cleanServices */, false /* destroy */, false /*clearProcess*/); cleanUpActivityLocked(record, true, false); removeActivityFromHistoryLocked(record, reason); } } Loading Loading @@ -4499,8 +4483,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai r.icicle = null; } } cleanUpActivityLocked(r, true /* cleanServices */, remove /* destroy */, true /*clearProcess*/); cleanUpActivityLocked(r, true, true); if (remove) { removeActivityFromHistoryLocked(r, "appDied"); } Loading services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java +0 −31 Original line number Diff line number Diff line Loading @@ -222,35 +222,4 @@ 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); } @Test public void testSetInvalidState() throws Exception { mActivity.setState(DESTROYED, "testInvalidState"); boolean exceptionEncountered = false; try { mActivity.setState(FINISHING, "testInvalidState"); } catch (IllegalArgumentException e) { exceptionEncountered = true; } assertTrue(exceptionEncountered); } } services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java +0 −22 Original line number Diff line number Diff line Loading @@ -478,28 +478,6 @@ public class ActivityStackTests extends ActivityTestsBase { return stack; } @Test public void testSuppressMultipleDestroy() throws Exception { final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build(); final ClientLifecycleManager lifecycleManager = mock(ClientLifecycleManager.class); final ProcessRecord app = r.app; // The mocked lifecycle manager must be set on the ActivityStackSupervisor's reference to // the service rather than mService as mService is a spy and setting the value will not // propagate as ActivityManagerService hands its own reference to the // ActivityStackSupervisor during construction. ((TestActivityManagerService) mSupervisor.mService).setLifecycleManager(lifecycleManager); mStack.destroyActivityLocked(r, true, "first invocation"); verify(lifecycleManager, times(1)).scheduleTransaction(eq(app.thread), eq(r.appToken), any(DestroyActivityItem.class)); assertTrue(r.isState(DESTROYED, DESTROYING)); mStack.destroyActivityLocked(r, true, "second invocation"); verify(lifecycleManager, times(1)).scheduleTransaction(eq(app.thread), eq(r.appToken), any(DestroyActivityItem.class)); } @Test public void testFinishDisabledPackageActivities() throws Exception { final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build(); Loading Loading
core/java/android/app/servertransaction/TransactionExecutor.java +4 −1 Original line number Diff line number Diff line Loading @@ -147,7 +147,10 @@ public class TransactionExecutor { pw.println("Executor:"); dump(pw, prefix); Slog.wtf(TAG, stringWriter.toString()); Slog.w(TAG, stringWriter.toString()); // Ignore requests for non-existent client records for now. return; } // Cycle to the state right before the final requested state. Loading
services/core/java/com/android/server/am/ActivityRecord.java +0 −23 Original line number Diff line number Diff line Loading @@ -1621,12 +1621,6 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo return; } if (isState(DESTROYED) || (state != DESTROYED && isState(DESTROYING))) { // We cannot move backwards from destroyed and destroying states. throw new IllegalArgumentException("cannot move back states once destroying" + "current:" + mState + " requested:" + state); } final ActivityState prev = mState; mState = state; Loading @@ -1641,23 +1635,6 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo if (parent != null) { parent.onActivityStateChanged(this, state, reason); } if (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 +10 −27 Original line number Diff line number Diff line Loading @@ -3811,14 +3811,6 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai final ActivityState prevState = r.getState(); if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to FINISHING: " + r); // We are already destroying / have already destroyed the activity. Do not continue to // modify it. Note that we do not use ActivityRecord#finishing here as finishing is not // indicative of destruction (though destruction is indicative of finishing) as finishing // can be delayed below. if (r.isState(DESTROYING, DESTROYED)) { return null; } r.setState(FINISHING, "finishCurrentActivityLocked"); final boolean finishingActivityInNonFocusedStack = r.getStack() != mStackSupervisor.getFocusedStack() Loading Loading @@ -4037,26 +4029,16 @@ 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 destroy, boolean clearProcess) { private void cleanUpActivityLocked(ActivityRecord r, boolean cleanServices, boolean setState) { onActivityRemovedFromStack(r); r.deferRelaunchUntilPaused = false; r.frozenBeforeDestroy = false; if (destroy) { if (setState) { 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 @@ -4271,7 +4253,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai + ", app=" + (r.app != null ? r.app.processName : "(null)")); if (r.isState(DESTROYING, DESTROYED)) { if (DEBUG_STATES) Slog.v(TAG_STATES, "activity " + r + " already finishing." if (DEBUG_STATES) Slog.v(TAG_STATES, "activity " + r + " already destroying." + "skipping request with reason:" + reason); return false; } Loading @@ -4282,8 +4264,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai boolean removedFromHistory = false; cleanUpActivityLocked(r, false /* cleanServices */, false /* destroy */, false /*clearProcess*/); cleanUpActivityLocked(r, false, false); final boolean hadApp = r.app != null; Loading Loading @@ -4380,6 +4361,10 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } } /** * This method is to only be called from the client via binder when the activity is destroyed * AND finished. */ final void activityDestroyedLocked(ActivityRecord record, String reason) { if (record != null) { mHandler.removeMessages(DESTROY_TIMEOUT_MSG, record); Loading @@ -4389,8 +4374,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai if (isInStackLocked(record) != null) { if (record.isState(DESTROYING, DESTROYED)) { cleanUpActivityLocked(record, true /* cleanServices */, false /* destroy */, false /*clearProcess*/); cleanUpActivityLocked(record, true, false); removeActivityFromHistoryLocked(record, reason); } } Loading Loading @@ -4499,8 +4483,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai r.icicle = null; } } cleanUpActivityLocked(r, true /* cleanServices */, remove /* destroy */, true /*clearProcess*/); cleanUpActivityLocked(r, true, true); if (remove) { removeActivityFromHistoryLocked(r, "appDied"); } Loading
services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java +0 −31 Original line number Diff line number Diff line Loading @@ -222,35 +222,4 @@ 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); } @Test public void testSetInvalidState() throws Exception { mActivity.setState(DESTROYED, "testInvalidState"); boolean exceptionEncountered = false; try { mActivity.setState(FINISHING, "testInvalidState"); } catch (IllegalArgumentException e) { exceptionEncountered = true; } assertTrue(exceptionEncountered); } }
services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java +0 −22 Original line number Diff line number Diff line Loading @@ -478,28 +478,6 @@ public class ActivityStackTests extends ActivityTestsBase { return stack; } @Test public void testSuppressMultipleDestroy() throws Exception { final ActivityRecord r = new ActivityBuilder(mService).setTask(mTask).build(); final ClientLifecycleManager lifecycleManager = mock(ClientLifecycleManager.class); final ProcessRecord app = r.app; // The mocked lifecycle manager must be set on the ActivityStackSupervisor's reference to // the service rather than mService as mService is a spy and setting the value will not // propagate as ActivityManagerService hands its own reference to the // ActivityStackSupervisor during construction. ((TestActivityManagerService) mSupervisor.mService).setLifecycleManager(lifecycleManager); mStack.destroyActivityLocked(r, true, "first invocation"); verify(lifecycleManager, times(1)).scheduleTransaction(eq(app.thread), eq(r.appToken), any(DestroyActivityItem.class)); assertTrue(r.isState(DESTROYED, DESTROYING)); mStack.destroyActivityLocked(r, true, "second invocation"); verify(lifecycleManager, times(1)).scheduleTransaction(eq(app.thread), eq(r.appToken), any(DestroyActivityItem.class)); } @Test public void testFinishDisabledPackageActivities() throws Exception { final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build(); Loading