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

Commit 7e58a08c authored by Adrian Roos's avatar Adrian Roos
Browse files

Multi Cutout: Fix more cutout issues

Ensures that the navigation bar extends all the way to the bottom of the display.

Also ensures the nav bar window is properly padded.

Also ensures that windows that do not hide the navigation bar can extend behind the cutout if
the cutout is within the navigation bar region.

Also ensures that wallpapers (just like dreams) are not letterboxed

Bug: 74195186
Test: Turn on multi-cutout; verify the wallpaper and navigation bars extend all the way to the bottom
Test: Open an immersive app, verify it gets letterboxed
Change-Id: I724080edc26d7ee09dba690f6670d4f66d1c93f6
parent 6a4fa0ec
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ import android.util.MathUtils;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
@@ -912,4 +913,16 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
            return (secure && !canSkipBouncer) ? SECURE_CAMERA_INTENT : INSECURE_CAMERA_INTENT;
        }
    }

    @Override
    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
        int bottom = insets.getDisplayCutout() != null
                ? insets.getDisplayCutout().getSafeInsetBottom() : 0;
        if (isPaddingRelative()) {
            setPaddingRelative(getPaddingStart(), getPaddingTop(), getPaddingEnd(), bottom);
        } else {
            setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), bottom);
        }
        return insets;
    }
}
+9 −0
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.FrameLayout;
@@ -1028,6 +1029,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        requestApplyInsets();
        reorient();
        onPluginDisconnected(null); // Create default gesture helper
        Dependency.get(PluginManager.class).addPluginListener(this,
@@ -1105,6 +1107,13 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
        pw.println("    }");
    }

    @Override
    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
        setPadding(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(),
                insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom());
        return super.onApplyWindowInsets(insets);
    }

    private static void dumpButton(PrintWriter pw, String caption, ButtonDispatcher button) {
        pw.print("      " + caption + ": ");
        if (button == null) {
+33 −14
Original line number Diff line number Diff line
@@ -2680,8 +2680,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                attrs.flags &= ~WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
                break;
            case TYPE_DREAM:
                // Dreams don't have an app window token and can thus not be letterboxed.
                // Hence always let them extend under the cutout.
            case TYPE_WALLPAPER:
                // Dreams and wallpapers don't have an app window token and can thus not be
                // letterboxed. Hence always let them extend under the cutout.
                attrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
                break;
            case TYPE_STATUS_BAR:
@@ -4748,7 +4749,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            // It's a system nav bar or a portrait screen; nav bar goes on bottom.
            final int top = cutoutSafeUnrestricted.bottom
                    - getNavigationBarHeight(rotation, uiMode);
            mTmpNavigationFrame.set(0, top, displayWidth, cutoutSafeUnrestricted.bottom);
            mTmpNavigationFrame.set(0, top, displayWidth, displayFrames.mUnrestricted.bottom);
            displayFrames.mStable.bottom = displayFrames.mStableFullscreen.bottom = top;
            if (transientNavBarShowing) {
                mNavigationBarController.setBarShowingLw(true);
@@ -4771,7 +4772,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            // Landscape screen; nav bar goes to the right.
            final int left = cutoutSafeUnrestricted.right
                    - getNavigationBarWidth(rotation, uiMode);
            mTmpNavigationFrame.set(left, 0, cutoutSafeUnrestricted.right, displayHeight);
            mTmpNavigationFrame.set(left, 0, displayFrames.mUnrestricted.right, displayHeight);
            displayFrames.mStable.right = displayFrames.mStableFullscreen.right = left;
            if (transientNavBarShowing) {
                mNavigationBarController.setBarShowingLw(true);
@@ -4794,7 +4795,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            // Seascape screen; nav bar goes to the left.
            final int right = cutoutSafeUnrestricted.left
                    + getNavigationBarWidth(rotation, uiMode);
            mTmpNavigationFrame.set(cutoutSafeUnrestricted.left, 0, right, displayHeight);
            mTmpNavigationFrame.set(displayFrames.mUnrestricted.left, 0, right, displayHeight);
            displayFrames.mStable.left = displayFrames.mStableFullscreen.left = right;
            if (transientNavBarShowing) {
                mNavigationBarController.setBarShowingLw(true);
@@ -4823,8 +4824,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        mStatusBarLayer = mNavigationBar.getSurfaceLayer();
        // And compute the final frame.
        mNavigationBar.computeFrameLw(mTmpNavigationFrame, mTmpNavigationFrame,
                mTmpNavigationFrame, mTmpNavigationFrame, mTmpNavigationFrame, dcf,
                mTmpNavigationFrame, mTmpNavigationFrame, displayFrames.mDisplayCutout);
                mTmpNavigationFrame, displayFrames.mDisplayCutoutSafe, mTmpNavigationFrame, dcf,
                mTmpNavigationFrame, displayFrames.mDisplayCutoutSafe,
                displayFrames.mDisplayCutout);
        if (DEBUG_LAYOUT) Slog.i(TAG, "mNavigationBar frame: " + mTmpNavigationFrame);
        return mNavigationBarController.checkHiddenLw();
    }
@@ -5292,27 +5294,44 @@ public class PhoneWindowManager implements WindowManagerPolicy {

        final int cutoutMode = attrs.layoutInDisplayCutoutMode;
        final boolean attachedInParent = attached != null && !layoutInScreen;
        final boolean requestedHideNavigation =
                (requestedSysUiFl & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0;
        // 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 displayCutoutSafeExceptMaybeTop = mTmpRect;
            displayCutoutSafeExceptMaybeTop.set(displayFrames.mDisplayCutoutSafe);
            final Rect displayCutoutSafeExceptMaybeBars = mTmpRect;
            displayCutoutSafeExceptMaybeBars.set(displayFrames.mDisplayCutoutSafe);
            if (layoutInScreen && layoutInsetDecor && !requestedFullscreen
                    && cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT) {
                // At the top we have the status bar, so apps that are
                // LAYOUT_IN_SCREEN | LAYOUT_INSET_DECOR but not FULLSCREEN
                // already expect that there's an inset there and we don't need to exclude
                // the window from that area.
                displayCutoutSafeExceptMaybeTop.top = Integer.MIN_VALUE;
                displayCutoutSafeExceptMaybeBars.top = Integer.MIN_VALUE;
            }
            if (layoutInScreen && layoutInsetDecor && !requestedHideNavigation
                    && cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT) {
                // Same for the navigation bar.
                switch (mNavigationBarPosition) {
                    case NAV_BAR_BOTTOM:
                        displayCutoutSafeExceptMaybeBars.bottom = Integer.MAX_VALUE;
                        break;
                    case NAV_BAR_RIGHT:
                        displayCutoutSafeExceptMaybeBars.right = Integer.MAX_VALUE;
                        break;
                    case NAV_BAR_LEFT:
                        displayCutoutSafeExceptMaybeBars.left = Integer.MIN_VALUE;
                        break;
                }
            }
            // 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.
            if (!attachedInParent) {
                pf.intersectUnchecked(displayCutoutSafeExceptMaybeTop);
                pf.intersectUnchecked(displayCutoutSafeExceptMaybeBars);
            }
            // Make sure that NO_LIMITS windows clipped to the display don't extend into the display
            // don't extend under the cutout.
            df.intersectUnchecked(displayCutoutSafeExceptMaybeTop);
            // Make sure that NO_LIMITS windows clipped to the display don't extend under the
            // cutout.
            df.intersectUnchecked(displayCutoutSafeExceptMaybeBars);
        }

        // Content should never appear in the cutout.