diff options
4 files changed, 107 insertions, 29 deletions
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 f0f6db232f13..35be0f3bc942 100644 --- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java +++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java @@ -183,15 +183,17 @@ public class DisplayManagerFlags { Flags::offloadDozeOverrideHoldsWakelock ); - private final FlagState mOffloadSessionCancelBlockScreenOn = - new FlagState( - Flags.FLAG_OFFLOAD_SESSION_CANCEL_BLOCK_SCREEN_ON, - Flags::offloadSessionCancelBlockScreenOn); + private final FlagState mOffloadSessionCancelBlockScreenOn = new FlagState( + Flags.FLAG_OFFLOAD_SESSION_CANCEL_BLOCK_SCREEN_ON, + Flags::offloadSessionCancelBlockScreenOn); - private final FlagState mNewHdrBrightnessModifier = - new FlagState( - Flags.FLAG_NEW_HDR_BRIGHTNESS_MODIFIER, - Flags::newHdrBrightnessModifier); + private final FlagState mNewHdrBrightnessModifier = new FlagState( + Flags.FLAG_NEW_HDR_BRIGHTNESS_MODIFIER, + Flags::newHdrBrightnessModifier); + + private final FlagState mIdleScreenConfigInSubscribingLightSensor = new FlagState( + Flags.FLAG_IDLE_SCREEN_CONFIG_IN_SUBSCRIBING_LIGHT_SENSOR, + Flags::idleScreenConfigInSubscribingLightSensor); private final FlagState mNormalBrightnessForDozeParameter = new FlagState( Flags.FLAG_NORMAL_BRIGHTNESS_FOR_DOZE_PARAMETER, @@ -404,6 +406,14 @@ public class DisplayManagerFlags { return mNormalBrightnessForDozeParameter.isEnabled(); } + /** + * @return {@code true} if idle timer refresh rate config is accounted for while subscribing to + * the light sensor + */ + public boolean isIdleScreenConfigInSubscribingLightSensorEnabled() { + return mIdleScreenConfigInSubscribingLightSensor.isEnabled(); + } + /** * dumps all flagstates * @param pw printWriter @@ -444,6 +454,7 @@ public class DisplayManagerFlags { pw.println(" " + mOffloadSessionCancelBlockScreenOn); pw.println(" " + mNewHdrBrightnessModifier); pw.println(" " + mNormalBrightnessForDozeParameter); + pw.println(" " + mIdleScreenConfigInSubscribingLightSensor); } private static class FlagState { 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 d92924957242..da5063acd5a9 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 @@ -330,3 +330,14 @@ flag { bug: "331275392" is_fixed_read_only: true } + +flag { + name: "idle_screen_config_in_subscribing_light_sensor" + namespace: "display_manager" + description: "Account for Idle screen refresh rate configs while subscribing to light sensor" + bug: "358019330" + is_fixed_read_only: true + metadata { + purpose: PURPOSE_BUGFIX + } +} diff --git a/services/core/java/com/android/server/display/mode/DisplayModeDirector.java b/services/core/java/com/android/server/display/mode/DisplayModeDirector.java index 5e471c82e108..4daf8c485191 100644 --- a/services/core/java/com/android/server/display/mode/DisplayModeDirector.java +++ b/services/core/java/com/android/server/display/mode/DisplayModeDirector.java @@ -483,6 +483,7 @@ public class DisplayModeDirector { /* attemptReadFromFeatureParams= */ true); mBrightnessObserver.updateBlockingZoneThresholds(displayDeviceConfig, /* attemptReadFromFeatureParams= */ true); + mBrightnessObserver.loadIdleScreenRefreshRateConfigs(displayDeviceConfig); mBrightnessObserver.reloadLightSensor(displayDeviceConfig); mHbmObserver.setupHdrRefreshRates(displayDeviceConfig); } @@ -1745,6 +1746,10 @@ public class DisplayModeDirector { private SparseArray<RefreshRateRange> mHighZoneRefreshRateForThermals; private int mRefreshRateInHighZone; + @Nullable + private List<IdleScreenRefreshRateTimeoutLuxThresholdPoint> + mIdleScreenRefreshRateTimeoutLuxThresholdPoints; + @GuardedBy("mLock") private @Temperature.ThrottlingStatus int mThermalStatus = Temperature.THROTTLING_NONE; @@ -1758,6 +1763,24 @@ public class DisplayModeDirector { mRefreshRateInHighZone = context.getResources().getInteger( R.integer.config_fixedRefreshRateInHighZone); mVsyncLowLightBlockingVoteEnabled = flags.isVsyncLowLightVoteEnabled(); + loadIdleScreenRefreshRateConfigs(/* displayDeviceConfig= */ null); + } + + private void loadIdleScreenRefreshRateConfigs(DisplayDeviceConfig displayDeviceConfig) { + synchronized (mLock) { + if (!mDisplayManagerFlags.isIdleScreenConfigInSubscribingLightSensorEnabled() + || displayDeviceConfig == null || displayDeviceConfig + .getIdleScreenRefreshRateTimeoutLuxThresholdPoint().isEmpty()) { + // Setting this to null will let surface flinger know that the idle timer is not + // configured in the display configs + mIdleScreenRefreshRateConfig = null; + mIdleScreenRefreshRateTimeoutLuxThresholdPoints = null; + return; + } + mIdleScreenRefreshRateTimeoutLuxThresholdPoints = + displayDeviceConfig + .getIdleScreenRefreshRateTimeoutLuxThresholdPoint(); + } } /** @@ -1806,11 +1829,19 @@ public class DisplayModeDirector { return mRefreshRateInLowZone; } + @Nullable @VisibleForTesting IdleScreenRefreshRateConfig getIdleScreenRefreshRateConfig() { return mIdleScreenRefreshRateConfig; } + @Nullable + @VisibleForTesting + List<IdleScreenRefreshRateTimeoutLuxThresholdPoint> + getIdleScreenRefreshRateTimeoutLuxThresholdPoints() { + return mIdleScreenRefreshRateTimeoutLuxThresholdPoints; + } + private void loadLowBrightnessThresholds(@Nullable DisplayDeviceConfig displayDeviceConfig, boolean attemptReadFromFeatureParams) { loadRefreshRateInHighZone(displayDeviceConfig, attemptReadFromFeatureParams); @@ -2205,12 +2236,11 @@ public class DisplayModeDirector { mShouldObserveAmbientHighChange = false; } - if (mShouldObserveAmbientLowChange || mShouldObserveAmbientHighChange) { + if (shouldRegisterLightSensor()) { Sensor lightSensor = getLightSensor(); if (lightSensor != null && lightSensor != mLightSensor) { final Resources res = mContext.getResources(); - mAmbientFilter = AmbientFilterFactory.createBrightnessFilter(TAG, res); mLightSensor = lightSensor; } @@ -2436,8 +2466,8 @@ public class DisplayModeDirector { } boolean registerForThermals = false; - if ((mShouldObserveAmbientLowChange || mShouldObserveAmbientHighChange) - && isDeviceActive() && !mLowPowerModeEnabled && mRefreshRateChangeable) { + if (shouldRegisterLightSensor() && isDeviceActive() && !mLowPowerModeEnabled + && mRefreshRateChangeable) { registerLightSensor(); registerForThermals = mLowZoneRefreshRateForThermals != null || mHighZoneRefreshRateForThermals != null; @@ -2456,6 +2486,17 @@ public class DisplayModeDirector { } } + private boolean shouldRegisterLightSensor() { + return mShouldObserveAmbientLowChange || mShouldObserveAmbientHighChange + || isIdleScreenRefreshRateConfigDefined(); + } + + private boolean isIdleScreenRefreshRateConfigDefined() { + return mDisplayManagerFlags.isIdleScreenConfigInSubscribingLightSensorEnabled() + && mIdleScreenRefreshRateTimeoutLuxThresholdPoints != null + && !mIdleScreenRefreshRateTimeoutLuxThresholdPoints.isEmpty(); + } + private void registerLightSensor() { if (mRegisteredLightSensor == mLightSensor) { return; @@ -2556,7 +2597,6 @@ public class DisplayModeDirector { // is interrupted by a new sensor event. mHandler.postDelayed(mInjectSensorEventRunnable, INJECT_EVENTS_INTERVAL_MS); } - if (mDisplayManagerFlags.isIdleScreenRefreshRateTimeoutEnabled()) { updateIdleScreenRefreshRate(mAmbientLux); } @@ -2621,24 +2661,15 @@ public class DisplayModeDirector { } private void updateIdleScreenRefreshRate(float ambientLux) { - List<IdleScreenRefreshRateTimeoutLuxThresholdPoint> - idleScreenRefreshRateTimeoutLuxThresholdPoints; - synchronized (mLock) { - if (mDefaultDisplayDeviceConfig == null || mDefaultDisplayDeviceConfig - .getIdleScreenRefreshRateTimeoutLuxThresholdPoint().isEmpty()) { - // Setting this to null will let surface flinger know that the idle timer is not - // configured in the display configs - mIdleScreenRefreshRateConfig = null; - return; - } - - idleScreenRefreshRateTimeoutLuxThresholdPoints = - mDefaultDisplayDeviceConfig - .getIdleScreenRefreshRateTimeoutLuxThresholdPoint(); + if (mIdleScreenRefreshRateTimeoutLuxThresholdPoints == null + || mIdleScreenRefreshRateTimeoutLuxThresholdPoints.isEmpty()) { + mIdleScreenRefreshRateConfig = null; + return; } + int newTimeout = -1; for (IdleScreenRefreshRateTimeoutLuxThresholdPoint point : - idleScreenRefreshRateTimeoutLuxThresholdPoints) { + mIdleScreenRefreshRateTimeoutLuxThresholdPoints) { int newLux = point.getLux().intValue(); if (newLux <= ambientLux) { newTimeout = point.getTimeout().intValue(); diff --git a/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java b/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java index 62400ebed149..ab0f0c1fe5ff 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java @@ -1557,6 +1557,19 @@ public class DisplayModeDirectorTest { when(ddcMock.getIdleScreenRefreshRateTimeoutLuxThresholdPoint()) .thenReturn(List.of(getIdleScreenRefreshRateTimeoutLuxThresholdPoint(6, 1000), getIdleScreenRefreshRateTimeoutLuxThresholdPoint(100, 800))); + director.defaultDisplayDeviceUpdated(ddcMock); // set the updated ddc + + // idleScreenRefreshRate config is still null because the flag to enable subscription to + // light sensor is not enabled + sensorListener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 4)); + waitForIdleSync(); + assertNull(director.getBrightnessObserver().getIdleScreenRefreshRateConfig()); + + // Flag to subscribe to light sensor is enabled, and the sensor subscription is attempted + // again to load the idle screen refresh rate config + when(mDisplayManagerFlags.isIdleScreenConfigInSubscribingLightSensorEnabled()) + .thenReturn(true); + director.defaultDisplayDeviceUpdated(ddcMock); // set the updated ddc // Sensor reads 5 lux sensorListener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 5)); @@ -1575,7 +1588,6 @@ public class DisplayModeDirectorTest { waitForIdleSync(); assertEquals(new SurfaceControl.IdleScreenRefreshRateConfig(800), director.getBrightnessObserver().getIdleScreenRefreshRateConfig()); - } @Test @@ -3231,6 +3243,8 @@ public class DisplayModeDirectorTest { @Test public void testNotifyDefaultDisplayDeviceUpdated() { + when(mDisplayManagerFlags.isIdleScreenConfigInSubscribingLightSensorEnabled()) + .thenReturn(true); when(mResources.getInteger(com.android.internal.R.integer.config_defaultPeakRefreshRate)) .thenReturn(75); when(mResources.getInteger(R.integer.config_defaultRefreshRate)) @@ -3289,6 +3303,8 @@ public class DisplayModeDirectorTest { new float[]{ BrightnessSynchronizer.brightnessIntToFloat(5) }, /* delta= */ 0); assertArrayEquals(director.getBrightnessObserver().getLowAmbientBrightnessThresholds(), new float[]{10}, /* delta= */ 0); + assertNull(director.getBrightnessObserver() + .getIdleScreenRefreshRateTimeoutLuxThresholdPoints()); // Notify that the default display is updated, such that DisplayDeviceConfig has new values @@ -3300,6 +3316,10 @@ public class DisplayModeDirectorTest { /* defaultRefreshRateInHbmSunlight= */ 75, /* lowPowerSupportedModes= */ List.of(), /* lowLightBlockingZoneSupportedModes= */ List.of()); + List<IdleScreenRefreshRateTimeoutLuxThresholdPoint> + idleScreenRefreshRateTimeoutLuxThresholdPoints = + List.of(getIdleScreenRefreshRateTimeoutLuxThresholdPoint(0, 1500), + getIdleScreenRefreshRateTimeoutLuxThresholdPoint(50, 1000)); when(displayDeviceConfig.getRefreshRateData()).thenReturn(refreshRateData); when(displayDeviceConfig.getDefaultLowBlockingZoneRefreshRate()).thenReturn(50); when(displayDeviceConfig.getDefaultHighBlockingZoneRefreshRate()).thenReturn(55); @@ -3311,6 +3331,8 @@ public class DisplayModeDirectorTest { .thenReturn(new float[]{0.21f}); when(displayDeviceConfig.getHighAmbientBrightnessThresholds()) .thenReturn(new float[]{2100}); + when(displayDeviceConfig.getIdleScreenRefreshRateTimeoutLuxThresholdPoint()) + .thenReturn(idleScreenRefreshRateTimeoutLuxThresholdPoints); director.defaultDisplayDeviceUpdated(displayDeviceConfig); // Verify the new values are from the freshly loaded DisplayDeviceConfig. @@ -3329,6 +3351,9 @@ public class DisplayModeDirectorTest { new float[]{30}, /* delta= */ 0); assertEquals(director.getHbmObserver().getRefreshRateInHbmHdr(), 65); assertEquals(director.getHbmObserver().getRefreshRateInHbmSunlight(), 75); + assertEquals(director.getBrightnessObserver() + .getIdleScreenRefreshRateTimeoutLuxThresholdPoints(), + idleScreenRefreshRateTimeoutLuxThresholdPoints); // Notify that the default display is updated, such that DeviceConfig has new values FakeDeviceConfig config = mInjector.getDeviceConfig(); |