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

Commit 11c25584 authored by Adrian Roos's avatar Adrian Roos
Browse files

DisplayCutout: account for cutout in appWidth/appHeight etc.

Makes sure to take into account the area blocked by the cutout when
calculating the nonDecor / config / stable insets, widths and heights.

Fixes: 72995358
Fixes: 72444324
Test: atest PhoneWindowManagerInsetsTest
Test: go/wm-smoke
Test: Enter splitscreen, verify that both windows are same size

Change-Id: Iff58235b5bdfd0d49df259a91b05e54e3864f41c
parent 24264214
Loading
Loading
Loading
Loading
+37 −15
Original line number Diff line number Diff line
@@ -2818,16 +2818,20 @@ public class PhoneWindowManager implements WindowManagerPolicy {

    @Override
    public int getNonDecorDisplayWidth(int fullWidth, int fullHeight, int rotation, int uiMode,
            int displayId) {
            int displayId, DisplayCutout displayCutout) {
        int width = fullWidth;
        // TODO(multi-display): Support navigation bar on secondary displays.
        if (displayId == DEFAULT_DISPLAY && mHasNavigationBar) {
            // For a basic navigation bar, when we are in landscape mode we place
            // the navigation bar to the side.
            if (mNavigationBarCanMove && fullWidth > fullHeight) {
                return fullWidth - getNavigationBarWidth(rotation, uiMode);
                width -= getNavigationBarWidth(rotation, uiMode);
            }
        }
        return fullWidth;
        if (displayCutout != null) {
            width -= displayCutout.getSafeInsetLeft() + displayCutout.getSafeInsetRight();
        }
        return width;
    }

    private int getNavigationBarHeight(int rotation, int uiMode) {
@@ -2840,35 +2844,46 @@ public class PhoneWindowManager implements WindowManagerPolicy {

    @Override
    public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation, int uiMode,
            int displayId) {
            int displayId, DisplayCutout displayCutout) {
        int height = fullHeight;
        // TODO(multi-display): Support navigation bar on secondary displays.
        if (displayId == DEFAULT_DISPLAY && mHasNavigationBar) {
            // For a basic navigation bar, when we are in portrait mode we place
            // the navigation bar to the bottom.
            if (!mNavigationBarCanMove || fullWidth < fullHeight) {
                return fullHeight - getNavigationBarHeight(rotation, uiMode);
                height -= getNavigationBarHeight(rotation, uiMode);
            }
        }
        return fullHeight;
        if (displayCutout != null) {
            height -= displayCutout.getSafeInsetTop() + displayCutout.getSafeInsetBottom();
        }
        return height;
    }

    @Override
    public int getConfigDisplayWidth(int fullWidth, int fullHeight, int rotation, int uiMode,
            int displayId) {
        return getNonDecorDisplayWidth(fullWidth, fullHeight, rotation, uiMode, displayId);
            int displayId, DisplayCutout displayCutout) {
        return getNonDecorDisplayWidth(fullWidth, fullHeight, rotation, uiMode, displayId,
                displayCutout);
    }

    @Override
    public int getConfigDisplayHeight(int fullWidth, int fullHeight, int rotation, int uiMode,
            int displayId) {
            int displayId, DisplayCutout displayCutout) {
        // There is a separate status bar at the top of the display.  We don't count that as part
        // of the fixed decor, since it can hide; however, for purposes of configurations,
        // we do want to exclude it since applications can't generally use that part
        // of the screen.
        // TODO(multi-display): Support status bars on secondary displays.
        if (displayId == DEFAULT_DISPLAY) {
            return getNonDecorDisplayHeight(fullWidth, fullHeight, rotation, uiMode, displayId)
                    - mStatusBarHeight;
            int statusBarHeight = mStatusBarHeight;
            if (displayCutout != null) {
                // If there is a cutout, it may already have accounted for some part of the status
                // bar height.
                statusBarHeight = Math.max(0, mStatusBarHeight - displayCutout.getSafeInsetTop());
            }
            return getNonDecorDisplayHeight(fullWidth, fullHeight, rotation, uiMode, displayId,
                    displayCutout) - statusBarHeight;
        }
        return fullHeight;
    }
@@ -6905,17 +6920,17 @@ public class PhoneWindowManager implements WindowManagerPolicy {

    @Override
    public void getStableInsetsLw(int displayRotation, int displayWidth, int displayHeight,
            Rect outInsets) {
            DisplayCutout displayCutout, Rect outInsets) {
        outInsets.setEmpty();

        // Navigation bar and status bar.
        getNonDecorInsetsLw(displayRotation, displayWidth, displayHeight, outInsets);
        outInsets.top = mStatusBarHeight;
        getNonDecorInsetsLw(displayRotation, displayWidth, displayHeight, displayCutout, outInsets);
        outInsets.top = Math.max(outInsets.top, mStatusBarHeight);
    }

    @Override
    public void getNonDecorInsetsLw(int displayRotation, int displayWidth, int displayHeight,
            Rect outInsets) {
            DisplayCutout displayCutout, Rect outInsets) {
        outInsets.setEmpty();

        // Only navigation bar
@@ -6929,6 +6944,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                outInsets.left = getNavigationBarWidth(displayRotation, mUiMode);
            }
        }

        if (displayCutout != null) {
            outInsets.left += displayCutout.getSafeInsetLeft();
            outInsets.top += displayCutout.getSafeInsetTop();
            outInsets.right += displayCutout.getSafeInsetRight();
            outInsets.bottom += displayCutout.getSafeInsetBottom();
        }
    }

    @Override
+12 −10
Original line number Diff line number Diff line
@@ -922,7 +922,7 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
     * button bar.
     */
    public int getNonDecorDisplayWidth(int fullWidth, int fullHeight, int rotation,
            int uiMode, int displayId);
            int uiMode, int displayId, DisplayCutout displayCutout);

    /**
     * Return the display height available after excluding any screen
@@ -930,25 +930,25 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
     * button bar.
     */
    public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation,
            int uiMode, int displayId);
            int uiMode, int displayId, DisplayCutout displayCutout);

    /**
     * Return the available screen width that we should report for the
     * configuration.  This must be no larger than
     * {@link #getNonDecorDisplayWidth(int, int, int, int int, int)}; it may be smaller than
     * that to account for more transient decoration like a status bar.
     * {@link #getNonDecorDisplayWidth(int, int, int, int, int, DisplayCutout)}; it may be smaller
     * than that to account for more transient decoration like a status bar.
     */
    public int getConfigDisplayWidth(int fullWidth, int fullHeight, int rotation,
            int uiMode, int displayId);
            int uiMode, int displayId, DisplayCutout displayCutout);

    /**
     * Return the available screen height that we should report for the
     * configuration.  This must be no larger than
     * {@link #getNonDecorDisplayHeight(int, int, int, int, int)}; it may be smaller than
     * that to account for more transient decoration like a status bar.
     * {@link #getNonDecorDisplayHeight(int, int, int, int, int, DisplayCutout)}; it may be smaller
     * than that to account for more transient decoration like a status bar.
     */
    public int getConfigDisplayHeight(int fullWidth, int fullHeight, int rotation,
            int uiMode, int displayId);
            int uiMode, int displayId, DisplayCutout displayCutout);

    /**
     * Return whether the given window can become the Keyguard window. Typically returns true for
@@ -1639,10 +1639,11 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
     * @param displayRotation the current display rotation
     * @param displayWidth the current display width
     * @param displayHeight the current display height
     * @param displayCutout the current display cutout
     * @param outInsets the insets to return
     */
    public void getStableInsetsLw(int displayRotation, int displayWidth, int displayHeight,
            Rect outInsets);
            DisplayCutout displayCutout, Rect outInsets);


    /**
@@ -1666,10 +1667,11 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
     * @param displayRotation the current display rotation
     * @param displayWidth the current display width
     * @param displayHeight the current display height
     * @param displayCutout the current display cutout
     * @param outInsets the insets to return
     */
    public void getNonDecorInsetsLw(int displayRotation, int displayWidth, int displayHeight,
            Rect outInsets);
            DisplayCutout displayCutout, Rect outInsets);

    /**
     * @return True if a specified {@param dockSide} is allowed on the current device, or false
+25 −19
Original line number Diff line number Diff line
@@ -138,7 +138,6 @@ import android.os.Trace;
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.MutableBoolean;
import android.util.Size;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import android.view.Display;
@@ -1160,10 +1159,12 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        }

        // Update application display metrics.
        final DisplayCutout displayCutout = calculateDisplayCutoutForRotation(
                mRotation);
        final int appWidth = mService.mPolicy.getNonDecorDisplayWidth(dw, dh, mRotation, uiMode,
                mDisplayId);
                mDisplayId, displayCutout);
        final int appHeight = mService.mPolicy.getNonDecorDisplayHeight(dw, dh, mRotation, uiMode,
                mDisplayId);
                mDisplayId, displayCutout);
        mDisplayInfo.rotation = mRotation;
        mDisplayInfo.logicalWidth = dw;
        mDisplayInfo.logicalHeight = dh;
@@ -1174,7 +1175,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
            mDisplayInfo.getLogicalMetrics(mRealDisplayMetrics,
                    CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
        }
        mDisplayInfo.displayCutout = calculateDisplayCutoutForCurrentRotation();
        mDisplayInfo.displayCutout = displayCutout;
        mDisplayInfo.getAppMetrics(mDisplayMetrics);
        if (mDisplayScalingDisabled) {
            mDisplayInfo.flags |= Display.FLAG_SCALING_DISABLED;
@@ -1196,18 +1197,18 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        return mDisplayInfo;
    }

    DisplayCutout calculateDisplayCutoutForCurrentRotation() {
    DisplayCutout calculateDisplayCutoutForRotation(int rotation) {
        final DisplayCutout cutout = mInitialDisplayCutout;
        if (cutout == null || cutout == DisplayCutout.NO_CUTOUT) {
            return cutout;
        }
        if (mRotation == ROTATION_0) {
        if (rotation == ROTATION_0) {
            return cutout.computeSafeInsets(mInitialDisplayWidth, mInitialDisplayHeight);
        }
        final boolean rotated = (mRotation == ROTATION_90 || mRotation == ROTATION_270);
        final boolean rotated = (rotation == ROTATION_90 || mRotation == ROTATION_270);
        final Path bounds = cutout.getBounds().getBoundaryPath();
        transformPhysicalToLogicalCoordinates(mRotation, mInitialDisplayWidth,
                mInitialDisplayHeight, mTmpMatrix);
        transformPhysicalToLogicalCoordinates(rotation, mInitialDisplayWidth, mInitialDisplayHeight,
                mTmpMatrix);
        bounds.transform(mTmpMatrix);
        return DisplayCutout.fromBounds(bounds).computeSafeInsets(
                rotated ? mInitialDisplayHeight : mInitialDisplayWidth,
@@ -1228,14 +1229,16 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        // so the display can be configured for things like fullscreen.
        config.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);

        final float density = mDisplayMetrics.density;
        config.screenWidthDp =
                (int)(mService.mPolicy.getConfigDisplayWidth(dw, dh, displayInfo.rotation,
                        config.uiMode, mDisplayId) / mDisplayMetrics.density);
                        config.uiMode, mDisplayId, displayInfo.displayCutout) / density);
        config.screenHeightDp =
                (int)(mService.mPolicy.getConfigDisplayHeight(dw, dh, displayInfo.rotation,
                        config.uiMode, mDisplayId) / mDisplayMetrics.density);
                        config.uiMode, mDisplayId, displayInfo.displayCutout) / density);

        mService.mPolicy.getNonDecorInsetsLw(displayInfo.rotation, dw, dh, mTmpRect);
        mService.mPolicy.getNonDecorInsetsLw(displayInfo.rotation, dw, dh,
                displayInfo.displayCutout, mTmpRect);
        final int leftInset = mTmpRect.left;
        final int topInset = mTmpRect.top;
        // appBounds at the root level should mirror the app screen size.
@@ -1246,7 +1249,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
                || displayInfo.rotation == Surface.ROTATION_270);

        computeSizeRangesAndScreenLayout(displayInfo, mDisplayId, rotated, config.uiMode, dw, dh,
                mDisplayMetrics.density, config);
                density, config);

        config.screenLayout = (config.screenLayout & ~Configuration.SCREENLAYOUT_ROUND_MASK)
                | ((displayInfo.flags & Display.FLAG_ROUND) != 0
@@ -1358,9 +1361,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
    private int reduceCompatConfigWidthSize(int curSize, int rotation, int uiMode,
            DisplayMetrics dm, int dw, int dh, int displayId) {
        dm.noncompatWidthPixels = mService.mPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode,
                displayId);
                displayId, mDisplayInfo.displayCutout);
        dm.noncompatHeightPixels = mService.mPolicy.getNonDecorDisplayHeight(dw, dh, rotation,
                uiMode, displayId);
                uiMode, displayId, mDisplayInfo.displayCutout);
        float scale = CompatibilityInfo.computeCompatibleScaling(dm, null);
        int size = (int)(((dm.noncompatWidthPixels / scale) / dm.density) + .5f);
        if (curSize == 0 || size < curSize) {
@@ -1412,8 +1415,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
    private int reduceConfigLayout(int curLayout, int rotation, float density, int dw, int dh,
            int uiMode, int displayId) {
        // Get the app screen size at this rotation.
        int w = mService.mPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode, displayId);
        int h = mService.mPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode, displayId);
        int w = mService.mPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode, displayId,
                mDisplayInfo.displayCutout);
        int h = mService.mPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode, displayId,
                mDisplayInfo.displayCutout);

        // Compute the screen layout size class for this rotation.
        int longSize = w;
@@ -1430,8 +1435,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo

    private void adjustDisplaySizeRanges(DisplayInfo displayInfo, int displayId, int rotation,
            int uiMode, int dw, int dh) {
        final DisplayCutout displayCutout = calculateDisplayCutoutForRotation(rotation);
        final int width = mService.mPolicy.getConfigDisplayWidth(dw, dh, rotation, uiMode,
                displayId);
                displayId, displayCutout);
        if (width < displayInfo.smallestNominalAppWidth) {
            displayInfo.smallestNominalAppWidth = width;
        }
@@ -1439,7 +1445,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
            displayInfo.largestNominalAppWidth = width;
        }
        final int height = mService.mPolicy.getConfigDisplayHeight(dw, dh, rotation, uiMode,
                displayId);
                displayId, displayCutout);
        if (height < displayInfo.smallestNominalAppHeight) {
            displayInfo.smallestNominalAppHeight = height;
        }
+17 −12
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import android.os.RemoteException;
import android.util.ArraySet;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import android.view.DisplayCutout;
import android.view.DisplayInfo;
import android.view.IDockedStackListener;
import android.view.animation.AnimationUtils;
@@ -173,6 +174,9 @@ public class DockedStackDividerController {
            final int position = DockedDividerUtils.calculatePositionForBounds(mTmpRect, dockSide,
                    getContentWidth());

            DisplayCutout displayCutout = mDisplayContent.calculateDisplayCutoutForRotation(
                    rotation);

            // Since we only care about feasible states, snap to the closest snap target, like it
            // would happen when actually rotating the screen.
            final int snappedPosition = mSnapAlgorithmForRotation[rotation]
@@ -180,7 +184,7 @@ public class DockedStackDividerController {
            DockedDividerUtils.calculateBoundsForPosition(snappedPosition, dockSide, mTmpRect,
                    mTmpRect2.width(), mTmpRect2.height(), getContentWidth());
            mService.mPolicy.getStableInsetsLw(rotation, mTmpRect2.width(), mTmpRect2.height(),
                    mTmpRect3);
                    displayCutout, mTmpRect3);
            mService.intersectDisplayInsetBounds(mTmpRect2, mTmpRect3, mTmpRect);
            minWidth = Math.min(mTmpRect.width(), minWidth);
        }
@@ -190,7 +194,7 @@ public class DockedStackDividerController {
    void getHomeStackBoundsInDockedMode(Rect outBounds) {
        final DisplayInfo di = mDisplayContent.getDisplayInfo();
        mService.mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight,
                mTmpRect);
                di.displayCutout, mTmpRect);
        int dividerSize = mDividerWindowWidth - 2 * mDividerInsets;
        Configuration configuration = mDisplayContent.getConfiguration();
        // The offset in the left (landscape)/top (portrait) is calculated with the minimized
@@ -228,28 +232,29 @@ public class DockedStackDividerController {
            final int dh = rotated
                    ? mDisplayContent.mBaseDisplayWidth
                    : mDisplayContent.mBaseDisplayHeight;
            mService.mPolicy.getStableInsetsLw(rotation, dw, dh, mTmpRect);
            final DisplayCutout displayCutout =
                    mDisplayContent.calculateDisplayCutoutForRotation(rotation);
            mService.mPolicy.getStableInsetsLw(rotation, dw, dh, displayCutout, mTmpRect);
            config.unset();
            config.orientation = (dw <= dh) ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;

            final int displayId = mDisplayContent.getDisplayId();
            final int appWidth = mService.mPolicy.getNonDecorDisplayWidth(dw, dh, rotation,
                baseConfig.uiMode, displayId);
                baseConfig.uiMode, displayId, displayCutout);
            final int appHeight = mService.mPolicy.getNonDecorDisplayHeight(dw, dh, rotation,
                baseConfig.uiMode, displayId);
            mService.mPolicy.getNonDecorInsetsLw(rotation, dw, dh, mTmpRect);
                baseConfig.uiMode, displayId, mDisplayContent.getDisplayInfo().displayCutout);
            mService.mPolicy.getNonDecorInsetsLw(rotation, dw, dh, displayCutout, mTmpRect);
            final int leftInset = mTmpRect.left;
            final int topInset = mTmpRect.top;

            config.windowConfiguration.setAppBounds(leftInset /*left*/, topInset /*top*/,
                    leftInset + appWidth /*right*/, topInset + appHeight /*bottom*/);

            config.screenWidthDp = (int)
                    (mService.mPolicy.getConfigDisplayWidth(dw, dh, rotation, baseConfig.uiMode,
                            displayId) / mDisplayContent.getDisplayMetrics().density);
            config.screenHeightDp = (int)
                    (mService.mPolicy.getConfigDisplayHeight(dw, dh, rotation, baseConfig.uiMode,
                            displayId) / mDisplayContent.getDisplayMetrics().density);
            final float density = mDisplayContent.getDisplayMetrics().density;
            config.screenWidthDp = (int) (mService.mPolicy.getConfigDisplayWidth(dw, dh,
                    rotation, baseConfig.uiMode, displayId, displayCutout) / density);
            config.screenHeightDp = (int) (mService.mPolicy.getConfigDisplayHeight(dw, dh,
                    rotation, baseConfig.uiMode, displayId, displayCutout) / density);
            final Context rotationContext = mService.mContext.createConfigurationContext(config);
            mSnapAlgorithmForRotation[rotation] = new DividerSnapAlgorithm(
                    rotationContext.getResources(), dw, dh, getContentWidth(),
+1 −1
Original line number Diff line number Diff line
@@ -480,7 +480,7 @@ class PinnedStackController {
    private void getInsetBounds(Rect outRect) {
        synchronized (mService.mWindowMap) {
            mService.mPolicy.getStableInsetsLw(mDisplayInfo.rotation, mDisplayInfo.logicalWidth,
                    mDisplayInfo.logicalHeight, mTmpInsets);
                    mDisplayInfo.logicalHeight, mDisplayInfo.displayCutout, mTmpInsets);
            outRect.set(mTmpInsets.left + mScreenEdgeInsets.x, mTmpInsets.top + mScreenEdgeInsets.y,
                    mDisplayInfo.logicalWidth - mTmpInsets.right - mScreenEdgeInsets.x,
                    mDisplayInfo.logicalHeight - mTmpInsets.bottom - mScreenEdgeInsets.y);
Loading