Loading core/res/res/values/config.xml +32 −0 Original line number Diff line number Diff line Loading @@ -1178,6 +1178,38 @@ <integer-array name="config_dynamicHysteresisLuxLevels"> </integer-array> <!-- This flag requires config_dozeSensorLuxLevels to have one or more entries and only affects the screen brightness while dozing. The screen brightness of a device is based off of a ring buffer of the last n seconds of ambient light sensor sample readings. If this flag is true, then this buffer is cleared and the screen brightness is based off of ambient light sensor readings that are obtained while the device is dozing. This mode may be better suited for watches. If this flag is false, then this buffer is untouched. --> <bool name="config_useNewSensorSamplesForDoze">false</bool> <!-- Array of ambient light sensor lux threshold values for determining screen brightness for devices that have both an ambient light sensor and the screen on while dozing. This is used to determine the screen brightness while dozing by calculating the index to use for lookup and then setting the screen brightness value to the corresponding value of config_dozeBrightnessBacklightValues. The (zero-based) index is calculated as follows: (MAX is the largest index of the array) condition calculated index value < lux[0] 0 lux[n] <= value < lux[n+1] n+1 lux[MAX] <= value MAX+1 --> <integer-array name="config_dozeSensorLuxLevels"> </integer-array> <!-- Array of values for determining screen brightness for devices that have both an ambient light sensor and the screen on while dozing. The length of this array is assumed to be one greater than config_dozeModeSensorLuxLevels if they are not both empty. See the config_dozeModeSensorLuxLevels description for how the backlight value is chosen. --> <integer-array name="config_dozeBrightnessBacklightValues"> </integer-array> <!-- Amount of time it takes for the light sensor to warm up in milliseconds. For this time after the screen turns on, the Power Manager will not debounce light sensor readings --> Loading core/res/res/values/symbols.xml +3 −0 Original line number Diff line number Diff line Loading @@ -1648,6 +1648,8 @@ <java-symbol type="array" name="config_dynamicHysteresisBrightLevels" /> <java-symbol type="array" name="config_dynamicHysteresisDarkLevels" /> <java-symbol type="array" name="config_dynamicHysteresisLuxLevels" /> <java-symbol type="array" name="config_dozeBrightnessBacklightValues" /> <java-symbol type="array" name="config_dozeSensorLuxLevels" /> <java-symbol type="array" name="config_protectedNetworks" /> <java-symbol type="array" name="config_statusBarIcons" /> <java-symbol type="array" name="config_tether_bluetooth_regexs" /> Loading @@ -1665,6 +1667,7 @@ <java-symbol type="array" name="config_defaultNotificationVibePattern" /> <java-symbol type="array" name="config_notificationFallbackVibePattern" /> <java-symbol type="array" name="config_onlySingleDcAllowed" /> <java-symbol type="bool" name="config_useNewSensorSamplesForDoze" /> <java-symbol type="bool" name="config_useAttentionLight" /> <java-symbol type="bool" name="config_animateScreenLights" /> <java-symbol type="bool" name="config_automatic_brightness_available" /> Loading services/core/java/com/android/server/display/AutomaticBrightnessController.java +42 −13 Original line number Diff line number Diff line Loading @@ -109,8 +109,8 @@ class AutomaticBrightnessController { // weighting values positive. private final int mWeightingIntercept; // accessor object for determining thresholds to change brightness dynamically private final HysteresisLevels mDynamicHysteresis; // accessor object for determining lux levels private final LuxLevels mLuxLevels; // Amount of time to delay auto-brightness after screen on while waiting for // the light sensor to warm-up in milliseconds. Loading Loading @@ -172,6 +172,9 @@ class AutomaticBrightnessController { // Are we going to adjust brightness while dozing. private boolean mDozing; // True if we are collecting one last light sample when dozing to set the screen brightness private boolean mActiveDozeLightSensor = false; // True if we are collecting a brightness adjustment sample, along with some data // for the initial state of the sample. private boolean mBrightnessAdjustmentSamplePending; Loading @@ -188,7 +191,7 @@ class AutomaticBrightnessController { int lightSensorRate, long brighteningLightDebounceConfig, long darkeningLightDebounceConfig, boolean resetAmbientLuxAfterWarmUpConfig, int ambientLightHorizon, float autoBrightnessAdjustmentMaxGamma, HysteresisLevels dynamicHysteresis) { LuxLevels luxLevels) { mCallbacks = callbacks; mTwilight = LocalServices.getService(TwilightManager.class); mSensorManager = sensorManager; Loading @@ -204,7 +207,7 @@ class AutomaticBrightnessController { mAmbientLightHorizon = ambientLightHorizon; mWeightingIntercept = ambientLightHorizon; mScreenAutoBrightnessAdjustmentMaxGamma = autoBrightnessAdjustmentMaxGamma; mDynamicHysteresis = dynamicHysteresis; mLuxLevels = luxLevels; mHandler = new AutomaticBrightnessHandler(looper); mAmbientLightRingBuffer = Loading @@ -218,7 +221,7 @@ class AutomaticBrightnessController { } public int getAutomaticScreenBrightness() { if (mDozing) { if (mDozing && !mLuxLevels.hasDynamicDozeBrightness()) { return (int) (mScreenAutoBrightness * mDozeScaleFactor); } return mScreenAutoBrightness; Loading @@ -232,13 +235,26 @@ class AutomaticBrightnessController { // and hold onto the last computed screen auto brightness. We save the dozing flag for // debugging purposes. mDozing = dozing; boolean changed = setLightSensorEnabled(enable && !dozing); boolean enableSensor = enable && !dozing; if (enableSensor && !mLightSensorEnabled && mActiveDozeLightSensor) { mActiveDozeLightSensor = false; } else if (!enableSensor && mLightSensorEnabled && mLuxLevels.hasDynamicDozeBrightness()) { // keep the light sensor active until another light sample is taken in doze mode mActiveDozeLightSensor = true; if (mLuxLevels.useNewSensorSamplesForDoze()) { mAmbientLightRingBuffer.clear(); mInitialHorizonAmbientLightRingBuffer.clear(); mAmbientLuxValid = false; return; } } boolean changed = setLightSensorEnabled(enableSensor); changed |= setScreenAutoBrightnessAdjustment(adjustment); changed |= setUseTwilight(useTwilight); if (changed) { updateAutoBrightness(false /*sendUpdate*/); } if (enable && !dozing && userInitiatedChange) { if (enableSensor && userInitiatedChange) { prepareBrightnessAdjustmentSample(); } } Loading Loading @@ -292,6 +308,9 @@ class AutomaticBrightnessController { if (enable) { if (!mLightSensorEnabled) { mLightSensorEnabled = true; mAmbientLightRingBuffer.clear(); mInitialHorizonAmbientLightRingBuffer.clear(); mAmbientLuxValid = !mResetAmbientLuxAfterWarmUpConfig; mLightSensorEnableTime = SystemClock.uptimeMillis(); mSensorManager.registerListener(mLightSensorListener, mLightSensor, mLightSensorRate * 1000, mHandler); Loading @@ -300,11 +319,9 @@ class AutomaticBrightnessController { } else { if (mLightSensorEnabled) { mLightSensorEnabled = false; mAmbientLuxValid = !mResetAmbientLuxAfterWarmUpConfig; mRecentLightSamples = 0; mAmbientLightRingBuffer.clear(); mInitialHorizonAmbientLightRingBuffer.clear(); mHandler.removeMessages(MSG_UPDATE_AMBIENT_LUX); Slog.d(TAG, "disabling light sensor"); mSensorManager.unregisterListener(mLightSensorListener); } } Loading @@ -316,6 +333,11 @@ class AutomaticBrightnessController { applyLightSensorMeasurement(time, lux); updateAmbientLux(time); if (mActiveDozeLightSensor) { // disable the ambient light sensor and update the screen brightness setLightSensorEnabled(false); updateAutoBrightness(true /*sendUpdate*/); } } private void applyLightSensorMeasurement(long time, float lux) { Loading @@ -327,6 +349,7 @@ class AutomaticBrightnessController { } mAmbientLightRingBuffer.prune(time - mAmbientLightHorizon); mAmbientLightRingBuffer.push(time, lux); Slog.d(TAG, "pushing lux: " + lux); // Remember this sample value. mLastObservedLux = lux; Loading @@ -343,8 +366,8 @@ class AutomaticBrightnessController { private void setAmbientLux(float lux) { mAmbientLux = lux; mBrighteningLuxThreshold = mDynamicHysteresis.getBrighteningThreshold(lux); mDarkeningLuxThreshold = mDynamicHysteresis.getDarkeningThreshold(lux); mBrighteningLuxThreshold = mLuxLevels.getBrighteningThreshold(lux); mDarkeningLuxThreshold = mLuxLevels.getDarkeningThreshold(lux); } private float calculateAmbientLux(long now) { Loading Loading @@ -516,8 +539,14 @@ class AutomaticBrightnessController { } } int newScreenAutoBrightness = int newScreenAutoBrightness; if (mActiveDozeLightSensor) { newScreenAutoBrightness = mLuxLevels.getDozeBrightness(mAmbientLux); } else { newScreenAutoBrightness = clampScreenBrightness(Math.round(value * PowerManager.BRIGHTNESS_ON)); } if (mScreenAutoBrightness != newScreenAutoBrightness) { if (DEBUG) { Slog.d(TAG, "updateAutoBrightness: mScreenAutoBrightness=" Loading services/core/java/com/android/server/display/DisplayPowerController.java +19 −10 Original line number Diff line number Diff line Loading @@ -322,15 +322,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call com.android.internal.R.fraction.config_autoBrightnessAdjustmentMaxGamma, 1, 1); int[] brightLevels = resources.getIntArray( com.android.internal.R.array.config_dynamicHysteresisBrightLevels); int[] darkLevels = resources.getIntArray( com.android.internal.R.array.config_dynamicHysteresisDarkLevels); int[] luxLevels = resources.getIntArray( com.android.internal.R.array.config_dynamicHysteresisLuxLevels); HysteresisLevels dynamicHysteresis = new HysteresisLevels( brightLevels, darkLevels, luxLevels); if (mUseSoftwareAutoBrightnessConfig) { int[] lux = resources.getIntArray( com.android.internal.R.array.config_autoBrightnessLevels); Loading @@ -342,6 +333,24 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor, 1, 1); // hysteresis configs int[] brightHysteresisLevels = resources.getIntArray( com.android.internal.R.array.config_dynamicHysteresisBrightLevels); int[] darkHysteresisLevels = resources.getIntArray( com.android.internal.R.array.config_dynamicHysteresisDarkLevels); int[] luxHysteresisLevels = resources.getIntArray( com.android.internal.R.array.config_dynamicHysteresisLuxLevels); // doze brightness configs int[] dozeSensorLuxLevels = resources.getIntArray( com.android.internal.R.array.config_dozeSensorLuxLevels); int[] dozeBrightnessBacklightValues = resources.getIntArray( com.android.internal.R.array.config_dozeBrightnessBacklightValues); boolean useNewSensorSamplesForDoze = resources.getBoolean( com.android.internal.R.bool.config_useNewSensorSamplesForDoze); LuxLevels luxLevels = new LuxLevels(brightHysteresisLevels, darkHysteresisLevels, luxHysteresisLevels, useNewSensorSamplesForDoze, dozeSensorLuxLevels, dozeBrightnessBacklightValues); Spline screenAutoBrightnessSpline = createAutoBrightnessSpline(lux, screenBrightness); if (screenAutoBrightnessSpline == null) { Slog.e(TAG, "Error in config.xml. config_autoBrightnessLcdBacklightValues " Loading @@ -368,7 +377,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mScreenBrightnessRangeMaximum, dozeScaleFactor, lightSensorRate, brighteningLightDebounce, darkeningLightDebounce, autoBrightnessResetAmbientLuxAfterWarmUp, ambientLightHorizon, autoBrightnessAdjustmentMaxGamma, dynamicHysteresis); autoBrightnessAdjustmentMaxGamma, luxLevels); } } Loading services/core/java/com/android/server/display/HysteresisLevels.java→services/core/java/com/android/server/display/LuxLevels.java +145 −0 Original line number Diff line number Diff line Loading @@ -19,48 +19,63 @@ package com.android.server.display; import android.util.Slog; /** * A helper class for handling access to illuminance hysteresis level values. * A helper class for handling access to illuminance level values. */ final class HysteresisLevels { private static final String TAG = "HysteresisLevels"; final class LuxLevels { private static final String TAG = "LuxLevels"; // Default hysteresis constraints for brightening or darkening. // The recent lux must have changed by at least this fraction relative to the // current ambient lux before a change will be considered. private static final float DEFAULT_BRIGHTENING_HYSTERESIS = 0.10f; private static final float DEFAULT_DARKENING_HYSTERESIS = 0.20f; private static final boolean DEBUG = true; private static final boolean DEBUG = false; private final boolean mUseNewSensorSamplesForDoze; private final float[] mBrightLevels; private final float[] mDarkLevels; private final float[] mLuxLevels; private final float[] mLuxHysteresisLevels; private final float[] mDozeBacklightLevels; private final float[] mDozeSensorLuxLevels; /** * Creates a {@code HysteresisLevels} object with the given equal-length * integer arrays. * Creates a {@code LuxLevels} object with the given integer arrays. The following arrays * are either empty or have the following relations: * {@code brightLevels} and {@code darkLevels} have the same length n. * {@code luxLevels} has length n+1. * * {@code dozeSensorLuxLevels} has length r. * {@code dozeBacklightLevels} has length r+1. * * @param brightLevels an array of brightening hysteresis constraint constants * @param darkLevels an array of darkening hysteresis constraint constants * @param luxLevels a monotonically increasing array of illuminance * thresholds in units of lux * @param luxHysteresisLevels a monotonically increasing array of illuminance thresholds in lux * @param dozeSensorLuxLevels a monotonically increasing array of ALS thresholds in lux * @param dozeBacklightLevels an array of screen brightness values for doze mode in lux */ public HysteresisLevels(int[] brightLevels, int[] darkLevels, int[] luxLevels) { if (brightLevels.length != darkLevels.length || darkLevels.length != luxLevels.length + 1) { public LuxLevels(int[] brightLevels, int[] darkLevels, int[] luxHysteresisLevels, boolean useNewSensorSamplesForDoze, int[] dozeSensorLuxLevels, int[] dozeBacklightLevels) { if (brightLevels.length != darkLevels.length || darkLevels.length !=luxHysteresisLevels.length + 1) { throw new IllegalArgumentException("Mismatch between hysteresis array lengths."); } if (dozeBacklightLevels.length > 0 && dozeSensorLuxLevels.length > 0 && dozeBacklightLevels.length != dozeSensorLuxLevels.length + 1) { throw new IllegalArgumentException("Mismatch between doze lux array lengths."); } mBrightLevels = setArrayFormat(brightLevels, 1000.0f); mDarkLevels = setArrayFormat(darkLevels, 1000.0f); mLuxLevels = setArrayFormat(luxLevels, 1.0f); mLuxHysteresisLevels = setArrayFormat(luxHysteresisLevels, 1.0f); mUseNewSensorSamplesForDoze = useNewSensorSamplesForDoze; mDozeSensorLuxLevels = setArrayFormat(dozeSensorLuxLevels, 1.0f); mDozeBacklightLevels = setArrayFormat(dozeBacklightLevels, 1.0f); } /** * Return the brightening hysteresis threshold for the given lux level. */ public float getBrighteningThreshold(float lux) { float brightConstant = getReferenceLevel(lux, mBrightLevels); float brightConstant = getReferenceLevel(lux, mBrightLevels, mLuxHysteresisLevels); float brightThreshold = lux * (1.0f + brightConstant); if (DEBUG) { Slog.d(TAG, "bright hysteresis constant=: " + brightConstant + ", threshold=" Slog.d(TAG, "bright hysteresis constant= " + brightConstant + ", threshold=" + brightThreshold + ", lux=" + lux); } return brightThreshold; Loading @@ -70,27 +85,53 @@ final class HysteresisLevels { * Return the darkening hysteresis threshold for the given lux level. */ public float getDarkeningThreshold(float lux) { float darkConstant = getReferenceLevel(lux, mDarkLevels); float darkConstant = getReferenceLevel(lux, mDarkLevels, mLuxHysteresisLevels); float darkThreshold = lux * (1.0f - darkConstant); if (DEBUG) { Slog.d(TAG, "dark hysteresis constant=: " + darkConstant + ", threshold=" Slog.d(TAG, "dark hysteresis constant= " + darkConstant + ", threshold=" + darkThreshold + ", lux=" + lux); } return darkThreshold; } /** * Return the hysteresis constant for the closest lux threshold value to the * current illuminance from the given array. * Return the doze backlight brightness level for the given ambient sensor lux level. */ public int getDozeBrightness(float lux) { int dozeBrightness = (int) getReferenceLevel(lux, mDozeBacklightLevels, mDozeSensorLuxLevels); if (DEBUG) { Slog.d(TAG, "doze brightness: " + dozeBrightness + ", lux=" + lux); } return dozeBrightness; } /** * Find the index of the closest value in {@code thresholdLevels} to {@code lux} and return * the {@code referenceLevels} entry with that index. */ private float getReferenceLevel(float lux, float[] referenceLevels) { private float getReferenceLevel(float lux, float[] referenceLevels, float[] thresholdLevels) { int index = 0; while (mLuxLevels.length > index && lux >= mLuxLevels[index]) { while (thresholdLevels.length > index && lux >= thresholdLevels[index]) { ++index; } return referenceLevels[index]; } /** * Return if the doze backlight brightness level is specified dynamically. */ public boolean hasDynamicDozeBrightness() { return mDozeSensorLuxLevels.length > 0; } /** * Return if new ALS samples should be used for determining screen brightness while dozing. */ public boolean useNewSensorSamplesForDoze() { return mUseNewSensorSamplesForDoze; } /** * Return a float array where each i-th element equals {@code configArray[i]/divideFactor}. */ Loading Loading
core/res/res/values/config.xml +32 −0 Original line number Diff line number Diff line Loading @@ -1178,6 +1178,38 @@ <integer-array name="config_dynamicHysteresisLuxLevels"> </integer-array> <!-- This flag requires config_dozeSensorLuxLevels to have one or more entries and only affects the screen brightness while dozing. The screen brightness of a device is based off of a ring buffer of the last n seconds of ambient light sensor sample readings. If this flag is true, then this buffer is cleared and the screen brightness is based off of ambient light sensor readings that are obtained while the device is dozing. This mode may be better suited for watches. If this flag is false, then this buffer is untouched. --> <bool name="config_useNewSensorSamplesForDoze">false</bool> <!-- Array of ambient light sensor lux threshold values for determining screen brightness for devices that have both an ambient light sensor and the screen on while dozing. This is used to determine the screen brightness while dozing by calculating the index to use for lookup and then setting the screen brightness value to the corresponding value of config_dozeBrightnessBacklightValues. The (zero-based) index is calculated as follows: (MAX is the largest index of the array) condition calculated index value < lux[0] 0 lux[n] <= value < lux[n+1] n+1 lux[MAX] <= value MAX+1 --> <integer-array name="config_dozeSensorLuxLevels"> </integer-array> <!-- Array of values for determining screen brightness for devices that have both an ambient light sensor and the screen on while dozing. The length of this array is assumed to be one greater than config_dozeModeSensorLuxLevels if they are not both empty. See the config_dozeModeSensorLuxLevels description for how the backlight value is chosen. --> <integer-array name="config_dozeBrightnessBacklightValues"> </integer-array> <!-- Amount of time it takes for the light sensor to warm up in milliseconds. For this time after the screen turns on, the Power Manager will not debounce light sensor readings --> Loading
core/res/res/values/symbols.xml +3 −0 Original line number Diff line number Diff line Loading @@ -1648,6 +1648,8 @@ <java-symbol type="array" name="config_dynamicHysteresisBrightLevels" /> <java-symbol type="array" name="config_dynamicHysteresisDarkLevels" /> <java-symbol type="array" name="config_dynamicHysteresisLuxLevels" /> <java-symbol type="array" name="config_dozeBrightnessBacklightValues" /> <java-symbol type="array" name="config_dozeSensorLuxLevels" /> <java-symbol type="array" name="config_protectedNetworks" /> <java-symbol type="array" name="config_statusBarIcons" /> <java-symbol type="array" name="config_tether_bluetooth_regexs" /> Loading @@ -1665,6 +1667,7 @@ <java-symbol type="array" name="config_defaultNotificationVibePattern" /> <java-symbol type="array" name="config_notificationFallbackVibePattern" /> <java-symbol type="array" name="config_onlySingleDcAllowed" /> <java-symbol type="bool" name="config_useNewSensorSamplesForDoze" /> <java-symbol type="bool" name="config_useAttentionLight" /> <java-symbol type="bool" name="config_animateScreenLights" /> <java-symbol type="bool" name="config_automatic_brightness_available" /> Loading
services/core/java/com/android/server/display/AutomaticBrightnessController.java +42 −13 Original line number Diff line number Diff line Loading @@ -109,8 +109,8 @@ class AutomaticBrightnessController { // weighting values positive. private final int mWeightingIntercept; // accessor object for determining thresholds to change brightness dynamically private final HysteresisLevels mDynamicHysteresis; // accessor object for determining lux levels private final LuxLevels mLuxLevels; // Amount of time to delay auto-brightness after screen on while waiting for // the light sensor to warm-up in milliseconds. Loading Loading @@ -172,6 +172,9 @@ class AutomaticBrightnessController { // Are we going to adjust brightness while dozing. private boolean mDozing; // True if we are collecting one last light sample when dozing to set the screen brightness private boolean mActiveDozeLightSensor = false; // True if we are collecting a brightness adjustment sample, along with some data // for the initial state of the sample. private boolean mBrightnessAdjustmentSamplePending; Loading @@ -188,7 +191,7 @@ class AutomaticBrightnessController { int lightSensorRate, long brighteningLightDebounceConfig, long darkeningLightDebounceConfig, boolean resetAmbientLuxAfterWarmUpConfig, int ambientLightHorizon, float autoBrightnessAdjustmentMaxGamma, HysteresisLevels dynamicHysteresis) { LuxLevels luxLevels) { mCallbacks = callbacks; mTwilight = LocalServices.getService(TwilightManager.class); mSensorManager = sensorManager; Loading @@ -204,7 +207,7 @@ class AutomaticBrightnessController { mAmbientLightHorizon = ambientLightHorizon; mWeightingIntercept = ambientLightHorizon; mScreenAutoBrightnessAdjustmentMaxGamma = autoBrightnessAdjustmentMaxGamma; mDynamicHysteresis = dynamicHysteresis; mLuxLevels = luxLevels; mHandler = new AutomaticBrightnessHandler(looper); mAmbientLightRingBuffer = Loading @@ -218,7 +221,7 @@ class AutomaticBrightnessController { } public int getAutomaticScreenBrightness() { if (mDozing) { if (mDozing && !mLuxLevels.hasDynamicDozeBrightness()) { return (int) (mScreenAutoBrightness * mDozeScaleFactor); } return mScreenAutoBrightness; Loading @@ -232,13 +235,26 @@ class AutomaticBrightnessController { // and hold onto the last computed screen auto brightness. We save the dozing flag for // debugging purposes. mDozing = dozing; boolean changed = setLightSensorEnabled(enable && !dozing); boolean enableSensor = enable && !dozing; if (enableSensor && !mLightSensorEnabled && mActiveDozeLightSensor) { mActiveDozeLightSensor = false; } else if (!enableSensor && mLightSensorEnabled && mLuxLevels.hasDynamicDozeBrightness()) { // keep the light sensor active until another light sample is taken in doze mode mActiveDozeLightSensor = true; if (mLuxLevels.useNewSensorSamplesForDoze()) { mAmbientLightRingBuffer.clear(); mInitialHorizonAmbientLightRingBuffer.clear(); mAmbientLuxValid = false; return; } } boolean changed = setLightSensorEnabled(enableSensor); changed |= setScreenAutoBrightnessAdjustment(adjustment); changed |= setUseTwilight(useTwilight); if (changed) { updateAutoBrightness(false /*sendUpdate*/); } if (enable && !dozing && userInitiatedChange) { if (enableSensor && userInitiatedChange) { prepareBrightnessAdjustmentSample(); } } Loading Loading @@ -292,6 +308,9 @@ class AutomaticBrightnessController { if (enable) { if (!mLightSensorEnabled) { mLightSensorEnabled = true; mAmbientLightRingBuffer.clear(); mInitialHorizonAmbientLightRingBuffer.clear(); mAmbientLuxValid = !mResetAmbientLuxAfterWarmUpConfig; mLightSensorEnableTime = SystemClock.uptimeMillis(); mSensorManager.registerListener(mLightSensorListener, mLightSensor, mLightSensorRate * 1000, mHandler); Loading @@ -300,11 +319,9 @@ class AutomaticBrightnessController { } else { if (mLightSensorEnabled) { mLightSensorEnabled = false; mAmbientLuxValid = !mResetAmbientLuxAfterWarmUpConfig; mRecentLightSamples = 0; mAmbientLightRingBuffer.clear(); mInitialHorizonAmbientLightRingBuffer.clear(); mHandler.removeMessages(MSG_UPDATE_AMBIENT_LUX); Slog.d(TAG, "disabling light sensor"); mSensorManager.unregisterListener(mLightSensorListener); } } Loading @@ -316,6 +333,11 @@ class AutomaticBrightnessController { applyLightSensorMeasurement(time, lux); updateAmbientLux(time); if (mActiveDozeLightSensor) { // disable the ambient light sensor and update the screen brightness setLightSensorEnabled(false); updateAutoBrightness(true /*sendUpdate*/); } } private void applyLightSensorMeasurement(long time, float lux) { Loading @@ -327,6 +349,7 @@ class AutomaticBrightnessController { } mAmbientLightRingBuffer.prune(time - mAmbientLightHorizon); mAmbientLightRingBuffer.push(time, lux); Slog.d(TAG, "pushing lux: " + lux); // Remember this sample value. mLastObservedLux = lux; Loading @@ -343,8 +366,8 @@ class AutomaticBrightnessController { private void setAmbientLux(float lux) { mAmbientLux = lux; mBrighteningLuxThreshold = mDynamicHysteresis.getBrighteningThreshold(lux); mDarkeningLuxThreshold = mDynamicHysteresis.getDarkeningThreshold(lux); mBrighteningLuxThreshold = mLuxLevels.getBrighteningThreshold(lux); mDarkeningLuxThreshold = mLuxLevels.getDarkeningThreshold(lux); } private float calculateAmbientLux(long now) { Loading Loading @@ -516,8 +539,14 @@ class AutomaticBrightnessController { } } int newScreenAutoBrightness = int newScreenAutoBrightness; if (mActiveDozeLightSensor) { newScreenAutoBrightness = mLuxLevels.getDozeBrightness(mAmbientLux); } else { newScreenAutoBrightness = clampScreenBrightness(Math.round(value * PowerManager.BRIGHTNESS_ON)); } if (mScreenAutoBrightness != newScreenAutoBrightness) { if (DEBUG) { Slog.d(TAG, "updateAutoBrightness: mScreenAutoBrightness=" Loading
services/core/java/com/android/server/display/DisplayPowerController.java +19 −10 Original line number Diff line number Diff line Loading @@ -322,15 +322,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call com.android.internal.R.fraction.config_autoBrightnessAdjustmentMaxGamma, 1, 1); int[] brightLevels = resources.getIntArray( com.android.internal.R.array.config_dynamicHysteresisBrightLevels); int[] darkLevels = resources.getIntArray( com.android.internal.R.array.config_dynamicHysteresisDarkLevels); int[] luxLevels = resources.getIntArray( com.android.internal.R.array.config_dynamicHysteresisLuxLevels); HysteresisLevels dynamicHysteresis = new HysteresisLevels( brightLevels, darkLevels, luxLevels); if (mUseSoftwareAutoBrightnessConfig) { int[] lux = resources.getIntArray( com.android.internal.R.array.config_autoBrightnessLevels); Loading @@ -342,6 +333,24 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor, 1, 1); // hysteresis configs int[] brightHysteresisLevels = resources.getIntArray( com.android.internal.R.array.config_dynamicHysteresisBrightLevels); int[] darkHysteresisLevels = resources.getIntArray( com.android.internal.R.array.config_dynamicHysteresisDarkLevels); int[] luxHysteresisLevels = resources.getIntArray( com.android.internal.R.array.config_dynamicHysteresisLuxLevels); // doze brightness configs int[] dozeSensorLuxLevels = resources.getIntArray( com.android.internal.R.array.config_dozeSensorLuxLevels); int[] dozeBrightnessBacklightValues = resources.getIntArray( com.android.internal.R.array.config_dozeBrightnessBacklightValues); boolean useNewSensorSamplesForDoze = resources.getBoolean( com.android.internal.R.bool.config_useNewSensorSamplesForDoze); LuxLevels luxLevels = new LuxLevels(brightHysteresisLevels, darkHysteresisLevels, luxHysteresisLevels, useNewSensorSamplesForDoze, dozeSensorLuxLevels, dozeBrightnessBacklightValues); Spline screenAutoBrightnessSpline = createAutoBrightnessSpline(lux, screenBrightness); if (screenAutoBrightnessSpline == null) { Slog.e(TAG, "Error in config.xml. config_autoBrightnessLcdBacklightValues " Loading @@ -368,7 +377,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mScreenBrightnessRangeMaximum, dozeScaleFactor, lightSensorRate, brighteningLightDebounce, darkeningLightDebounce, autoBrightnessResetAmbientLuxAfterWarmUp, ambientLightHorizon, autoBrightnessAdjustmentMaxGamma, dynamicHysteresis); autoBrightnessAdjustmentMaxGamma, luxLevels); } } Loading
services/core/java/com/android/server/display/HysteresisLevels.java→services/core/java/com/android/server/display/LuxLevels.java +145 −0 Original line number Diff line number Diff line Loading @@ -19,48 +19,63 @@ package com.android.server.display; import android.util.Slog; /** * A helper class for handling access to illuminance hysteresis level values. * A helper class for handling access to illuminance level values. */ final class HysteresisLevels { private static final String TAG = "HysteresisLevels"; final class LuxLevels { private static final String TAG = "LuxLevels"; // Default hysteresis constraints for brightening or darkening. // The recent lux must have changed by at least this fraction relative to the // current ambient lux before a change will be considered. private static final float DEFAULT_BRIGHTENING_HYSTERESIS = 0.10f; private static final float DEFAULT_DARKENING_HYSTERESIS = 0.20f; private static final boolean DEBUG = true; private static final boolean DEBUG = false; private final boolean mUseNewSensorSamplesForDoze; private final float[] mBrightLevels; private final float[] mDarkLevels; private final float[] mLuxLevels; private final float[] mLuxHysteresisLevels; private final float[] mDozeBacklightLevels; private final float[] mDozeSensorLuxLevels; /** * Creates a {@code HysteresisLevels} object with the given equal-length * integer arrays. * Creates a {@code LuxLevels} object with the given integer arrays. The following arrays * are either empty or have the following relations: * {@code brightLevels} and {@code darkLevels} have the same length n. * {@code luxLevels} has length n+1. * * {@code dozeSensorLuxLevels} has length r. * {@code dozeBacklightLevels} has length r+1. * * @param brightLevels an array of brightening hysteresis constraint constants * @param darkLevels an array of darkening hysteresis constraint constants * @param luxLevels a monotonically increasing array of illuminance * thresholds in units of lux * @param luxHysteresisLevels a monotonically increasing array of illuminance thresholds in lux * @param dozeSensorLuxLevels a monotonically increasing array of ALS thresholds in lux * @param dozeBacklightLevels an array of screen brightness values for doze mode in lux */ public HysteresisLevels(int[] brightLevels, int[] darkLevels, int[] luxLevels) { if (brightLevels.length != darkLevels.length || darkLevels.length != luxLevels.length + 1) { public LuxLevels(int[] brightLevels, int[] darkLevels, int[] luxHysteresisLevels, boolean useNewSensorSamplesForDoze, int[] dozeSensorLuxLevels, int[] dozeBacklightLevels) { if (brightLevels.length != darkLevels.length || darkLevels.length !=luxHysteresisLevels.length + 1) { throw new IllegalArgumentException("Mismatch between hysteresis array lengths."); } if (dozeBacklightLevels.length > 0 && dozeSensorLuxLevels.length > 0 && dozeBacklightLevels.length != dozeSensorLuxLevels.length + 1) { throw new IllegalArgumentException("Mismatch between doze lux array lengths."); } mBrightLevels = setArrayFormat(brightLevels, 1000.0f); mDarkLevels = setArrayFormat(darkLevels, 1000.0f); mLuxLevels = setArrayFormat(luxLevels, 1.0f); mLuxHysteresisLevels = setArrayFormat(luxHysteresisLevels, 1.0f); mUseNewSensorSamplesForDoze = useNewSensorSamplesForDoze; mDozeSensorLuxLevels = setArrayFormat(dozeSensorLuxLevels, 1.0f); mDozeBacklightLevels = setArrayFormat(dozeBacklightLevels, 1.0f); } /** * Return the brightening hysteresis threshold for the given lux level. */ public float getBrighteningThreshold(float lux) { float brightConstant = getReferenceLevel(lux, mBrightLevels); float brightConstant = getReferenceLevel(lux, mBrightLevels, mLuxHysteresisLevels); float brightThreshold = lux * (1.0f + brightConstant); if (DEBUG) { Slog.d(TAG, "bright hysteresis constant=: " + brightConstant + ", threshold=" Slog.d(TAG, "bright hysteresis constant= " + brightConstant + ", threshold=" + brightThreshold + ", lux=" + lux); } return brightThreshold; Loading @@ -70,27 +85,53 @@ final class HysteresisLevels { * Return the darkening hysteresis threshold for the given lux level. */ public float getDarkeningThreshold(float lux) { float darkConstant = getReferenceLevel(lux, mDarkLevels); float darkConstant = getReferenceLevel(lux, mDarkLevels, mLuxHysteresisLevels); float darkThreshold = lux * (1.0f - darkConstant); if (DEBUG) { Slog.d(TAG, "dark hysteresis constant=: " + darkConstant + ", threshold=" Slog.d(TAG, "dark hysteresis constant= " + darkConstant + ", threshold=" + darkThreshold + ", lux=" + lux); } return darkThreshold; } /** * Return the hysteresis constant for the closest lux threshold value to the * current illuminance from the given array. * Return the doze backlight brightness level for the given ambient sensor lux level. */ public int getDozeBrightness(float lux) { int dozeBrightness = (int) getReferenceLevel(lux, mDozeBacklightLevels, mDozeSensorLuxLevels); if (DEBUG) { Slog.d(TAG, "doze brightness: " + dozeBrightness + ", lux=" + lux); } return dozeBrightness; } /** * Find the index of the closest value in {@code thresholdLevels} to {@code lux} and return * the {@code referenceLevels} entry with that index. */ private float getReferenceLevel(float lux, float[] referenceLevels) { private float getReferenceLevel(float lux, float[] referenceLevels, float[] thresholdLevels) { int index = 0; while (mLuxLevels.length > index && lux >= mLuxLevels[index]) { while (thresholdLevels.length > index && lux >= thresholdLevels[index]) { ++index; } return referenceLevels[index]; } /** * Return if the doze backlight brightness level is specified dynamically. */ public boolean hasDynamicDozeBrightness() { return mDozeSensorLuxLevels.length > 0; } /** * Return if new ALS samples should be used for determining screen brightness while dozing. */ public boolean useNewSensorSamplesForDoze() { return mUseNewSensorSamplesForDoze; } /** * Return a float array where each i-th element equals {@code configArray[i]/divideFactor}. */ Loading