Loading services/core/java/com/android/server/display/DisplayDeviceConfig.java +57 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ import com.android.server.display.config.DisplayConfiguration; import com.android.server.display.config.DisplayQuirks; import com.android.server.display.config.HbmTiming; import com.android.server.display.config.HighBrightnessMode; import com.android.server.display.config.IntegerArray; import com.android.server.display.config.NitsMap; import com.android.server.display.config.Point; import com.android.server.display.config.RefreshRateConfigs; Loading Loading @@ -213,6 +214,10 @@ import javax.xml.datatype.DatatypeConfigurationException; * <type>android.sensor.light</type> * <name>1234 Ambient Light Sensor</name> * </lightSensor> * <screenOffBrightnessSensor> * <type>com.google.sensor.binned_brightness</type> * <name>Binned Brightness 0 (wake-up)</name> * </screenOffBrightnessSensor> * <proxSensor> * <type>android.sensor.proximity</type> * <name>1234 Proximity Sensor</name> Loading Loading @@ -368,6 +373,13 @@ import javax.xml.datatype.DatatypeConfigurationException; * </brightnessThresholdPoints> * </darkeningThresholds> * </displayBrightnessChangeThresholdsIdle> * <screenOffBrightnessSensorValueToLux> * <item>-1</item> * <item>0</item> * <item>5</item> * <item>80</item> * <item>1500</item> * </screenOffBrightnessSensorValueToLux> * </displayConfiguration> * } * </pre> Loading Loading @@ -428,6 +440,9 @@ public class DisplayDeviceConfig { // The details of the ambient light sensor associated with this display. private final SensorData mAmbientLightSensor = new SensorData(); // The details of the doze brightness sensor associated with this display. private final SensorData mScreenOffBrightnessSensor = new SensorData(); // The details of the proximity sensor associated with this display. private final SensorData mProximitySensor = new SensorData(); Loading Loading @@ -523,6 +538,9 @@ public class DisplayDeviceConfig { private float[] mAmbientDarkeningLevelsIdle = DEFAULT_AMBIENT_THRESHOLD_LEVELS; private float[] mAmbientDarkeningPercentagesIdle = DEFAULT_AMBIENT_DARKENING_THRESHOLDS; // A mapping between screen off sensor values and lux values private int[] mScreenOffBrightnessSensorValueToLux; private Spline mBrightnessToBacklightSpline; private Spline mBacklightToBrightnessSpline; private Spline mBacklightToNitsSpline; Loading Loading @@ -1198,6 +1216,10 @@ public class DisplayDeviceConfig { return mAmbientLightSensor; } SensorData getScreenOffBrightnessSensor() { return mScreenOffBrightnessSensor; } SensorData getProximitySensor() { return mProximitySensor; } Loading Loading @@ -1321,6 +1343,14 @@ public class DisplayDeviceConfig { return mHighAmbientBrightnessThresholds; } /** * @return A mapping from screen off brightness sensor readings to lux values. This estimates * the ambient lux when the screen is off to determine the initial brightness */ public int[] getScreenOffBrightnessSensorValueToLux() { return mScreenOffBrightnessSensorValueToLux; } @Override public String toString() { return "DisplayDeviceConfig{" Loading Loading @@ -1399,6 +1429,7 @@ public class DisplayDeviceConfig { mScreenDarkeningPercentagesIdle) + "\n" + ", mAmbientLightSensor=" + mAmbientLightSensor + ", mScreenOffBrightnessSensor=" + mScreenOffBrightnessSensor + ", mProximitySensor=" + mProximitySensor + ", mRefreshRateLimitations= " + Arrays.toString(mRefreshRateLimitations.toArray()) + ", mDensityMapping= " + mDensityMapping Loading @@ -1421,6 +1452,9 @@ public class DisplayDeviceConfig { + Arrays.toString(mHighDisplayBrightnessThresholds) + ", mHighAmbientBrightnessThresholds= " + Arrays.toString(mHighAmbientBrightnessThresholds) + "\n" + ", mScreenOffBrightnessSensorValueToLux=" + Arrays.toString( mScreenOffBrightnessSensorValueToLux) + "}"; } Loading Loading @@ -1474,11 +1508,13 @@ public class DisplayDeviceConfig { loadQuirks(config); loadBrightnessRamps(config); loadAmbientLightSensorFromDdc(config); loadScreenOffBrightnessSensorFromDdc(config); loadProxSensorFromDdc(config); loadAmbientHorizonFromDdc(config); loadBrightnessChangeThresholds(config); loadAutoBrightnessConfigValues(config); loadRefreshRateSetting(config); loadScreenOffBrightnessSensorValueToLuxFromDdc(config); } else { Slog.w(TAG, "DisplayDeviceConfig file is null"); } Loading Loading @@ -2175,6 +2211,14 @@ public class DisplayDeviceConfig { mProximitySensor.type = ""; } private void loadScreenOffBrightnessSensorFromDdc(DisplayConfiguration config) { final SensorDetails sensorDetails = config.getScreenOffBrightnessSensor(); if (sensorDetails != null) { mScreenOffBrightnessSensor.type = sensorDetails.getType(); mScreenOffBrightnessSensor.name = sensorDetails.getName(); } } private void loadProxSensorFromDdc(DisplayConfiguration config) { SensorDetails sensorDetails = config.getProxSensor(); if (sensorDetails != null) { Loading Loading @@ -2587,6 +2631,19 @@ public class DisplayDeviceConfig { && mDdcAutoBrightnessAvailable; } private void loadScreenOffBrightnessSensorValueToLuxFromDdc(DisplayConfiguration config) { IntegerArray sensorValueToLux = config.getScreenOffBrightnessSensorValueToLux(); if (sensorValueToLux == null) { return; } List<BigInteger> items = sensorValueToLux.getItem(); mScreenOffBrightnessSensorValueToLux = new int[items.size()]; for (int i = 0; i < items.size(); i++) { mScreenOffBrightnessSensorValueToLux[i] = items.get(i).intValue(); } } static class SensorData { public String type; public String name; Loading services/core/java/com/android/server/display/DisplayPowerController.java +51 −1 Original line number Diff line number Diff line Loading @@ -414,7 +414,12 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call @Nullable private AutomaticBrightnessController mAutomaticBrightnessController; // The controller for the sensor used to estimate ambient lux while the display is off. @Nullable private ScreenOffBrightnessSensorController mScreenOffBrightnessSensorController; private Sensor mLightSensor; private Sensor mScreenOffBrightnessSensor; // The mappers between ambient lux, display backlight values, and display brightness. // We will switch between the idle mapper and active mapper in AutomaticBrightnessController. Loading Loading @@ -1098,6 +1103,19 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mBrightnessEventRingBuffer = new RingBuffer<>(BrightnessEvent.class, RINGBUFFER_MAX); loadScreenOffBrightnessSensor(); int[] sensorValueToLux = mDisplayDeviceConfig.getScreenOffBrightnessSensorValueToLux(); if (mScreenOffBrightnessSensor != null && sensorValueToLux != null) { mScreenOffBrightnessSensorController = new ScreenOffBrightnessSensorController( mSensorManager, mScreenOffBrightnessSensor, mHandler, SystemClock::uptimeMillis, sensorValueToLux, mInteractiveModeBrightnessMapper ); } } else { mUseSoftwareAutoBrightnessConfig = false; } Loading Loading @@ -1275,6 +1293,12 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } assert(state != Display.STATE_UNKNOWN); if (mScreenOffBrightnessSensorController != null) { mScreenOffBrightnessSensorController.setLightSensorEnabled(mUseAutoBrightness && (state == Display.STATE_OFF || (state == Display.STATE_DOZE && !mAllowAutoBrightnessWhileDozingConfig))); } boolean skipRampBecauseOfProximityChangeToNegative = false; // Apply the proximity sensor. if (mProximitySensor != null) { Loading Loading @@ -1454,6 +1478,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call updateScreenBrightnessSetting = mCurrentScreenBrightnessSetting != brightnessState; mAppliedAutoBrightness = true; mBrightnessReasonTemp.setReason(BrightnessReason.REASON_AUTOMATIC); if (mScreenOffBrightnessSensorController != null) { mScreenOffBrightnessSensorController.setLightSensorEnabled(false); } } else { mAppliedAutoBrightness = false; } Loading Loading @@ -1481,6 +1508,19 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE_DEFAULT); } // The ALS is not available yet - use the screen off sensor to determine the initial // brightness if (Float.isNaN(brightnessState) && autoBrightnessEnabled && mScreenOffBrightnessSensorController != null) { brightnessState = mScreenOffBrightnessSensorController.getAutomaticScreenBrightness(); if (isValidBrightnessValue(brightnessState)) { brightnessState = clampScreenBrightness(brightnessState); updateScreenBrightnessSetting = mCurrentScreenBrightnessSetting != brightnessState; mBrightnessReasonTemp.setReason( BrightnessReason.REASON_SCREEN_OFF_BRIGHTNESS_SENSOR); } } // Apply manual brightness. if (Float.isNaN(brightnessState)) { brightnessState = clampScreenBrightness(mCurrentScreenBrightnessSetting); Loading Loading @@ -2052,6 +2092,14 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call fallbackType); } private void loadScreenOffBrightnessSensor() { DisplayDeviceConfig.SensorData screenOffBrightnessSensor = mDisplayDeviceConfig.getScreenOffBrightnessSensor(); mScreenOffBrightnessSensor = SensorUtils.findSensor(mSensorManager, screenOffBrightnessSensor.type, screenOffBrightnessSensor.name, SensorUtils.NO_FALLBACK); } private void loadProximitySensor() { if (DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) { return; Loading Loading @@ -3201,7 +3249,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call static final int REASON_OVERRIDE = 7; static final int REASON_TEMPORARY = 8; static final int REASON_BOOST = 9; static final int REASON_MAX = REASON_BOOST; static final int REASON_SCREEN_OFF_BRIGHTNESS_SENSOR = 10; static final int REASON_MAX = REASON_SCREEN_OFF_BRIGHTNESS_SENSOR; static final int MODIFIER_DIMMED = 0x1; static final int MODIFIER_LOW_POWER = 0x2; Loading Loading @@ -3311,6 +3360,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call case REASON_OVERRIDE: return "override"; case REASON_TEMPORARY: return "temporary"; case REASON_BOOST: return "boost"; case REASON_SCREEN_OFF_BRIGHTNESS_SENSOR: return "screen_off_brightness_sensor"; default: return Integer.toString(reason); } } Loading services/core/java/com/android/server/display/ScreenOffBrightnessSensorController.java 0 → 100644 +127 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.display; import android.annotation.Nullable; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Handler; import android.os.PowerManager; import android.util.IndentingPrintWriter; import com.android.internal.annotations.VisibleForTesting; import java.io.PrintWriter; /** * Controls the light sensor when the screen is off. The sensor used here does not report lux values * but an index that needs to be mapped to a lux value. */ public class ScreenOffBrightnessSensorController implements SensorEventListener { private static final String TAG = "ScreenOffBrightnessSensorController"; private static final int SENSOR_INVALID_VALUE = -1; private static final long SENSOR_VALUE_VALID_TIME_MILLIS = 1500; private final Handler mHandler; private final Clock mClock; private final SensorManager mSensorManager; private final Sensor mLightSensor; private final int[] mSensorValueToLux; private boolean mRegistered; private int mLastSensorValue = SENSOR_INVALID_VALUE; private long mSensorDisableTime = -1; // The mapper to translate ambient lux to screen brightness in the range [0, 1.0]. @Nullable private final BrightnessMappingStrategy mBrightnessMapper; public ScreenOffBrightnessSensorController( SensorManager sensorManager, Sensor lightSensor, Handler handler, Clock clock, int[] sensorValueToLux, BrightnessMappingStrategy brightnessMapper) { mSensorManager = sensorManager; mLightSensor = lightSensor; mHandler = handler; mClock = clock; mSensorValueToLux = sensorValueToLux; mBrightnessMapper = brightnessMapper; } @Override public void onSensorChanged(SensorEvent event) { if (mRegistered) { mLastSensorValue = (int) event.values[0]; } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } void setLightSensorEnabled(boolean enabled) { if (enabled && !mRegistered) { // Wait until we get an event from the sensor indicating ready. mRegistered = mSensorManager.registerListener(this, mLightSensor, SensorManager.SENSOR_DELAY_NORMAL, mHandler); mLastSensorValue = SENSOR_INVALID_VALUE; } else if (!enabled && mRegistered) { mSensorManager.unregisterListener(this); mRegistered = false; mSensorDisableTime = mClock.uptimeMillis(); } } float getAutomaticScreenBrightness() { if (mLastSensorValue < 0 || mLastSensorValue >= mSensorValueToLux.length || (!mRegistered && mClock.uptimeMillis() - mSensorDisableTime > SENSOR_VALUE_VALID_TIME_MILLIS)) { return PowerManager.BRIGHTNESS_INVALID_FLOAT; } int lux = mSensorValueToLux[mLastSensorValue]; if (lux < 0) { return PowerManager.BRIGHTNESS_INVALID_FLOAT; } return mBrightnessMapper.getBrightness(lux); } /** Dump current state */ public void dump(PrintWriter pw) { pw.println("ScreenOffBrightnessSensorController:"); IndentingPrintWriter idpw = new IndentingPrintWriter(pw); idpw.increaseIndent(); idpw.println("registered=" + mRegistered); idpw.println("lastSensorValue=" + mLastSensorValue); } /** Functional interface for providing time. */ @VisibleForTesting interface Clock { /** * Returns current time in milliseconds since boot, not counting time spent in deep sleep. */ long uptimeMillis(); } } services/core/xsd/display-device-config/display-device-config.xsd +14 −0 Original line number Diff line number Diff line Loading @@ -74,6 +74,9 @@ <xs:element type="sensorDetails" name="lightSensor"> <xs:annotation name="final"/> </xs:element> <xs:element type="sensorDetails" name="screenOffBrightnessSensor"> <xs:annotation name="final"/> </xs:element> <xs:element type="sensorDetails" name="proxSensor"> <xs:annotation name="final"/> </xs:element> Loading Loading @@ -109,6 +112,11 @@ <xs:element type="thresholds" name="ambientBrightnessChangeThresholdsIdle" minOccurs="0" maxOccurs="1"> <xs:annotation name="final"/> </xs:element> <!-- Table that translates sensor values from the screenOffBrightnessSensor to lux values; -1 means the lux reading is not available. --> <xs:element type="integer-array" name="screenOffBrightnessSensorValueToLux"> <xs:annotation name="final"/> </xs:element> </xs:sequence> </xs:complexType> </xs:element> Loading Loading @@ -485,4 +493,10 @@ </xs:element> </xs:sequence> </xs:complexType> <xs:complexType name="integer-array"> <xs:sequence> <xs:element name="item" type="xs:nonNegativeInteger" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:schema> services/core/xsd/display-device-config/schema/current.txt +9 −0 Original line number Diff line number Diff line Loading @@ -98,6 +98,8 @@ package com.android.server.display.config { method public final java.math.BigInteger getScreenBrightnessRampIncreaseMaxMillis(); method public final java.math.BigDecimal getScreenBrightnessRampSlowDecrease(); method public final java.math.BigDecimal getScreenBrightnessRampSlowIncrease(); method public final com.android.server.display.config.SensorDetails getScreenOffBrightnessSensor(); method public final com.android.server.display.config.IntegerArray getScreenOffBrightnessSensorValueToLux(); method @NonNull public final com.android.server.display.config.ThermalThrottling getThermalThrottling(); method public final void setAmbientBrightnessChangeThresholds(@NonNull com.android.server.display.config.Thresholds); method public final void setAmbientBrightnessChangeThresholdsIdle(com.android.server.display.config.Thresholds); Loading @@ -120,6 +122,8 @@ package com.android.server.display.config { method public final void setScreenBrightnessRampIncreaseMaxMillis(java.math.BigInteger); method public final void setScreenBrightnessRampSlowDecrease(java.math.BigDecimal); method public final void setScreenBrightnessRampSlowIncrease(java.math.BigDecimal); method public final void setScreenOffBrightnessSensor(com.android.server.display.config.SensorDetails); method public final void setScreenOffBrightnessSensorValueToLux(com.android.server.display.config.IntegerArray); method public final void setThermalThrottling(@NonNull com.android.server.display.config.ThermalThrottling); } Loading Loading @@ -160,6 +164,11 @@ package com.android.server.display.config { method public final void setTransitionPoint_all(@NonNull java.math.BigDecimal); } public class IntegerArray { ctor public IntegerArray(); method public java.util.List<java.math.BigInteger> getItem(); } public class NitsMap { ctor public NitsMap(); method public String getInterpolation(); Loading Loading
services/core/java/com/android/server/display/DisplayDeviceConfig.java +57 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ import com.android.server.display.config.DisplayConfiguration; import com.android.server.display.config.DisplayQuirks; import com.android.server.display.config.HbmTiming; import com.android.server.display.config.HighBrightnessMode; import com.android.server.display.config.IntegerArray; import com.android.server.display.config.NitsMap; import com.android.server.display.config.Point; import com.android.server.display.config.RefreshRateConfigs; Loading Loading @@ -213,6 +214,10 @@ import javax.xml.datatype.DatatypeConfigurationException; * <type>android.sensor.light</type> * <name>1234 Ambient Light Sensor</name> * </lightSensor> * <screenOffBrightnessSensor> * <type>com.google.sensor.binned_brightness</type> * <name>Binned Brightness 0 (wake-up)</name> * </screenOffBrightnessSensor> * <proxSensor> * <type>android.sensor.proximity</type> * <name>1234 Proximity Sensor</name> Loading Loading @@ -368,6 +373,13 @@ import javax.xml.datatype.DatatypeConfigurationException; * </brightnessThresholdPoints> * </darkeningThresholds> * </displayBrightnessChangeThresholdsIdle> * <screenOffBrightnessSensorValueToLux> * <item>-1</item> * <item>0</item> * <item>5</item> * <item>80</item> * <item>1500</item> * </screenOffBrightnessSensorValueToLux> * </displayConfiguration> * } * </pre> Loading Loading @@ -428,6 +440,9 @@ public class DisplayDeviceConfig { // The details of the ambient light sensor associated with this display. private final SensorData mAmbientLightSensor = new SensorData(); // The details of the doze brightness sensor associated with this display. private final SensorData mScreenOffBrightnessSensor = new SensorData(); // The details of the proximity sensor associated with this display. private final SensorData mProximitySensor = new SensorData(); Loading Loading @@ -523,6 +538,9 @@ public class DisplayDeviceConfig { private float[] mAmbientDarkeningLevelsIdle = DEFAULT_AMBIENT_THRESHOLD_LEVELS; private float[] mAmbientDarkeningPercentagesIdle = DEFAULT_AMBIENT_DARKENING_THRESHOLDS; // A mapping between screen off sensor values and lux values private int[] mScreenOffBrightnessSensorValueToLux; private Spline mBrightnessToBacklightSpline; private Spline mBacklightToBrightnessSpline; private Spline mBacklightToNitsSpline; Loading Loading @@ -1198,6 +1216,10 @@ public class DisplayDeviceConfig { return mAmbientLightSensor; } SensorData getScreenOffBrightnessSensor() { return mScreenOffBrightnessSensor; } SensorData getProximitySensor() { return mProximitySensor; } Loading Loading @@ -1321,6 +1343,14 @@ public class DisplayDeviceConfig { return mHighAmbientBrightnessThresholds; } /** * @return A mapping from screen off brightness sensor readings to lux values. This estimates * the ambient lux when the screen is off to determine the initial brightness */ public int[] getScreenOffBrightnessSensorValueToLux() { return mScreenOffBrightnessSensorValueToLux; } @Override public String toString() { return "DisplayDeviceConfig{" Loading Loading @@ -1399,6 +1429,7 @@ public class DisplayDeviceConfig { mScreenDarkeningPercentagesIdle) + "\n" + ", mAmbientLightSensor=" + mAmbientLightSensor + ", mScreenOffBrightnessSensor=" + mScreenOffBrightnessSensor + ", mProximitySensor=" + mProximitySensor + ", mRefreshRateLimitations= " + Arrays.toString(mRefreshRateLimitations.toArray()) + ", mDensityMapping= " + mDensityMapping Loading @@ -1421,6 +1452,9 @@ public class DisplayDeviceConfig { + Arrays.toString(mHighDisplayBrightnessThresholds) + ", mHighAmbientBrightnessThresholds= " + Arrays.toString(mHighAmbientBrightnessThresholds) + "\n" + ", mScreenOffBrightnessSensorValueToLux=" + Arrays.toString( mScreenOffBrightnessSensorValueToLux) + "}"; } Loading Loading @@ -1474,11 +1508,13 @@ public class DisplayDeviceConfig { loadQuirks(config); loadBrightnessRamps(config); loadAmbientLightSensorFromDdc(config); loadScreenOffBrightnessSensorFromDdc(config); loadProxSensorFromDdc(config); loadAmbientHorizonFromDdc(config); loadBrightnessChangeThresholds(config); loadAutoBrightnessConfigValues(config); loadRefreshRateSetting(config); loadScreenOffBrightnessSensorValueToLuxFromDdc(config); } else { Slog.w(TAG, "DisplayDeviceConfig file is null"); } Loading Loading @@ -2175,6 +2211,14 @@ public class DisplayDeviceConfig { mProximitySensor.type = ""; } private void loadScreenOffBrightnessSensorFromDdc(DisplayConfiguration config) { final SensorDetails sensorDetails = config.getScreenOffBrightnessSensor(); if (sensorDetails != null) { mScreenOffBrightnessSensor.type = sensorDetails.getType(); mScreenOffBrightnessSensor.name = sensorDetails.getName(); } } private void loadProxSensorFromDdc(DisplayConfiguration config) { SensorDetails sensorDetails = config.getProxSensor(); if (sensorDetails != null) { Loading Loading @@ -2587,6 +2631,19 @@ public class DisplayDeviceConfig { && mDdcAutoBrightnessAvailable; } private void loadScreenOffBrightnessSensorValueToLuxFromDdc(DisplayConfiguration config) { IntegerArray sensorValueToLux = config.getScreenOffBrightnessSensorValueToLux(); if (sensorValueToLux == null) { return; } List<BigInteger> items = sensorValueToLux.getItem(); mScreenOffBrightnessSensorValueToLux = new int[items.size()]; for (int i = 0; i < items.size(); i++) { mScreenOffBrightnessSensorValueToLux[i] = items.get(i).intValue(); } } static class SensorData { public String type; public String name; Loading
services/core/java/com/android/server/display/DisplayPowerController.java +51 −1 Original line number Diff line number Diff line Loading @@ -414,7 +414,12 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call @Nullable private AutomaticBrightnessController mAutomaticBrightnessController; // The controller for the sensor used to estimate ambient lux while the display is off. @Nullable private ScreenOffBrightnessSensorController mScreenOffBrightnessSensorController; private Sensor mLightSensor; private Sensor mScreenOffBrightnessSensor; // The mappers between ambient lux, display backlight values, and display brightness. // We will switch between the idle mapper and active mapper in AutomaticBrightnessController. Loading Loading @@ -1098,6 +1103,19 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mBrightnessEventRingBuffer = new RingBuffer<>(BrightnessEvent.class, RINGBUFFER_MAX); loadScreenOffBrightnessSensor(); int[] sensorValueToLux = mDisplayDeviceConfig.getScreenOffBrightnessSensorValueToLux(); if (mScreenOffBrightnessSensor != null && sensorValueToLux != null) { mScreenOffBrightnessSensorController = new ScreenOffBrightnessSensorController( mSensorManager, mScreenOffBrightnessSensor, mHandler, SystemClock::uptimeMillis, sensorValueToLux, mInteractiveModeBrightnessMapper ); } } else { mUseSoftwareAutoBrightnessConfig = false; } Loading Loading @@ -1275,6 +1293,12 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } assert(state != Display.STATE_UNKNOWN); if (mScreenOffBrightnessSensorController != null) { mScreenOffBrightnessSensorController.setLightSensorEnabled(mUseAutoBrightness && (state == Display.STATE_OFF || (state == Display.STATE_DOZE && !mAllowAutoBrightnessWhileDozingConfig))); } boolean skipRampBecauseOfProximityChangeToNegative = false; // Apply the proximity sensor. if (mProximitySensor != null) { Loading Loading @@ -1454,6 +1478,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call updateScreenBrightnessSetting = mCurrentScreenBrightnessSetting != brightnessState; mAppliedAutoBrightness = true; mBrightnessReasonTemp.setReason(BrightnessReason.REASON_AUTOMATIC); if (mScreenOffBrightnessSensorController != null) { mScreenOffBrightnessSensorController.setLightSensorEnabled(false); } } else { mAppliedAutoBrightness = false; } Loading Loading @@ -1481,6 +1508,19 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE_DEFAULT); } // The ALS is not available yet - use the screen off sensor to determine the initial // brightness if (Float.isNaN(brightnessState) && autoBrightnessEnabled && mScreenOffBrightnessSensorController != null) { brightnessState = mScreenOffBrightnessSensorController.getAutomaticScreenBrightness(); if (isValidBrightnessValue(brightnessState)) { brightnessState = clampScreenBrightness(brightnessState); updateScreenBrightnessSetting = mCurrentScreenBrightnessSetting != brightnessState; mBrightnessReasonTemp.setReason( BrightnessReason.REASON_SCREEN_OFF_BRIGHTNESS_SENSOR); } } // Apply manual brightness. if (Float.isNaN(brightnessState)) { brightnessState = clampScreenBrightness(mCurrentScreenBrightnessSetting); Loading Loading @@ -2052,6 +2092,14 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call fallbackType); } private void loadScreenOffBrightnessSensor() { DisplayDeviceConfig.SensorData screenOffBrightnessSensor = mDisplayDeviceConfig.getScreenOffBrightnessSensor(); mScreenOffBrightnessSensor = SensorUtils.findSensor(mSensorManager, screenOffBrightnessSensor.type, screenOffBrightnessSensor.name, SensorUtils.NO_FALLBACK); } private void loadProximitySensor() { if (DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) { return; Loading Loading @@ -3201,7 +3249,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call static final int REASON_OVERRIDE = 7; static final int REASON_TEMPORARY = 8; static final int REASON_BOOST = 9; static final int REASON_MAX = REASON_BOOST; static final int REASON_SCREEN_OFF_BRIGHTNESS_SENSOR = 10; static final int REASON_MAX = REASON_SCREEN_OFF_BRIGHTNESS_SENSOR; static final int MODIFIER_DIMMED = 0x1; static final int MODIFIER_LOW_POWER = 0x2; Loading Loading @@ -3311,6 +3360,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call case REASON_OVERRIDE: return "override"; case REASON_TEMPORARY: return "temporary"; case REASON_BOOST: return "boost"; case REASON_SCREEN_OFF_BRIGHTNESS_SENSOR: return "screen_off_brightness_sensor"; default: return Integer.toString(reason); } } Loading
services/core/java/com/android/server/display/ScreenOffBrightnessSensorController.java 0 → 100644 +127 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.display; import android.annotation.Nullable; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Handler; import android.os.PowerManager; import android.util.IndentingPrintWriter; import com.android.internal.annotations.VisibleForTesting; import java.io.PrintWriter; /** * Controls the light sensor when the screen is off. The sensor used here does not report lux values * but an index that needs to be mapped to a lux value. */ public class ScreenOffBrightnessSensorController implements SensorEventListener { private static final String TAG = "ScreenOffBrightnessSensorController"; private static final int SENSOR_INVALID_VALUE = -1; private static final long SENSOR_VALUE_VALID_TIME_MILLIS = 1500; private final Handler mHandler; private final Clock mClock; private final SensorManager mSensorManager; private final Sensor mLightSensor; private final int[] mSensorValueToLux; private boolean mRegistered; private int mLastSensorValue = SENSOR_INVALID_VALUE; private long mSensorDisableTime = -1; // The mapper to translate ambient lux to screen brightness in the range [0, 1.0]. @Nullable private final BrightnessMappingStrategy mBrightnessMapper; public ScreenOffBrightnessSensorController( SensorManager sensorManager, Sensor lightSensor, Handler handler, Clock clock, int[] sensorValueToLux, BrightnessMappingStrategy brightnessMapper) { mSensorManager = sensorManager; mLightSensor = lightSensor; mHandler = handler; mClock = clock; mSensorValueToLux = sensorValueToLux; mBrightnessMapper = brightnessMapper; } @Override public void onSensorChanged(SensorEvent event) { if (mRegistered) { mLastSensorValue = (int) event.values[0]; } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } void setLightSensorEnabled(boolean enabled) { if (enabled && !mRegistered) { // Wait until we get an event from the sensor indicating ready. mRegistered = mSensorManager.registerListener(this, mLightSensor, SensorManager.SENSOR_DELAY_NORMAL, mHandler); mLastSensorValue = SENSOR_INVALID_VALUE; } else if (!enabled && mRegistered) { mSensorManager.unregisterListener(this); mRegistered = false; mSensorDisableTime = mClock.uptimeMillis(); } } float getAutomaticScreenBrightness() { if (mLastSensorValue < 0 || mLastSensorValue >= mSensorValueToLux.length || (!mRegistered && mClock.uptimeMillis() - mSensorDisableTime > SENSOR_VALUE_VALID_TIME_MILLIS)) { return PowerManager.BRIGHTNESS_INVALID_FLOAT; } int lux = mSensorValueToLux[mLastSensorValue]; if (lux < 0) { return PowerManager.BRIGHTNESS_INVALID_FLOAT; } return mBrightnessMapper.getBrightness(lux); } /** Dump current state */ public void dump(PrintWriter pw) { pw.println("ScreenOffBrightnessSensorController:"); IndentingPrintWriter idpw = new IndentingPrintWriter(pw); idpw.increaseIndent(); idpw.println("registered=" + mRegistered); idpw.println("lastSensorValue=" + mLastSensorValue); } /** Functional interface for providing time. */ @VisibleForTesting interface Clock { /** * Returns current time in milliseconds since boot, not counting time spent in deep sleep. */ long uptimeMillis(); } }
services/core/xsd/display-device-config/display-device-config.xsd +14 −0 Original line number Diff line number Diff line Loading @@ -74,6 +74,9 @@ <xs:element type="sensorDetails" name="lightSensor"> <xs:annotation name="final"/> </xs:element> <xs:element type="sensorDetails" name="screenOffBrightnessSensor"> <xs:annotation name="final"/> </xs:element> <xs:element type="sensorDetails" name="proxSensor"> <xs:annotation name="final"/> </xs:element> Loading Loading @@ -109,6 +112,11 @@ <xs:element type="thresholds" name="ambientBrightnessChangeThresholdsIdle" minOccurs="0" maxOccurs="1"> <xs:annotation name="final"/> </xs:element> <!-- Table that translates sensor values from the screenOffBrightnessSensor to lux values; -1 means the lux reading is not available. --> <xs:element type="integer-array" name="screenOffBrightnessSensorValueToLux"> <xs:annotation name="final"/> </xs:element> </xs:sequence> </xs:complexType> </xs:element> Loading Loading @@ -485,4 +493,10 @@ </xs:element> </xs:sequence> </xs:complexType> <xs:complexType name="integer-array"> <xs:sequence> <xs:element name="item" type="xs:nonNegativeInteger" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:schema>
services/core/xsd/display-device-config/schema/current.txt +9 −0 Original line number Diff line number Diff line Loading @@ -98,6 +98,8 @@ package com.android.server.display.config { method public final java.math.BigInteger getScreenBrightnessRampIncreaseMaxMillis(); method public final java.math.BigDecimal getScreenBrightnessRampSlowDecrease(); method public final java.math.BigDecimal getScreenBrightnessRampSlowIncrease(); method public final com.android.server.display.config.SensorDetails getScreenOffBrightnessSensor(); method public final com.android.server.display.config.IntegerArray getScreenOffBrightnessSensorValueToLux(); method @NonNull public final com.android.server.display.config.ThermalThrottling getThermalThrottling(); method public final void setAmbientBrightnessChangeThresholds(@NonNull com.android.server.display.config.Thresholds); method public final void setAmbientBrightnessChangeThresholdsIdle(com.android.server.display.config.Thresholds); Loading @@ -120,6 +122,8 @@ package com.android.server.display.config { method public final void setScreenBrightnessRampIncreaseMaxMillis(java.math.BigInteger); method public final void setScreenBrightnessRampSlowDecrease(java.math.BigDecimal); method public final void setScreenBrightnessRampSlowIncrease(java.math.BigDecimal); method public final void setScreenOffBrightnessSensor(com.android.server.display.config.SensorDetails); method public final void setScreenOffBrightnessSensorValueToLux(com.android.server.display.config.IntegerArray); method public final void setThermalThrottling(@NonNull com.android.server.display.config.ThermalThrottling); } Loading Loading @@ -160,6 +164,11 @@ package com.android.server.display.config { method public final void setTransitionPoint_all(@NonNull java.math.BigDecimal); } public class IntegerArray { ctor public IntegerArray(); method public java.util.List<java.math.BigInteger> getItem(); } public class NitsMap { ctor public NitsMap(); method public String getInterpolation(); Loading