Merge "Use sync transaction for prepare open transition." into main
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index 4e4616d..0646fb7 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -1072,8 +1072,10 @@
             return close.asWindowState() != null;
         }
 
-        private void initiate(@NonNull WindowContainer close, @NonNull WindowContainer[] open,
+        private void initiate(ScheduleAnimationBuilder builder,
                 @NonNull ActivityRecord[] openingActivities)  {
+            WindowContainer close = builder.mCloseTarget;
+            WindowContainer[] open = builder.mOpenTargets;
             if (isActivitySwitch(close, open)) {
                 mSwitchType = ACTIVITY_SWITCH;
                 if (Flags.migratePredictiveBackTransition()) {
@@ -1091,9 +1093,17 @@
                 return;
             }
 
-            mCloseAdaptor = createAdaptor(close, false, mSwitchType);
+            final Transition prepareTransition = builder.prepareTransitionIfNeeded(
+                    openingActivities);
+            final SurfaceControl.Transaction st = openingActivities[0].getSyncTransaction();
+            final SurfaceControl.Transaction ct = prepareTransition != null
+                    ? st : close.getPendingTransaction();
+            mCloseAdaptor = createAdaptor(close, false, mSwitchType, ct);
             if (mCloseAdaptor.mAnimationTarget == null) {
                 Slog.w(TAG, "composeNewAnimations fail, skip");
+                if (prepareTransition != null) {
+                    prepareTransition.abort();
+                }
                 clearBackAnimateTarget(true /* cancel */);
                 return;
             }
@@ -1110,12 +1120,17 @@
                             next.getWindowConfiguration().getRotation());
                 }
             }
-            mOpenAnimAdaptor = new BackWindowAnimationAdaptorWrapper(true, mSwitchType, open);
+            mOpenAnimAdaptor = new BackWindowAnimationAdaptorWrapper(
+                    true, mSwitchType, st, open);
             if (!mOpenAnimAdaptor.isValid()) {
                 Slog.w(TAG, "compose animations fail, skip");
+                if (prepareTransition != null) {
+                    prepareTransition.abort();
+                }
                 clearBackAnimateTarget(true /* cancel */);
                 return;
             }
+            mOpenAnimAdaptor.mPreparedOpenTransition = prepareTransition;
             mOpenActivities = openingActivities;
         }
 
@@ -1147,19 +1162,21 @@
             return new Pair<>(replaceClose, replaceOpen);
         }
 
-        private boolean composeAnimations(@NonNull WindowContainer close,
-                @NonNull WindowContainer[] open, @NonNull ActivityRecord[] openingActivities) {
+        private boolean composeAnimations(@NonNull ScheduleAnimationBuilder builder,
+                @NonNull ActivityRecord[] openingActivities) {
             if (mComposed || mWaitTransition) {
                 Slog.e(TAG, "Previous animation is running " + this);
                 return false;
             }
             clearBackAnimateTarget(true /* cancel */);
-            if (close == null || open == null || open.length == 0 || open.length > 2) {
+            final WindowContainer[] open = builder.mOpenTargets;
+            if (builder.mCloseTarget == null || open == null || open.length == 0
+                    || open.length > 2) {
                 Slog.e(TAG, "reset animation with null target close: "
-                        + close + " open: " + Arrays.toString(open));
+                        + builder.mCloseTarget + " open: " + Arrays.toString(open));
                 return false;
             }
-            initiate(close, open, openingActivities);
+            initiate(builder, openingActivities);
             if (mSwitchType == UNKNOWN) {
                 return false;
             }
@@ -1384,10 +1401,10 @@
         }
 
         @NonNull private static BackWindowAnimationAdaptor createAdaptor(
-                @NonNull WindowContainer target, boolean isOpen, int switchType) {
+                @NonNull WindowContainer target, boolean isOpen, int switchType,
+                SurfaceControl.Transaction st) {
             final BackWindowAnimationAdaptor adaptor =
                     new BackWindowAnimationAdaptor(target, isOpen, switchType);
-            final SurfaceControl.Transaction pt = target.getPendingTransaction();
             // Workaround to show TaskFragment which can be hide in Transitions and won't show
             // during isAnimating.
             if (isOpen && target.asActivityRecord() != null) {
@@ -1395,10 +1412,10 @@
                 if (fragment != null) {
                     // Ensure task fragment surface has updated, in case configuration has changed.
                     fragment.updateOrganizedTaskFragmentSurface();
-                    pt.show(fragment.mSurfaceControl);
+                    st.show(fragment.mSurfaceControl);
                 }
             }
-            target.startAnimation(pt, adaptor, false /* hidden */, ANIMATION_TYPE_PREDICT_BACK);
+            target.startAnimation(st, adaptor, false /* hidden */, ANIMATION_TYPE_PREDICT_BACK);
             return adaptor;
         }
 
@@ -1417,12 +1434,12 @@
             private Transition mPreparedOpenTransition;
 
             BackWindowAnimationAdaptorWrapper(boolean isOpen, int switchType,
-                    @NonNull WindowContainer... targets) {
+                    SurfaceControl.Transaction st, @NonNull WindowContainer... targets) {
                 mAdaptors = new BackWindowAnimationAdaptor[targets.length];
                 for (int i = targets.length - 1; i >= 0; --i) {
-                    mAdaptors[i] = createAdaptor(targets[i], isOpen, switchType);
+                    mAdaptors[i] = createAdaptor(targets[i], isOpen, switchType, st);
                 }
-                mRemoteAnimationTarget = targets.length > 1 ? createWrapTarget()
+                mRemoteAnimationTarget = targets.length > 1 ? createWrapTarget(st)
                         : mAdaptors[0].mAnimationTarget;
             }
 
@@ -1448,7 +1465,7 @@
                 mPreparedOpenTransition = null;
             }
 
-            private RemoteAnimationTarget createWrapTarget() {
+            private RemoteAnimationTarget createWrapTarget(SurfaceControl.Transaction st) {
                 // Special handle for opening two activities together.
                 // If we animate both activities separately, the animation area and rounded corner
                 // would also being handled separately. To make them seem like "open" together, wrap
@@ -1470,12 +1487,11 @@
                         .build();
                 mCloseTransaction = new SurfaceControl.Transaction();
                 mCloseTransaction.reparent(leashSurface, null);
-                final SurfaceControl.Transaction pt = wc.getPendingTransaction();
-                pt.setLayer(leashSurface, wc.getLastLayer());
+                st.setLayer(leashSurface, wc.getLastLayer());
                 for (int i = mAdaptors.length - 1; i >= 0; --i) {
                     BackWindowAnimationAdaptor adaptor = mAdaptors[i];
-                    pt.reparent(adaptor.mAnimationTarget.leash, leashSurface);
-                    pt.setPosition(adaptor.mAnimationTarget.leash,
+                    st.reparent(adaptor.mAnimationTarget.leash, leashSurface);
+                    st.setPosition(adaptor.mAnimationTarget.leash,
                             adaptor.mAnimationTarget.localBounds.left,
                             adaptor.mAnimationTarget.localBounds.top);
                     // For adjacent activity embedded, reparent Activity to TaskFragment when
@@ -1738,6 +1754,7 @@
             WindowContainer mCloseTarget;
             WindowContainer[] mOpenTargets;
             boolean mIsLaunchBehind;
+            TaskSnapshot mSnapshot;
 
             ScheduleAnimationBuilder(int type, BackAnimationAdapter adapter,
                     NavigationMonitor monitor) {
@@ -1771,6 +1788,13 @@
                 return wc == mCloseTarget || mCloseTarget.hasChild(wc) || wc.hasChild(mCloseTarget);
             }
 
+            private Transition prepareTransitionIfNeeded(ActivityRecord[] visibleOpenActivities) {
+                if (mSnapshot == null) {
+                    return setLaunchBehind(visibleOpenActivities);
+                }
+                return null;
+            }
+
             /**
              * Apply preview strategy on the opening target
              *
@@ -1780,26 +1804,17 @@
             private void applyPreviewStrategy(
                     @NonNull BackWindowAnimationAdaptorWrapper openAnimationAdaptor,
                     @NonNull ActivityRecord[] visibleOpenActivities) {
-                boolean needsLaunchBehind = true;
                 if (isSupportWindowlessSurface() && mShowWindowlessSurface && !mIsLaunchBehind) {
                     boolean activitiesAreDrawn = false;
                     for (int i = visibleOpenActivities.length - 1; i >= 0; --i) {
                         // If the activity hasn't stopped, it's window should remain drawn.
                         activitiesAreDrawn |= visibleOpenActivities[i].firstWindowDrawn;
                     }
-                    final WindowContainer mainOpen = openAnimationAdaptor.mAdaptors[0].mTarget;
-                    final TaskSnapshot snapshot = getSnapshot(mainOpen, visibleOpenActivities);
                     // Don't create starting surface if previous activities haven't stopped or
                     // the snapshot does not exist.
-                    if (snapshot != null || !activitiesAreDrawn) {
-                        openAnimationAdaptor.createStartingSurface(snapshot);
+                    if (mSnapshot != null || !activitiesAreDrawn) {
+                        openAnimationAdaptor.createStartingSurface(mSnapshot);
                     }
-                    // Only use LaunchBehind if snapshot does not exist.
-                    needsLaunchBehind = snapshot == null;
-                }
-                if (needsLaunchBehind) {
-                    openAnimationAdaptor.mPreparedOpenTransition =
-                            setLaunchBehind(visibleOpenActivities);
                 }
                 // Force update mLastSurfaceShowing for opening activity and its task.
                 if (mWindowManagerService.mRoot.mTransitionController.isShellTransitionsEnabled()) {
@@ -1821,7 +1836,11 @@
                     return null;
                 }
 
-                if (!composeAnimations(mCloseTarget, mOpenTargets, openingActivities)) {
+                if (!shouldLaunchBehind && mShowWindowlessSurface) {
+                    mSnapshot = getSnapshot(mOpenTargets[0], openingActivities);
+                }
+
+                if (!composeAnimations(this, openingActivities)) {
                     return null;
                 }
                 mCloseTarget.mTransitionController.mSnapshotController