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

Commit 900077e1 authored by Rupesh Bansal's avatar Rupesh Bansal
Browse files

Add support to make the refresh rate used when the device has HDR enabled...

Add support to make the refresh rate used when the device has HDR enabled configurable for each display.

This is a step forward to prepare DisplayModeDirector to load the config
per display when hdr is enabled for the device to keep the changes
contained. As a followup, we will add support to also load the config from the
respective display config file.

Bug: 264965782
Bug: 265126371
Test: atest DisplayModeDirectorTest
Change-Id: I553d8bb4c71305728f52796ff60c103988fd231b
parent 33ab8684
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -1344,6 +1344,23 @@ public class DisplayDeviceConfig {
        return mDefaultRefreshRate;
    }

    /**
     * @return Default refresh rate while the device has high brightness mode enabled for HDR.
     */
    public int getDefaultRefreshRateInHbmHdr() {
        return mContext.getResources().getInteger(
            R.integer.config_defaultRefreshRateInHbmHdr);
    }

    /**
     * @return Default refresh rate while the device has high brightness mode enabled because of
     * high lux.
     */
    public int getDefaultRefreshRateInHbmSunlight() {
        return mContext.getResources().getInteger(
            R.integer.config_defaultRefreshRateInHbmSunlight);
    }

    /**
     * @return Default refresh rate in the higher blocking zone of the associated display
     */
+65 −31
Original line number Diff line number Diff line
@@ -123,6 +123,10 @@ public class DisplayModeDirector {
    private final DeviceConfigInterface mDeviceConfig;
    private final DeviceConfigDisplaySettings mDeviceConfigDisplaySettings;

    @GuardedBy("mLock")
    @Nullable
    private DisplayDeviceConfig mDefaultDisplayDeviceConfig;

    // A map from the display ID to the collection of votes and their priority. The latter takes
    // the form of another map from the priority to the vote itself so that each priority is
    // guaranteed to have exactly one vote, which is also easily and efficiently replaceable.
@@ -163,6 +167,7 @@ public class DisplayModeDirector {
        mDeviceConfigDisplaySettings = new DeviceConfigDisplaySettings();
        mSettingsObserver = new SettingsObserver(context, handler);
        mBrightnessObserver = new BrightnessObserver(context, handler, injector);
        mDefaultDisplayDeviceConfig = null;
        mUdfpsObserver = new UdfpsObserver();
        final BallotBox ballotBox = (displayId, priority, vote) -> {
            synchronized (mLock) {
@@ -701,11 +706,15 @@ public class DisplayModeDirector {
     * @param displayDeviceConfig configurations relating to the underlying display device.
     */
    public void defaultDisplayDeviceUpdated(DisplayDeviceConfig displayDeviceConfig) {
        synchronized (mLock) {
            mDefaultDisplayDeviceConfig = displayDeviceConfig;
            mSettingsObserver.setRefreshRates(displayDeviceConfig,
                /* attemptLoadingFromDeviceConfig= */ true);
            mBrightnessObserver.updateBlockingZoneThresholds(displayDeviceConfig,
                /* attemptLoadingFromDeviceConfig= */ true);
            mBrightnessObserver.reloadLightSensor(displayDeviceConfig);
            mHbmObserver.setupHdrRefreshRates(displayDeviceConfig);
        }
    }

    /**
@@ -2766,7 +2775,7 @@ public class DisplayModeDirector {
     * HBM that are associated with that display. Restrictions are retrieved from
     * DisplayManagerInternal but originate in the display-device-config file.
     */
    public static class HbmObserver implements DisplayManager.DisplayListener {
    public class HbmObserver implements DisplayManager.DisplayListener {
        private final BallotBox mBallotBox;
        private final Handler mHandler;
        private final SparseIntArray mHbmMode = new SparseIntArray();
@@ -2786,10 +2795,24 @@ public class DisplayModeDirector {
            mDeviceConfigDisplaySettings = displaySettings;
        }

        public void observe() {
            mRefreshRateInHbmSunlight = mDeviceConfigDisplaySettings.getRefreshRateInHbmSunlight();
            mRefreshRateInHbmHdr = mDeviceConfigDisplaySettings.getRefreshRateInHbmHdr();
        /**
         * Sets up the refresh rate to be used when HDR is enabled
         */
        public void setupHdrRefreshRates(DisplayDeviceConfig displayDeviceConfig) {
            mRefreshRateInHbmHdr = mDeviceConfigDisplaySettings
                .getRefreshRateInHbmHdr(displayDeviceConfig);
            mRefreshRateInHbmSunlight = mDeviceConfigDisplaySettings
                .getRefreshRateInHbmSunlight(displayDeviceConfig);
        }

        /**
         * Sets up the HDR refresh rates, and starts observing for the changes in the display that
         * might impact it
         */
        public void observe() {
            synchronized (mLock) {
                setupHdrRefreshRates(mDefaultDisplayDeviceConfig);
            }
            mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
            mInjector.registerDisplayListener(this, mHandler,
                    DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS
@@ -3021,26 +3044,33 @@ public class DisplayModeDirector {
                    -1);
        }

        public int getRefreshRateInHbmSunlight() {
            final int defaultRefreshRateInHbmSunlight =
                    mContext.getResources().getInteger(
                            R.integer.config_defaultRefreshRateInHbmSunlight);

            final int refreshRate = mDeviceConfig.getInt(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
                    DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HBM_SUNLIGHT,
                    defaultRefreshRateInHbmSunlight);

        public int getRefreshRateInHbmHdr(DisplayDeviceConfig displayDeviceConfig) {
            int refreshRate =
                    (displayDeviceConfig == null) ? mContext.getResources().getInteger(
                            R.integer.config_defaultRefreshRateInHbmHdr)
                            : displayDeviceConfig.getDefaultRefreshRateInHbmHdr();
            try {
                refreshRate = mDeviceConfig.getInt(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
                    DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HBM_HDR,
                    refreshRate);
            } catch (NullPointerException e) {
                // Do Nothing
            }
            return refreshRate;
        }

        public int getRefreshRateInHbmHdr() {
            final int defaultRefreshRateInHbmHdr =
                    mContext.getResources().getInteger(R.integer.config_defaultRefreshRateInHbmHdr);

            final int refreshRate = mDeviceConfig.getInt(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
                    DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HBM_HDR,
                    defaultRefreshRateInHbmHdr);

        public int getRefreshRateInHbmSunlight(DisplayDeviceConfig displayDeviceConfig) {
            int refreshRate =
                    (displayDeviceConfig == null) ? mContext.getResources()
                        .getInteger(R.integer.config_defaultRefreshRateInHbmSunlight)
                        : displayDeviceConfig.getDefaultRefreshRateInHbmSunlight();
            try {
                refreshRate = mDeviceConfig.getInt(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
                    DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HBM_SUNLIGHT,
                    refreshRate);
            } catch (NullPointerException e) {
                // Do Nothing
            }
            return refreshRate;
        }

@@ -3090,15 +3120,19 @@ public class DisplayModeDirector {
                        0).sendToTarget();
            }

            final int refreshRateInHbmSunlight = getRefreshRateInHbmSunlight();
            synchronized (mLock) {
                final int refreshRateInHbmSunlight =
                        getRefreshRateInHbmSunlight(mDefaultDisplayDeviceConfig);
                mHandler.obtainMessage(MSG_REFRESH_RATE_IN_HBM_SUNLIGHT_CHANGED,
                        refreshRateInHbmSunlight, 0)
                    .sendToTarget();

            final int refreshRateInHbmHdr = getRefreshRateInHbmHdr();
                final int refreshRateInHbmHdr =
                        getRefreshRateInHbmHdr(mDefaultDisplayDeviceConfig);
                mHandler.obtainMessage(MSG_REFRESH_RATE_IN_HBM_HDR_CHANGED, refreshRateInHbmHdr, 0)
                    .sendToTarget();
            }
        }

        private int[] getIntArrayProperty(String prop) {
            String strArray = mDeviceConfig.getString(DeviceConfig.NAMESPACE_DISPLAY_MANAGER, prop,
+12 −2
Original line number Diff line number Diff line
@@ -55,6 +55,8 @@ public final class DisplayDeviceConfigTest {
    private static final int DEFAULT_REFRESH_RATE = 120;
    private static final int DEFAULT_HIGH_BLOCKING_ZONE_REFRESH_RATE = 55;
    private static final int DEFAULT_LOW_BLOCKING_ZONE_REFRESH_RATE = 95;
    private static final int DEFAULT_REFRESH_RATE_IN_HBM_HDR = 90;
    private static final int DEFAULT_REFRESH_RATE_IN_HBM_SUNLIGHT = 100;
    private static final int[] LOW_BRIGHTNESS_THRESHOLD_OF_PEAK_REFRESH_RATE = new int[]{10, 30};
    private static final int[] LOW_AMBIENT_THRESHOLD_OF_PEAK_REFRESH_RATE = new int[]{1, 21};
    private static final int[] HIGH_BRIGHTNESS_THRESHOLD_OF_PEAK_REFRESH_RATE = new int[]{160};
@@ -295,9 +297,11 @@ public final class DisplayDeviceConfigTest {
                DEFAULT_HIGH_BLOCKING_ZONE_REFRESH_RATE);
        assertEquals(mDisplayDeviceConfig.getDefaultPeakRefreshRate(), DEFAULT_PEAK_REFRESH_RATE);
        assertEquals(mDisplayDeviceConfig.getDefaultRefreshRate(), DEFAULT_REFRESH_RATE);

        assertEquals(0, mDisplayDeviceConfig.getRefreshRangeProfiles().size());

        assertEquals(mDisplayDeviceConfig.getDefaultRefreshRateInHbmSunlight(),
                DEFAULT_REFRESH_RATE_IN_HBM_SUNLIGHT);
        assertEquals(mDisplayDeviceConfig.getDefaultRefreshRateInHbmHdr(),
                DEFAULT_REFRESH_RATE_IN_HBM_HDR);
        assertArrayEquals(mDisplayDeviceConfig.getLowDisplayBrightnessThresholds(),
                LOW_BRIGHTNESS_THRESHOLD_OF_PEAK_REFRESH_RATE);
        assertArrayEquals(mDisplayDeviceConfig.getLowAmbientBrightnessThresholds(),
@@ -694,6 +698,12 @@ public final class DisplayDeviceConfigTest {
        when(mResources.getIntArray(
                R.array.config_highAmbientBrightnessThresholdsOfFixedRefreshRate))
                .thenReturn(HIGH_AMBIENT_THRESHOLD_OF_PEAK_REFRESH_RATE);
        when(mResources.getInteger(
            R.integer.config_defaultRefreshRateInHbmHdr))
            .thenReturn(DEFAULT_REFRESH_RATE_IN_HBM_HDR);
        when(mResources.getInteger(
            R.integer.config_defaultRefreshRateInHbmSunlight))
            .thenReturn(DEFAULT_REFRESH_RATE_IN_HBM_SUNLIGHT);

        mDisplayDeviceConfig = DisplayDeviceConfig.create(mContext, true);
    }
+30 −2
Original line number Diff line number Diff line
@@ -2264,6 +2264,10 @@ public class DisplayModeDirectorTest {
            .thenReturn(65);
        when(resources.getInteger(R.integer.config_defaultRefreshRateInZone))
            .thenReturn(85);
        when(resources.getInteger(R.integer.config_defaultRefreshRateInHbmHdr))
            .thenReturn(95);
        when(resources.getInteger(R.integer.config_defaultRefreshRateInHbmSunlight))
            .thenReturn(100);
        when(resources.getIntArray(R.array.config_brightnessThresholdsOfPeakRefreshRate))
            .thenReturn(new int[]{5});
        when(resources.getIntArray(R.array.config_ambientThresholdsOfPeakRefreshRate))
@@ -2274,8 +2278,21 @@ public class DisplayModeDirectorTest {
        when(
            resources.getIntArray(R.array.config_highAmbientBrightnessThresholdsOfFixedRefreshRate))
            .thenReturn(new int[]{7000});
        when(resources.getInteger(
            com.android.internal.R.integer.config_displayWhiteBalanceBrightnessFilterHorizon))
            .thenReturn(3);
        ArgumentCaptor<TypedValue> valueArgumentCaptor = ArgumentCaptor.forClass(TypedValue.class);
        doAnswer((Answer<Void>) invocation -> {
            valueArgumentCaptor.getValue().type = 4;
            valueArgumentCaptor.getValue().data = 13;
            return null;
        }).when(resources).getValue(eq(com.android.internal.R.dimen
                .config_displayWhiteBalanceBrightnessFilterIntercept),
                valueArgumentCaptor.capture(), eq(true));
        DisplayModeDirector director =
                createDirectorFromRefreshRateArray(new float[]{60.0f, 90.0f}, 0);
        SensorManager sensorManager = createMockSensorManager(createLightSensor());
        director.start(sensorManager);
        // We don't expect any interaction with DeviceConfig when the director is initialized
        // because we explicitly avoid doing this as this can lead to a latency spike in the
        // startup of DisplayManagerService
@@ -2285,6 +2302,8 @@ public class DisplayModeDirectorTest {
                0.0);
        assertEquals(director.getBrightnessObserver().getRefreshRateInHighZone(), 65);
        assertEquals(director.getBrightnessObserver().getRefreshRateInLowZone(), 85);
        assertEquals(director.getHbmObserver().getRefreshRateInHbmHdr(), 95);
        assertEquals(director.getHbmObserver().getRefreshRateInHbmSunlight(), 100);
        assertArrayEquals(director.getBrightnessObserver().getHighDisplayBrightnessThreshold(),
                new int[]{250});
        assertArrayEquals(director.getBrightnessObserver().getHighAmbientBrightnessThreshold(),
@@ -2294,6 +2313,7 @@ public class DisplayModeDirectorTest {
        assertArrayEquals(director.getBrightnessObserver().getLowAmbientBrightnessThreshold(),
                new int[]{10});


        // Notify that the default display is updated, such that DisplayDeviceConfig has new values
        DisplayDeviceConfig displayDeviceConfig = mock(DisplayDeviceConfig.class);
        when(displayDeviceConfig.getDefaultLowBlockingZoneRefreshRate()).thenReturn(50);
@@ -2304,6 +2324,8 @@ public class DisplayModeDirectorTest {
        when(displayDeviceConfig.getLowAmbientBrightnessThresholds()).thenReturn(new int[]{30});
        when(displayDeviceConfig.getHighDisplayBrightnessThresholds()).thenReturn(new int[]{210});
        when(displayDeviceConfig.getHighAmbientBrightnessThresholds()).thenReturn(new int[]{2100});
        when(displayDeviceConfig.getDefaultRefreshRateInHbmHdr()).thenReturn(65);
        when(displayDeviceConfig.getDefaultRefreshRateInHbmSunlight()).thenReturn(75);
        director.defaultDisplayDeviceUpdated(displayDeviceConfig);

        assertEquals(director.getSettingsObserver().getDefaultRefreshRate(), 60, 0.0);
@@ -2319,6 +2341,8 @@ public class DisplayModeDirectorTest {
                new int[]{25});
        assertArrayEquals(director.getBrightnessObserver().getLowAmbientBrightnessThreshold(),
                new int[]{30});
        assertEquals(director.getHbmObserver().getRefreshRateInHbmHdr(), 65);
        assertEquals(director.getHbmObserver().getRefreshRateInHbmSunlight(), 75);

        // Notify that the default display is updated, such that DeviceConfig has new values
        FakeDeviceConfig config = mInjector.getDeviceConfig();
@@ -2329,8 +2353,10 @@ public class DisplayModeDirectorTest {
        config.setLowDisplayBrightnessThresholds(new int[]{10});
        config.setHighDisplayBrightnessThresholds(new int[]{255});
        config.setHighAmbientBrightnessThresholds(new int[]{8000});

        director.defaultDisplayDeviceUpdated(displayDeviceConfig);
        config.setRefreshRateInHbmHdr(70);
        config.setRefreshRateInHbmSunlight(80);
        // Need to wait for the property change to propagate to the main thread.
        waitForIdleSync();

        assertEquals(director.getSettingsObserver().getDefaultRefreshRate(), 60, 0.0);
        assertEquals(director.getSettingsObserver().getDefaultPeakRefreshRate(), 60,
@@ -2345,6 +2371,8 @@ public class DisplayModeDirectorTest {
                new int[]{10});
        assertArrayEquals(director.getBrightnessObserver().getLowAmbientBrightnessThreshold(),
                new int[]{20});
        assertEquals(director.getHbmObserver().getRefreshRateInHbmHdr(), 70);
        assertEquals(director.getHbmObserver().getRefreshRateInHbmSunlight(), 80);
    }

    @Test