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 @@ -1197,6 +1215,10 @@ public class DisplayDeviceConfig { return mAmbientLightSensor; } SensorData getScreenOffBrightnessSensor() { return mScreenOffBrightnessSensor; } SensorData getProximitySensor() { return mProximitySensor; } Loading Loading @@ -1320,6 +1342,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 @@ -1398,6 +1428,7 @@ public class DisplayDeviceConfig { mScreenDarkeningPercentagesIdle) + "\n" + ", mAmbientLightSensor=" + mAmbientLightSensor + ", mScreenOffBrightnessSensor=" + mScreenOffBrightnessSensor + ", mProximitySensor=" + mProximitySensor + ", mRefreshRateLimitations= " + Arrays.toString(mRefreshRateLimitations.toArray()) + ", mDensityMapping= " + mDensityMapping Loading @@ -1420,6 +1451,9 @@ public class DisplayDeviceConfig { + Arrays.toString(mHighDisplayBrightnessThresholds) + ", mHighAmbientBrightnessThresholds= " + Arrays.toString(mHighAmbientBrightnessThresholds) + "\n" + ", mScreenOffBrightnessSensorValueToLux=" + Arrays.toString( mScreenOffBrightnessSensorValueToLux) + "}"; } Loading Loading @@ -1473,11 +1507,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 @@ -2169,6 +2205,14 @@ public class DisplayDeviceConfig { mProximitySensor.type = null; } 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 @@ -2573,6 +2617,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 +48 −0 Original line number Diff line number Diff line Loading @@ -408,7 +408,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 @@ -1077,6 +1082,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 @@ -1262,6 +1280,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 @@ -1433,6 +1457,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 @@ -1460,6 +1487,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 @@ -2034,6 +2074,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 services/core/java/com/android/server/display/DisplayPowerController2.java +49 −0 Original line number Diff line number Diff line Loading @@ -360,7 +360,12 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal @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 @@ -994,6 +999,19 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal 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 @@ -1135,6 +1153,13 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal int state = mDisplayStateController .updateDisplayState(mPowerRequest, mIsEnabled, mIsInTransition); if (mScreenOffBrightnessSensorController != null) { mScreenOffBrightnessSensorController.setLightSensorEnabled(mUseAutoBrightness && (state == Display.STATE_OFF || (state == Display.STATE_DOZE && !mDisplayBrightnessController.isAllowAutoBrightnessWhileDozingConfig()))); } // Initialize things the first time the power state is changed. if (mustInitialize) { initialize(state); Loading Loading @@ -1224,6 +1249,9 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal updateScreenBrightnessSetting = mCurrentScreenBrightnessSetting != brightnessState; mAppliedAutoBrightness = true; mBrightnessReasonTemp.setReason(BrightnessReason.REASON_AUTOMATIC); if (mScreenOffBrightnessSensorController != null) { mScreenOffBrightnessSensorController.setLightSensorEnabled(false); } } else { mAppliedAutoBrightness = false; } Loading Loading @@ -1251,6 +1279,19 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal 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 @@ -1819,6 +1860,14 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal fallbackType); } private void loadScreenOffBrightnessSensor() { DisplayDeviceConfig.SensorData screenOffBrightnessSensor = mDisplayDeviceConfig.getScreenOffBrightnessSensor(); mScreenOffBrightnessSensor = SensorUtils.findSensor(mSensorManager, screenOffBrightnessSensor.type, screenOffBrightnessSensor.name, SensorUtils.NO_FALLBACK); } private float clampScreenBrightness(float value) { if (Float.isNaN(value)) { value = PowerManager.BRIGHTNESS_MIN; 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/java/com/android/server/display/brightness/BrightnessReason.java +4 −1 Original line number Diff line number Diff line Loading @@ -37,7 +37,8 @@ public final class BrightnessReason { public static final int REASON_OVERRIDE = 6; public static final int REASON_TEMPORARY = 7; public static final int REASON_BOOST = 8; public static final int REASON_MAX = REASON_BOOST; public static final int REASON_SCREEN_OFF_BRIGHTNESS_SENSOR = 9; public static final int REASON_MAX = REASON_SCREEN_OFF_BRIGHTNESS_SENSOR; public static final int MODIFIER_DIMMED = 0x1; public static final int MODIFIER_LOW_POWER = 0x2; Loading Loading @@ -190,6 +191,8 @@ public final class BrightnessReason { return "temporary"; case REASON_BOOST: return "boost"; case REASON_SCREEN_OFF_BRIGHTNESS_SENSOR: return "screen_off_brightness_sensor"; default: return Integer.toString(reason); } 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 @@ -1197,6 +1215,10 @@ public class DisplayDeviceConfig { return mAmbientLightSensor; } SensorData getScreenOffBrightnessSensor() { return mScreenOffBrightnessSensor; } SensorData getProximitySensor() { return mProximitySensor; } Loading Loading @@ -1320,6 +1342,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 @@ -1398,6 +1428,7 @@ public class DisplayDeviceConfig { mScreenDarkeningPercentagesIdle) + "\n" + ", mAmbientLightSensor=" + mAmbientLightSensor + ", mScreenOffBrightnessSensor=" + mScreenOffBrightnessSensor + ", mProximitySensor=" + mProximitySensor + ", mRefreshRateLimitations= " + Arrays.toString(mRefreshRateLimitations.toArray()) + ", mDensityMapping= " + mDensityMapping Loading @@ -1420,6 +1451,9 @@ public class DisplayDeviceConfig { + Arrays.toString(mHighDisplayBrightnessThresholds) + ", mHighAmbientBrightnessThresholds= " + Arrays.toString(mHighAmbientBrightnessThresholds) + "\n" + ", mScreenOffBrightnessSensorValueToLux=" + Arrays.toString( mScreenOffBrightnessSensorValueToLux) + "}"; } Loading Loading @@ -1473,11 +1507,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 @@ -2169,6 +2205,14 @@ public class DisplayDeviceConfig { mProximitySensor.type = null; } 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 @@ -2573,6 +2617,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 +48 −0 Original line number Diff line number Diff line Loading @@ -408,7 +408,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 @@ -1077,6 +1082,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 @@ -1262,6 +1280,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 @@ -1433,6 +1457,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 @@ -1460,6 +1487,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 @@ -2034,6 +2074,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
services/core/java/com/android/server/display/DisplayPowerController2.java +49 −0 Original line number Diff line number Diff line Loading @@ -360,7 +360,12 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal @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 @@ -994,6 +999,19 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal 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 @@ -1135,6 +1153,13 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal int state = mDisplayStateController .updateDisplayState(mPowerRequest, mIsEnabled, mIsInTransition); if (mScreenOffBrightnessSensorController != null) { mScreenOffBrightnessSensorController.setLightSensorEnabled(mUseAutoBrightness && (state == Display.STATE_OFF || (state == Display.STATE_DOZE && !mDisplayBrightnessController.isAllowAutoBrightnessWhileDozingConfig()))); } // Initialize things the first time the power state is changed. if (mustInitialize) { initialize(state); Loading Loading @@ -1224,6 +1249,9 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal updateScreenBrightnessSetting = mCurrentScreenBrightnessSetting != brightnessState; mAppliedAutoBrightness = true; mBrightnessReasonTemp.setReason(BrightnessReason.REASON_AUTOMATIC); if (mScreenOffBrightnessSensorController != null) { mScreenOffBrightnessSensorController.setLightSensorEnabled(false); } } else { mAppliedAutoBrightness = false; } Loading Loading @@ -1251,6 +1279,19 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal 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 @@ -1819,6 +1860,14 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal fallbackType); } private void loadScreenOffBrightnessSensor() { DisplayDeviceConfig.SensorData screenOffBrightnessSensor = mDisplayDeviceConfig.getScreenOffBrightnessSensor(); mScreenOffBrightnessSensor = SensorUtils.findSensor(mSensorManager, screenOffBrightnessSensor.type, screenOffBrightnessSensor.name, SensorUtils.NO_FALLBACK); } private float clampScreenBrightness(float value) { if (Float.isNaN(value)) { value = PowerManager.BRIGHTNESS_MIN; 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/java/com/android/server/display/brightness/BrightnessReason.java +4 −1 Original line number Diff line number Diff line Loading @@ -37,7 +37,8 @@ public final class BrightnessReason { public static final int REASON_OVERRIDE = 6; public static final int REASON_TEMPORARY = 7; public static final int REASON_BOOST = 8; public static final int REASON_MAX = REASON_BOOST; public static final int REASON_SCREEN_OFF_BRIGHTNESS_SENSOR = 9; public static final int REASON_MAX = REASON_SCREEN_OFF_BRIGHTNESS_SENSOR; public static final int MODIFIER_DIMMED = 0x1; public static final int MODIFIER_LOW_POWER = 0x2; Loading Loading @@ -190,6 +191,8 @@ public final class BrightnessReason { return "temporary"; case REASON_BOOST: return "boost"; case REASON_SCREEN_OFF_BRIGHTNESS_SENSOR: return "screen_off_brightness_sensor"; default: return Integer.toString(reason); } Loading