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

Commit 9374f3cb authored by Graciela Wissen Putri's avatar Graciela Wissen Putri
Browse files

Overlap navbar with letterboxed immersive app

When immersive app is letterboxed, it has a large space not occupied
left at the bottom of the screen in 3 button navigation mode. This is
due to transient nav bar insets not included to calculate
positionMultiplier. To overlap app with navbar, bounds should be used
instead of appBounds.

Fix: 277543176
Test: Manual && atest WmTests:SizeCompatTests
Change-Id: I93f40e4d23193485015c26c3ec3f808675d1cd64
parent e0fe75c3
Loading
Loading
Loading
Loading
+20 −11
Original line number Diff line number Diff line
@@ -8445,21 +8445,23 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    private void updateResolvedBoundsPosition(Configuration newParentConfiguration) {
        final Configuration resolvedConfig = getResolvedOverrideConfiguration();
        final Rect resolvedBounds = resolvedConfig.windowConfiguration.getBounds();
        if (resolvedBounds.isEmpty()) {
            return;
        }
        final Rect screenResolvedBounds =
                mSizeCompatBounds != null ? mSizeCompatBounds : resolvedBounds;
        final Rect parentAppBounds = newParentConfiguration.windowConfiguration.getAppBounds();
        final Rect parentBounds = newParentConfiguration.windowConfiguration.getBounds();
        if (resolvedBounds.isEmpty()) {
            return;
        }
        final float screenResolvedBoundsWidth = screenResolvedBounds.width();
        final float parentAppBoundsWidth = parentAppBounds.width();
        // Horizontal position
        int offsetX = 0;
        if (parentBounds.width() != screenResolvedBounds.width()) {
            if (screenResolvedBounds.width() <= parentAppBounds.width()) {
        if (parentBounds.width() != screenResolvedBoundsWidth) {
            if (screenResolvedBoundsWidth <= parentAppBoundsWidth) {
                float positionMultiplier = mLetterboxUiController.getHorizontalPositionMultiplier(
                        newParentConfiguration);
                offsetX = Math.max(0, (int) Math.ceil((parentAppBounds.width()
                        - screenResolvedBounds.width()) * positionMultiplier)
                offsetX = Math.max(0, (int) Math.ceil((parentAppBoundsWidth
                        - screenResolvedBoundsWidth) * positionMultiplier)
                        // This is added to make sure that insets added inside
                        // CompatDisplayInsets#getContainerBounds() do not break the alignment
                        // provided by the positionMultiplier
@@ -8467,14 +8469,21 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
            }
        }

        final float parentAppBoundsHeight = parentAppBounds.height();
        final float parentBoundsHeight = parentBounds.height();
        final float screenResolvedBoundsHeight = screenResolvedBounds.height();
        // Vertical position
        int offsetY = 0;
        if (parentBounds.height() != screenResolvedBounds.height()) {
            if (screenResolvedBounds.height() <= parentAppBounds.height()) {
        if (parentBoundsHeight != screenResolvedBoundsHeight) {
            if (screenResolvedBoundsHeight <= parentAppBoundsHeight) {
                float positionMultiplier = mLetterboxUiController.getVerticalPositionMultiplier(
                        newParentConfiguration);
                offsetY = Math.max(0, (int) Math.ceil((parentAppBounds.height()
                        - screenResolvedBounds.height()) * positionMultiplier)
                // If in immersive mode, always align to bottom and overlap bottom insets (nav bar,
                // task bar) as they are transient and hidden. This removes awkward bottom spacing.
                final float newHeight = mDisplayContent.getDisplayPolicy().isImmersiveMode()
                        ? parentBoundsHeight : parentAppBoundsHeight;
                offsetY = Math.max(0, (int) Math.ceil((newHeight
                        - screenResolvedBoundsHeight) * positionMultiplier)
                        // This is added to make sure that insets added inside
                        // CompatDisplayInsets#getContainerBounds() do not break the alignment
                        // provided by the positionMultiplier
+4 −0
Original line number Diff line number Diff line
@@ -1248,6 +1248,10 @@ public class DisplayPolicy {
        return mNavigationBar;
    }

    boolean isImmersiveMode() {
        return mIsImmersiveMode;
    }

    /**
     * Control the animation to run when a window's state changes.  Return a positive number to
     * force the animation to a specific resource ID, {@link #ANIMATION_STYLEABLE} to use the
+46 −1
Original line number Diff line number Diff line
@@ -3510,6 +3510,51 @@ public class SizeCompatTests extends WindowTestsBase {
        assertEquals(expectedHeight, capturedCrops.get(1).bottom);
    }

    @Test
    public void testLetterboxAlignedToBottom_NotOverlappingNavbar() {
        assertLandscapeActivityAlignedToBottomWithNavbar(false /* immersive */);
    }

    @Test
    public void testImmersiveLetterboxAlignedToBottom_OverlappingNavbar() {
        assertLandscapeActivityAlignedToBottomWithNavbar(true /* immersive */);
    }

    private void assertLandscapeActivityAlignedToBottomWithNavbar(boolean immersive) {
        final int screenHeight = 2800;
        final int screenWidth = 1400;
        final int taskbarHeight = 200;
        setUpDisplaySizeWithApp(screenWidth, screenHeight);

        mActivity.mDisplayContent.setIgnoreOrientationRequest(true);
        mActivity.mWmService.mLetterboxConfiguration.setLetterboxVerticalPositionMultiplier(1.0f);

        final InsetsSource navSource = new InsetsSource(
                InsetsSource.createId(null, 0, navigationBars()), navigationBars());
        navSource.setInsetsRoundedCornerFrame(true);
        // Immersive activity has transient navbar
        navSource.setVisible(!immersive);
        navSource.setFrame(new Rect(0, screenHeight - taskbarHeight, screenWidth, screenHeight));
        mActivity.mWmService.mLetterboxConfiguration.setLetterboxActivityCornersRadius(15);

        final WindowState w1 = addWindowToActivity(mActivity);
        w1.mAboveInsetsState.addSource(navSource);

        // Prepare unresizable landscape activity
        prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE);
        final DisplayPolicy displayPolicy = mActivity.mDisplayContent.getDisplayPolicy();
        doReturn(immersive).when(displayPolicy).isImmersiveMode();

        mActivity.mRootWindowContainer.performSurfacePlacement();

        LetterboxDetails letterboxDetails = mActivity.mLetterboxUiController.getLetterboxDetails();

        // Letterboxed activity at bottom
        assertEquals(new Rect(0, 2100, 1400, 2800), mActivity.getBounds());
        final int expectedHeight = immersive ? screenHeight : screenHeight - taskbarHeight;
        assertEquals(expectedHeight, letterboxDetails.getLetterboxInnerBounds().bottom);
    }

    @Test
    public void testSplitScreenLetterboxDetailsForStatusBar_twoLetterboxedApps() {
        mAtm.mDevEnableNonResizableMultiWindow = true;
@@ -3938,7 +3983,7 @@ public class SizeCompatTests extends WindowTestsBase {
        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
        mWm.mLetterboxConfiguration.setIsAutomaticReachabilityInBookModeEnabled(true);
        mWm.mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(
                1.0f /*letterboxVerticalPositionMultiplier*/);
                1.0f /*letterboxHorizontalPositionMultiplier*/);
        prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);

        Rect letterboxNoFold = new Rect(2100, 0, 2800, 1400);