Handle z-layering in animation layer

We use the prefix order to determine base layer within the
animation layer. This ensure that for the animation windows, the
z-ordering during animations doesn't change.

We then boost anything that needs a z-boost to 800570000 + prefix
order, such order within the boosted layers is preserved as well.

Also fix an issue where the thumbnail wasn't attached to the
animation layer.

Test: WindowContainerTests
Test: go/wm-smoke
Bug: 64674361
Change-Id: If5909bd87a12f1d8920c7232acab0f3d17be0f6c
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 444a05d..af7523c 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -65,6 +65,7 @@
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
 import android.view.DisplayInfo;
+import android.view.SurfaceControl.Transaction;
 import android.view.animation.Animation;
 import android.view.IApplicationToken;
 import android.view.SurfaceControl;
@@ -91,6 +92,11 @@
 class AppWindowToken extends WindowToken implements WindowManagerService.AppFreezeListener {
     private static final String TAG = TAG_WITH_CLASS_NAME ? "AppWindowToken" : TAG_WM;
 
+    /**
+     * Value to increment the z-layer when boosting a layer during animations. BOOST in l33tsp34k.
+     */
+    private static final int Z_BOOST_BASE = 800570000;
+
     // Non-null only for application tokens.
     final IApplicationToken appToken;
 
@@ -1537,11 +1543,10 @@
                         new WindowAnimationSpec(a, mTmpPoint,
                                 mService.mAppTransition.canSkipFirstFrame()),
                         mService.mSurfaceAnimationRunner);
-                startAnimation(getPendingTransaction(), adapter, !isVisible());
                 if (a.getZAdjustment() == Animation.ZORDER_TOP) {
                     mNeedsZBoost = true;
-                    getDisplayContent().assignWindowLayers(false /* setLayoutNeeded */);
                 }
+                startAnimation(getPendingTransaction(), adapter, !isVisible());
                 mTransit = transit;
                 mTransitFlags = mService.mAppTransition.getTransitFlags();
                 // TODO: Skip first frame and app stack clip mode.
@@ -1610,6 +1615,39 @@
         return a;
     }
 
+    @Override
+    protected void setLayer(Transaction t, int layer) {
+        if (!mSurfaceAnimator.hasLeash()) {
+            t.setLayer(mSurfaceControl, layer);
+        }
+    }
+
+    @Override
+    protected void setRelativeLayer(Transaction t, SurfaceControl relativeTo, int layer) {
+        if (!mSurfaceAnimator.hasLeash()) {
+            t.setRelativeLayer(mSurfaceControl, relativeTo, layer);
+        }
+    }
+
+    @Override
+    protected void reparentSurfaceControl(Transaction t, SurfaceControl newParent) {
+        if (!mSurfaceAnimator.hasLeash()) {
+            t.reparent(mSurfaceControl, newParent.getHandle());
+        }
+    }
+
+    @Override
+    public void onAnimationLeashCreated(Transaction t, SurfaceControl leash) {
+
+        // The leash is parented to the animation layer. We need to preserve the z-order by using
+        // the prefix order index, but we boost if necessary.
+        int layer = getPrefixOrderIndex();
+        if (mNeedsZBoost) {
+            layer += Z_BOOST_BASE;
+        }
+        leash.setLayer(layer);
+    }
+
     /**
      * This must be called while inside a transaction.
      */