diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 130da2dfe9c52..dcdbfdedb0c86 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -2669,15 +2669,28 @@ 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()) { - getDisplay().ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, - false /* preserveWindows */, false /* notifyClients */); + final boolean isCurrentVisible = mVisibleRequested || isState(PAUSED); + if (isCurrentVisible) { + final ActivityStack stack = getStack(); + final ActivityRecord activity = stack.mResumedActivity; + boolean ensureVisibility = false; + if (activity != null && !activity.occludesParent()) { + // If the resume activity is not opaque, we need to make sure the visibilities of + // activities be updated, they may be seen by users. + ensureVisibility = true; + } else if (mStackSupervisor.getKeyguardController().isKeyguardLocked() + && stack.topActivityOccludesKeyguard()) { + // 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. + ensureVisibility = true; + } + + if (ensureVisibility) { + getDisplay().ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, + false /* preserveWindows */, true /* notifyClients */); + } } boolean activityRemoved = false; @@ -2698,7 +2711,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // than destroy immediately. final boolean isNextNotYetVisible = next != null && (!next.nowVisible || !next.mVisibleRequested); - if ((mVisibleRequested || isState(PAUSED)) && isNextNotYetVisible) { + if (isCurrentVisible && isNextNotYetVisible) { // Add this activity to the list of stopping activities. It will be processed and // destroyed when the next activity reports idle. addToStopping(false /* scheduleIdle */, false /* idleDelayed */, 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 6a28918eab005..364845c0ff4ae 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -1082,6 +1082,46 @@ public class ActivityRecordTests extends ActivityTestsBase { assertFalse(mStack.topActivityOccludesKeyguard()); } + /** + * Verify that complete finish request for an activity which the resume activity is translucent + * must ensure the visibilities of activities being updated. + */ + @Test + public void testCompleteFinishing_ensureActivitiesVisible() { + final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build(); + firstActivity.mVisibleRequested = false; + firstActivity.nowVisible = false; + firstActivity.setState(STOPPED, "true"); + + final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask).build(); + secondActivity.mVisibleRequested = true; + secondActivity.nowVisible = true; + secondActivity.setState(PAUSED, "true"); + + final ActivityRecord translucentActivity = + new ActivityBuilder(mService).setTask(mTask).build(); + translucentActivity.mVisibleRequested = true; + translucentActivity.nowVisible = true; + translucentActivity.setState(RESUMED, "true"); + + doReturn(false).when(translucentActivity).occludesParent(); + + // Finish the second activity + secondActivity.finishing = true; + secondActivity.completeFinishing("test"); + verify(secondActivity.getDisplay()).ensureActivitiesVisible(null /* starting */, + 0 /* configChanges */ , false /* preserveWindows */, + true /* notifyClients */); + + // Finish the first activity + firstActivity.finishing = true; + firstActivity.mVisibleRequested = true; + firstActivity.completeFinishing("test"); + verify(firstActivity.getDisplay(), times(2)).ensureActivitiesVisible(null /* starting */, + 0 /* configChanges */ , false /* preserveWindows */, + true /* notifyClients */); + } + /** * Verify destroy activity request completes successfully. */