Compute visibilities when finishing activity with a translucent resume activity

When there is a translucent activity in foreground and finishing
a next intermediate activity. Since the visibility of next below
activity was not updated. The black background shown below the
translucent resume activity.

The CL update the visibilities with above condition and add test
case to verify.

Bug: 153927250
Test: atest WmTests:ActivityRecordTests
Change-Id: Ie5fc13872becb48b8bdcd572d710111534424a72
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 130da2d..dcdbfded 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 @@
             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 @@
         // 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 6a28918..364845c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -1083,6 +1083,46 @@
     }
 
     /**
+     * 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.
      */
     @Test