Loading services/core/java/com/android/server/am/ActivityStack.java +20 −0 Original line number Diff line number Diff line Loading @@ -1152,6 +1152,18 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep needs to pause " + mResumedActivity); if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING, "Sleep => pause with userLeaving=false"); // If we are in the middle of resuming the top activity in // {@link #resumeTopActivityUncheckedLocked}, mResumedActivity will be set but not // resumed yet. We must not proceed pausing the activity here. This method will be // called again if necessary as part of // {@link ActivityStackSupervisor#checkReadyForSleepLocked}. if (mStackSupervisor.inResumeTopActivity) { if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "In the middle of resuming top activity " + mResumedActivity); return true; } startPausingLocked(false, true, null, false); return true; } Loading Loading @@ -1229,6 +1241,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } } ActivityRecord prev = mResumedActivity; if (prev == null) { if (resuming == null) { Slog.wtf(TAG, "Trying to pause when nothing is resumed"); Loading Loading @@ -2191,6 +2204,13 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } finally { mStackSupervisor.inResumeTopActivity = false; } // When resuming the top activity, it may be necessary to pause the top activity (for // example, returning to the lock screen. We suppress the normal pause logic in // {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the end. // We call the {@link ActivityStackSupervisor#checkReadyForSleepLocked} again here to ensure // any necessary pause logic occurs. mStackSupervisor.checkReadyForSleepLocked(); return result; } Loading services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java +24 −0 Original line number Diff line number Diff line Loading @@ -16,8 +16,10 @@ package com.android.server.am; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import android.content.ComponentName; import android.platform.test.annotations.Presubmit; Loading Loading @@ -50,6 +52,7 @@ public class ActivityStackTests extends ActivityTestsBase { "testEmptyTaskCleanupOnRemove", ActivityStack.REMOVE_TASK_MODE_DESTROYING); assertNull(task.getWindowContainerController()); } @Test public void testOccupiedTaskCleanupOnRemove() throws Exception { final ActivityManagerService service = createActivityManagerService(); Loading @@ -60,4 +63,25 @@ public class ActivityStackTests extends ActivityTestsBase { "testOccupiedTaskCleanupOnRemove", ActivityStack.REMOVE_TASK_MODE_DESTROYING); assertNotNull(task.getWindowContainerController()); } @Test public void testNoPauseDuringResumeTopActivity() throws Exception { final ActivityManagerService service = createActivityManagerService(); final TaskRecord task = createTask(service, testActivityComponent, TEST_STACK_ID); final ActivityRecord activityRecord = createActivity(service, testActivityComponent, task); final ActivityStack testStack = service.mStackSupervisor.getStack(TEST_STACK_ID); // Simulate the a resumed activity set during // {@link ActivityStack#resumeTopActivityUncheckedLocked}. service.mStackSupervisor.inResumeTopActivity = true; testStack.mResumedActivity = activityRecord; final boolean waiting = testStack.checkReadyForSleepLocked(); // Ensure we report not being ready for sleep. assertTrue(waiting); // Make sure the resumed activity is untouched. assertEquals(testStack.mResumedActivity, activityRecord); } } Loading
services/core/java/com/android/server/am/ActivityStack.java +20 −0 Original line number Diff line number Diff line Loading @@ -1152,6 +1152,18 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Sleep needs to pause " + mResumedActivity); if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING, "Sleep => pause with userLeaving=false"); // If we are in the middle of resuming the top activity in // {@link #resumeTopActivityUncheckedLocked}, mResumedActivity will be set but not // resumed yet. We must not proceed pausing the activity here. This method will be // called again if necessary as part of // {@link ActivityStackSupervisor#checkReadyForSleepLocked}. if (mStackSupervisor.inResumeTopActivity) { if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "In the middle of resuming top activity " + mResumedActivity); return true; } startPausingLocked(false, true, null, false); return true; } Loading Loading @@ -1229,6 +1241,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } } ActivityRecord prev = mResumedActivity; if (prev == null) { if (resuming == null) { Slog.wtf(TAG, "Trying to pause when nothing is resumed"); Loading Loading @@ -2191,6 +2204,13 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } finally { mStackSupervisor.inResumeTopActivity = false; } // When resuming the top activity, it may be necessary to pause the top activity (for // example, returning to the lock screen. We suppress the normal pause logic in // {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the end. // We call the {@link ActivityStackSupervisor#checkReadyForSleepLocked} again here to ensure // any necessary pause logic occurs. mStackSupervisor.checkReadyForSleepLocked(); return result; } Loading
services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java +24 −0 Original line number Diff line number Diff line Loading @@ -16,8 +16,10 @@ package com.android.server.am; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import android.content.ComponentName; import android.platform.test.annotations.Presubmit; Loading Loading @@ -50,6 +52,7 @@ public class ActivityStackTests extends ActivityTestsBase { "testEmptyTaskCleanupOnRemove", ActivityStack.REMOVE_TASK_MODE_DESTROYING); assertNull(task.getWindowContainerController()); } @Test public void testOccupiedTaskCleanupOnRemove() throws Exception { final ActivityManagerService service = createActivityManagerService(); Loading @@ -60,4 +63,25 @@ public class ActivityStackTests extends ActivityTestsBase { "testOccupiedTaskCleanupOnRemove", ActivityStack.REMOVE_TASK_MODE_DESTROYING); assertNotNull(task.getWindowContainerController()); } @Test public void testNoPauseDuringResumeTopActivity() throws Exception { final ActivityManagerService service = createActivityManagerService(); final TaskRecord task = createTask(service, testActivityComponent, TEST_STACK_ID); final ActivityRecord activityRecord = createActivity(service, testActivityComponent, task); final ActivityStack testStack = service.mStackSupervisor.getStack(TEST_STACK_ID); // Simulate the a resumed activity set during // {@link ActivityStack#resumeTopActivityUncheckedLocked}. service.mStackSupervisor.inResumeTopActivity = true; testStack.mResumedActivity = activityRecord; final boolean waiting = testStack.checkReadyForSleepLocked(); // Ensure we report not being ready for sleep. assertTrue(waiting); // Make sure the resumed activity is untouched. assertEquals(testStack.mResumedActivity, activityRecord); } }