From e2e67c4010389dc60a80147d6c3dff079268942b Mon Sep 17 00:00:00 2001 From: Rupesh Bansal Date: Tue, 12 Mar 2024 13:00:48 +0000 Subject: Add display config for configuring the idle state refresh rate timeout bands This is a step forward to attain the functionality where if the screen is idle for a configurable time, we would want to switch the screen to a lower refresh rate to preserve the battery Bug: 310026579 Test: atest DisplayDeviceConfigTest Change-Id: I92435cb355e0538171a07cc08c56bae561ab0ce4 --- .../server/display/DisplayDeviceConfig.java | 66 ++++++++++++++++++++++ .../display/feature/DisplayManagerFlags.java | 10 ++++ .../server/display/feature/display_flags.aconfig | 8 +++ .../display-device-config.xsd | 28 +++++++++ .../xsd/display-device-config/schema/current.txt | 21 +++++++ .../server/display/DisplayDeviceConfigTest.java | 31 ++++++++++ 6 files changed, 164 insertions(+) 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; * 0 * * 0.1 + * + * + * + * 6 + * 1000 + * + * + * 10 + * 800 + * + * + * * * } * @@ -843,6 +858,14 @@ public class DisplayDeviceConfig { private final Map> mLuxThrottlingData = new HashMap<>(); + /** + * The idle screen timeout configuration for switching to lower refresh rate + */ + @NonNull + private List + 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 = ""; } @@ -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 + 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 3c98ee453913..492ef451e41c 100644 --- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java +++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java @@ -126,6 +126,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, @@ -263,6 +268,10 @@ public class DisplayManagerFlags { return mSensorBasedBrightnessThrottling.isEnabled(); } + public boolean isIdleScreenRefreshRateTimeoutEnabled() { + return mIdleScreenRefreshRateTimeout.isEnabled(); + } + public boolean isRefactorDisplayPowerControllerEnabled() { return mRefactorDisplayPowerController.isEnabled(); } @@ -291,6 +300,7 @@ public class DisplayManagerFlags { pw.println(" " + mFastHdrTransitions); pw.println(" " + mRefreshRateVotingTelemetry); 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 34045273c93a..5fbed1f546cb 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 @@ -200,3 +200,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 @@ + + + + @@ -772,6 +776,30 @@ + + + + + + + + + + + + + + + + + + + + + + + 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 getPoint(); + } + public class IntegerArray { ctor public IntegerArray(); method public java.util.List 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 + 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 { + "" + "0.1" + "" + + "" + + "" + + "" + + "6" + + "1000" + + "" + + "" + + "10" + + "800" + + "" + + "" + + "" + "\n"; } -- cgit v1.2.3-59-g8ed1b