Merge "Fix transition animation of ResolverActivity for home" into qt-dev
diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java
index ee258cb..3092ef9 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimation.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimation.java
@@ -220,7 +220,9 @@
             // Unregister for stack order changes
             mDefaultDisplay.unregisterStackOrderChangedListener(this);
 
-            if (mWindowManager.getRecentsAnimationController() == null) return;
+            final RecentsAnimationController controller =
+                    mWindowManager.getRecentsAnimationController();
+            if (controller == null) return;
 
             // Just to be sure end the launch hint in case the target activity was never launched.
             // However, if we're keeping the activity and making it visible, we can leave it on.
@@ -292,6 +294,16 @@
                             }
                         }
                     } else {
+                        // If there is no recents screenshot animation, we can update the visibility
+                        // of target stack immediately because it is visually invisible and the
+                        // launch-behind state is restored. That also prevents the next transition
+                        // type being disturbed if the visibility is updated after setting the next
+                        // transition (the target activity will be one of closing apps).
+                        if (!controller.shouldCancelWithDeferredScreenshot()
+                                && !targetStack.isFocusedStackOnDisplay()) {
+                            targetStack.ensureActivitiesVisibleLocked(null /* starting */,
+                                    0 /* starting */, false /* preserveWindows */);
+                        }
                         // Keep target stack in place, nothing changes, so ignore the transition
                         // logic below
                         return;
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
index 708493b..8b2912c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
@@ -21,6 +21,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 
 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.mock;
@@ -32,6 +33,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 
 import android.content.ComponentName;
@@ -71,6 +73,36 @@
     }
 
     @Test
+    public void testRecentsActivityVisiblility() {
+        ActivityDisplay display = mRootActivityContainer.getDefaultDisplay();
+        ActivityStack recentsStack = display.createStack(WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_RECENTS, true /* onTop */);
+        ActivityRecord recentActivity = new ActivityBuilder(mService)
+                .setComponent(mRecentsComponent)
+                .setCreateTask(true)
+                .setStack(recentsStack)
+                .build();
+        ActivityRecord topActivity = new ActivityBuilder(mService).setCreateTask(true).build();
+        topActivity.fullscreen = true;
+        topActivity.getActivityStack().moveToFront("testRecentsActivityVisiblility");
+
+        doCallRealMethod().when(mRootActivityContainer).ensureActivitiesVisible(
+                any() /* starting */, anyInt() /* configChanges */,
+                anyBoolean() /* preserveWindows */);
+
+        RecentsAnimationCallbacks recentsAnimation = startRecentsActivity(
+                mRecentsComponent, true /* getRecentsAnimation */);
+        // The launch-behind state should make the recents activity visible.
+        assertTrue(recentActivity.visible);
+
+        // Simulate the animation is cancelled without changing the stack order.
+        recentsAnimation.onAnimationFinished(REORDER_KEEP_IN_PLACE, true /* runSychronously */,
+                false /* sendUserLeaveHint */);
+        // The non-top recents activity should be invisible by the restored launch-behind state.
+        assertFalse(recentActivity.visible);
+    }
+
+    @Test
     public void testSetLaunchTaskBehindOfTargetActivity() {
         ActivityDisplay display = mRootActivityContainer.getDefaultDisplay();
         display.mDisplayContent.mBoundsAnimationController = mock(BoundsAnimationController.class);