Avoid remove starting window too early when playing multiple transitions

The app window would choose sync transaction for prepareSurfaceLocked
if there are more than one transacition hasn't handled in shell, so the
app window would only commit visilble after all start transactions
applied. Defer remove starting window until the transaction commit count
to zero.

Flag: EXEMPT bugfix
Bug: 362347290
Test: verify starting window won't stuck from normal launch.
Change-Id: I756e4f9930f8a91023c0e7da10f632da8839d745
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index ff6f021..9da7936 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -2641,7 +2641,7 @@
             return true;
         }
         // Only do transfer after transaction has done when starting window exist.
-        if (mStartingData != null && mStartingData.mWaitForSyncTransactionCommit) {
+        if (mStartingData != null && mStartingData.mWaitForSyncTransactionCommitCount > 0) {
             mStartingData.mRemoveAfterTransaction = AFTER_TRANSACTION_COPY_TO_CLIENT;
             return true;
         }
@@ -2804,9 +2804,11 @@
 
     @Override
     void waitForSyncTransactionCommit(ArraySet<WindowContainer> wcAwaitingCommit) {
+        // Only add once per transition.
+        final boolean added = wcAwaitingCommit.contains(this);
         super.waitForSyncTransactionCommit(wcAwaitingCommit);
-        if (mStartingData != null) {
-            mStartingData.mWaitForSyncTransactionCommit = true;
+        if (!added && mStartingData != null) {
+            mStartingData.mWaitForSyncTransactionCommitCount++;
         }
     }
 
@@ -2817,7 +2819,7 @@
             return;
         }
         final StartingData lastData = mStartingData;
-        lastData.mWaitForSyncTransactionCommit = false;
+        lastData.mWaitForSyncTransactionCommitCount--;
         if (lastData.mRemoveAfterTransaction == AFTER_TRANSACTION_REMOVE_DIRECTLY) {
             removeStartingWindowAnimation(lastData.mPrepareRemoveAnimation);
         } else if (lastData.mRemoveAfterTransaction == AFTER_TRANSACTION_COPY_TO_CLIENT) {
@@ -2847,7 +2849,7 @@
         final boolean animate;
         final boolean hasImeSurface;
         if (mStartingData != null) {
-            if (mStartingData.mWaitForSyncTransactionCommit
+            if (mStartingData.mWaitForSyncTransactionCommitCount > 0
                     || mSyncState != SYNC_STATE_NONE) {
                 mStartingData.mRemoveAfterTransaction = AFTER_TRANSACTION_REMOVE_DIRECTLY;
                 mStartingData.mPrepareRemoveAnimation = prepareAnimation;
diff --git a/services/core/java/com/android/server/wm/StartingData.java b/services/core/java/com/android/server/wm/StartingData.java
index 24fb207..22c7e8c 100644
--- a/services/core/java/com/android/server/wm/StartingData.java
+++ b/services/core/java/com/android/server/wm/StartingData.java
@@ -69,7 +69,7 @@
      * Note this isn't equal to transition playing, the period should be
      * Sync finishNow -> Start transaction apply.
      */
-    boolean mWaitForSyncTransactionCommit;
+    int mWaitForSyncTransactionCommitCount;
 
     /**
      * For Shell transition.
@@ -112,7 +112,7 @@
     public String toString() {
         return getClass().getSimpleName() + "{"
                 + Integer.toHexString(System.identityHashCode(this))
-                + " waitForSyncTransactionCommit=" + mWaitForSyncTransactionCommit
+                + " mWaitForSyncTransactionCommitCount=" + mWaitForSyncTransactionCommitCount
                 + " removeAfterTransaction= " + mRemoveAfterTransaction
                 + "}";
     }