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

Commit 0a08be31 authored by Oleg Blinnikov's avatar Oleg Blinnikov
Browse files

Check resolution changes in DisplayInfo.equals.

The previous check for display updates only checked if the display's
id changed when compareOnlyBasicChanges=false. With
compareOnlyBasicChanges=true
this could cause updates to be ignored.

This change adds a check for the current active display mode in
DisplayInfo.equals, and only returns that the info is equal if the
display mode ids are the same, or both mode's dimensions are the same.

Test: atest DisplayInfoTest
Test: manual see change is received in Settings
Bug: 413014130
Bug: 424418347
Flag: EXEMPT simple bugfix
Change-Id: I9c103002a1a99f3921546238c1612869310046fe
parent 6a7970f4
Loading
Loading
Loading
Loading
+41 −1
Original line number Diff line number Diff line
@@ -478,6 +478,7 @@ public final class DisplayInfo implements Parcelable {
                && largestNominalAppHeight == other.largestNominalAppHeight
                && logicalWidth == other.logicalWidth
                && logicalHeight == other.logicalHeight
                && isDisplayModeSizeEqual(other)
                && Objects.equals(displayCutout, other.displayCutout)
                && rotation == other.rotation
                && hasArrSupport == other.hasArrSupport
@@ -784,12 +785,20 @@ public final class DisplayInfo implements Parcelable {
        return findMode(defaultModeId);
    }

    private Display.Mode findMode(int id) {
    private Display.Mode findModeOrNull(int id) {
        for (int i = 0; i < supportedModes.length; i++) {
            if (supportedModes[i].getModeId() == id) {
                return supportedModes[i];
            }
        }
        return null;
    }

    private Display.Mode findMode(int id) {
        var mode = findModeOrNull(id);
        if (mode != null) {
            return mode;
        }
        throw new IllegalStateException(
                "Unable to locate mode id=" + id + ",supportedModes=" + Arrays.toString(
                        supportedModes));
@@ -914,6 +923,37 @@ public final class DisplayInfo implements Parcelable {
        return Display.hasAccess(uid, flags, ownerUid, displayId);
    }

    /**
     * Checks whether the physical mode display size changed.
     * This is important for sending notifications to the rest of the system
     * whenever physical display size changes. E.g. WindowManager and Settings
     * rely on this information.
     * ModeId change may also not involve display size changes, but rather only
     * refresh rate may change. Refresh rate changes are tracked via other means,
     * and physical display size change needs to be checked independently.
     * These are the reasons for existence of this method.
     */
    private boolean isDisplayModeSizeEqual(DisplayInfo other) {
        if (modeId == other.modeId) {
            // If the mode ids are the same, the sizes are equal.
            return true;
        }
        var currentMode = findModeOrNull(modeId);
        var otherMode = other.findModeOrNull(other.modeId);
        if (otherMode == currentMode) {
            // If the modes are the same, the sizes are equal.
            return true;
        } else if (currentMode == null || otherMode == null) {
            // Only one of the displays has a mode, we can't compare the sizes.
            // Mark infos as different.
            return false;
        } else {
            // Both displays have a mode, compare the sizes.
            return otherMode.getPhysicalWidth() == currentMode.getPhysicalWidth()
                    && otherMode.getPhysicalHeight() == currentMode.getPhysicalHeight();
        }
    }

    private void getMetricsWithSize(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
            Configuration configuration, int width, int height) {
        outMetrics.densityDpi = outMetrics.noncompatDensityDpi = logicalDensityDpi;
+74 −0
Original line number Diff line number Diff line
@@ -108,6 +108,80 @@ public class DisplayInfoTest {
        assertFalse(displayInfo1.equals(displayInfo2));
    }

    @Test
    public void testResolutionChange_makesDisplayInfosDifferent() {
        var modes = new Display.Mode[] {
            new Display.Mode(/*modeId=*/1, /*width=*/1024, /*height=*/768, /*refreshRate=*/60),
            new Display.Mode(/*modeId=*/2, /*width=*/1024, /*height=*/768, /*refreshRate=*/120),
            new Display.Mode(/*modeId=*/3, /*width=*/800, /*height=*/600, /*refreshRate=*/60),
            new Display.Mode(/*modeId=*/4, /*width=*/800, /*height=*/600, /*refreshRate=*/120)
        };
        DisplayInfo displayInfo1 = new DisplayInfo();
        setSupportedModes(displayInfo1, modes, 1);

        DisplayInfo displayInfo2 = new DisplayInfo();
        setSupportedModes(displayInfo2, modes, 3);

        assertFalse(displayInfo1.equals(displayInfo2, /* compareOnlyBasicChanges= */ true));
    }

    @Test
    public void testNoResolutionChange_keepsDisplayInfosEqual() {
        var modes = new Display.Mode[] {
            new Display.Mode(/*modeId=*/1, /*width=*/1024, /*height=*/768, /*refreshRate=*/60),
            new Display.Mode(/*modeId=*/2, /*width=*/1024, /*height=*/768, /*refreshRate=*/120),
            new Display.Mode(/*modeId=*/3, /*width=*/800, /*height=*/600, /*refreshRate=*/60),
            new Display.Mode(/*modeId=*/4, /*width=*/800, /*height=*/600, /*refreshRate=*/120)
        };
        DisplayInfo displayInfo1 = new DisplayInfo();
        setSupportedModes(displayInfo1, modes, 1);

        DisplayInfo displayInfo2 = new DisplayInfo();
        setSupportedModes(displayInfo2, modes, 2);

        assertTrue(displayInfo1.equals(displayInfo2, /* compareOnlyBasicChanges= */ true));
    }

    @Test
    public void testOneModeNotFound_makesDisplayInfosDifferent() {
        var modes = new Display.Mode[] {
            new Display.Mode(/*modeId=*/1, /*width=*/1024, /*height=*/768, /*refreshRate=*/60),
            new Display.Mode(/*modeId=*/2, /*width=*/1024, /*height=*/768, /*refreshRate=*/120),
            new Display.Mode(/*modeId=*/3, /*width=*/800, /*height=*/600, /*refreshRate=*/60),
            new Display.Mode(/*modeId=*/4, /*width=*/800, /*height=*/600, /*refreshRate=*/120)
        };
        DisplayInfo displayInfo1 = new DisplayInfo();
        setSupportedModes(displayInfo1, modes, 1);

        DisplayInfo displayInfo2 = new DisplayInfo();
        setSupportedModes(displayInfo2, modes, 0);

        assertFalse(displayInfo1.equals(displayInfo2, /* compareOnlyBasicChanges= */ true));
    }

    @Test
    public void testBothModesNotFound_makesDisplayInfosEqual() {
        var modes = new Display.Mode[] {
            new Display.Mode(/*modeId=*/1, /*width=*/1024, /*height=*/768, /*refreshRate=*/60),
            new Display.Mode(/*modeId=*/2, /*width=*/1024, /*height=*/768, /*refreshRate=*/120),
            new Display.Mode(/*modeId=*/3, /*width=*/800, /*height=*/600, /*refreshRate=*/60),
            new Display.Mode(/*modeId=*/4, /*width=*/800, /*height=*/600, /*refreshRate=*/120)
        };
        DisplayInfo displayInfo1 = new DisplayInfo();
        setSupportedModes(displayInfo1, modes, 0);

        DisplayInfo displayInfo2 = new DisplayInfo();
        setSupportedModes(displayInfo2, modes, 0);

        assertTrue(displayInfo1.equals(displayInfo2, /* compareOnlyBasicChanges= */ true));
    }

    private void setSupportedModes(DisplayInfo info, Display.Mode[] modes, int modeId) {
        info.supportedModes = modes;
        info.modeId = modeId;
        info.refreshRateOverride = 90;
    }

    private void setSupportedMode(DisplayInfo info, Display.Mode mode) {
        info.supportedModes = new Display.Mode[]{mode};
        info.modeId = mode.getModeId();