Loading core/res/res/values/config.xml +62 −28 Original line number Diff line number Diff line Loading @@ -1437,26 +1437,6 @@ <integer-array name="config_autoBrightnessKeyboardBacklightValues"> </integer-array> <!-- Array of hysteresis constraint values for brightening, represented as tenths of a percent. The length of this array is assumed to be one greater than config_dynamicHysteresisLuxLevels. The brightening threshold is calculated as lux * (1.0f + CONSTRAINT_VALUE). When the current lux is higher than this threshold, the screen brightness is recalculated. See the config_dynamicHysteresisLuxLevels description for how the constraint value is chosen. --> <integer-array name="config_dynamicHysteresisBrightLevels"> <item>100</item> </integer-array> <!-- Array of hysteresis constraint values for darkening, represented as tenths of a percent. The length of this array is assumed to be one greater than config_dynamicHysteresisLuxLevels. The darkening threshold is calculated as lux * (1.0f - CONSTRAINT_VALUE). When the current lux is lower than this threshold, the screen brightness is recalculated. See the config_dynamicHysteresisLuxLevels description for how the constraint value is chosen. --> <integer-array name="config_dynamicHysteresisDarkLevels"> <item>200</item> </integer-array> <!-- An array describing the screen's backlight values corresponding to the brightness values in the config_screenBrightnessNits array. Loading @@ -1474,19 +1454,73 @@ <array name="config_screenBrightnessNits"> </array> <!-- Array of ambient lux threshold values. This is used for determining hysteresis constraint values by calculating the index to use for lookup and then setting the constraint value to the corresponding value of the array. The new brightening hysteresis constraint value is the n-th element of config_dynamicHysteresisBrightLevels, and the new darkening hysteresis constraint value is the n-th element of config_dynamicHysteresisDarkLevels. is the n-th element of config_ambientBrighteningThresholds, and the new darkening hysteresis constraint value is the n-th element of config_ambientDarkeningThresholds. The (zero-based) index is calculated as follows: (MAX is the largest index of the array) condition calculated index value < level[0] 0 level[n] <= value < level[n+1] n+1 level[MAX] <= value MAX+1 --> <integer-array name="config_ambientThresholdLevels"> </integer-array> <!-- Array of hysteresis constraint values for brightening, represented as tenths of a percent. The length of this array is assumed to be one greater than config_ambientThresholdLevels. The brightening threshold is calculated as lux * (1.0f + CONSTRAINT_VALUE). When the current lux is higher than this threshold, the screen brightness is recalculated. See the config_ambientThresholdLevels description for how the constraint value is chosen. --> <integer-array name="config_ambientBrighteningThresholds"> <item>100</item> </integer-array> <!-- Array of hysteresis constraint values for darkening, represented as tenths of a percent. The length of this array is assumed to be one greater than config_ambientThresholdLevels. The darkening threshold is calculated as lux * (1.0f - CONSTRAINT_VALUE). When the current lux is lower than this threshold, the screen brightness is recalculated. See the config_ambientThresholdLevels description for how the constraint value is chosen. --> <integer-array name="config_ambientDarkeningThresholds"> <item>200</item> </integer-array> <!-- Array of screen brightness threshold values. This is used for determining hysteresis constraint values by calculating the index to use for lookup and then setting the constraint value to the corresponding value of the array. The new brightening hysteresis constraint value is the n-th element of config_screenBrighteningThresholds, and the new darkening hysteresis constraint value is the n-th element of config_screenDarkeningThresholds. 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_dynamicHysteresisLuxLevels"> value < level[0] 0 level[n] <= value < level[n+1] n+1 level[MAX] <= value MAX+1 --> <integer-array name="config_screenThresholdLevels"> </integer-array> <!-- Array of hysteresis constraint values for brightening, represented as tenths of a percent. The length of this array is assumed to be one greater than config_screenThresholdLevels. The brightening threshold is calculated as screenBrightness * (1.0f + CONSTRAINT_VALUE). When the new screen brightness is higher than this threshold, it is applied. See the config_screenThresholdLevels description for how the constraint value is chosen. --> <integer-array name="config_screenBrighteningThresholds"> <item>100</item> </integer-array> <!-- Array of hysteresis constraint values for darkening, represented as tenths of a percent. The length of this array is assumed to be one greater than config_screenThresholdLevels. The darkening threshold is calculated as screenBrightness * (1.0f - CONSTRAINT_VALUE). When the new screen brightness is lower than this threshold, it is applied. See the config_screenThresholdLevels description for how the constraint value is chosen. --> <integer-array name="config_screenDarkeningThresholds"> <item>200</item> </integer-array> <!-- Amount of time it takes for the light sensor to warm up in milliseconds. Loading core/res/res/values/symbols.xml +6 −3 Original line number Diff line number Diff line Loading @@ -1829,9 +1829,12 @@ <java-symbol type="array" name="config_autoBrightnessKeyboardBacklightValues" /> <java-symbol type="array" name="config_autoBrightnessLcdBacklightValues" /> <java-symbol type="array" name="config_autoBrightnessLevels" /> <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_ambientThresholdLevels" /> <java-symbol type="array" name="config_ambientBrighteningThresholds" /> <java-symbol type="array" name="config_ambientDarkeningThresholds" /> <java-symbol type="array" name="config_screenThresholdLevels" /> <java-symbol type="array" name="config_screenBrighteningThresholds" /> <java-symbol type="array" name="config_screenDarkeningThresholds" /> <java-symbol type="array" name="config_minimumBrightnessCurveLux" /> <java-symbol type="array" name="config_minimumBrightnessCurveNits" /> <java-symbol type="array" name="config_protectedNetworks" /> Loading services/core/java/com/android/server/display/AutomaticBrightnessController.java +55 −30 Original line number Diff line number Diff line Loading @@ -16,30 +16,26 @@ package com.android.server.display; import com.android.server.EventLogTags; import com.android.server.LocalServices; import android.annotation.Nullable; import android.app.ActivityManager; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.hardware.display.BrightnessConfiguration; import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest; import android.os.Build; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.PowerManager; import android.os.SystemClock; import android.os.Trace; import android.text.format.DateUtils; import android.util.EventLog; import android.util.MathUtils; import android.util.Slog; import android.util.TimeUtils; import com.android.server.EventLogTags; import java.io.PrintWriter; class AutomaticBrightnessController { Loading Loading @@ -127,7 +123,8 @@ class AutomaticBrightnessController { private final int mWeightingIntercept; // Configuration object for determining thresholds to change brightness dynamically private final HysteresisLevels mHysteresisLevels; private final HysteresisLevels mAmbientBrightnessThresholds; private final HysteresisLevels mScreenBrightnessThresholds; // Amount of time to delay auto-brightness after screen on while waiting for // the light sensor to warm-up in milliseconds. Loading @@ -147,8 +144,12 @@ class AutomaticBrightnessController { private boolean mAmbientLuxValid; // The ambient light level threshold at which to brighten or darken the screen. private float mBrighteningLuxThreshold; private float mDarkeningLuxThreshold; private float mAmbientBrighteningThreshold; private float mAmbientDarkeningThreshold; // The screen brightness threshold at which to brighten or darken the screen. private float mScreenBrighteningThreshold; private float mScreenDarkeningThreshold; // The most recent light sample. private float mLastObservedLux; Loading Loading @@ -196,7 +197,8 @@ class AutomaticBrightnessController { int lightSensorWarmUpTime, int brightnessMin, int brightnessMax, float dozeScaleFactor, int lightSensorRate, int initialLightSensorRate, long brighteningLightDebounceConfig, long darkeningLightDebounceConfig, boolean resetAmbientLuxAfterWarmUpConfig, HysteresisLevels hysteresisLevels) { HysteresisLevels ambientBrightnessThresholds, HysteresisLevels screenBrightnessThresholds) { mCallbacks = callbacks; mSensorManager = sensorManager; mBrightnessMapper = mapper; Loading @@ -212,7 +214,8 @@ class AutomaticBrightnessController { mResetAmbientLuxAfterWarmUpConfig = resetAmbientLuxAfterWarmUpConfig; mAmbientLightHorizon = AMBIENT_LIGHT_LONG_HORIZON_MILLIS; mWeightingIntercept = AMBIENT_LIGHT_LONG_HORIZON_MILLIS; mHysteresisLevels = hysteresisLevels; mAmbientBrightnessThresholds = ambientBrightnessThresholds; mScreenBrightnessThresholds = screenBrightnessThresholds; mShortTermModelValid = true; mShortTermModelAnchor = -1; Loading Loading @@ -364,8 +367,10 @@ class AutomaticBrightnessController { pw.println(" mCurrentLightSensorRate=" + mCurrentLightSensorRate); pw.println(" mAmbientLux=" + mAmbientLux); pw.println(" mAmbientLuxValid=" + mAmbientLuxValid); pw.println(" mBrighteningLuxThreshold=" + mBrighteningLuxThreshold); pw.println(" mDarkeningLuxThreshold=" + mDarkeningLuxThreshold); pw.println(" mAmbientBrighteningThreshold=" + mAmbientBrighteningThreshold); pw.println(" mAmbientDarkeningThreshold=" + mAmbientDarkeningThreshold); pw.println(" mScreenBrighteningThreshold=" + mScreenBrighteningThreshold); pw.println(" mScreenDarkeningThreshold=" + mScreenDarkeningThreshold); pw.println(" mLastObservedLux=" + mLastObservedLux); pw.println(" mLastObservedLuxTime=" + TimeUtils.formatUptime(mLastObservedLuxTime)); pw.println(" mRecentLightSamples=" + mRecentLightSamples); Loading @@ -384,7 +389,8 @@ class AutomaticBrightnessController { mBrightnessMapper.dump(pw); pw.println(); mHysteresisLevels.dump(pw); mAmbientBrightnessThresholds.dump(pw); mScreenBrightnessThresholds.dump(pw); } private boolean setLightSensorEnabled(boolean enable) { Loading Loading @@ -460,8 +466,8 @@ class AutomaticBrightnessController { lux = 0; } mAmbientLux = lux; mBrighteningLuxThreshold = mHysteresisLevels.getBrighteningThreshold(lux); mDarkeningLuxThreshold = mHysteresisLevels.getDarkeningThreshold(lux); mAmbientBrighteningThreshold = mAmbientBrightnessThresholds.getBrighteningThreshold(lux); mAmbientDarkeningThreshold = mAmbientBrightnessThresholds.getDarkeningThreshold(lux); // If the short term model was invalidated and the change is drastic enough, reset it. if (!mShortTermModelValid && mShortTermModelAnchor != -1) { Loading Loading @@ -552,7 +558,7 @@ class AutomaticBrightnessController { final int N = mAmbientLightRingBuffer.size(); long earliestValidTime = time; for (int i = N - 1; i >= 0; i--) { if (mAmbientLightRingBuffer.getLux(i) <= mBrighteningLuxThreshold) { if (mAmbientLightRingBuffer.getLux(i) <= mAmbientBrighteningThreshold) { break; } earliestValidTime = mAmbientLightRingBuffer.getTime(i); Loading @@ -564,7 +570,7 @@ class AutomaticBrightnessController { final int N = mAmbientLightRingBuffer.size(); long earliestValidTime = time; for (int i = N - 1; i >= 0; i--) { if (mAmbientLightRingBuffer.getLux(i) >= mDarkeningLuxThreshold) { if (mAmbientLightRingBuffer.getLux(i) >= mAmbientDarkeningThreshold) { break; } earliestValidTime = mAmbientLightRingBuffer.getTime(i); Loading Loading @@ -617,20 +623,19 @@ class AutomaticBrightnessController { float slowAmbientLux = calculateAmbientLux(time, AMBIENT_LIGHT_LONG_HORIZON_MILLIS); float fastAmbientLux = calculateAmbientLux(time, AMBIENT_LIGHT_SHORT_HORIZON_MILLIS); if ((slowAmbientLux >= mBrighteningLuxThreshold && fastAmbientLux >= mBrighteningLuxThreshold && nextBrightenTransition <= time) || (slowAmbientLux <= mDarkeningLuxThreshold && fastAmbientLux <= mDarkeningLuxThreshold && nextDarkenTransition <= time)) { if ((slowAmbientLux >= mAmbientBrighteningThreshold && fastAmbientLux >= mAmbientBrighteningThreshold && nextBrightenTransition <= time) || (slowAmbientLux <= mAmbientDarkeningThreshold && fastAmbientLux <= mAmbientDarkeningThreshold && nextDarkenTransition <= time)) { setAmbientLux(fastAmbientLux); if (DEBUG) { Slog.d(TAG, "updateAmbientLux: " + ((fastAmbientLux > mAmbientLux) ? "Brightened" : "Darkened") + ": " + "mBrighteningLuxThreshold=" + mBrighteningLuxThreshold + ", " + "mAmbientLightRingBuffer=" + mAmbientLightRingBuffer + ", " + "mAmbientLux=" + mAmbientLux); Slog.d(TAG, "updateAmbientLux: " + ((fastAmbientLux > mAmbientLux) ? "Brightened" : "Darkened") + ": " + "mAmbientBrighteningThreshold=" + mAmbientBrighteningThreshold + ", " + "mAmbientLightRingBuffer=" + mAmbientLightRingBuffer + ", " + "mAmbientLux=" + mAmbientLux); } updateAutoBrightness(true); nextBrightenTransition = nextAmbientLightBrighteningTransition(time); Loading Loading @@ -661,7 +666,22 @@ class AutomaticBrightnessController { int newScreenAutoBrightness = clampScreenBrightness(Math.round(value * PowerManager.BRIGHTNESS_ON)); // If screenAutoBrightness is set, we should have screen{Brightening,Darkening}Threshold, // in which case we ignore the new screen brightness if it doesn't differ enough from the // previous one. if (mScreenAutoBrightness != -1 && newScreenAutoBrightness > mScreenDarkeningThreshold && newScreenAutoBrightness < mScreenBrighteningThreshold) { if (DEBUG) { Slog.d(TAG, "ignoring newScreenAutoBrightness: " + mScreenDarkeningThreshold + " < " + newScreenAutoBrightness + " < " + mScreenBrighteningThreshold); } return; } if (mScreenAutoBrightness != newScreenAutoBrightness) { if (DEBUG) { Slog.d(TAG, "updateAutoBrightness: " + "mScreenAutoBrightness=" + mScreenAutoBrightness + ", " + Loading @@ -669,6 +689,11 @@ class AutomaticBrightnessController { } mScreenAutoBrightness = newScreenAutoBrightness; mScreenBrighteningThreshold = mScreenBrightnessThresholds.getBrighteningThreshold(newScreenAutoBrightness); mScreenDarkeningThreshold = mScreenBrightnessThresholds.getDarkeningThreshold(newScreenAutoBrightness); if (sendUpdate) { mCallbacks.updateBrightness(); } Loading services/core/java/com/android/server/display/DisplayPowerController.java +26 −15 Original line number Diff line number Diff line Loading @@ -16,16 +16,11 @@ package com.android.server.display; import android.app.ActivityManager; import com.android.internal.app.IBatteryStats; import com.android.server.LocalServices; import com.android.server.am.BatteryStatsService; import com.android.server.policy.WindowManagerPolicy; import android.animation.Animator; import android.animation.ObjectAnimator; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManager; import android.content.Context; import android.content.pm.ParceledListSlice; import android.content.res.Resources; Loading Loading @@ -54,6 +49,11 @@ import android.util.Slog; import android.util.TimeUtils; import android.view.Display; import com.android.internal.app.IBatteryStats; import com.android.server.LocalServices; import com.android.server.am.BatteryStatsService; import com.android.server.policy.WindowManagerPolicy; import java.io.PrintWriter; /** Loading Loading @@ -422,14 +422,24 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor, 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[] luxHysteresisLevels = resources.getIntArray( com.android.internal.R.array.config_dynamicHysteresisLuxLevels); HysteresisLevels hysteresisLevels = new HysteresisLevels( brightLevels, darkLevels, luxHysteresisLevels); int[] ambientBrighteningThresholds = resources.getIntArray( com.android.internal.R.array.config_ambientBrighteningThresholds); int[] ambientDarkeningThresholds = resources.getIntArray( com.android.internal.R.array.config_ambientDarkeningThresholds); int[] ambientThresholdLevels = resources.getIntArray( com.android.internal.R.array.config_ambientThresholdLevels); HysteresisLevels ambientBrightnessThresholds = new HysteresisLevels( ambientBrighteningThresholds, ambientDarkeningThresholds, ambientThresholdLevels); int[] screenBrighteningThresholds = resources.getIntArray( com.android.internal.R.array.config_screenBrighteningThresholds); int[] screenDarkeningThresholds = resources.getIntArray( com.android.internal.R.array.config_screenDarkeningThresholds); int[] screenThresholdLevels = resources.getIntArray( com.android.internal.R.array.config_screenThresholdLevels); HysteresisLevels screenBrightnessThresholds = new HysteresisLevels( screenBrighteningThresholds, screenDarkeningThresholds, screenThresholdLevels); long brighteningLightDebounce = resources.getInteger( com.android.internal.R.integer.config_autoBrightnessBrighteningLightDebounce); Loading Loading @@ -459,7 +469,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call lightSensorWarmUpTimeConfig, mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum, dozeScaleFactor, lightSensorRate, initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce, autoBrightnessResetAmbientLuxAfterWarmUp, hysteresisLevels); autoBrightnessResetAmbientLuxAfterWarmUp, ambientBrightnessThresholds, screenBrightnessThresholds); } else { mUseSoftwareAutoBrightnessConfig = false; } Loading services/core/java/com/android/server/display/HysteresisLevels.java +37 −37 Original line number Diff line number Diff line Loading @@ -28,67 +28,67 @@ final class HysteresisLevels { private static final String TAG = "HysteresisLevels"; // 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. // The recent value must have changed by at least this fraction relative to the // current value 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 = false; private final float[] mBrightLevels; private final float[] mDarkLevels; private final float[] mLuxLevels; private final float[] mBrighteningThresholds; private final float[] mDarkeningThresholds; private final float[] mThresholdLevels; /** * Creates a {@code HysteresisLevels} object with the given equal-length * integer arrays. * @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 brighteningThresholds an array of brightening hysteresis constraint constants. * @param darkeningThresholds an array of darkening hysteresis constraint constants. * @param thresholdLevels a monotonically increasing array of threshold levels. */ public HysteresisLevels(int[] brightLevels, int[] darkLevels, int[] luxLevels) { if (brightLevels.length != darkLevels.length || darkLevels.length != luxLevels.length + 1) { HysteresisLevels(int[] brighteningThresholds, int[] darkeningThresholds, int[] thresholdLevels) { if (brighteningThresholds.length != darkeningThresholds.length || darkeningThresholds.length != thresholdLevels.length + 1) { throw new IllegalArgumentException("Mismatch between hysteresis array lengths."); } mBrightLevels = setArrayFormat(brightLevels, 1000.0f); mDarkLevels = setArrayFormat(darkLevels, 1000.0f); mLuxLevels = setArrayFormat(luxLevels, 1.0f); mBrighteningThresholds = setArrayFormat(brighteningThresholds, 1000.0f); mDarkeningThresholds = setArrayFormat(darkeningThresholds, 1000.0f); mThresholdLevels = setArrayFormat(thresholdLevels, 1.0f); } /** * Return the brightening hysteresis threshold for the given lux level. * Return the brightening hysteresis threshold for the given value level. */ public float getBrighteningThreshold(float lux) { float brightConstant = getReferenceLevel(lux, mBrightLevels); float brightThreshold = lux * (1.0f + brightConstant); float getBrighteningThreshold(float value) { float brightConstant = getReferenceLevel(value, mBrighteningThresholds); float brightThreshold = value * (1.0f + brightConstant); if (DEBUG) { Slog.d(TAG, "bright hysteresis constant=: " + brightConstant + ", threshold=" + brightThreshold + ", lux=" + lux); Slog.d(TAG, "bright hysteresis constant=" + brightConstant + ", threshold=" + brightThreshold + ", value=" + value); } return brightThreshold; } /** * Return the darkening hysteresis threshold for the given lux level. * Return the darkening hysteresis threshold for the given value level. */ public float getDarkeningThreshold(float lux) { float darkConstant = getReferenceLevel(lux, mDarkLevels); float darkThreshold = lux * (1.0f - darkConstant); float getDarkeningThreshold(float value) { float darkConstant = getReferenceLevel(value, mDarkeningThresholds); float darkThreshold = value * (1.0f - darkConstant); if (DEBUG) { Slog.d(TAG, "dark hysteresis constant=: " + darkConstant + ", threshold=" + darkThreshold + ", lux=" + lux); + darkThreshold + ", value=" + value); } return darkThreshold; } /** * Return the hysteresis constant for the closest lux threshold value to the * current illuminance from the given array. * Return the hysteresis constant for the closest threshold value from the given array. */ private float getReferenceLevel(float lux, float[] referenceLevels) { private float getReferenceLevel(float value, float[] referenceLevels) { int index = 0; while (mLuxLevels.length > index && lux >= mLuxLevels[index]) { while (mThresholdLevels.length > index && value >= mThresholdLevels[index]) { ++index; } return referenceLevels[index]; Loading @@ -105,10 +105,10 @@ final class HysteresisLevels { return levelArray; } public void dump(PrintWriter pw) { void dump(PrintWriter pw) { pw.println("HysteresisLevels"); pw.println(" mBrightLevels=" + Arrays.toString(mBrightLevels)); pw.println(" mDarkLevels=" + Arrays.toString(mDarkLevels)); pw.println(" mLuxLevels=" + Arrays.toString(mLuxLevels)); pw.println(" mBrighteningThresholds=" + Arrays.toString(mBrighteningThresholds)); pw.println(" mDarkeningThresholds=" + Arrays.toString(mDarkeningThresholds)); pw.println(" mThresholdLevels=" + Arrays.toString(mThresholdLevels)); } } Loading
core/res/res/values/config.xml +62 −28 Original line number Diff line number Diff line Loading @@ -1437,26 +1437,6 @@ <integer-array name="config_autoBrightnessKeyboardBacklightValues"> </integer-array> <!-- Array of hysteresis constraint values for brightening, represented as tenths of a percent. The length of this array is assumed to be one greater than config_dynamicHysteresisLuxLevels. The brightening threshold is calculated as lux * (1.0f + CONSTRAINT_VALUE). When the current lux is higher than this threshold, the screen brightness is recalculated. See the config_dynamicHysteresisLuxLevels description for how the constraint value is chosen. --> <integer-array name="config_dynamicHysteresisBrightLevels"> <item>100</item> </integer-array> <!-- Array of hysteresis constraint values for darkening, represented as tenths of a percent. The length of this array is assumed to be one greater than config_dynamicHysteresisLuxLevels. The darkening threshold is calculated as lux * (1.0f - CONSTRAINT_VALUE). When the current lux is lower than this threshold, the screen brightness is recalculated. See the config_dynamicHysteresisLuxLevels description for how the constraint value is chosen. --> <integer-array name="config_dynamicHysteresisDarkLevels"> <item>200</item> </integer-array> <!-- An array describing the screen's backlight values corresponding to the brightness values in the config_screenBrightnessNits array. Loading @@ -1474,19 +1454,73 @@ <array name="config_screenBrightnessNits"> </array> <!-- Array of ambient lux threshold values. This is used for determining hysteresis constraint values by calculating the index to use for lookup and then setting the constraint value to the corresponding value of the array. The new brightening hysteresis constraint value is the n-th element of config_dynamicHysteresisBrightLevels, and the new darkening hysteresis constraint value is the n-th element of config_dynamicHysteresisDarkLevels. is the n-th element of config_ambientBrighteningThresholds, and the new darkening hysteresis constraint value is the n-th element of config_ambientDarkeningThresholds. The (zero-based) index is calculated as follows: (MAX is the largest index of the array) condition calculated index value < level[0] 0 level[n] <= value < level[n+1] n+1 level[MAX] <= value MAX+1 --> <integer-array name="config_ambientThresholdLevels"> </integer-array> <!-- Array of hysteresis constraint values for brightening, represented as tenths of a percent. The length of this array is assumed to be one greater than config_ambientThresholdLevels. The brightening threshold is calculated as lux * (1.0f + CONSTRAINT_VALUE). When the current lux is higher than this threshold, the screen brightness is recalculated. See the config_ambientThresholdLevels description for how the constraint value is chosen. --> <integer-array name="config_ambientBrighteningThresholds"> <item>100</item> </integer-array> <!-- Array of hysteresis constraint values for darkening, represented as tenths of a percent. The length of this array is assumed to be one greater than config_ambientThresholdLevels. The darkening threshold is calculated as lux * (1.0f - CONSTRAINT_VALUE). When the current lux is lower than this threshold, the screen brightness is recalculated. See the config_ambientThresholdLevels description for how the constraint value is chosen. --> <integer-array name="config_ambientDarkeningThresholds"> <item>200</item> </integer-array> <!-- Array of screen brightness threshold values. This is used for determining hysteresis constraint values by calculating the index to use for lookup and then setting the constraint value to the corresponding value of the array. The new brightening hysteresis constraint value is the n-th element of config_screenBrighteningThresholds, and the new darkening hysteresis constraint value is the n-th element of config_screenDarkeningThresholds. 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_dynamicHysteresisLuxLevels"> value < level[0] 0 level[n] <= value < level[n+1] n+1 level[MAX] <= value MAX+1 --> <integer-array name="config_screenThresholdLevels"> </integer-array> <!-- Array of hysteresis constraint values for brightening, represented as tenths of a percent. The length of this array is assumed to be one greater than config_screenThresholdLevels. The brightening threshold is calculated as screenBrightness * (1.0f + CONSTRAINT_VALUE). When the new screen brightness is higher than this threshold, it is applied. See the config_screenThresholdLevels description for how the constraint value is chosen. --> <integer-array name="config_screenBrighteningThresholds"> <item>100</item> </integer-array> <!-- Array of hysteresis constraint values for darkening, represented as tenths of a percent. The length of this array is assumed to be one greater than config_screenThresholdLevels. The darkening threshold is calculated as screenBrightness * (1.0f - CONSTRAINT_VALUE). When the new screen brightness is lower than this threshold, it is applied. See the config_screenThresholdLevels description for how the constraint value is chosen. --> <integer-array name="config_screenDarkeningThresholds"> <item>200</item> </integer-array> <!-- Amount of time it takes for the light sensor to warm up in milliseconds. Loading
core/res/res/values/symbols.xml +6 −3 Original line number Diff line number Diff line Loading @@ -1829,9 +1829,12 @@ <java-symbol type="array" name="config_autoBrightnessKeyboardBacklightValues" /> <java-symbol type="array" name="config_autoBrightnessLcdBacklightValues" /> <java-symbol type="array" name="config_autoBrightnessLevels" /> <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_ambientThresholdLevels" /> <java-symbol type="array" name="config_ambientBrighteningThresholds" /> <java-symbol type="array" name="config_ambientDarkeningThresholds" /> <java-symbol type="array" name="config_screenThresholdLevels" /> <java-symbol type="array" name="config_screenBrighteningThresholds" /> <java-symbol type="array" name="config_screenDarkeningThresholds" /> <java-symbol type="array" name="config_minimumBrightnessCurveLux" /> <java-symbol type="array" name="config_minimumBrightnessCurveNits" /> <java-symbol type="array" name="config_protectedNetworks" /> Loading
services/core/java/com/android/server/display/AutomaticBrightnessController.java +55 −30 Original line number Diff line number Diff line Loading @@ -16,30 +16,26 @@ package com.android.server.display; import com.android.server.EventLogTags; import com.android.server.LocalServices; import android.annotation.Nullable; import android.app.ActivityManager; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.hardware.display.BrightnessConfiguration; import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest; import android.os.Build; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.PowerManager; import android.os.SystemClock; import android.os.Trace; import android.text.format.DateUtils; import android.util.EventLog; import android.util.MathUtils; import android.util.Slog; import android.util.TimeUtils; import com.android.server.EventLogTags; import java.io.PrintWriter; class AutomaticBrightnessController { Loading Loading @@ -127,7 +123,8 @@ class AutomaticBrightnessController { private final int mWeightingIntercept; // Configuration object for determining thresholds to change brightness dynamically private final HysteresisLevels mHysteresisLevels; private final HysteresisLevels mAmbientBrightnessThresholds; private final HysteresisLevels mScreenBrightnessThresholds; // Amount of time to delay auto-brightness after screen on while waiting for // the light sensor to warm-up in milliseconds. Loading @@ -147,8 +144,12 @@ class AutomaticBrightnessController { private boolean mAmbientLuxValid; // The ambient light level threshold at which to brighten or darken the screen. private float mBrighteningLuxThreshold; private float mDarkeningLuxThreshold; private float mAmbientBrighteningThreshold; private float mAmbientDarkeningThreshold; // The screen brightness threshold at which to brighten or darken the screen. private float mScreenBrighteningThreshold; private float mScreenDarkeningThreshold; // The most recent light sample. private float mLastObservedLux; Loading Loading @@ -196,7 +197,8 @@ class AutomaticBrightnessController { int lightSensorWarmUpTime, int brightnessMin, int brightnessMax, float dozeScaleFactor, int lightSensorRate, int initialLightSensorRate, long brighteningLightDebounceConfig, long darkeningLightDebounceConfig, boolean resetAmbientLuxAfterWarmUpConfig, HysteresisLevels hysteresisLevels) { HysteresisLevels ambientBrightnessThresholds, HysteresisLevels screenBrightnessThresholds) { mCallbacks = callbacks; mSensorManager = sensorManager; mBrightnessMapper = mapper; Loading @@ -212,7 +214,8 @@ class AutomaticBrightnessController { mResetAmbientLuxAfterWarmUpConfig = resetAmbientLuxAfterWarmUpConfig; mAmbientLightHorizon = AMBIENT_LIGHT_LONG_HORIZON_MILLIS; mWeightingIntercept = AMBIENT_LIGHT_LONG_HORIZON_MILLIS; mHysteresisLevels = hysteresisLevels; mAmbientBrightnessThresholds = ambientBrightnessThresholds; mScreenBrightnessThresholds = screenBrightnessThresholds; mShortTermModelValid = true; mShortTermModelAnchor = -1; Loading Loading @@ -364,8 +367,10 @@ class AutomaticBrightnessController { pw.println(" mCurrentLightSensorRate=" + mCurrentLightSensorRate); pw.println(" mAmbientLux=" + mAmbientLux); pw.println(" mAmbientLuxValid=" + mAmbientLuxValid); pw.println(" mBrighteningLuxThreshold=" + mBrighteningLuxThreshold); pw.println(" mDarkeningLuxThreshold=" + mDarkeningLuxThreshold); pw.println(" mAmbientBrighteningThreshold=" + mAmbientBrighteningThreshold); pw.println(" mAmbientDarkeningThreshold=" + mAmbientDarkeningThreshold); pw.println(" mScreenBrighteningThreshold=" + mScreenBrighteningThreshold); pw.println(" mScreenDarkeningThreshold=" + mScreenDarkeningThreshold); pw.println(" mLastObservedLux=" + mLastObservedLux); pw.println(" mLastObservedLuxTime=" + TimeUtils.formatUptime(mLastObservedLuxTime)); pw.println(" mRecentLightSamples=" + mRecentLightSamples); Loading @@ -384,7 +389,8 @@ class AutomaticBrightnessController { mBrightnessMapper.dump(pw); pw.println(); mHysteresisLevels.dump(pw); mAmbientBrightnessThresholds.dump(pw); mScreenBrightnessThresholds.dump(pw); } private boolean setLightSensorEnabled(boolean enable) { Loading Loading @@ -460,8 +466,8 @@ class AutomaticBrightnessController { lux = 0; } mAmbientLux = lux; mBrighteningLuxThreshold = mHysteresisLevels.getBrighteningThreshold(lux); mDarkeningLuxThreshold = mHysteresisLevels.getDarkeningThreshold(lux); mAmbientBrighteningThreshold = mAmbientBrightnessThresholds.getBrighteningThreshold(lux); mAmbientDarkeningThreshold = mAmbientBrightnessThresholds.getDarkeningThreshold(lux); // If the short term model was invalidated and the change is drastic enough, reset it. if (!mShortTermModelValid && mShortTermModelAnchor != -1) { Loading Loading @@ -552,7 +558,7 @@ class AutomaticBrightnessController { final int N = mAmbientLightRingBuffer.size(); long earliestValidTime = time; for (int i = N - 1; i >= 0; i--) { if (mAmbientLightRingBuffer.getLux(i) <= mBrighteningLuxThreshold) { if (mAmbientLightRingBuffer.getLux(i) <= mAmbientBrighteningThreshold) { break; } earliestValidTime = mAmbientLightRingBuffer.getTime(i); Loading @@ -564,7 +570,7 @@ class AutomaticBrightnessController { final int N = mAmbientLightRingBuffer.size(); long earliestValidTime = time; for (int i = N - 1; i >= 0; i--) { if (mAmbientLightRingBuffer.getLux(i) >= mDarkeningLuxThreshold) { if (mAmbientLightRingBuffer.getLux(i) >= mAmbientDarkeningThreshold) { break; } earliestValidTime = mAmbientLightRingBuffer.getTime(i); Loading Loading @@ -617,20 +623,19 @@ class AutomaticBrightnessController { float slowAmbientLux = calculateAmbientLux(time, AMBIENT_LIGHT_LONG_HORIZON_MILLIS); float fastAmbientLux = calculateAmbientLux(time, AMBIENT_LIGHT_SHORT_HORIZON_MILLIS); if ((slowAmbientLux >= mBrighteningLuxThreshold && fastAmbientLux >= mBrighteningLuxThreshold && nextBrightenTransition <= time) || (slowAmbientLux <= mDarkeningLuxThreshold && fastAmbientLux <= mDarkeningLuxThreshold && nextDarkenTransition <= time)) { if ((slowAmbientLux >= mAmbientBrighteningThreshold && fastAmbientLux >= mAmbientBrighteningThreshold && nextBrightenTransition <= time) || (slowAmbientLux <= mAmbientDarkeningThreshold && fastAmbientLux <= mAmbientDarkeningThreshold && nextDarkenTransition <= time)) { setAmbientLux(fastAmbientLux); if (DEBUG) { Slog.d(TAG, "updateAmbientLux: " + ((fastAmbientLux > mAmbientLux) ? "Brightened" : "Darkened") + ": " + "mBrighteningLuxThreshold=" + mBrighteningLuxThreshold + ", " + "mAmbientLightRingBuffer=" + mAmbientLightRingBuffer + ", " + "mAmbientLux=" + mAmbientLux); Slog.d(TAG, "updateAmbientLux: " + ((fastAmbientLux > mAmbientLux) ? "Brightened" : "Darkened") + ": " + "mAmbientBrighteningThreshold=" + mAmbientBrighteningThreshold + ", " + "mAmbientLightRingBuffer=" + mAmbientLightRingBuffer + ", " + "mAmbientLux=" + mAmbientLux); } updateAutoBrightness(true); nextBrightenTransition = nextAmbientLightBrighteningTransition(time); Loading Loading @@ -661,7 +666,22 @@ class AutomaticBrightnessController { int newScreenAutoBrightness = clampScreenBrightness(Math.round(value * PowerManager.BRIGHTNESS_ON)); // If screenAutoBrightness is set, we should have screen{Brightening,Darkening}Threshold, // in which case we ignore the new screen brightness if it doesn't differ enough from the // previous one. if (mScreenAutoBrightness != -1 && newScreenAutoBrightness > mScreenDarkeningThreshold && newScreenAutoBrightness < mScreenBrighteningThreshold) { if (DEBUG) { Slog.d(TAG, "ignoring newScreenAutoBrightness: " + mScreenDarkeningThreshold + " < " + newScreenAutoBrightness + " < " + mScreenBrighteningThreshold); } return; } if (mScreenAutoBrightness != newScreenAutoBrightness) { if (DEBUG) { Slog.d(TAG, "updateAutoBrightness: " + "mScreenAutoBrightness=" + mScreenAutoBrightness + ", " + Loading @@ -669,6 +689,11 @@ class AutomaticBrightnessController { } mScreenAutoBrightness = newScreenAutoBrightness; mScreenBrighteningThreshold = mScreenBrightnessThresholds.getBrighteningThreshold(newScreenAutoBrightness); mScreenDarkeningThreshold = mScreenBrightnessThresholds.getDarkeningThreshold(newScreenAutoBrightness); if (sendUpdate) { mCallbacks.updateBrightness(); } Loading
services/core/java/com/android/server/display/DisplayPowerController.java +26 −15 Original line number Diff line number Diff line Loading @@ -16,16 +16,11 @@ package com.android.server.display; import android.app.ActivityManager; import com.android.internal.app.IBatteryStats; import com.android.server.LocalServices; import com.android.server.am.BatteryStatsService; import com.android.server.policy.WindowManagerPolicy; import android.animation.Animator; import android.animation.ObjectAnimator; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManager; import android.content.Context; import android.content.pm.ParceledListSlice; import android.content.res.Resources; Loading Loading @@ -54,6 +49,11 @@ import android.util.Slog; import android.util.TimeUtils; import android.view.Display; import com.android.internal.app.IBatteryStats; import com.android.server.LocalServices; import com.android.server.am.BatteryStatsService; import com.android.server.policy.WindowManagerPolicy; import java.io.PrintWriter; /** Loading Loading @@ -422,14 +422,24 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor, 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[] luxHysteresisLevels = resources.getIntArray( com.android.internal.R.array.config_dynamicHysteresisLuxLevels); HysteresisLevels hysteresisLevels = new HysteresisLevels( brightLevels, darkLevels, luxHysteresisLevels); int[] ambientBrighteningThresholds = resources.getIntArray( com.android.internal.R.array.config_ambientBrighteningThresholds); int[] ambientDarkeningThresholds = resources.getIntArray( com.android.internal.R.array.config_ambientDarkeningThresholds); int[] ambientThresholdLevels = resources.getIntArray( com.android.internal.R.array.config_ambientThresholdLevels); HysteresisLevels ambientBrightnessThresholds = new HysteresisLevels( ambientBrighteningThresholds, ambientDarkeningThresholds, ambientThresholdLevels); int[] screenBrighteningThresholds = resources.getIntArray( com.android.internal.R.array.config_screenBrighteningThresholds); int[] screenDarkeningThresholds = resources.getIntArray( com.android.internal.R.array.config_screenDarkeningThresholds); int[] screenThresholdLevels = resources.getIntArray( com.android.internal.R.array.config_screenThresholdLevels); HysteresisLevels screenBrightnessThresholds = new HysteresisLevels( screenBrighteningThresholds, screenDarkeningThresholds, screenThresholdLevels); long brighteningLightDebounce = resources.getInteger( com.android.internal.R.integer.config_autoBrightnessBrighteningLightDebounce); Loading Loading @@ -459,7 +469,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call lightSensorWarmUpTimeConfig, mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum, dozeScaleFactor, lightSensorRate, initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce, autoBrightnessResetAmbientLuxAfterWarmUp, hysteresisLevels); autoBrightnessResetAmbientLuxAfterWarmUp, ambientBrightnessThresholds, screenBrightnessThresholds); } else { mUseSoftwareAutoBrightnessConfig = false; } Loading
services/core/java/com/android/server/display/HysteresisLevels.java +37 −37 Original line number Diff line number Diff line Loading @@ -28,67 +28,67 @@ final class HysteresisLevels { private static final String TAG = "HysteresisLevels"; // 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. // The recent value must have changed by at least this fraction relative to the // current value 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 = false; private final float[] mBrightLevels; private final float[] mDarkLevels; private final float[] mLuxLevels; private final float[] mBrighteningThresholds; private final float[] mDarkeningThresholds; private final float[] mThresholdLevels; /** * Creates a {@code HysteresisLevels} object with the given equal-length * integer arrays. * @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 brighteningThresholds an array of brightening hysteresis constraint constants. * @param darkeningThresholds an array of darkening hysteresis constraint constants. * @param thresholdLevels a monotonically increasing array of threshold levels. */ public HysteresisLevels(int[] brightLevels, int[] darkLevels, int[] luxLevels) { if (brightLevels.length != darkLevels.length || darkLevels.length != luxLevels.length + 1) { HysteresisLevels(int[] brighteningThresholds, int[] darkeningThresholds, int[] thresholdLevels) { if (brighteningThresholds.length != darkeningThresholds.length || darkeningThresholds.length != thresholdLevels.length + 1) { throw new IllegalArgumentException("Mismatch between hysteresis array lengths."); } mBrightLevels = setArrayFormat(brightLevels, 1000.0f); mDarkLevels = setArrayFormat(darkLevels, 1000.0f); mLuxLevels = setArrayFormat(luxLevels, 1.0f); mBrighteningThresholds = setArrayFormat(brighteningThresholds, 1000.0f); mDarkeningThresholds = setArrayFormat(darkeningThresholds, 1000.0f); mThresholdLevels = setArrayFormat(thresholdLevels, 1.0f); } /** * Return the brightening hysteresis threshold for the given lux level. * Return the brightening hysteresis threshold for the given value level. */ public float getBrighteningThreshold(float lux) { float brightConstant = getReferenceLevel(lux, mBrightLevels); float brightThreshold = lux * (1.0f + brightConstant); float getBrighteningThreshold(float value) { float brightConstant = getReferenceLevel(value, mBrighteningThresholds); float brightThreshold = value * (1.0f + brightConstant); if (DEBUG) { Slog.d(TAG, "bright hysteresis constant=: " + brightConstant + ", threshold=" + brightThreshold + ", lux=" + lux); Slog.d(TAG, "bright hysteresis constant=" + brightConstant + ", threshold=" + brightThreshold + ", value=" + value); } return brightThreshold; } /** * Return the darkening hysteresis threshold for the given lux level. * Return the darkening hysteresis threshold for the given value level. */ public float getDarkeningThreshold(float lux) { float darkConstant = getReferenceLevel(lux, mDarkLevels); float darkThreshold = lux * (1.0f - darkConstant); float getDarkeningThreshold(float value) { float darkConstant = getReferenceLevel(value, mDarkeningThresholds); float darkThreshold = value * (1.0f - darkConstant); if (DEBUG) { Slog.d(TAG, "dark hysteresis constant=: " + darkConstant + ", threshold=" + darkThreshold + ", lux=" + lux); + darkThreshold + ", value=" + value); } return darkThreshold; } /** * Return the hysteresis constant for the closest lux threshold value to the * current illuminance from the given array. * Return the hysteresis constant for the closest threshold value from the given array. */ private float getReferenceLevel(float lux, float[] referenceLevels) { private float getReferenceLevel(float value, float[] referenceLevels) { int index = 0; while (mLuxLevels.length > index && lux >= mLuxLevels[index]) { while (mThresholdLevels.length > index && value >= mThresholdLevels[index]) { ++index; } return referenceLevels[index]; Loading @@ -105,10 +105,10 @@ final class HysteresisLevels { return levelArray; } public void dump(PrintWriter pw) { void dump(PrintWriter pw) { pw.println("HysteresisLevels"); pw.println(" mBrightLevels=" + Arrays.toString(mBrightLevels)); pw.println(" mDarkLevels=" + Arrays.toString(mDarkLevels)); pw.println(" mLuxLevels=" + Arrays.toString(mLuxLevels)); pw.println(" mBrighteningThresholds=" + Arrays.toString(mBrighteningThresholds)); pw.println(" mDarkeningThresholds=" + Arrays.toString(mDarkeningThresholds)); pw.println(" mThresholdLevels=" + Arrays.toString(mThresholdLevels)); } }