DO NOT MERGE WM: correctly draw the rounded corner / cutout overlay during rotation

When we freeze the screen, we really don't want the overlay to appear
on the screenshot - otherwise this will lead to it rotating with the
screen content. This means the overlay currently disappears during the
transition. We cannot just draw it over the screenshot, because it
might be in inconsistent state.

We fix this by temporarily undoing the effects of the screen rotation
transform on the overlay's window token. Then, once the window has
performed relayout and is redrawn in the new orientation, we switch to
that representation. This is mostly seamless rotation, with the
difference that we force it always, and it must also work for 180
degree rotation (which regular seamless rotation does not).

Do not merge, because we want to harmonize seamless rotation and the
newly added forced seamless rotation in Q.

Also move the rounded corner overlay from the display overlay layer
to the root of the hierarchy such that it can draw over the screen
off animation's ColorLayer.

Bug: 79112140
Test: Enable display cutout overlay, rotate phone to all orientations, ensure that emulated display cutout never flashes or disappears.
Test: atest CoordinateTransformsTest
Change-Id: I90451c14dc28daa3f90a74c3117548fead25af3f
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 2857603..5386b1a 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1106,6 +1106,10 @@
             }
         }
 
+        forAllWindows(w -> {
+            w.forceSeamlesslyRotateIfAllowed(oldRotation, rotation);
+        }, true /* traverseTopToBottom */);
+
         if (rotateSeamlessly) {
             seamlesslyRotate(getPendingTransaction(), oldRotation, rotation);
         }
@@ -3691,6 +3695,19 @@
         }
 
         @Override
+        SurfaceControl.Builder makeChildSurface(WindowContainer child) {
+            final SurfaceControl.Builder builder = super.makeChildSurface(child);
+            if (child instanceof WindowToken && ((WindowToken) child).mRoundedCornerOverlay) {
+                // To draw above the ColorFade layer during the screen off transition, the
+                // rounded corner overlays need to be at the root of the surface hierarchy.
+                // TODO: move the ColorLayer into the display overlay layer such that this is not
+                // necessary anymore.
+                builder.setParent(null);
+            }
+            return builder;
+        }
+
+        @Override
         void assignChildLayers(SurfaceControl.Transaction t) {
             assignChildLayers(t, null /* imeContainer */);
         }
@@ -3706,6 +3723,10 @@
                     wt.assignRelativeLayer(t, mTaskStackContainers.getSplitScreenDividerAnchor(), 1);
                     continue;
                 }
+                if (wt.mRoundedCornerOverlay) {
+                    wt.assignLayer(t, WindowManagerPolicy.COLOR_FADE_LAYER + 1);
+                    continue;
+                }
                 wt.assignLayer(t, j);
                 wt.assignChildLayers(t);