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

Commit 465b7dea authored by shawnlin's avatar shawnlin
Browse files

Make SHORT_EDGES mode only extends on the short edges

- In R, we allow long edge cutouts and therefore a new ALWAYS flag is
added which allow apps to be laid out in all edges. So now we have to
ensure apps with SHORT_EDGES mode to be laid out only in short edges.

- Set wallpapaer window to ALWAYS mode

Bug: 146876976
Test: atest DisplayPolicyLayoutTests
Test: atest WallpaperTests
Change-Id: Iaf820b5c8105927e61b30d389a659b9d28db3f94
parent ed1e5bb8
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -3687,6 +3687,8 @@ public interface WindowManager extends ViewManager {
                    return "always";
                case LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER:
                    return "never";
                case LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES:
                    return "shortEdges";
                default:
                    return "unknown(" + mode + ")";
            }
+17 −7
Original line number Diff line number Diff line
@@ -57,8 +57,8 @@ import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATIO
import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
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_DEFAULT;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR;
@@ -855,7 +855,7 @@ public class DisplayPolicy {
            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_SHORT_EDGES;
                attrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
                break;
            case TYPE_NOTIFICATION_SHADE:
                // If the Keyguard is in a hidden state (occluded by another window), we force to
@@ -2298,15 +2298,24 @@ public class DisplayPolicy {
        // cropped / shifted to the displayFrame in WindowState.
        final boolean floatingInScreenWindow = !attrs.isFullscreen() && layoutInScreen
                && type != TYPE_BASE_APPLICATION;

        // 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_DEFAULT
                || cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER) {
        if (cutoutMode != LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS) {
            final Rect displayCutoutSafeExceptMaybeBars = sTmpDisplayCutoutSafeExceptMaybeBarsRect;
            displayCutoutSafeExceptMaybeBars.set(displayFrames.mDisplayCutoutSafe);
            if (cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES) {
                if (displayFrames.mDisplayWidth < displayFrames.mDisplayHeight) {
                    displayCutoutSafeExceptMaybeBars.top = Integer.MIN_VALUE;
                    displayCutoutSafeExceptMaybeBars.bottom = Integer.MAX_VALUE;
                } else {
                    displayCutoutSafeExceptMaybeBars.left = Integer.MIN_VALUE;
                    displayCutoutSafeExceptMaybeBars.right = Integer.MAX_VALUE;
                }
            }

            if (layoutInScreen && layoutInsetDecor && !requestedFullscreen
                    && cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT) {
                    && (cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
                    || cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES)) {
                // 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
@@ -2314,7 +2323,8 @@ public class DisplayPolicy {
                displayCutoutSafeExceptMaybeBars.top = Integer.MIN_VALUE;
            }
            if (layoutInScreen && layoutInsetDecor && !requestedHideNavigation
                    && cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT) {
                    && (cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
                    || cutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES)) {
                // Same for the navigation bar.
                switch (mNavigationBarPosition) {
                    case NAV_BAR_BOTTOM:
+1 −1
Original line number Diff line number Diff line
@@ -174,6 +174,6 @@ public class DisplayPolicyInsetsTests extends DisplayPolicyTestsBase {
    }

    private static DisplayInfo displayInfoForRotation(int rotation, boolean withDisplayCutout) {
        return displayInfoAndCutoutForRotation(rotation, withDisplayCutout).first;
        return displayInfoAndCutoutForRotation(rotation, withDisplayCutout, false).first;
    }
}
+131 −1
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
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.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
@@ -91,6 +92,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
    private WindowState mWindow;
    private int mRotation = ROTATION_0;
    private boolean mHasDisplayCutout;
    private boolean mIsLongEdgeDisplayCutout;
    private static final int DECOR_WINDOW_INSET = 50;

    @Before
@@ -124,6 +126,12 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
        updateDisplayFrames();
    }

    public void addLongEdgeDisplayCutout() {
        mHasDisplayCutout = true;
        mIsLongEdgeDisplayCutout = true;
        updateDisplayFrames();
    }

    private void updateDisplayFrames() {
        mFrames = createDisplayFrames();
        mDisplayContent.mDisplayFrames = mFrames;
@@ -131,7 +139,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {

    private DisplayFrames createDisplayFrames() {
        final Pair<DisplayInfo, WmDisplayCutout> info = displayInfoAndCutoutForRotation(mRotation,
                mHasDisplayCutout);
                mHasDisplayCutout, mIsLongEdgeDisplayCutout);
        return new DisplayFrames(mDisplayContent.getDisplayId(), info.first, info.second);
    }

@@ -375,6 +383,46 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
        assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, 0);
    }

    @Test
    public void layoutWindowLw_withDisplayCutout_shortEdges() {
        addDisplayCutout();

        mWindow.mAttrs.flags =
                FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
        mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
        mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
        addWindow(mWindow);

        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);

        assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0);
        assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
        assertInsetBy(mWindow.getContentFrameLw(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
        assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
        assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
    }

    @Test
    public void layoutWindowLw_withDisplayCutout_always() {
        addDisplayCutout();

        mWindow.mAttrs.flags =
                FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
        mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
        mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
        addWindow(mWindow);

        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);

        assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0);
        assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
        assertInsetBy(mWindow.getContentFrameLw(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
        assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
        assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
    }

    @Test
    public void layoutWindowLw_withDisplayCutout_layoutFullscreen() {
        addDisplayCutout();
@@ -550,6 +598,88 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
        assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
    }

    @Test
    public void layoutWindowLw_withLongEdgeDisplayCutout() {
        addLongEdgeDisplayCutout();

        mWindow.mAttrs.flags =
                FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
        addWindow(mWindow);

        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);

        assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
        assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
        assertInsetBy(mWindow.getContentFrameLw(), DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, 0,
                NAV_BAR_HEIGHT);
        assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
        assertInsetBy(mWindow.getDisplayFrameLw(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
    }

    @Test
    public void layoutWindowLw_withLongEdgeDisplayCutout_never() {
        addLongEdgeDisplayCutout();

        mWindow.mAttrs.flags =
                FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
        mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
        addWindow(mWindow);

        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);

        assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
        assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, 0,
                NAV_BAR_HEIGHT);
        assertInsetBy(mWindow.getContentFrameLw(), DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, 0,
                NAV_BAR_HEIGHT);
        assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
        assertInsetBy(mWindow.getDisplayFrameLw(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
    }

    @Test
    public void layoutWindowLw_withLongEdgeDisplayCutout_shortEdges() {
        addLongEdgeDisplayCutout();

        mWindow.mAttrs.flags =
                FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
        mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
        mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
        addWindow(mWindow);

        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);

        assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
        assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
        assertInsetBy(mWindow.getContentFrameLw(), DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, 0,
                NAV_BAR_HEIGHT);
        assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
        assertInsetBy(mWindow.getDisplayFrameLw(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
    }

    @Test
    public void layoutWindowLw_withLongEdgeDisplayCutout_always() {
        addLongEdgeDisplayCutout();

        mWindow.mAttrs.flags =
                FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
        mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
        mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
        addWindow(mWindow);

        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);

        assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0);
        assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT);
        assertInsetBy(mWindow.getContentFrameLw(), DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, 0,
                NAV_BAR_HEIGHT);
        assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
        assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
    }

    @Test
    public void layoutWindowLw_withForwardInset_SoftInputAdjustResize() {
        assumeTrue(ViewRootImpl.sNewInsetsMode == ViewRootImpl.NEW_INSETS_MODE_NONE);
+13 −9
Original line number Diff line number Diff line
@@ -111,7 +111,7 @@ public class DisplayPolicyTestsBase extends WindowTestsBase {
    }

    static Pair<DisplayInfo, WmDisplayCutout> displayInfoAndCutoutForRotation(int rotation,
            boolean withDisplayCutout) {
            boolean withDisplayCutout, boolean isLongEdgeCutout) {
        final DisplayInfo info = new DisplayInfo();
        WmDisplayCutout cutout = null;

@@ -121,7 +121,7 @@ public class DisplayPolicyTestsBase extends WindowTestsBase {
        info.rotation = rotation;
        if (withDisplayCutout) {
            cutout = WmDisplayCutout.computeSafeInsets(
                    displayCutoutForRotation(rotation), info.logicalWidth,
                    displayCutoutForRotation(rotation, isLongEdgeCutout), info.logicalWidth,
                    info.logicalHeight);
            info.displayCutout = cutout.getDisplayCutout();
        } else {
@@ -130,9 +130,13 @@ public class DisplayPolicyTestsBase extends WindowTestsBase {
        return Pair.create(info, cutout);
    }

    private static DisplayCutout displayCutoutForRotation(int rotation) {
        final RectF rectF =
                new RectF(DISPLAY_WIDTH / 4, 0, DISPLAY_WIDTH * 3 / 4, DISPLAY_CUTOUT_HEIGHT);
    private static DisplayCutout displayCutoutForRotation(int rotation, boolean isLongEdgeCutout) {
        RectF rectF = new RectF();
        if (isLongEdgeCutout) {
            rectF.set(0, DISPLAY_HEIGHT / 4, DISPLAY_CUTOUT_HEIGHT, DISPLAY_HEIGHT * 3 / 4);
        } else {
            rectF.set(DISPLAY_WIDTH / 4, 0, DISPLAY_WIDTH * 3 / 4, DISPLAY_CUTOUT_HEIGHT);
        }

        final Matrix m = new Matrix();
        transformPhysicalToLogicalCoordinates(rotation, DISPLAY_WIDTH, DISPLAY_HEIGHT, m);
@@ -141,16 +145,16 @@ public class DisplayPolicyTestsBase extends WindowTestsBase {
        int pos = -1;
        switch (rotation) {
            case ROTATION_0:
                pos = BOUNDS_POSITION_TOP;
                pos = isLongEdgeCutout ? BOUNDS_POSITION_LEFT : BOUNDS_POSITION_TOP;
                break;
            case ROTATION_90:
                pos = BOUNDS_POSITION_LEFT;
                pos = isLongEdgeCutout ? BOUNDS_POSITION_BOTTOM : BOUNDS_POSITION_LEFT;
                break;
            case ROTATION_180:
                pos = BOUNDS_POSITION_BOTTOM;
                pos = isLongEdgeCutout ? BOUNDS_POSITION_RIGHT : BOUNDS_POSITION_BOTTOM;
                break;
            case ROTATION_270:
                pos = BOUNDS_POSITION_RIGHT;
                pos = isLongEdgeCutout ? BOUNDS_POSITION_TOP : BOUNDS_POSITION_RIGHT;
                break;
        }