diff options
| -rw-r--r-- | services/core/java/com/android/server/am/ActivityStack.java | 20 | ||||
| -rw-r--r-- | services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java | 24 |
2 files changed, 44 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 85c5c647ceed..824ec68a8660 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -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; } @@ -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"); @@ -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; } diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java index f42abf1927f0..58166b6c1ac5 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java @@ -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; @@ -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(); @@ -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); + } } |