Revert "Remove WindowlessWindowLayout"

This reverts commit 6b2045872fa7ab5dfe1187ff9650c88ebdf46750.

Reason for revert: Breaks bounds computation for windowless windows by computing inset values

Change-Id: I11a4b8a16a905ab46b26b783f67bd1b3f2939e43
diff --git a/core/java/android/view/SurfaceControlViewHost.java b/core/java/android/view/SurfaceControlViewHost.java
index 3efbb75..c9eee6a 100644
--- a/core/java/android/view/SurfaceControlViewHost.java
+++ b/core/java/android/view/SurfaceControlViewHost.java
@@ -292,7 +292,7 @@
     public SurfaceControlViewHost(@NonNull Context c, @NonNull Display d,
             @NonNull WindowlessWindowManager wwm) {
         mWm = wwm;
-        mViewRoot = new ViewRootImpl(c, d, mWm);
+        mViewRoot = new ViewRootImpl(c, d, mWm, new WindowlessWindowLayout());
         addConfigCallback(c, d);
 
         WindowManagerGlobal.getInstance().addWindowlessRoot(mViewRoot);
@@ -322,7 +322,7 @@
         mWm = new WindowlessWindowManager(context.getResources().getConfiguration(),
                 mSurfaceControl, hostToken);
 
-        mViewRoot = new ViewRootImpl(context, display, mWm);
+        mViewRoot = new ViewRootImpl(context, display, mWm, new WindowlessWindowLayout());
         addConfigCallback(context, display);
 
         WindowManagerGlobal.getInstance().addWindowlessRoot(mViewRoot);
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 898e46e..f818283 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -922,13 +922,14 @@
     private String mTag = TAG;
 
     public ViewRootImpl(Context context, Display display) {
-        this(context, display, WindowManagerGlobal.getWindowSession());
+        this(context, display, WindowManagerGlobal.getWindowSession(), new WindowLayout());
     }
 
-    public ViewRootImpl(@UiContext Context context, Display display, IWindowSession session) {
+    public ViewRootImpl(@UiContext Context context, Display display, IWindowSession session,
+            WindowLayout windowLayout) {
         mContext = context;
         mWindowSession = session;
-        mWindowLayout = new WindowLayout();
+        mWindowLayout = windowLayout;
         mDisplay = display;
         mBasePackageName = context.getBasePackageName();
         mThread = Thread.currentThread();
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index acc0c0b..4a9dc5b 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -388,7 +388,8 @@
             if (windowlessSession == null) {
                 root = new ViewRootImpl(view.getContext(), display);
             } else {
-                root = new ViewRootImpl(view.getContext(), display, windowlessSession);
+                root = new ViewRootImpl(view.getContext(), display,
+                        windowlessSession, new WindowlessWindowLayout());
             }
 
             view.setLayoutParams(wparams);
diff --git a/core/java/android/view/WindowlessWindowLayout.java b/core/java/android/view/WindowlessWindowLayout.java
new file mode 100644
index 0000000..e2afaa5
--- /dev/null
+++ b/core/java/android/view/WindowlessWindowLayout.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
+
+import android.app.WindowConfiguration.WindowingMode;
+import android.graphics.Rect;
+import android.view.WindowInsets.Type.InsetsType;
+import android.window.ClientWindowFrames;
+
+/**
+ * Computes window frames for the windowless window.
+ *
+ * This can't be replaced with the regular WindowLayout because WindowLayout computes bounds
+ * with insets and cutout values. Since windowless windows aren't affected by insets and
+ * instead are bound by their parent, it will compute incorrect bounds for them if insets are used.
+ *
+ * @hide
+ */
+public class WindowlessWindowLayout extends WindowLayout {
+
+    @Override
+    public void computeFrames(WindowManager.LayoutParams attrs, InsetsState state,
+            Rect displayCutoutSafe, Rect windowBounds, @WindowingMode int windowingMode,
+            int requestedWidth, int requestedHeight, @InsetsType int requestedVisibleTypes,
+            float compatScale, ClientWindowFrames frames) {
+        if (frames.attachedFrame == null) {
+            frames.frame.set(0, 0, attrs.width, attrs.height);
+            frames.parentFrame.set(frames.frame);
+            frames.displayFrame.set(frames.frame);
+            return;
+        }
+
+        final int height = calculateLength(attrs.height, requestedHeight,
+                frames.attachedFrame.height());
+        final int width = calculateLength(attrs.width, requestedWidth,
+                frames.attachedFrame.width());
+        Gravity.apply(attrs.gravity, width, height, frames.attachedFrame,
+                (int) (attrs.x + attrs.horizontalMargin),
+                (int) (attrs.y + attrs.verticalMargin),
+                frames.frame);
+        frames.displayFrame.set(frames.frame);
+        frames.parentFrame.set(frames.attachedFrame);
+    }
+
+    private static int calculateLength(int attrLength, int requestedLength, int parentLength) {
+        if (attrLength == MATCH_PARENT) {
+            return parentLength;
+        }
+        if (attrLength == WRAP_CONTENT) {
+            return requestedLength;
+        }
+        return attrLength;
+    }
+}
diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java
index 4ddd485..021193e 100644
--- a/core/java/android/view/WindowlessWindowManager.java
+++ b/core/java/android/view/WindowlessWindowManager.java
@@ -94,10 +94,7 @@
     private InsetsState mInsetsState;
     private final ClientWindowFrames mTmpFrames = new ClientWindowFrames();
     private final MergedConfiguration mTmpConfig = new MergedConfiguration();
-    private final InsetsState mTmpInsetsState = new InsetsState();
-    private final Rect mTmpDisplayCutoutSafe = new Rect();
-    private final Rect mTmpWindowBounds = new Rect();
-    private final WindowLayout mLayout = new WindowLayout();
+    private final WindowlessWindowLayout mLayout = new WindowlessWindowLayout();
 
     public WindowlessWindowManager(Configuration c, SurfaceControl rootSurface,
             IBinder hostInputToken) {
@@ -349,27 +346,22 @@
         }
         WindowManager.LayoutParams attrs = state.mParams;
 
-        mTmpFrames.attachedFrame = state.mAttachedFrame;
+        ClientWindowFrames frames = new ClientWindowFrames();
+        frames.attachedFrame = state.mAttachedFrame;
 
-        if (state.mAttachedFrame == null) {
-            mTmpWindowBounds.set(0, 0, requestedWidth, requestedHeight);
-        } else {
-            mTmpWindowBounds.set(state.mAttachedFrame);
-        }
+        mLayout.computeFrames(attrs, null, null, null, WindowConfiguration.WINDOWING_MODE_UNDEFINED,
+                requestedWidth, requestedHeight, 0, 0,
+                frames);
 
-        mLayout.computeFrames(attrs, mTmpInsetsState, mTmpDisplayCutoutSafe, mTmpWindowBounds,
-                WindowConfiguration.WINDOWING_MODE_UNDEFINED, requestedWidth, requestedHeight, 0,
-                1f, mTmpFrames);
-
-        state.mFrame.set(mTmpFrames.frame);
+        state.mFrame.set(frames.frame);
         if (outFrames != null) {
-            outFrames.frame.set(mTmpFrames.frame);
-            outFrames.parentFrame.set(mTmpFrames.parentFrame);
-            outFrames.displayFrame.set(mTmpFrames.displayFrame);
+            outFrames.frame.set(frames.frame);
+            outFrames.parentFrame.set(frames.parentFrame);
+            outFrames.displayFrame.set(frames.displayFrame);
         }
 
-        t.setPosition(leash, mTmpFrames.frame.left, mTmpFrames.frame.top);
-        t.setWindowCrop(leash, mTmpFrames.frame.width(), mTmpFrames.frame.height());
+        t.setPosition(leash, frames.frame.left, frames.frame.top);
+        t.setWindowCrop(leash, frames.frame.width(), frames.frame.height());
 
         if (viewFlags == View.VISIBLE) {
             // TODO(b/262892794) ViewRootImpl modifies the app's rendering SurfaceControl