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

Commit 27cec324 authored by Bryce Lee's avatar Bryce Lee
Browse files

Add configuration for maximum UI width.

This changelist adds config_maxUiWidth, a new system resource
configuration which specifies the maximum width the user interface
can operate in. If the physical or specified width is greater than
this value, dimensions and density are scaled down accordingly. The
native mode resolution can be still discovered through
Display.Mode#getPhysicalWidth/getPhysicalHeight.

Test: Defined override for development device and verified values.
Test: bit FrameworksServicesTests:com.android.server.wm.DisplayContentTests#testMaxUiWidth
Change-Id: I12e7ad52f2aa8014e143bc7e80b020c9b24ed9c8
Fixes: 25820708
parent cf1f1d91
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -2801,4 +2801,9 @@

    <!-- Colon separated list of package names that should be granted Notification Listener access -->
    <string name="config_defaultListenerAccessPackages" translatable="false"></string>

    <!-- Maximum size, specified in pixels, to restrain the display space width to. Height and
         density will be scaled accordingly to maintain aspect ratio. A value of 0 indicates no
         constraint will be enforced. -->
    <integer name="config_maxUiWidth">0</integer>
</resources>
+3 −0
Original line number Diff line number Diff line
@@ -2923,6 +2923,9 @@
  <!-- Colon separated list of package names that should be granted Notification Listener access -->
  <java-symbol type="string" name="config_defaultListenerAccessPackages" />

  <!-- maximum width of the display -->
  <java-symbol type="integer" name="config_maxUiWidth" />

  <!-- system notification channels -->
  <java-symbol type="string" name="notification_channel_virtual_keyboard" />
  <java-symbol type="string" name="notification_channel_physical_keyboard" />
+34 −0
Original line number Diff line number Diff line
@@ -175,6 +175,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
    private boolean mTmpRecoveringMemory;
    private boolean mUpdateImeTarget;
    private boolean mTmpInitial;
    private int mMaxUiWidth;

    // Mapping from a token IBinder to a WindowToken object on this display.
    private final HashMap<IBinder, WindowToken> mTokenMap = new HashMap();
@@ -1559,6 +1560,39 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        }
    }

    /** Sets the maximum width the screen resolution can be */
    void setMaxUiWidth(int width) {
        if (DEBUG_DISPLAY) {
            Slog.v(TAG_WM, "Setting max ui width:" + width + " on display:" + getDisplayId());
        }

        mMaxUiWidth = width;

        // Update existing metrics.
        updateBaseDisplayMetrics(mBaseDisplayWidth, mBaseDisplayHeight, mBaseDisplayDensity);
    }

    /** Update base (override) display metrics. */
    void updateBaseDisplayMetrics(int baseWidth, int baseHeight, int baseDensity) {
        mBaseDisplayWidth = baseWidth;
        mBaseDisplayHeight = baseHeight;
        mBaseDisplayDensity = baseDensity;

        if (mMaxUiWidth > 0 && mBaseDisplayWidth > mMaxUiWidth) {
            mBaseDisplayHeight = (mMaxUiWidth * mBaseDisplayHeight) / mBaseDisplayWidth;
            mBaseDisplayDensity = (mMaxUiWidth * mBaseDisplayDensity) / mBaseDisplayWidth;
            mBaseDisplayWidth = mMaxUiWidth;

            if (DEBUG_DISPLAY) {
                Slog.v(TAG_WM, "Applying config restraints:" + mBaseDisplayWidth + "x"
                        + mBaseDisplayHeight + " at density:" + mBaseDisplayDensity
                        + " on display:" + getDisplayId());
            }
        }

        mBaseDisplayRect.set(0, 0, mBaseDisplayWidth, mBaseDisplayHeight);
    }

    void getContentRect(Rect out) {
        out.set(mContentRect);
    }
+6 −0
Original line number Diff line number Diff line
@@ -385,6 +385,7 @@ public class WindowManagerService extends IWindowManager.Stub
    final boolean mAllowBootMessages;

    final boolean mLimitedAlphaCompositing;
    final int mMaxUiWidth;

    final WindowManagerPolicy mPolicy;

@@ -949,6 +950,8 @@ public class WindowManagerService extends IWindowManager.Stub
                com.android.internal.R.integer.config_drawLockTimeoutMillis);
        mAllowAnimationsInLowPowerMode = context.getResources().getBoolean(
                com.android.internal.R.bool.config_allowAnimationsInLowPowerMode);
        mMaxUiWidth = context.getResources().getInteger(
                com.android.internal.R.integer.config_maxUiWidth);
        mInputManager = inputManager; // Must be before createDisplayContentLocked.
        mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
        mDisplaySettings = new DisplaySettings();
@@ -4572,6 +4575,9 @@ public class WindowManagerService extends IWindowManager.Stub

        synchronized(mWindowMap) {
            final DisplayContent displayContent = getDefaultDisplayContentLocked();
            if (mMaxUiWidth > 0) {
                displayContent.setMaxUiWidth(mMaxUiWidth);
            }
            readForcedDisplayPropertiesLocked(displayContent);
            mDisplayReady = true;
        }
+42 −0
Original line number Diff line number Diff line
@@ -254,6 +254,48 @@ public class DisplayContentTests extends WindowTestsBase {
        assertEquals(window1, sWm.mRoot.computeFocusedWindow());
    }

    /**
     * This tests setting the maximum ui width on a display.
     */
    @Test
    public void testMaxUiWidth() throws Exception {
        final int baseWidth = 1440;
        final int baseHeight = 2560;
        final int baseDensity = 300;

        sDisplayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);

        final int maxWidth = 300;
        final int resultingHeight = (maxWidth * baseHeight) / baseWidth;
        final int resultingDensity = (maxWidth * baseDensity) / baseWidth;

        sDisplayContent.setMaxUiWidth(maxWidth);
        verifySizes(sDisplayContent, maxWidth, resultingHeight, resultingDensity);

        // Assert setting values again does not change;
        sDisplayContent.updateBaseDisplayMetrics(baseWidth, baseHeight, baseDensity);
        verifySizes(sDisplayContent, maxWidth, resultingHeight, resultingDensity);

        final int smallerWidth = 200;
        final int smallerHeight = 400;
        final int smallerDensity = 100;

        // Specify smaller dimension, verify that it is honored
        sDisplayContent.updateBaseDisplayMetrics(smallerWidth, smallerHeight, smallerDensity);
        verifySizes(sDisplayContent, smallerWidth, smallerHeight, smallerDensity);

        // Verify that setting the max width to a greater value than the base width has no effect
        sDisplayContent.setMaxUiWidth(maxWidth);
        verifySizes(sDisplayContent, smallerWidth, smallerHeight, smallerDensity);
    }

    private static void verifySizes(DisplayContent displayContent, int expectedBaseWidth,
                             int expectedBaseHeight, int expectedBaseDensity) {
        assertEquals(displayContent.mBaseDisplayWidth, expectedBaseWidth);
        assertEquals(displayContent.mBaseDisplayHeight, expectedBaseHeight);
        assertEquals(displayContent.mBaseDisplayDensity, expectedBaseDensity);
    }

    private void assertForAllWindowsOrder(List<WindowState> expectedWindows) {
        final LinkedList<WindowState> actualWindows = new LinkedList();