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

Commit fab3737b authored by Naomi Musgrave's avatar Naomi Musgrave
Browse files

Do not allow Display#getRealMetrics to return values reflecting

the app bounds.

Fixes Display#getRealMetrics sandboxing bug, where a non-null
configuration results in DisplayInfo ignoring max bounds width
and height for app bounds. Consistent with non-sandboxing
implementation of Display#getRealMetrics

Bug: 182377479
Test: atest FrameworksMockingCoreTests:android.view.DisplayTests
Change-Id: I067aeb020e1ca214aa269182c475b4553de0eb09
parent d3035fe4
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -636,7 +636,9 @@ public final class DisplayInfo implements Parcelable {
    public void getMaxBoundsMetrics(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
            Configuration configuration) {
        Rect bounds = configuration.windowConfiguration.getMaxBounds();
        getMetricsWithSize(outMetrics, compatInfo, configuration, bounds.width(), bounds.height());
        // Pass in null configuration to ensure width and height are not overridden to app bounds.
        getMetricsWithSize(outMetrics, compatInfo, /* configuration= */ null,
                bounds.width(), bounds.height());
    }

    public int getNaturalWidth() {
+84 −23
Original line number Diff line number Diff line
@@ -73,6 +73,11 @@ public class DisplayTests {
    private static Rect sAppBoundsPortrait = buildAppBounds(LOGICAL_WIDTH, LOGICAL_HEIGHT);
    private static Rect sAppBoundsLandscape = buildAppBounds(LOGICAL_HEIGHT, LOGICAL_WIDTH);

    // Bounds of the device.
    private static Rect sDeviceBoundsPortrait = new Rect(0, 0, LOGICAL_WIDTH, LOGICAL_HEIGHT);
    private static Rect sDeviceBoundsLandscape = new Rect(0, 0, LOGICAL_HEIGHT, LOGICAL_WIDTH);


    private StaticMockitoSession mMockitoSession;

    private DisplayManagerGlobal mDisplayManagerGlobal;
@@ -278,29 +283,57 @@ public class DisplayTests {
    }

    @Test
    public void testGetRealSize_resourcesPortraitSandboxed_matchesSandboxBounds() {
    public void testGetRealSize_resourcesPortraitSandboxed_matchesAppSandboxBounds() {
        // GIVEN display is not rotated.
        setDisplayInfoPortrait(mDisplayInfo);
        // GIVEN app is letterboxed.
        setMaxBoundsSandboxedToMatchAppBounds(mApplicationContext.getResources(),
                sAppBoundsPortrait);
        setMaxBoundsSandboxed(mApplicationContext.getResources(), sAppBoundsPortrait);
        final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
                mApplicationContext.getResources());
        // THEN real size matches app bounds.
        verifyRealSizeMatchesApp(display, sAppBoundsPortrait);
        verifyRealSizeMatchesBounds(display, sAppBoundsPortrait);
    }

    @Test
    public void testGetRealSize_resourcesLandscapeSandboxed_matchesSandboxBounds() {
    public void testGetRealSize_resourcesPortraitSandboxed_matchesDisplayAreaSandboxBounds() {
        // GIVEN display is not rotated.
        setDisplayInfoPortrait(mDisplayInfo);
        // GIVEN max bounds reflect DisplayArea size, which is the same size as the display.
        setMaxBoundsSandboxed(mApplicationContext.getResources(), sDeviceBoundsPortrait);
        // GIVEN app bounds do not stretch to include the full DisplayArea.
        mApplicationContext.getResources().getConfiguration().windowConfiguration
                .setAppBounds(buildAppBounds(LOGICAL_WIDTH, LOGICAL_HEIGHT - 10));
        final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
                mApplicationContext.getResources());
        // THEN real metrics matches max bounds for the DisplayArea.
        verifyRealSizeMatchesBounds(display, sDeviceBoundsPortrait);
    }

    @Test
    public void testGetRealSize_resourcesLandscapeSandboxed_matchesAppSandboxBounds() {
        // GIVEN display is rotated.
        setDisplayInfoLandscape(mDisplayInfo);
        // GIVEN app is letterboxed.
        setMaxBoundsSandboxedToMatchAppBounds(mApplicationContext.getResources(),
                sAppBoundsLandscape);
        setMaxBoundsSandboxed(mApplicationContext.getResources(), sAppBoundsLandscape);
        final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
                mApplicationContext.getResources());
        // THEN real size matches app bounds.
        verifyRealSizeMatchesApp(display, sAppBoundsLandscape);
        verifyRealSizeMatchesBounds(display, sAppBoundsLandscape);
    }

    @Test
    public void testGetRealSize_resourcesLandscapeSandboxed_matchesDisplayAreaSandboxBounds() {
        // GIVEN display is rotated.
        setDisplayInfoLandscape(mDisplayInfo);
        // GIVEN max bounds reflect DisplayArea size, which is the same size as the display.
        setMaxBoundsSandboxed(mApplicationContext.getResources(), sDeviceBoundsLandscape);
        // GIVEN app bounds do not stretch to include the full DisplayArea.
        mApplicationContext.getResources().getConfiguration().windowConfiguration
                .setAppBounds(buildAppBounds(LOGICAL_HEIGHT, LOGICAL_WIDTH - 10));
        final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
                mApplicationContext.getResources());
        // THEN real metrics matches max bounds for the DisplayArea.
        verifyRealSizeMatchesBounds(display, sDeviceBoundsLandscape);
    }

    @Test
@@ -396,29 +429,57 @@ public class DisplayTests {
    }

    @Test
    public void testGetRealMetrics_resourcesPortraitSandboxed_matchesSandboxBounds() {
    public void testGetRealMetrics_resourcesPortraitSandboxed_matchesAppSandboxBounds() {
        // GIVEN display is not rotated.
        setDisplayInfoPortrait(mDisplayInfo);
        // GIVEN app is letterboxed.
        setMaxBoundsSandboxedToMatchAppBounds(mApplicationContext.getResources(),
                sAppBoundsPortrait);
        setMaxBoundsSandboxed(mApplicationContext.getResources(), sAppBoundsPortrait);
        final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
                mApplicationContext.getResources());
        // THEN real metrics matches app bounds.
        verifyRealMetricsMatchesApp(display, sAppBoundsPortrait);
        verifyRealMetricsMatchesBounds(display, sAppBoundsPortrait);
    }

    @Test
    public void testGetRealMetrics_resourcesPortraitSandboxed_matchesDisplayAreaSandboxBounds() {
        // GIVEN display is not rotated.
        setDisplayInfoPortrait(mDisplayInfo);
        // GIVEN max bounds reflect DisplayArea size, which is the same size as the display.
        setMaxBoundsSandboxed(mApplicationContext.getResources(), sDeviceBoundsPortrait);
        // GIVEN app bounds do not stretch to include the full DisplayArea.
        mApplicationContext.getResources().getConfiguration().windowConfiguration
                .setAppBounds(buildAppBounds(LOGICAL_WIDTH, LOGICAL_HEIGHT - 10));
        final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
                mApplicationContext.getResources());
        // THEN real metrics matches max bounds for the DisplayArea.
        verifyRealMetricsMatchesBounds(display, sDeviceBoundsPortrait);
    }

    @Test
    public void testGetRealMetrics_resourcesLandscapeSandboxed_matchesSandboxBounds() {
    public void testGetRealMetrics_resourcesLandscapeSandboxed_matchesAppSandboxBounds() {
        // GIVEN display is rotated.
        setDisplayInfoLandscape(mDisplayInfo);
        // GIVEN app is letterboxed.
        setMaxBoundsSandboxedToMatchAppBounds(mApplicationContext.getResources(),
                sAppBoundsLandscape);
        setMaxBoundsSandboxed(mApplicationContext.getResources(), sAppBoundsLandscape);
        final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
                mApplicationContext.getResources());
        // THEN real metrics matches app bounds.
        verifyRealMetricsMatchesApp(display, sAppBoundsLandscape);
        verifyRealMetricsMatchesBounds(display, sAppBoundsLandscape);
    }

    @Test
    public void testGetRealMetrics_resourcesLandscapeSandboxed_matchesDisplayAreaSandboxBounds() {
        // GIVEN display is rotated.
        setDisplayInfoLandscape(mDisplayInfo);
        // GIVEN max bounds reflect DisplayArea size, which is the same size as the display.
        setMaxBoundsSandboxed(mApplicationContext.getResources(), sDeviceBoundsLandscape);
        // GIVEN app bounds do not stretch to include the full DisplayArea.
        mApplicationContext.getResources().getConfiguration().windowConfiguration
                .setAppBounds(buildAppBounds(LOGICAL_HEIGHT, LOGICAL_WIDTH - 10));
        final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo,
                mApplicationContext.getResources());
        // THEN real metrics matches max bounds for the DisplayArea.
        verifyRealMetricsMatchesBounds(display, sDeviceBoundsLandscape);
    }

    // Given rotated display dimensions, calculate the letterboxed app bounds.
@@ -450,8 +511,8 @@ public class DisplayTests {
     * Set max bounds to be sandboxed to the app bounds, indicating the app is in
     * size compat mode or letterbox.
     */
    private static void setMaxBoundsSandboxedToMatchAppBounds(Resources resources, Rect appBounds) {
        resources.getConfiguration().windowConfiguration.setMaxBounds(appBounds);
    private static void setMaxBoundsSandboxed(Resources resources, Rect bounds) {
        resources.getConfiguration().windowConfiguration.setMaxBounds(bounds);
    }

    /**
@@ -492,17 +553,17 @@ public class DisplayTests {
        assertThat(metrics.heightPixels).isEqualTo(LOGICAL_HEIGHT);
    }

    private static void verifyRealSizeMatchesApp(Display display, Rect appBounds) {
    private static void verifyRealSizeMatchesBounds(Display display, Rect bounds) {
        Point size = new Point();
        display.getRealSize(size);
        assertThat(size).isEqualTo(new Point(appBounds.width(), appBounds.height()));
        assertThat(size).isEqualTo(new Point(bounds.width(), bounds.height()));
    }

    private static void verifyRealMetricsMatchesApp(Display display, Rect appBounds) {
    private static void verifyRealMetricsMatchesBounds(Display display, Rect bounds) {
        DisplayMetrics metrics = new DisplayMetrics();
        display.getRealMetrics(metrics);
        assertThat(metrics.widthPixels).isEqualTo(appBounds.width());
        assertThat(metrics.heightPixels).isEqualTo(appBounds.height());
        assertThat(metrics.widthPixels).isEqualTo(bounds.width());
        assertThat(metrics.heightPixels).isEqualTo(bounds.height());
    }

    private static FixedRotationAdjustments setOverrideFixedRotationAdjustments(