diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 93074f1d0ad7b..e79b804f76f9c 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -2669,6 +2669,17 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return this; } + // Ensure activity visibilities and update lockscreen occluded/dismiss state when + // finishing the top activity that occluded keyguard. So that, the + // ActivityStack#mTopActivityOccludesKeyguard can be updated and the activity below won't + // be resumed. + if (isState(PAUSED) + && mStackSupervisor.getKeyguardController().isKeyguardLocked() + && getStack().topActivityOccludesKeyguard()) { + getStack().ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, + false /* preserveWindows */, false /* notifyClients */); + } + boolean activityRemoved = false; // If this activity is currently visible, and the resumed activity is not yet visible, then diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index 3c111e21f7113..bc66fa7ff48d6 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -32,6 +32,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.any; import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean; import static com.android.dx.mockito.inline.extended.ExtendedMockito.atLeast; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.doCallRealMethod; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq; import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset; @@ -1024,6 +1025,38 @@ public class ActivityRecordTests extends ActivityTestsBase { verify(topActivity).destroyIfPossible(anyString()); } + /** + * Verify that complete finish request for a show-when-locked activity must ensure the + * keyguard occluded state being updated. + */ + @Test + public void testCompleteFinishing_showWhenLocked() { + // Make keyguard locked and set the top activity show-when-locked. + KeyguardController keyguardController = mActivity.mStackSupervisor.getKeyguardController(); + doReturn(true).when(keyguardController).isKeyguardLocked(); + final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build(); + topActivity.mVisibleRequested = true; + topActivity.nowVisible = true; + topActivity.setState(RESUMED, "true"); + doCallRealMethod().when(mRootWindowContainer).ensureActivitiesVisible( + any() /* starting */, anyInt() /* configChanges */, + anyBoolean() /* preserveWindows */, anyBoolean() /* notifyClients */); + topActivity.setShowWhenLocked(true); + + // Verify the stack-top activity is occluded keyguard. + assertEquals(topActivity, mStack.topRunningActivity()); + assertTrue(mStack.topActivityOccludesKeyguard()); + + // Finish the top activity + topActivity.setState(PAUSED, "true"); + topActivity.finishing = true; + topActivity.completeFinishing("test"); + + // Verify new top activity does not occlude keyguard. + assertEquals(mActivity, mStack.topRunningActivity()); + assertFalse(mStack.topActivityOccludesKeyguard()); + } + /** * Verify destroy activity request completes successfully. */