Fix issues with z-ordering during animations

- Make sure to use DC pending transaction when updating z-layers,
as it could lead to reordering of z-order assignment due to how
we apply pending transactions in the hierarchy

- Create a separate boosted animation layer in which AWT with
zOrder=top animate, which happens above all stack. This brings
back the boosting logic in O without boosting non-boosted stack
above non-animating tokens

Bug: 70730519
Bug: 72649981
Bug: 72686618
Bug: 37953606
Test: Share link from Chrome to Clipboard, make sure disappear
animation happens properly
Test: go/wm-smoke
Change-Id: I3957daac76b991402bf3f520c4a3d3f519933f72
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 85436da..56c9e51 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -1660,6 +1660,10 @@
                 true /* topToBottom */);
     }
 
+    SurfaceControl getAppAnimationLayer() {
+        return getAppAnimationLayer(needsZBoost());
+    }
+
     @Override
     public SurfaceControl getAnimationLeashParent() {
         // All normal app transitions take place in an animation layer which is below the pinned
@@ -1855,7 +1859,7 @@
         leash.setLayer(layer);
 
         final DisplayContent dc = getDisplayContent();
-        dc.assignStackOrdering(t);
+        dc.assignStackOrdering();
         if (mAnimatingAppWindowTokenRegistry != null) {
             mAnimatingAppWindowTokenRegistry.notifyStarting(this);
         }
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 3e47ea6..3c5fa14 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -3172,6 +3172,7 @@
          * A control placed at the appropriate level for transitions to occur.
          */
         SurfaceControl mAppAnimationLayer = null;
+        SurfaceControl mBoostedAppAnimationLayer = null;
 
         /**
          * Given that the split-screen divider does not have an AppWindowToken, it
@@ -3523,12 +3524,14 @@
         }
 
         void assignStackOrdering(SurfaceControl.Transaction t) {
+
             final int HOME_STACK_STATE = 0;
             final int NORMAL_STACK_STATE = 1;
             final int ALWAYS_ON_TOP_STATE = 2;
 
             int layer = 0;
             int layerForAnimationLayer = 0;
+            int layerForBoostedAnimationLayer = 0;
 
             for (int state = 0; state <= ALWAYS_ON_TOP_STATE; state++) {
                 for (int i = 0; i < mChildren.size(); i++) {
@@ -3550,16 +3553,22 @@
                         // highest animating stack and no higher.
                         layerForAnimationLayer = layer++;
                     }
+                    if (state != ALWAYS_ON_TOP_STATE) {
+                        layerForBoostedAnimationLayer = layer++;
+                    }
                 }
             }
             if (mAppAnimationLayer != null) {
                 t.setLayer(mAppAnimationLayer, layerForAnimationLayer);
             }
+            if (mBoostedAppAnimationLayer != null) {
+                t.setLayer(mBoostedAppAnimationLayer, layerForBoostedAnimationLayer);
+            }
         }
 
         @Override
-        SurfaceControl getAppAnimationLayer() {
-            return mAppAnimationLayer;
+        SurfaceControl getAppAnimationLayer(boolean boosted) {
+            return boosted ? mBoostedAppAnimationLayer : mAppAnimationLayer;
         }
 
         SurfaceControl getSplitScreenDividerAnchor() {
@@ -3573,16 +3582,22 @@
                 mAppAnimationLayer = makeChildSurface(null)
                         .setName("animationLayer")
                         .build();
+                mBoostedAppAnimationLayer = makeChildSurface(null)
+                        .setName("boostedAnimationLayer")
+                        .build();
                 mSplitScreenDividerAnchor = makeChildSurface(null)
                         .setName("splitScreenDividerAnchor")
                         .build();
                 getPendingTransaction()
                         .show(mAppAnimationLayer)
+                        .show(mBoostedAppAnimationLayer)
                         .show(mSplitScreenDividerAnchor);
                 scheduleAnimation();
             } else {
                 mAppAnimationLayer.destroy();
                 mAppAnimationLayer = null;
+                mBoostedAppAnimationLayer.destroy();
+                mBoostedAppAnimationLayer = null;
                 mSplitScreenDividerAnchor.destroy();
                 mSplitScreenDividerAnchor = null;
             }
@@ -3864,7 +3879,7 @@
         super.prepareSurfaces();
     }
 
-    void assignStackOrdering(SurfaceControl.Transaction t) {
-        mTaskStackContainers.assignStackOrdering(t);
+    void assignStackOrdering() {
+        mTaskStackContainers.assignStackOrdering(getPendingTransaction());
     }
 }
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 28fdaae..60e7c0d 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -1125,12 +1125,15 @@
     }
 
     /**
+     * @param boosted If true, returns an animation layer that happens above all {@link TaskStack}s
+     *                Otherwise, the layer will be positioned above all animating
+     *                {@link TaskStack}s.
      * @return The layer on which all app animations are happening.
      */
-    SurfaceControl getAppAnimationLayer() {
+    SurfaceControl getAppAnimationLayer(boolean boosted) {
         final WindowContainer parent = getParent();
         if (parent != null) {
-            return parent.getAppAnimationLayer();
+            return parent.getAppAnimationLayer(boosted);
         }
         return null;
     }