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: Ia76f732274eea08ad83e8479820fb096eb134dee
This commit is contained in:
Rupesh Bansal
2023-01-20 11:40:04 +00:00
parent 8b21166575
commit 35b8ec4aac
4 changed files with 122 additions and 34 deletions

View File

@@ -1344,6 +1344,23 @@ public class DisplayDeviceConfig {
return mDefaultRefreshRate; 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 * @return Default refresh rate in the higher blocking zone of the associated display
*/ */

View File

@@ -123,6 +123,10 @@ public class DisplayModeDirector {
private final DeviceConfigInterface mDeviceConfig; private final DeviceConfigInterface mDeviceConfig;
private final DeviceConfigDisplaySettings mDeviceConfigDisplaySettings; 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 // 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 // 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. // guaranteed to have exactly one vote, which is also easily and efficiently replaceable.
@@ -163,6 +167,7 @@ public class DisplayModeDirector {
mDeviceConfigDisplaySettings = new DeviceConfigDisplaySettings(); mDeviceConfigDisplaySettings = new DeviceConfigDisplaySettings();
mSettingsObserver = new SettingsObserver(context, handler); mSettingsObserver = new SettingsObserver(context, handler);
mBrightnessObserver = new BrightnessObserver(context, handler, injector); mBrightnessObserver = new BrightnessObserver(context, handler, injector);
mDefaultDisplayDeviceConfig = null;
mUdfpsObserver = new UdfpsObserver(); mUdfpsObserver = new UdfpsObserver();
final BallotBox ballotBox = (displayId, priority, vote) -> { final BallotBox ballotBox = (displayId, priority, vote) -> {
synchronized (mLock) { synchronized (mLock) {
@@ -701,11 +706,15 @@ public class DisplayModeDirector {
* @param displayDeviceConfig configurations relating to the underlying display device. * @param displayDeviceConfig configurations relating to the underlying display device.
*/ */
public void defaultDisplayDeviceUpdated(DisplayDeviceConfig displayDeviceConfig) { public void defaultDisplayDeviceUpdated(DisplayDeviceConfig displayDeviceConfig) {
synchronized (mLock) {
mDefaultDisplayDeviceConfig = displayDeviceConfig;
mSettingsObserver.setRefreshRates(displayDeviceConfig, mSettingsObserver.setRefreshRates(displayDeviceConfig,
/* attemptLoadingFromDeviceConfig= */ true); /* attemptLoadingFromDeviceConfig= */ true);
mBrightnessObserver.updateBlockingZoneThresholds(displayDeviceConfig, mBrightnessObserver.updateBlockingZoneThresholds(displayDeviceConfig,
/* attemptLoadingFromDeviceConfig= */ true); /* attemptLoadingFromDeviceConfig= */ true);
mBrightnessObserver.reloadLightSensor(displayDeviceConfig); mBrightnessObserver.reloadLightSensor(displayDeviceConfig);
mHbmObserver.setupHdrRefreshRates(displayDeviceConfig);
}
} }
/** /**
@@ -2766,7 +2775,7 @@ public class DisplayModeDirector {
* HBM that are associated with that display. Restrictions are retrieved from * HBM that are associated with that display. Restrictions are retrieved from
* DisplayManagerInternal but originate in the display-device-config file. * 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 BallotBox mBallotBox;
private final Handler mHandler; private final Handler mHandler;
private final SparseIntArray mHbmMode = new SparseIntArray(); private final SparseIntArray mHbmMode = new SparseIntArray();
@@ -2786,10 +2795,24 @@ public class DisplayModeDirector {
mDeviceConfigDisplaySettings = displaySettings; mDeviceConfigDisplaySettings = displaySettings;
} }
public void observe() { /**
mRefreshRateInHbmSunlight = mDeviceConfigDisplaySettings.getRefreshRateInHbmSunlight(); * Sets up the refresh rate to be used when HDR is enabled
mRefreshRateInHbmHdr = mDeviceConfigDisplaySettings.getRefreshRateInHbmHdr(); */
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); mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
mInjector.registerDisplayListener(this, mHandler, mInjector.registerDisplayListener(this, mHandler,
DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS
@@ -3021,26 +3044,33 @@ public class DisplayModeDirector {
-1); -1);
} }
public int getRefreshRateInHbmSunlight() { public int getRefreshRateInHbmHdr(DisplayDeviceConfig displayDeviceConfig) {
final int defaultRefreshRateInHbmSunlight = int refreshRate =
mContext.getResources().getInteger( (displayDeviceConfig == null) ? mContext.getResources().getInteger(
R.integer.config_defaultRefreshRateInHbmSunlight); R.integer.config_defaultRefreshRateInHbmHdr)
: displayDeviceConfig.getDefaultRefreshRateInHbmHdr();
final int refreshRate = mDeviceConfig.getInt(DeviceConfig.NAMESPACE_DISPLAY_MANAGER, try {
DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HBM_SUNLIGHT, refreshRate = mDeviceConfig.getInt(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
defaultRefreshRateInHbmSunlight); DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HBM_HDR,
refreshRate);
} catch (NullPointerException e) {
// Do Nothing
}
return refreshRate; return refreshRate;
} }
public int getRefreshRateInHbmHdr() { public int getRefreshRateInHbmSunlight(DisplayDeviceConfig displayDeviceConfig) {
final int defaultRefreshRateInHbmHdr = int refreshRate =
mContext.getResources().getInteger(R.integer.config_defaultRefreshRateInHbmHdr); (displayDeviceConfig == null) ? mContext.getResources()
.getInteger(R.integer.config_defaultRefreshRateInHbmSunlight)
final int refreshRate = mDeviceConfig.getInt(DeviceConfig.NAMESPACE_DISPLAY_MANAGER, : displayDeviceConfig.getDefaultRefreshRateInHbmSunlight();
DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HBM_HDR, try {
defaultRefreshRateInHbmHdr); refreshRate = mDeviceConfig.getInt(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
DisplayManager.DeviceConfig.KEY_REFRESH_RATE_IN_HBM_SUNLIGHT,
refreshRate);
} catch (NullPointerException e) {
// Do Nothing
}
return refreshRate; return refreshRate;
} }
@@ -3090,15 +3120,19 @@ public class DisplayModeDirector {
0).sendToTarget(); 0).sendToTarget();
} }
final int refreshRateInHbmSunlight = getRefreshRateInHbmSunlight(); synchronized (mLock) {
final int refreshRateInHbmSunlight =
getRefreshRateInHbmSunlight(mDefaultDisplayDeviceConfig);
mHandler.obtainMessage(MSG_REFRESH_RATE_IN_HBM_SUNLIGHT_CHANGED, mHandler.obtainMessage(MSG_REFRESH_RATE_IN_HBM_SUNLIGHT_CHANGED,
refreshRateInHbmSunlight, 0) refreshRateInHbmSunlight, 0)
.sendToTarget(); .sendToTarget();
final int refreshRateInHbmHdr = getRefreshRateInHbmHdr(); final int refreshRateInHbmHdr =
getRefreshRateInHbmHdr(mDefaultDisplayDeviceConfig);
mHandler.obtainMessage(MSG_REFRESH_RATE_IN_HBM_HDR_CHANGED, refreshRateInHbmHdr, 0) mHandler.obtainMessage(MSG_REFRESH_RATE_IN_HBM_HDR_CHANGED, refreshRateInHbmHdr, 0)
.sendToTarget(); .sendToTarget();
} }
}
private int[] getIntArrayProperty(String prop) { private int[] getIntArrayProperty(String prop) {
String strArray = mDeviceConfig.getString(DeviceConfig.NAMESPACE_DISPLAY_MANAGER, prop, String strArray = mDeviceConfig.getString(DeviceConfig.NAMESPACE_DISPLAY_MANAGER, prop,

View File

@@ -55,6 +55,8 @@ public final class DisplayDeviceConfigTest {
private static final int DEFAULT_REFRESH_RATE = 120; private static final int DEFAULT_REFRESH_RATE = 120;
private static final int DEFAULT_HIGH_BLOCKING_ZONE_REFRESH_RATE = 55; 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_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_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[] 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}; 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); DEFAULT_HIGH_BLOCKING_ZONE_REFRESH_RATE);
assertEquals(mDisplayDeviceConfig.getDefaultPeakRefreshRate(), DEFAULT_PEAK_REFRESH_RATE); assertEquals(mDisplayDeviceConfig.getDefaultPeakRefreshRate(), DEFAULT_PEAK_REFRESH_RATE);
assertEquals(mDisplayDeviceConfig.getDefaultRefreshRate(), DEFAULT_REFRESH_RATE); assertEquals(mDisplayDeviceConfig.getDefaultRefreshRate(), DEFAULT_REFRESH_RATE);
assertEquals(0, mDisplayDeviceConfig.getRefreshRangeProfiles().size()); 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(), assertArrayEquals(mDisplayDeviceConfig.getLowDisplayBrightnessThresholds(),
LOW_BRIGHTNESS_THRESHOLD_OF_PEAK_REFRESH_RATE); LOW_BRIGHTNESS_THRESHOLD_OF_PEAK_REFRESH_RATE);
assertArrayEquals(mDisplayDeviceConfig.getLowAmbientBrightnessThresholds(), assertArrayEquals(mDisplayDeviceConfig.getLowAmbientBrightnessThresholds(),
@@ -694,6 +698,12 @@ public final class DisplayDeviceConfigTest {
when(mResources.getIntArray( when(mResources.getIntArray(
R.array.config_highAmbientBrightnessThresholdsOfFixedRefreshRate)) R.array.config_highAmbientBrightnessThresholdsOfFixedRefreshRate))
.thenReturn(HIGH_AMBIENT_THRESHOLD_OF_PEAK_REFRESH_RATE); .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); mDisplayDeviceConfig = DisplayDeviceConfig.create(mContext, true);
} }

View File

@@ -2264,6 +2264,10 @@ public class DisplayModeDirectorTest {
.thenReturn(65); .thenReturn(65);
when(resources.getInteger(R.integer.config_defaultRefreshRateInZone)) when(resources.getInteger(R.integer.config_defaultRefreshRateInZone))
.thenReturn(85); .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)) when(resources.getIntArray(R.array.config_brightnessThresholdsOfPeakRefreshRate))
.thenReturn(new int[]{5}); .thenReturn(new int[]{5});
when(resources.getIntArray(R.array.config_ambientThresholdsOfPeakRefreshRate)) when(resources.getIntArray(R.array.config_ambientThresholdsOfPeakRefreshRate))
@@ -2274,8 +2278,21 @@ public class DisplayModeDirectorTest {
when( when(
resources.getIntArray(R.array.config_highAmbientBrightnessThresholdsOfFixedRefreshRate)) resources.getIntArray(R.array.config_highAmbientBrightnessThresholdsOfFixedRefreshRate))
.thenReturn(new int[]{7000}); .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 = DisplayModeDirector director =
createDirectorFromRefreshRateArray(new float[]{60.0f, 90.0f}, 0); 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 // 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 // because we explicitly avoid doing this as this can lead to a latency spike in the
// startup of DisplayManagerService // startup of DisplayManagerService
@@ -2285,6 +2302,8 @@ public class DisplayModeDirectorTest {
0.0); 0.0);
assertEquals(director.getBrightnessObserver().getRefreshRateInHighZone(), 65); assertEquals(director.getBrightnessObserver().getRefreshRateInHighZone(), 65);
assertEquals(director.getBrightnessObserver().getRefreshRateInLowZone(), 85); assertEquals(director.getBrightnessObserver().getRefreshRateInLowZone(), 85);
assertEquals(director.getHbmObserver().getRefreshRateInHbmHdr(), 95);
assertEquals(director.getHbmObserver().getRefreshRateInHbmSunlight(), 100);
assertArrayEquals(director.getBrightnessObserver().getHighDisplayBrightnessThreshold(), assertArrayEquals(director.getBrightnessObserver().getHighDisplayBrightnessThreshold(),
new int[]{250}); new int[]{250});
assertArrayEquals(director.getBrightnessObserver().getHighAmbientBrightnessThreshold(), assertArrayEquals(director.getBrightnessObserver().getHighAmbientBrightnessThreshold(),
@@ -2294,6 +2313,7 @@ public class DisplayModeDirectorTest {
assertArrayEquals(director.getBrightnessObserver().getLowAmbientBrightnessThreshold(), assertArrayEquals(director.getBrightnessObserver().getLowAmbientBrightnessThreshold(),
new int[]{10}); new int[]{10});
// Notify that the default display is updated, such that DisplayDeviceConfig has new values // Notify that the default display is updated, such that DisplayDeviceConfig has new values
DisplayDeviceConfig displayDeviceConfig = mock(DisplayDeviceConfig.class); DisplayDeviceConfig displayDeviceConfig = mock(DisplayDeviceConfig.class);
when(displayDeviceConfig.getDefaultLowBlockingZoneRefreshRate()).thenReturn(50); when(displayDeviceConfig.getDefaultLowBlockingZoneRefreshRate()).thenReturn(50);
@@ -2304,6 +2324,8 @@ public class DisplayModeDirectorTest {
when(displayDeviceConfig.getLowAmbientBrightnessThresholds()).thenReturn(new int[]{30}); when(displayDeviceConfig.getLowAmbientBrightnessThresholds()).thenReturn(new int[]{30});
when(displayDeviceConfig.getHighDisplayBrightnessThresholds()).thenReturn(new int[]{210}); when(displayDeviceConfig.getHighDisplayBrightnessThresholds()).thenReturn(new int[]{210});
when(displayDeviceConfig.getHighAmbientBrightnessThresholds()).thenReturn(new int[]{2100}); when(displayDeviceConfig.getHighAmbientBrightnessThresholds()).thenReturn(new int[]{2100});
when(displayDeviceConfig.getDefaultRefreshRateInHbmHdr()).thenReturn(65);
when(displayDeviceConfig.getDefaultRefreshRateInHbmSunlight()).thenReturn(75);
director.defaultDisplayDeviceUpdated(displayDeviceConfig); director.defaultDisplayDeviceUpdated(displayDeviceConfig);
assertEquals(director.getSettingsObserver().getDefaultRefreshRate(), 60, 0.0); assertEquals(director.getSettingsObserver().getDefaultRefreshRate(), 60, 0.0);
@@ -2319,6 +2341,8 @@ public class DisplayModeDirectorTest {
new int[]{25}); new int[]{25});
assertArrayEquals(director.getBrightnessObserver().getLowAmbientBrightnessThreshold(), assertArrayEquals(director.getBrightnessObserver().getLowAmbientBrightnessThreshold(),
new int[]{30}); 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 // Notify that the default display is updated, such that DeviceConfig has new values
FakeDeviceConfig config = mInjector.getDeviceConfig(); FakeDeviceConfig config = mInjector.getDeviceConfig();
@@ -2329,7 +2353,8 @@ public class DisplayModeDirectorTest {
config.setLowDisplayBrightnessThresholds(new int[]{10}); config.setLowDisplayBrightnessThresholds(new int[]{10});
config.setHighDisplayBrightnessThresholds(new int[]{255}); config.setHighDisplayBrightnessThresholds(new int[]{255});
config.setHighAmbientBrightnessThresholds(new int[]{8000}); config.setHighAmbientBrightnessThresholds(new int[]{8000});
config.setRefreshRateInHbmHdr(70);
config.setRefreshRateInHbmSunlight(80);
director.defaultDisplayDeviceUpdated(displayDeviceConfig); director.defaultDisplayDeviceUpdated(displayDeviceConfig);
assertEquals(director.getSettingsObserver().getDefaultRefreshRate(), 60, 0.0); assertEquals(director.getSettingsObserver().getDefaultRefreshRate(), 60, 0.0);
@@ -2345,6 +2370,8 @@ public class DisplayModeDirectorTest {
new int[]{10}); new int[]{10});
assertArrayEquals(director.getBrightnessObserver().getLowAmbientBrightnessThreshold(), assertArrayEquals(director.getBrightnessObserver().getLowAmbientBrightnessThreshold(),
new int[]{20}); new int[]{20});
assertEquals(director.getHbmObserver().getRefreshRateInHbmHdr(), 70);
assertEquals(director.getHbmObserver().getRefreshRateInHbmSunlight(), 80);
} }
@Test @Test