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

Commit eca441ee authored by Piotr Wilczyński's avatar Piotr Wilczyński
Browse files

DMD fix flicker vote

In ag/25829274, we made some code in DMD work for multiple displays, so what happened with mRefreshRateChangeable was that it was being set based on the min and max refresh rates of the display that was most recently updated. When using Screen Recording, a new virtual display is added with only one refresh rate 60, so mRefreshRateChangeable was being set to false, even though there are other displays with changeable refresh rates.

Bug: 25829274
Test: adb shell dumpsys display - look at mRefreshRateChangeable and PRIORITY_FLICKER_REFRESH_RATE
Test: atest com.android.server.display.mode
Change-Id: Ic05ab0401766f6d0edd295ca337b0713f7e367a5
parent 56dee36a
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -1109,7 +1109,11 @@ public class DisplayModeDirector {
                maxRefreshRate = Math.min(defaultRefreshRate, peakRefreshRate);
            }

            mBrightnessObserver.onRefreshRateSettingChangedLocked(minRefreshRate, maxRefreshRate);
            // TODO(b/310237068): Make this work for multiple displays
            if (displayId == Display.DEFAULT_DISPLAY) {
                mBrightnessObserver.onRefreshRateSettingChangedLocked(minRefreshRate,
                        maxRefreshRate);
            }
        }

        private void removeRefreshRateSetting(int displayId) {
+78 −0
Original line number Diff line number Diff line
@@ -1344,6 +1344,84 @@ public class DisplayModeDirectorTest {
        assertThat(vote).isNull();
    }

    @Test
    public void testLockFps_DisplayWithOneMode() throws Exception {
        when(mDisplayManagerFlags.isBackUpSmoothDisplayAndForcePeakRefreshRateEnabled())
                .thenReturn(true);
        DisplayModeDirector director =
                new DisplayModeDirector(mContext, mHandler, mInjector, mDisplayManagerFlags);
        director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON);

        Display.Mode[] modes1 = new Display.Mode[] {
                new Display.Mode(/* modeId= */ 1, /* width= */ 1280, /* height= */ 720,
                        /* refreshRate= */ 60),
                new Display.Mode(/* modeId= */ 2, /* width= */ 1280, /* height= */ 720,
                        /* refreshRate= */ 90),
        };
        Display.Mode[] modes2 = new Display.Mode[] {
                new Display.Mode(/* modeId= */ 1, /* width= */ 1280, /* height= */ 720,
                        /* refreshRate= */ 60),
        };
        SparseArray<Display.Mode[]> supportedModesByDisplay = new SparseArray<>();
        supportedModesByDisplay.put(DISPLAY_ID, modes1);
        supportedModesByDisplay.put(DISPLAY_ID_2, modes2);

        final FakeDeviceConfig config = mInjector.getDeviceConfig();
        config.setRefreshRateInLowZone(90);
        config.setLowDisplayBrightnessThresholds(new int[] { 10 });
        config.setLowAmbientBrightnessThresholds(new int[] { 20 });

        Sensor lightSensor = createLightSensor();
        SensorManager sensorManager = createMockSensorManager(lightSensor);

        director.start(sensorManager);
        director.injectSupportedModesByDisplay(supportedModesByDisplay);
        director.getSettingsObserver().setDefaultRefreshRate(90);

        setPeakRefreshRate(Float.POSITIVE_INFINITY);

        ArgumentCaptor<DisplayListener> displayListenerCaptor =
                ArgumentCaptor.forClass(DisplayListener.class);
        verify(mInjector).registerDisplayListener(displayListenerCaptor.capture(),
                any(Handler.class),
                eq(DisplayManager.EVENT_FLAG_DISPLAY_CHANGED
                        | DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS));
        DisplayListener displayListener = displayListenerCaptor.getValue();

        ArgumentCaptor<SensorEventListener> sensorListenerCaptor =
                ArgumentCaptor.forClass(SensorEventListener.class);
        Mockito.verify(sensorManager, Mockito.timeout(TimeUnit.SECONDS.toMillis(1)))
                .registerListener(
                        sensorListenerCaptor.capture(),
                        eq(lightSensor),
                        anyInt(),
                        any(Handler.class));
        SensorEventListener sensorListener = sensorListenerCaptor.getValue();

        setBrightness(10, 10, displayListener);
        // Sensor reads 20 lux
        sensorListener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, /* lux= */ 20));

        Vote vote = director.getVote(Display.DEFAULT_DISPLAY, Vote.PRIORITY_FLICKER_REFRESH_RATE);
        assertVoteForPhysicalRefreshRate(vote, /* fps= */ 90);
        vote = director.getVote(Display.DEFAULT_DISPLAY, Vote.PRIORITY_FLICKER_REFRESH_RATE_SWITCH);
        assertThat(vote).isNotNull();
        assertThat(vote).isInstanceOf(DisableRefreshRateSwitchingVote.class);
        DisableRefreshRateSwitchingVote disableVote = (DisableRefreshRateSwitchingVote) vote;
        assertThat(disableVote.mDisableRefreshRateSwitching).isTrue();

        // We expect DisplayModeDirector to act on BrightnessInfo.adjustedBrightness; set only this
        // parameter to the necessary threshold
        setBrightness(10, 125, displayListener);
        // Sensor reads 1000 lux
        sensorListener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, /* lux= */ 1000));

        vote = director.getVote(Display.DEFAULT_DISPLAY, Vote.PRIORITY_FLICKER_REFRESH_RATE);
        assertThat(vote).isNull();
        vote = director.getVote(Display.DEFAULT_DISPLAY, Vote.PRIORITY_FLICKER_REFRESH_RATE_SWITCH);
        assertThat(vote).isNull();
    }

    @Test
    public void testLockFpsForHighZone() throws Exception {
        DisplayModeDirector director =