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

Commit d947cc68 authored by Piotr Wilczyński's avatar Piotr Wilczyński Committed by David Lin
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
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:eca441ee844665ec3511b0709a69c27abc302f94)
Merged-In: Ic05ab0401766f6d0edd295ca337b0713f7e367a5
Change-Id: Ic05ab0401766f6d0edd295ca337b0713f7e367a5
24D1-dev is based on 24Q2-release. Therefore, we merged this CL to 24D1-dev.
parent b75186ff
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -1091,7 +1091,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 =