Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5ed644f2 authored by Adrian Roos's avatar Adrian Roos
Browse files

DisplayCutout: Properly letterbox bottom-only cutouts

Fixes an issue where bottom cutouts where not
letterboxed if there is no need to letterbox the top

Instead, the need to letterbox is derived from the
bounds.

Change-Id: I6053053066473bd78f21df978e6704043a85e80b
Fixes: 75024814
Test: Receive incoming call in double cutout mode, verify bottom of dialer is letterboxed.
parent 2034c837
Loading
Loading
Loading
Loading
+13 −8
Original line number Diff line number Diff line
@@ -660,6 +660,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    static final Rect mTmpStableFrame = new Rect();
    static final Rect mTmpNavigationFrame = new Rect();
    static final Rect mTmpOutsetFrame = new Rect();
    private static final Rect mTmpDisplayCutoutSafeExceptMaybeBarsRect = new Rect();
    private static final Rect mTmpRect = new Rect();

    WindowState mTopFullscreenOpaqueWindowState;
@@ -4636,7 +4637,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {

            w.computeFrameLw(pf /* parentFrame */, df /* displayFrame */, df /* overlayFrame */,
                    df /* contentFrame */, df /* visibleFrame */, dcf /* decorFrame */,
                    df /* stableFrame */, df /* outsetFrame */, displayFrames.mDisplayCutout);
                    df /* stableFrame */, df /* outsetFrame */, displayFrames.mDisplayCutout,
                    false /* parentFrameWasClippedByDisplayCutout */);
            final Rect frame = w.getFrameLw();

            if (frame.left <= 0 && frame.top <= 0) {
@@ -4699,7 +4701,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        mStatusBar.computeFrameLw(pf /* parentFrame */, df /* displayFrame */,
                vf /* overlayFrame */, vf /* contentFrame */, vf /* visibleFrame */,
                dcf /* decorFrame */, vf /* stableFrame */, vf /* outsetFrame */,
                displayFrames.mDisplayCutout);
                displayFrames.mDisplayCutout, false /* parentFrameWasClippedByDisplayCutout */);

        // For layout, the status bar is always at the top with our fixed height.
        displayFrames.mStable.top = displayFrames.mUnrestricted.top
@@ -4844,7 +4846,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        mNavigationBar.computeFrameLw(mTmpNavigationFrame, mTmpNavigationFrame,
                mTmpNavigationFrame, displayFrames.mDisplayCutoutSafe, mTmpNavigationFrame, dcf,
                mTmpNavigationFrame, displayFrames.mDisplayCutoutSafe,
                displayFrames.mDisplayCutout);
                displayFrames.mDisplayCutout, false /* parentFrameWasClippedByDisplayCutout */);
        mNavigationBarController.setContentFrame(mNavigationBar.getContentFrameLw());

        if (DEBUG_LAYOUT) Slog.i(TAG, "mNavigationBar frame: " + mTmpNavigationFrame);
@@ -5299,10 +5301,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                        vf.set(cf);
                    }
                }
                pf.intersectUnchecked(displayFrames.mDisplayCutoutSafe);
            }
        }

        boolean parentFrameWasClippedByDisplayCutout = false;
        final int cutoutMode = attrs.layoutInDisplayCutoutMode;
        final boolean attachedInParent = attached != null && !layoutInScreen;
        final boolean requestedHideNavigation =
@@ -5310,7 +5312,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        // Ensure that windows with a DEFAULT or NEVER display cutout mode are laid out in
        // the cutout safe zone.
        if (cutoutMode != LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS) {
            final Rect displayCutoutSafeExceptMaybeBars = mTmpRect;
            final Rect displayCutoutSafeExceptMaybeBars = mTmpDisplayCutoutSafeExceptMaybeBarsRect;
            displayCutoutSafeExceptMaybeBars.set(displayFrames.mDisplayCutoutSafe);
            if (layoutInScreen && layoutInsetDecor && !requestedFullscreen
                    && cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT) {
@@ -5339,10 +5341,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                // The IME can always extend under the bottom cutout if the navbar is there.
                displayCutoutSafeExceptMaybeBars.bottom = Integer.MAX_VALUE;
            }
            // Windows that are attached to a parent and laid out in said parent are already
            // avoidingthe cutout according to that parent and don't need to be further constrained.
            // Windows that are attached to a parent and laid out in said parent already avoid
            // the cutout according to that parent and don't need to be further constrained.
            if (!attachedInParent) {
                mTmpRect.set(pf);
                pf.intersectUnchecked(displayCutoutSafeExceptMaybeBars);
                parentFrameWasClippedByDisplayCutout |= !mTmpRect.equals(pf);
            }
            // Make sure that NO_LIMITS windows clipped to the display don't extend under the
            // cutout.
@@ -5400,7 +5404,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                + " sf=" + sf.toShortString()
                + " osf=" + (osf == null ? "null" : osf.toShortString()));

        win.computeFrameLw(pf, df, of, cf, vf, dcf, sf, osf, displayFrames.mDisplayCutout);
        win.computeFrameLw(pf, df, of, cf, vf, dcf, sf, osf, displayFrames.mDisplayCutout,
                parentFrameWasClippedByDisplayCutout);

        // Dock windows carve out the bottom of the screen, so normal windows
        // can't appear underneath them.
+4 −1
Original line number Diff line number Diff line
@@ -220,10 +220,13 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
         * @param outsetFrame The frame that includes areas that aren't part of the surface but we
         * want to treat them as such.
         * @param displayCutout the display cutout
         * @param parentFrameWasClippedByDisplayCutout true if the parent frame would have been
         * different if there was no display cutout.
         */
        public void computeFrameLw(Rect parentFrame, Rect displayFrame,
                Rect overlayFrame, Rect contentFrame, Rect visibleFrame, Rect decorFrame,
                Rect stableFrame, @Nullable Rect outsetFrame, WmDisplayCutout displayCutout);
                Rect stableFrame, @Nullable Rect outsetFrame, WmDisplayCutout displayCutout,
                boolean parentFrameWasClippedByDisplayCutout);

        /**
         * Retrieve the current frame of the window that has been assigned by
+24 −14
Original line number Diff line number Diff line
@@ -24,7 +24,6 @@ import static android.os.PowerManager.DRAW_WAKE_LOCK;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.SurfaceControl.Transaction;
import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
@@ -35,7 +34,6 @@ import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCRE
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
@@ -46,7 +44,6 @@ import static android.view.WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
import static android.view.WindowManager.LayoutParams.FORMAT_CHANGED;
import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
import static android.view.WindowManager.LayoutParams.MATCH_PARENT;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
@@ -410,6 +407,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP

    private final Rect mParentFrame = new Rect();

    /** Whether the parent frame would have been different if there was no display cutout. */
    private boolean mParentFrameWasClippedByDisplayCutout;

    // The entire screen area of the {@link TaskStack} this window is in. Usually equal to the
    // screen area of the device.
    final Rect mDisplayFrame = new Rect();
@@ -839,7 +839,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
    @Override
    public void computeFrameLw(Rect parentFrame, Rect displayFrame, Rect overscanFrame,
            Rect contentFrame, Rect visibleFrame, Rect decorFrame, Rect stableFrame,
            Rect outsetFrame, WmDisplayCutout displayCutout) {
            Rect outsetFrame, WmDisplayCutout displayCutout,
            boolean parentFrameWasClippedByDisplayCutout) {
        if (mWillReplaceWindow && (mAnimatingExit || !mReplacingRemoveRequested)) {
            // This window is being replaced and either already got information that it's being
            // removed or we are still waiting for some information. Because of this we don't
@@ -848,6 +849,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
            return;
        }
        mHaveFrame = true;
        mParentFrameWasClippedByDisplayCutout = parentFrameWasClippedByDisplayCutout;

        final Task task = getTask();
        final boolean inFullscreenContainer = inFullscreenContainer();
@@ -3055,23 +3057,31 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
            // Only windows with an AppWindowToken are letterboxed.
            return false;
        }
        if (getDisplayContent().getDisplayInfo().displayCutout == null) {
            // No cutout, no letterbox.
        if (!mParentFrameWasClippedByDisplayCutout) {
            // Cutout didn't make a difference, no letterbox
            return false;
        }
        if (mAttrs.layoutInDisplayCutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS) {
            // Layout in cutout, no letterbox.
            return false;
        }
        // TODO: handle dialogs and other non-filling windows
        if (mAttrs.layoutInDisplayCutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER) {
            // Never layout in cutout, always letterbox.
            return true;
        if (!mAttrs.isFullscreen()) {
            // Not filling the parent frame, no letterbox
            return false;
        }
        // Otherwise we need a letterbox if the layout was smaller than the app window token allowed
        // it to be.
        return !frameCoversEntireAppTokenBounds();
    }
        // Letterbox if any fullscreen mode is set.
        final int fl = mAttrs.flags;
        final int sysui = mSystemUiVisibility;
        return (fl & FLAG_FULLSCREEN) != 0 || (sysui & (SYSTEM_UI_FLAG_FULLSCREEN)) != 0;

    /**
     * @return true if this window covers the entire bounds of its app window token
     * @throws NullPointerException if there is no app window token for this window
     */
    private boolean frameCoversEntireAppTokenBounds() {
        mTmpRect.set(mAppToken.getBounds());
        mTmpRect.intersectUnchecked(mFrame);
        return mAppToken.getBounds().equals(mTmpRect);
    }

    @Override
+2 −1
Original line number Diff line number Diff line
@@ -63,7 +63,8 @@ public class FakeWindowState implements WindowManagerPolicy.WindowState {
    @Override
    public void computeFrameLw(Rect parentFrame, Rect displayFrame, Rect overlayFrame,
            Rect contentFrame, Rect visibleFrame, Rect decorFrame, Rect stableFrame,
            @Nullable Rect outsetFrame, WmDisplayCutout displayCutout) {
            @Nullable Rect outsetFrame, WmDisplayCutout displayCutout,
            boolean parentFrameWasClippedByDisplayCutout) {
        this.parentFrame.set(parentFrame);
        this.displayFrame.set(displayFrame);
        this.overscanFrame.set(overlayFrame);
+20 −20
Original line number Diff line number Diff line
@@ -160,7 +160,7 @@ public class WindowFrameTests extends WindowTestsBase {
        // When mFrame extends past cf, the content insets are
        // the difference between mFrame and ContentFrame. Visible
        // and stable frames work the same way.
        w.computeFrameLw(pf, df, of, cf, vf, dcf, sf, null, WmDisplayCutout.NO_CUTOUT);
        w.computeFrameLw(pf, df, of, cf, vf, dcf, sf, null, WmDisplayCutout.NO_CUTOUT, false);
        assertRect(w.mFrame,0, 0, 1000, 1000);
        assertRect(w.mContentInsets, 0, topContentInset, 0, bottomContentInset);
        assertRect(w.mVisibleInsets, 0, topVisibleInset, 0, bottomVisibleInset);
@@ -175,7 +175,7 @@ public class WindowFrameTests extends WindowTestsBase {
        w.mAttrs.width = 100; w.mAttrs.height = 100; //have to clear MATCH_PARENT
        w.mRequestedWidth = 100;
        w.mRequestedHeight = 100;
        w.computeFrameLw(pf, df, of, cf, vf, dcf, sf, null, WmDisplayCutout.NO_CUTOUT);
        w.computeFrameLw(pf, df, of, cf, vf, dcf, sf, null, WmDisplayCutout.NO_CUTOUT, false);
        assertRect(w.mFrame, 100, 100, 200, 200);
        assertRect(w.mContentInsets, 0, 0, 0, 0);
        // In this case the frames are shrunk to the window frame.
@@ -196,7 +196,7 @@ public class WindowFrameTests extends WindowTestsBase {

        // Here the window has FILL_PARENT, FILL_PARENT
        // so we expect it to fill the entire available frame.
        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, WmDisplayCutout.NO_CUTOUT);
        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, WmDisplayCutout.NO_CUTOUT, false);
        assertRect(w.mFrame, 0, 0, 1000, 1000);

        // It can select various widths and heights within the bounds.
@@ -204,14 +204,14 @@ public class WindowFrameTests extends WindowTestsBase {
        // and we use mRequestedWidth/mRequestedHeight
        w.mAttrs.width = 300;
        w.mAttrs.height = 300;
        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, WmDisplayCutout.NO_CUTOUT);
        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, WmDisplayCutout.NO_CUTOUT, false);
        // Explicit width and height without requested width/height
        // gets us nothing.
        assertRect(w.mFrame, 0, 0, 0, 0);

        w.mRequestedWidth = 300;
        w.mRequestedHeight = 300;
        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, WmDisplayCutout.NO_CUTOUT);
        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, WmDisplayCutout.NO_CUTOUT, false);
        // With requestedWidth/Height we can freely choose our size within the
        // parent bounds.
        assertRect(w.mFrame, 0, 0, 300, 300);
@@ -224,14 +224,14 @@ public class WindowFrameTests extends WindowTestsBase {
        w.mRequestedWidth = -1;
        w.mAttrs.width = 100;
        w.mAttrs.height = 100;
        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, WmDisplayCutout.NO_CUTOUT);
        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, WmDisplayCutout.NO_CUTOUT, false);
        assertRect(w.mFrame, 0, 0, 100, 100);
        w.mAttrs.flags = 0;

        // But sizes too large will be clipped to the containing frame
        w.mRequestedWidth = 1200;
        w.mRequestedHeight = 1200;
        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, WmDisplayCutout.NO_CUTOUT);
        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, WmDisplayCutout.NO_CUTOUT, false);
        assertRect(w.mFrame, 0, 0, 1000, 1000);

        // Before they are clipped though windows will be shifted
@@ -239,7 +239,7 @@ public class WindowFrameTests extends WindowTestsBase {
        w.mAttrs.y = 300;
        w.mRequestedWidth = 1000;
        w.mRequestedHeight = 1000;
        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, WmDisplayCutout.NO_CUTOUT);
        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, WmDisplayCutout.NO_CUTOUT, false);
        assertRect(w.mFrame, 0, 0, 1000, 1000);

        // If there is room to move around in the parent frame the window will be shifted according
@@ -249,16 +249,16 @@ public class WindowFrameTests extends WindowTestsBase {
        w.mRequestedWidth = 300;
        w.mRequestedHeight = 300;
        w.mAttrs.gravity = Gravity.RIGHT | Gravity.TOP;
        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, WmDisplayCutout.NO_CUTOUT);
        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, WmDisplayCutout.NO_CUTOUT, false);
        assertRect(w.mFrame, 700, 0, 1000, 300);
        w.mAttrs.gravity = Gravity.RIGHT | Gravity.BOTTOM;
        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, WmDisplayCutout.NO_CUTOUT);
        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, WmDisplayCutout.NO_CUTOUT, false);
        assertRect(w.mFrame, 700, 700, 1000, 1000);
        // Window specified  x and y are interpreted as offsets in the opposite
        // direction of gravity
        w.mAttrs.x = 100;
        w.mAttrs.y = 100;
        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, WmDisplayCutout.NO_CUTOUT);
        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, WmDisplayCutout.NO_CUTOUT, false);
        assertRect(w.mFrame, 600, 600, 900, 900);
    }

@@ -279,7 +279,7 @@ public class WindowFrameTests extends WindowTestsBase {
        w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;

        final Rect pf = new Rect(0, 0, logicalWidth, logicalHeight);
        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, null, WmDisplayCutout.NO_CUTOUT);
        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, null, WmDisplayCutout.NO_CUTOUT, false);
        // For non fullscreen tasks the containing frame is based off the
        // task bounds not the parent frame.
        assertRect(w.mFrame, taskLeft, taskTop, taskRight, taskBottom);
@@ -291,7 +291,7 @@ public class WindowFrameTests extends WindowTestsBase {
        final int cfRight = logicalWidth / 2;
        final int cfBottom = logicalHeight / 2;
        final Rect cf = new Rect(0, 0, cfRight, cfBottom);
        w.computeFrameLw(pf, pf, pf, cf, cf, pf, cf, null, WmDisplayCutout.NO_CUTOUT);
        w.computeFrameLw(pf, pf, pf, cf, cf, pf, cf, null, WmDisplayCutout.NO_CUTOUT, false);
        assertRect(w.mFrame, taskLeft, taskTop, taskRight, taskBottom);
        int contentInsetRight = taskRight - cfRight;
        int contentInsetBottom = taskBottom - cfBottom;
@@ -308,7 +308,7 @@ public class WindowFrameTests extends WindowTestsBase {
        final int insetRight = insetLeft + (taskRight - taskLeft);
        final int insetBottom = insetTop + (taskBottom - taskTop);
        task.mInsetBounds.set(insetLeft, insetTop, insetRight, insetBottom);
        w.computeFrameLw(pf, pf, pf, cf, cf, pf, cf, null, WmDisplayCutout.NO_CUTOUT);
        w.computeFrameLw(pf, pf, pf, cf, cf, pf, cf, null, WmDisplayCutout.NO_CUTOUT, false);
        assertRect(w.mFrame, taskLeft, taskTop, taskRight, taskBottom);
        contentInsetRight = insetRight - cfRight;
        contentInsetBottom = insetBottom - cfBottom;
@@ -340,13 +340,13 @@ public class WindowFrameTests extends WindowTestsBase {

        final Rect policyCrop = new Rect();

        w.computeFrameLw(pf, df, of, cf, vf, dcf, sf, null, WmDisplayCutout.NO_CUTOUT);
        w.computeFrameLw(pf, df, of, cf, vf, dcf, sf, null, WmDisplayCutout.NO_CUTOUT, false);
        w.calculatePolicyCrop(policyCrop);
        assertRect(policyCrop, 0, cf.top, logicalWidth, cf.bottom);

        dcf.setEmpty();
        // Likewise with no decor frame we would get no crop
        w.computeFrameLw(pf, df, of, cf, vf, dcf, sf, null, WmDisplayCutout.NO_CUTOUT);
        w.computeFrameLw(pf, df, of, cf, vf, dcf, sf, null, WmDisplayCutout.NO_CUTOUT, false);
        w.calculatePolicyCrop(policyCrop);
        assertRect(policyCrop, 0, 0, logicalWidth, logicalHeight);

@@ -359,7 +359,7 @@ public class WindowFrameTests extends WindowTestsBase {
        w.mAttrs.height = logicalHeight / 2;
        w.mRequestedWidth = logicalWidth / 2;
        w.mRequestedHeight = logicalHeight / 2;
        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, WmDisplayCutout.NO_CUTOUT);
        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, WmDisplayCutout.NO_CUTOUT, false);

        w.calculatePolicyCrop(policyCrop);
        // Normally the crop is shrunk from the decor frame
@@ -396,7 +396,7 @@ public class WindowFrameTests extends WindowTestsBase {
        final Rect pf = new Rect(0, 0, logicalWidth, logicalHeight);
        w.computeFrameLw(pf /* parentFrame */, pf /* displayFrame */, pf /* overscanFrame */,
                pf /* contentFrame */, pf /* visibleFrame */, pf /* decorFrame */,
                pf /* stableFrame */, null /* outsetFrame */, WmDisplayCutout.NO_CUTOUT);
                pf /* stableFrame */, null /* outsetFrame */, WmDisplayCutout.NO_CUTOUT, false);
        // For non fullscreen tasks the containing frame is based off the
        // task bounds not the parent frame.
        assertRect(w.mFrame, taskLeft, taskTop, taskRight, taskBottom);
@@ -415,7 +415,7 @@ public class WindowFrameTests extends WindowTestsBase {

        w.computeFrameLw(pf /* parentFrame */, pf /* displayFrame */, pf /* overscanFrame */,
                cf /* contentFrame */, cf /* visibleFrame */, pf /* decorFrame */,
                cf /* stableFrame */, null /* outsetFrame */, WmDisplayCutout.NO_CUTOUT);
                cf /* stableFrame */, null /* outsetFrame */, WmDisplayCutout.NO_CUTOUT, false);
        assertEquals(cf, w.mFrame);
        assertEquals(cf, w.getContentFrameLw());
        assertRect(w.mContentInsets, 0, 0, 0, 0);
@@ -433,7 +433,7 @@ public class WindowFrameTests extends WindowTestsBase {
        final WmDisplayCutout cutout = WmDisplayCutout.computeSafeInsets(
                fromBoundingRect(500, 0, 550, 50), pf.width(), pf.height());

        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, cutout);
        w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, cutout, false);

        assertEquals(w.mDisplayCutout.getDisplayCutout().getSafeInsetTop(), 50);
        assertEquals(w.mDisplayCutout.getDisplayCutout().getSafeInsetBottom(), 0);