Animate home in separate layer

Such that it always stays at the bottom.

Test: Open app in split-screen
Test: go/wm-smoke
Change-Id: If713c6c04e6616ff04d8475ea2da0241ed863628
Fixes: 77144130
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 5676f58..a701d42 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -1662,7 +1662,9 @@
     }
 
     SurfaceControl getAppAnimationLayer() {
-        return getAppAnimationLayer(needsZBoost());
+        return getAppAnimationLayer(isActivityTypeHome() ? ANIMATION_LAYER_HOME
+                : needsZBoost() ? ANIMATION_LAYER_BOOSTED
+                : ANIMATION_LAYER_STANDARD);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 79eb2c9..4fd31ff 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -3190,6 +3190,7 @@
          */
         SurfaceControl mAppAnimationLayer = null;
         SurfaceControl mBoostedAppAnimationLayer = null;
+        SurfaceControl mHomeAppAnimationLayer = null;
 
         /**
          * Given that the split-screen divider does not have an AppWindowToken, it
@@ -3552,6 +3553,7 @@
             int layer = 0;
             int layerForAnimationLayer = 0;
             int layerForBoostedAnimationLayer = 0;
+            int layerForHomeAnimationLayer = 0;
 
             for (int state = 0; state <= ALWAYS_ON_TOP_STATE; state++) {
                 for (int i = 0; i < mChildren.size(); i++) {
@@ -3578,6 +3580,9 @@
                         layerForBoostedAnimationLayer = layer++;
                     }
                 }
+                if (state == HOME_STACK_STATE) {
+                    layerForHomeAnimationLayer = layer++;
+                }
             }
             if (mAppAnimationLayer != null) {
                 t.setLayer(mAppAnimationLayer, layerForAnimationLayer);
@@ -3585,11 +3590,22 @@
             if (mBoostedAppAnimationLayer != null) {
                 t.setLayer(mBoostedAppAnimationLayer, layerForBoostedAnimationLayer);
             }
+            if (mHomeAppAnimationLayer != null) {
+                t.setLayer(mHomeAppAnimationLayer, layerForHomeAnimationLayer);
+            }
         }
 
         @Override
-        SurfaceControl getAppAnimationLayer(boolean boosted) {
-            return boosted ? mBoostedAppAnimationLayer : mAppAnimationLayer;
+        SurfaceControl getAppAnimationLayer(@AnimationLayer int animationLayer) {
+            switch (animationLayer) {
+                case ANIMATION_LAYER_BOOSTED:
+                    return mBoostedAppAnimationLayer;
+                case ANIMATION_LAYER_HOME:
+                    return mHomeAppAnimationLayer;
+                case ANIMATION_LAYER_STANDARD:
+                default:
+                    return mAppAnimationLayer;
+            }
         }
 
         SurfaceControl getSplitScreenDividerAnchor() {
@@ -3606,12 +3622,16 @@
                 mBoostedAppAnimationLayer = makeChildSurface(null)
                         .setName("boostedAnimationLayer")
                         .build();
+                mHomeAppAnimationLayer = makeChildSurface(null)
+                        .setName("homeAnimationLayer")
+                        .build();
                 mSplitScreenDividerAnchor = makeChildSurface(null)
                         .setName("splitScreenDividerAnchor")
                         .build();
                 getPendingTransaction()
                         .show(mAppAnimationLayer)
                         .show(mBoostedAppAnimationLayer)
+                        .show(mHomeAppAnimationLayer)
                         .show(mSplitScreenDividerAnchor);
                 scheduleAnimation();
             } else {
@@ -3619,6 +3639,8 @@
                 mAppAnimationLayer = null;
                 mBoostedAppAnimationLayer.destroy();
                 mBoostedAppAnimationLayer = null;
+                mHomeAppAnimationLayer.destroy();
+                mHomeAppAnimationLayer = null;
                 mSplitScreenDividerAnchor.destroy();
                 mSplitScreenDividerAnchor = null;
             }
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 95223d8..f87538a 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -564,7 +564,7 @@
     public SurfaceControl getAnimationLeashParent() {
         // Reparent to the animation layer so that we aren't clipped by the non-minimized
         // stack bounds, currently we only animate the task for the recents animation
-        return getAppAnimationLayer(false /* boosted */);
+        return getAppAnimationLayer(ANIMATION_LAYER_STANDARD);
     }
 
     boolean isTaskAnimating() {
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 60e7c0d..331a0bd 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -29,6 +29,8 @@
 import static com.android.server.wm.WindowContainerProto.VISIBLE;
 
 import android.annotation.CallSuper;
+import android.annotation.IntDef;
+import android.app.WindowConfiguration;
 import android.content.res.Configuration;
 import android.graphics.Point;
 import android.graphics.Rect;
@@ -60,6 +62,25 @@
 
     private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowContainer" : TAG_WM;
 
+    /** Animation layer that happens above all animating {@link TaskStack}s. */
+    static final int ANIMATION_LAYER_STANDARD = 0;
+
+    /** Animation layer that happens above all {@link TaskStack}s. */
+    static final int ANIMATION_LAYER_BOOSTED = 1;
+
+    /**
+     * Animation layer that is reserved for {@link WindowConfiguration#ACTIVITY_TYPE_HOME}
+     * activities that happens below all {@link TaskStack}s.
+     */
+    static final int ANIMATION_LAYER_HOME = 2;
+
+    @IntDef(prefix = { "ANIMATION_LAYER_" }, value = {
+            ANIMATION_LAYER_STANDARD,
+            ANIMATION_LAYER_BOOSTED,
+            ANIMATION_LAYER_HOME,
+    })
+    @interface AnimationLayer {}
+
     static final int POSITION_TOP = Integer.MAX_VALUE;
     static final int POSITION_BOTTOM = Integer.MIN_VALUE;
 
@@ -1125,15 +1146,12 @@
     }
 
     /**
-     * @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(boolean boosted) {
+    SurfaceControl getAppAnimationLayer(@AnimationLayer int animationLayer) {
         final WindowContainer parent = getParent();
         if (parent != null) {
-            return parent.getAppAnimationLayer(boosted);
+            return parent.getAppAnimationLayer(animationLayer);
         }
         return null;
     }