[Shell Transition] Defer remove splash screen window when it is
inTransition.

If splash screen window was in transition, the client side is unable
to draw because of Session#cancelDraw, which can also blocking the
reveal animation. But since the client side may alreday report draw
finish after prepareSync, defer the remove starting window signal
after the start transaction applied.

Bug: 246518648
Test: repeat run atest testConvertTranslucentOnTranslucentActivity
Change-Id: I54f61bb160bf6b3d10c9a47ae6d0d341944a5fb1
Merged-In: Ia6a555b5657f531dfed1d2f97e23302f7cd584a2
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 6538ee3..3da572e8 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -2747,6 +2747,7 @@
 
         final StartingSurfaceController.StartingSurface surface;
         final StartingData startingData = mStartingData;
+        final WindowState startingWindow = mStartingWindow;
         if (mStartingData != null) {
             surface = mStartingSurface;
             mStartingData = null;
@@ -2765,21 +2766,31 @@
             return;
         }
 
-
         ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Schedule remove starting %s startingWindow=%s"
                 + " startingView=%s Callers=%s", this, mStartingWindow, mStartingSurface,
                 Debug.getCallers(5));
-
+        final boolean removeWithAnimate = prepareAnimation && startingData.needRevealAnimation();
         final Runnable removeSurface = () -> {
             ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Removing startingView=%s", surface);
             try {
-                surface.remove(prepareAnimation && startingData.needRevealAnimation());
+                surface.remove(removeWithAnimate);
             } catch (Exception e) {
                 Slog.w(TAG_WM, "Exception when removing starting window", e);
             }
         };
-
-        removeSurface.run();
+        if (removeWithAnimate && mTransitionController.inCollectingTransition(startingWindow)
+                && startingWindow.cancelAndRedraw()) {
+            // Defer remove starting window after transition start.
+            // If splash screen window was in collecting, the client side is unable to draw because
+            // of Session#cancelDraw, which will blocking the remove animation.
+            startingWindow.mSyncTransaction.addTransactionCommittedListener(Runnable::run, () -> {
+                synchronized (mAtmService.mGlobalLock) {
+                    removeSurface.run();
+                }
+            });
+        } else {
+            removeSurface.run();
+        }
     }
 
     /**