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).

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.

Cherry picked from ag/4226061

Bug: 111504081
Test: Enable display cutout overlay, rotate phone to all orientations, ensure that emulated display cutout never flashes or disappears.
Test: atest CoordinateTransformsTest
Test: atest FlickerTests
Change-Id: I8c538b4a5402560c63578c954e8ee7d371079d89
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index efe4d6f..fb09092 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1136,6 +1136,11 @@
             }
         }
 
+        forAllWindows(w -> {
+            w.forceSeamlesslyRotateIfAllowed(oldRotation, rotation);
+        }, true /* traverseTopToBottom */);
+
+        // TODO(b/111504081): Consolidate seamless rotation logic.
         if (rotateSeamlessly) {
             seamlesslyRotate(getPendingTransaction(), oldRotation, rotation);
         }
@@ -3767,6 +3772,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 */);
         }
@@ -3782,6 +3800,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);