diff options
| author | 2024-03-14 14:00:50 +0000 | |
|---|---|---|
| committer | 2024-03-14 14:00:50 +0000 | |
| commit | 90ce0b13a36158250852cbfbc6e2861ed12939ff (patch) | |
| tree | 651844f93314da1ea336f953bf2dfbb49e5c5e61 | |
| parent | 139426f7e53c5efecbe992c06656a9f1ed790d34 (diff) | |
| parent | e2e67c4010389dc60a80147d6c3dff079268942b (diff) | |
Merge "Add display config for configuring the idle state refresh rate timeout bands" into main
6 files changed, 164 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java index 9b2dcc53f456..411666942b6d 100644 --- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java +++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java @@ -57,6 +57,9 @@ import com.android.server.display.config.DisplayQuirks; import com.android.server.display.config.HbmTiming; import com.android.server.display.config.HdrBrightnessData; import com.android.server.display.config.HighBrightnessMode; +import com.android.server.display.config.IdleScreenRefreshRateTimeout; +import com.android.server.display.config.IdleScreenRefreshRateTimeoutLuxThresholdPoint; +import com.android.server.display.config.IdleScreenRefreshRateTimeoutLuxThresholds; import com.android.server.display.config.IntegerArray; import com.android.server.display.config.LuxThrottling; import com.android.server.display.config.NitsMap; @@ -553,6 +556,18 @@ import javax.xml.datatype.DatatypeConfigurationException; * <minorVersion>0</minorVersion> * </usiVersion> * <screenBrightnessCapForWearBedtimeMode>0.1</screenBrightnessCapForWearBedtimeMode> + * <idleScreenRefreshRateTimeout> + * <luxThresholds> + * <point> + * <lux>6</lux> + * <timeout>1000</timeout> + * </point> + * <point> + * <lux>10</lux> + * <timeout>800</timeout> + * </point> + * </luxThresholds> + * </idleScreenRefreshRateTimeout> * </displayConfiguration> * } * </pre> @@ -843,6 +858,14 @@ public class DisplayDeviceConfig { private final Map<BrightnessLimitMapType, Map<Float, Float>> mLuxThrottlingData = new HashMap<>(); + /** + * The idle screen timeout configuration for switching to lower refresh rate + */ + @NonNull + private List<IdleScreenRefreshRateTimeoutLuxThresholdPoint> + mIdleScreenRefreshRateTimeoutLuxThresholds = new ArrayList<>(); + + @Nullable private HostUsiVersion mHostUsiVersion; @@ -1999,6 +2022,7 @@ public class DisplayDeviceConfig { loadUsiVersion(config); mHdrBrightnessData = HdrBrightnessData.loadConfig(config); loadBrightnessCapForWearBedtimeMode(config); + loadIdleScreenRefreshRateTimeoutConfigs(config); } else { Slog.w(TAG, "DisplayDeviceConfig file is null"); } @@ -2024,6 +2048,7 @@ public class DisplayDeviceConfig { loadAutoBrightnessAvailableFromConfigXml(); loadRefreshRateSetting(null); loadBrightnessCapForWearBedtimeModeFromConfigXml(); + loadIdleScreenRefreshRateTimeoutConfigs(null); mLoadedFrom = "<config.xml>"; } @@ -3326,6 +3351,47 @@ public class DisplayDeviceConfig { } } + private void loadIdleScreenRefreshRateTimeoutConfigs(@Nullable DisplayConfiguration config) { + if (mFlags.isIdleScreenRefreshRateTimeoutEnabled() + && config != null && config.getIdleScreenRefreshRateTimeout() != null) { + validateIdleScreenRefreshRateTimeoutConfig( + config.getIdleScreenRefreshRateTimeout()); + mIdleScreenRefreshRateTimeoutLuxThresholds = config + .getIdleScreenRefreshRateTimeout().getLuxThresholds().getPoint(); + } + } + + private void validateIdleScreenRefreshRateTimeoutConfig( + IdleScreenRefreshRateTimeout idleScreenRefreshRateTimeoutConfig) { + IdleScreenRefreshRateTimeoutLuxThresholds idleScreenRefreshRateTimeoutLuxThresholds = + idleScreenRefreshRateTimeoutConfig.getLuxThresholds(); + + if (idleScreenRefreshRateTimeoutLuxThresholds != null) { + int previousLux = -1; + // Validate that the lux values are in the increasing order + for (IdleScreenRefreshRateTimeoutLuxThresholdPoint point : + idleScreenRefreshRateTimeoutLuxThresholds.getPoint()) { + int newLux = point.getLux().intValue(); + if (previousLux >= newLux) { + throw new RuntimeException("Lux values should be in ascending order in the" + + " idle screen refresh rate timeout config"); + } + previousLux = newLux; + } + } + } + + /** + * Gets the idle screen refresh rate timeout(in ms) configuration list. For each entry, the lux + * value represent the lower bound of the lux range, and the value of the lux in the next + * point(INF if not present) represents the upper bound for the corresponding timeout(in ms) + */ + @NonNull + public List<IdleScreenRefreshRateTimeoutLuxThresholdPoint> + getIdleScreenRefreshRateTimeoutLuxThresholdPoint() { + return mIdleScreenRefreshRateTimeoutLuxThresholds; + } + /** * Extracts a float array from the specified {@link TypedArray}. * diff --git a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java index 5f455db39dd4..31524dc7056d 100644 --- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java +++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java @@ -135,6 +135,11 @@ public class DisplayManagerFlags { Flags::sensorBasedBrightnessThrottling ); + private final FlagState mIdleScreenRefreshRateTimeout = new FlagState( + Flags.FLAG_IDLE_SCREEN_REFRESH_RATE_TIMEOUT, + Flags::idleScreenRefreshRateTimeout + ); + private final FlagState mRefactorDisplayPowerController = new FlagState( Flags.FLAG_REFACTOR_DISPLAY_POWER_CONTROLLER, @@ -280,6 +285,10 @@ public class DisplayManagerFlags { return mSensorBasedBrightnessThrottling.isEnabled(); } + public boolean isIdleScreenRefreshRateTimeoutEnabled() { + return mIdleScreenRefreshRateTimeout.isEnabled(); + } + public boolean isRefactorDisplayPowerControllerEnabled() { return mRefactorDisplayPowerController.isEnabled(); } @@ -310,6 +319,7 @@ public class DisplayManagerFlags { pw.println(" " + mRefreshRateVotingTelemetry); pw.println(" " + mPixelAnisotropyCorrectionEnabled); pw.println(" " + mSensorBasedBrightnessThrottling); + pw.println(" " + mIdleScreenRefreshRateTimeout); pw.println(" " + mRefactorDisplayPowerController); } diff --git a/services/core/java/com/android/server/display/feature/display_flags.aconfig b/services/core/java/com/android/server/display/feature/display_flags.aconfig index d2909b898704..ff0f597ab607 100644 --- a/services/core/java/com/android/server/display/feature/display_flags.aconfig +++ b/services/core/java/com/android/server/display/feature/display_flags.aconfig @@ -219,3 +219,11 @@ flag { bug: "294444204" is_fixed_read_only: true } + +flag { + name: "idle_screen_refresh_rate_timeout" + namespace: "display_manager" + description: "Feature flag for reducing the refresh rate when the screen is idle after a timeout" + bug: "310026579" + is_fixed_read_only: true +} diff --git a/services/core/xsd/display-device-config/display-device-config.xsd b/services/core/xsd/display-device-config/display-device-config.xsd index b38a2f9558e9..d0df2b20721b 100644 --- a/services/core/xsd/display-device-config/display-device-config.xsd +++ b/services/core/xsd/display-device-config/display-device-config.xsd @@ -168,6 +168,10 @@ <xs:element type="nonNegativeDecimal" name="screenBrightnessCapForWearBedtimeMode"> <xs:annotation name="final"/> </xs:element> + <!-- Timeout after which we reduce the refresh rate if the screen has been idle, in order to save power. --> + <xs:element type="idleScreenRefreshRateTimeout" name="idleScreenRefreshRateTimeout" minOccurs="0"> + <xs:annotation name="final"/> + </xs:element> </xs:sequence> </xs:complexType> </xs:element> @@ -772,6 +776,30 @@ </xs:sequence> </xs:complexType> + <xs:complexType name="idleScreenRefreshRateTimeout"> + <xs:element name="luxThresholds" type="idleScreenRefreshRateTimeoutLuxThresholds" minOccurs="0"> + <xs:annotation name="final"/> + </xs:element> + </xs:complexType> + + <!-- Lux based timeout after which we reduce the refresh rate if the screen has been idle, in order to save power. --> + <xs:complexType name="idleScreenRefreshRateTimeoutLuxThresholds"> + <xs:sequence> + <xs:element name="point" type="idleScreenRefreshRateTimeoutLuxThresholdPoint" maxOccurs="unbounded" /> + </xs:sequence> + </xs:complexType> + + <!-- Represents a tuple of lux and timeout(in ms), which represents the timeout value for the lux in + the [luxValue, nextLuxValue (INF if missing)) --> + <xs:complexType name="idleScreenRefreshRateTimeoutLuxThresholdPoint"> + <xs:element name="lux" type="xs:nonNegativeInteger"> + <xs:annotation name="final"/> + </xs:element> + <xs:element name="timeout" type="xs:nonNegativeInteger"> + <xs:annotation name="final"/> + </xs:element> + </xs:complexType> + <!-- Predefined type names as defined by AutomaticBrightnessController.AutomaticBrightnessMode --> <xs:simpleType name="AutoBrightnessModeName"> diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt index b329db4a2076..00dc90828d90 100644 --- a/services/core/xsd/display-device-config/schema/current.txt +++ b/services/core/xsd/display-device-config/schema/current.txt @@ -111,6 +111,7 @@ package com.android.server.display.config { method public final com.android.server.display.config.Thresholds getDisplayBrightnessChangeThresholdsIdle(); method @Nullable public final com.android.server.display.config.HdrBrightnessConfig getHdrBrightnessConfig(); method public com.android.server.display.config.HighBrightnessMode getHighBrightnessMode(); + method public final com.android.server.display.config.IdleScreenRefreshRateTimeout getIdleScreenRefreshRateTimeout(); method public final com.android.server.display.config.SensorDetails getLightSensor(); method public com.android.server.display.config.LuxThrottling getLuxThrottling(); method @Nullable public final String getName(); @@ -146,6 +147,7 @@ package com.android.server.display.config { method public final void setDisplayBrightnessChangeThresholdsIdle(com.android.server.display.config.Thresholds); method public final void setHdrBrightnessConfig(@Nullable com.android.server.display.config.HdrBrightnessConfig); method public void setHighBrightnessMode(com.android.server.display.config.HighBrightnessMode); + method public final void setIdleScreenRefreshRateTimeout(com.android.server.display.config.IdleScreenRefreshRateTimeout); method public final void setLightSensor(com.android.server.display.config.SensorDetails); method public void setLuxThrottling(com.android.server.display.config.LuxThrottling); method public final void setName(@Nullable String); @@ -222,6 +224,25 @@ package com.android.server.display.config { method public final void setTransitionPoint_all(@NonNull java.math.BigDecimal); } + public class IdleScreenRefreshRateTimeout { + ctor public IdleScreenRefreshRateTimeout(); + method public final com.android.server.display.config.IdleScreenRefreshRateTimeoutLuxThresholds getLuxThresholds(); + method public final void setLuxThresholds(com.android.server.display.config.IdleScreenRefreshRateTimeoutLuxThresholds); + } + + public class IdleScreenRefreshRateTimeoutLuxThresholdPoint { + ctor public IdleScreenRefreshRateTimeoutLuxThresholdPoint(); + method public final java.math.BigInteger getLux(); + method public final java.math.BigInteger getTimeout(); + method public final void setLux(java.math.BigInteger); + method public final void setTimeout(java.math.BigInteger); + } + + public class IdleScreenRefreshRateTimeoutLuxThresholds { + ctor public IdleScreenRefreshRateTimeoutLuxThresholds(); + method public java.util.List<com.android.server.display.config.IdleScreenRefreshRateTimeoutLuxThresholdPoint> getPoint(); + } + public class IntegerArray { ctor public IntegerArray(); method public java.util.List<java.math.BigInteger> getItem(); diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java index 2867041511b5..35b69f812ff0 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java @@ -54,6 +54,7 @@ import androidx.test.filters.SmallTest; import com.android.internal.R; import com.android.server.display.config.HdrBrightnessData; +import com.android.server.display.config.IdleScreenRefreshRateTimeoutLuxThresholdPoint; import com.android.server.display.config.ThermalStatus; import com.android.server.display.feature.DisplayManagerFlags; @@ -108,6 +109,7 @@ public final class DisplayDeviceConfigTest { when(mContext.getResources()).thenReturn(mResources); when(mFlags.areAutoBrightnessModesEnabled()).thenReturn(true); when(mFlags.isSensorBasedBrightnessThrottlingEnabled()).thenReturn(true); + when(mFlags.isIdleScreenRefreshRateTimeoutEnabled()).thenReturn(true); mockDeviceConfigs(); } @@ -146,6 +148,8 @@ public final class DisplayDeviceConfigTest { assertNull(mDisplayDeviceConfig.getProximitySensor().type); assertNull(mDisplayDeviceConfig.getProximitySensor().name); assertEquals(TEMPERATURE_TYPE_SKIN, mDisplayDeviceConfig.getTempSensor().type); + assertEquals(List.of(), mDisplayDeviceConfig + .getIdleScreenRefreshRateTimeoutLuxThresholdPoint()); assertNull(mDisplayDeviceConfig.getTempSensor().name); assertTrue(mDisplayDeviceConfig.isAutoBrightnessAvailable()); } @@ -226,6 +230,19 @@ public final class DisplayDeviceConfigTest { assertNotNull(mDisplayDeviceConfig.getHostUsiVersion()); assertEquals(mDisplayDeviceConfig.getHostUsiVersion().getMajorVersion(), 2); assertEquals(mDisplayDeviceConfig.getHostUsiVersion().getMinorVersion(), 0); + + List<IdleScreenRefreshRateTimeoutLuxThresholdPoint> + idleScreenRefreshRateTimeoutLuxThresholdPoints = + mDisplayDeviceConfig.getIdleScreenRefreshRateTimeoutLuxThresholdPoint(); + assertEquals(2, idleScreenRefreshRateTimeoutLuxThresholdPoints.size()); + assertEquals(6, idleScreenRefreshRateTimeoutLuxThresholdPoints.get(0).getLux() + .intValue()); + assertEquals(1000, idleScreenRefreshRateTimeoutLuxThresholdPoints.get(0) + .getTimeout().intValue()); + assertEquals(10, idleScreenRefreshRateTimeoutLuxThresholdPoints.get(1) + .getLux().intValue()); + assertEquals(800, idleScreenRefreshRateTimeoutLuxThresholdPoints.get(1) + .getTimeout().intValue()); } @Test @@ -734,6 +751,8 @@ public final class DisplayDeviceConfigTest { assertEquals(brightnessIntToFloat(35), mDisplayDeviceConfig.getBrightnessCapForWearBedtimeMode(), ZERO_DELTA); + assertEquals(List.of(), mDisplayDeviceConfig + .getIdleScreenRefreshRateTimeoutLuxThresholdPoint()); } @Test @@ -1587,6 +1606,18 @@ public final class DisplayDeviceConfigTest { + "<screenBrightnessCapForWearBedtimeMode>" + "0.1" + "</screenBrightnessCapForWearBedtimeMode>" + + "<idleScreenRefreshRateTimeout>" + + "<luxThresholds>" + + "<point>" + + "<lux>6</lux>" + + "<timeout>1000</timeout>" + + "</point>" + + "<point>" + + "<lux>10</lux>" + + "<timeout>800</timeout>" + + "</point>" + + "</luxThresholds>" + + "</idleScreenRefreshRateTimeout>" + "</displayConfiguration>\n"; } |