Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6fc42f54 authored by Zoran Jovanovic's avatar Zoran Jovanovic
Browse files

Customize auto-brightness parameters

Auto-brightness parameters are device dependent so they should be
configurable.

The common issue with original values manifests as the screen being
perceived as too bright in dark rooms with minimum brightness and
also laginess on backlight change.

Change-Id: I2b040608bca73a3397c65c24d3b28a1514499ae6
parent 85b010b8
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -1002,6 +1002,10 @@
    <!-- Light sensor event rate in milliseconds for automatic brightness control. -->
    <integer name="config_autoBrightnessLightSensorRate">250</integer>

    <!-- The maximum range of gamma adjustment possible using the screen
         auto-brightness adjustment setting. -->
    <fraction name="config_autoBrightnessAdjustmentMaxGamma">300%</fraction>

    <!-- If we allow automatic adjustment of screen brightness while dozing, how many times we want
         to reduce it to preserve the battery. Value of 100% means no scaling. -->
    <fraction name="config_screenAutoBrightnessDozeScaleFactor">100%</fraction>
@@ -1019,6 +1023,9 @@
         adapt to the environment.  This mode may be better suited for watches. -->
    <bool name="config_autoBrightnessResetAmbientLuxAfterWarmUp">true</bool>

    <!-- Period of time in which to consider light samples in milliseconds. -->
    <integer name="config_autoBrightnessAmbientLightHorizon">10000</integer>

    <!-- Screen brightness used to dim the screen when the user activity
         timeout expires.  May be less than the minimum allowed brightness setting
         that can be set by the user. -->
+2 −0
Original line number Diff line number Diff line
@@ -1689,6 +1689,8 @@
  <java-symbol type="id" name="replace_message" />
  <java-symbol type="fraction" name="config_dimBehindFadeDuration" />
  <java-symbol type="fraction" name="config_screenAutoBrightnessDozeScaleFactor" />
  <java-symbol type="fraction" name="config_autoBrightnessAdjustmentMaxGamma" />
  <java-symbol type="integer" name="config_autoBrightnessAmbientLightHorizon"/>
  <java-symbol type="integer" name="config_autoBrightnessBrighteningLightDebounce"/>
  <java-symbol type="integer" name="config_autoBrightnessDarkeningLightDebounce"/>
  <java-symbol type="integer" name="config_autoBrightnessLightSensorRate"/>
+28 −22
Original line number Diff line number Diff line
@@ -49,23 +49,12 @@ class AutomaticBrightnessController {
    // If true, enables the use of the screen auto-brightness adjustment setting.
    private static final boolean USE_SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT = true;

    // The maximum range of gamma adjustment possible using the screen
    // auto-brightness adjustment setting.
    private static final float SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT_MAX_GAMMA = 3.0f;

    // Period of time in which to consider light samples in milliseconds.
    private static final int AMBIENT_LIGHT_HORIZON = 10000;

    // 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 BRIGHTENING_LIGHT_HYSTERESIS = 0.10f;
    private static final float DARKENING_LIGHT_HYSTERESIS = 0.20f;

    // The intercept used for the weighting calculation. This is used in order to keep all possible
    // weighting values positive.
    private static final int WEIGHTING_INTERCEPT = AMBIENT_LIGHT_HORIZON;

    // How long the current sensor reading is assumed to be valid beyond the current time.
    // This provides a bit of prediction, as well as ensures that the weight for the last sample is
    // non-zero, which in turn ensures that the total weight is non-zero.
@@ -132,6 +121,13 @@ class AutomaticBrightnessController {
    // and only then decide whether to change brightness.
    private final boolean mResetAmbientLuxAfterWarmUpConfig;

    // Period of time in which to consider light samples in milliseconds.
    private final int mAmbientLightHorizon;

    // The intercept used for the weighting calculation. This is used in order to keep all possible
    // weighting values positive.
    private final int mWeightingIntercept;

    // Amount of time to delay auto-brightness after screen on while waiting for
    // the light sensor to warm-up in milliseconds.
    // May be 0 if no warm-up is required.
@@ -179,6 +175,10 @@ class AutomaticBrightnessController {
    // The screen auto-brightness adjustment factor in the range -1 (dimmer) to 1 (brighter)
    private float mScreenAutoBrightnessAdjustment = 0.0f;

    // The maximum range of gamma adjustment possible using the screen
    // auto-brightness adjustment setting.
    private float mScreenAutoBrightnessAdjustmentMaxGamma;

    // The last screen auto-brightness gamma.  (For printing in dump() only.)
    private float mLastScreenAutoBrightnessGamma = 1.0f;

@@ -197,7 +197,8 @@ class AutomaticBrightnessController {
            SensorManager sensorManager, Spline autoBrightnessSpline, int lightSensorWarmUpTime,
            int brightnessMin, int brightnessMax, float dozeScaleFactor,
            int lightSensorRate, long brighteningLightDebounceConfig,
            long darkeningLightDebounceConfig, boolean resetAmbientLuxAfterWarmUpConfig) {
            long darkeningLightDebounceConfig, boolean resetAmbientLuxAfterWarmUpConfig,
            int ambientLightHorizon, float autoBrightnessAdjustmentMaxGamma ) {
        mCallbacks = callbacks;
        mTwilight = LocalServices.getService(TwilightManager.class);
        mSensorManager = sensorManager;
@@ -210,9 +211,12 @@ class AutomaticBrightnessController {
        mBrighteningLightDebounceConfig = brighteningLightDebounceConfig;
        mDarkeningLightDebounceConfig = darkeningLightDebounceConfig;
        mResetAmbientLuxAfterWarmUpConfig = resetAmbientLuxAfterWarmUpConfig;
        mAmbientLightHorizon = ambientLightHorizon;
        mWeightingIntercept = ambientLightHorizon;
        mScreenAutoBrightnessAdjustmentMaxGamma = autoBrightnessAdjustmentMaxGamma;

        mHandler = new AutomaticBrightnessHandler(looper);
        mAmbientLightRingBuffer = new AmbientLightRingBuffer(mLightSensorRate);
        mAmbientLightRingBuffer = new AmbientLightRingBuffer(mLightSensorRate, mAmbientLightHorizon);

        if (!DEBUG_PRETEND_LIGHT_SENSOR_ABSENT) {
            mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
@@ -266,6 +270,7 @@ class AutomaticBrightnessController {
        pw.println("  mLightSensorEnabled=" + mLightSensorEnabled);
        pw.println("  mLightSensorEnableTime=" + TimeUtils.formatUptime(mLightSensorEnableTime));
        pw.println("  mAmbientLux=" + mAmbientLux);
        pw.println("  mAmbientLightHorizon=" + mAmbientLightHorizon);
        pw.println("  mBrighteningLuxThreshold=" + mBrighteningLuxThreshold);
        pw.println("  mDarkeningLuxThreshold=" + mDarkeningLuxThreshold);
        pw.println("  mLastObservedLux=" + mLastObservedLux);
@@ -274,6 +279,7 @@ class AutomaticBrightnessController {
        pw.println("  mAmbientLightRingBuffer=" + mAmbientLightRingBuffer);
        pw.println("  mScreenAutoBrightness=" + mScreenAutoBrightness);
        pw.println("  mScreenAutoBrightnessAdjustment=" + mScreenAutoBrightnessAdjustment);
        pw.println("  mScreenAutoBrightnessAdjustmentMaxGamma=" + mScreenAutoBrightnessAdjustmentMaxGamma);
        pw.println("  mLastScreenAutoBrightnessGamma=" + mLastScreenAutoBrightnessGamma);
        pw.println("  mDozing=" + mDozing);
    }
@@ -309,7 +315,7 @@ class AutomaticBrightnessController {

    private void applyLightSensorMeasurement(long time, float lux) {
        mRecentLightSamples++;
        mAmbientLightRingBuffer.prune(time - AMBIENT_LIGHT_HORIZON);
        mAmbientLightRingBuffer.prune(time - mAmbientLightHorizon);
        mAmbientLightRingBuffer.push(time, lux);

        // Remember this sample value.
@@ -360,14 +366,14 @@ class AutomaticBrightnessController {
        return sum / totalWeight;
    }

    private static float calculateWeight(long startDelta, long endDelta) {
    private float calculateWeight(long startDelta, long endDelta) {
        return weightIntegral(endDelta) - weightIntegral(startDelta);
    }

    // Evaluates the integral of y = x + WEIGHTING_INTERCEPT. This is always positive for the
    // Evaluates the integral of y = x + mWeightingIntercept. This is always positive for the
    // horizon we're looking at and provides a non-linear weighting for light samples.
    private static float weightIntegral(long x) {
        return x * (x * 0.5f + WEIGHTING_INTERCEPT);
    private float weightIntegral(long x) {
        return x * (x * 0.5f + mWeightingIntercept);
    }

    private long nextAmbientLightBrighteningTransition(long time) {
@@ -396,7 +402,7 @@ class AutomaticBrightnessController {

    private void updateAmbientLux() {
        long time = SystemClock.uptimeMillis();
        mAmbientLightRingBuffer.prune(time - AMBIENT_LIGHT_HORIZON);
        mAmbientLightRingBuffer.prune(time - mAmbientLightHorizon);
        updateAmbientLux(time);
    }

@@ -470,7 +476,7 @@ class AutomaticBrightnessController {

        if (USE_SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT
                && mScreenAutoBrightnessAdjustment != 0.0f) {
            final float adjGamma = MathUtils.pow(SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT_MAX_GAMMA,
            final float adjGamma = MathUtils.pow(mScreenAutoBrightnessAdjustmentMaxGamma,
                    Math.min(1.0f, Math.max(-1.0f, -mScreenAutoBrightnessAdjustment)));
            gamma *= adjGamma;
            if (DEBUG) {
@@ -653,8 +659,8 @@ class AutomaticBrightnessController {
        private int mEnd;
        private int mCount;

        public AmbientLightRingBuffer(long lightSensorRate) {
            mCapacity = (int) Math.ceil(AMBIENT_LIGHT_HORIZON * BUFFER_SLACK / lightSensorRate);
        public AmbientLightRingBuffer(long lightSensorRate, int ambientLightHorizon) {
            mCapacity = (int) Math.ceil(ambientLightHorizon * BUFFER_SLACK / lightSensorRate);
            mRingLux = new float[mCapacity];
            mRingTime = new long[mCapacity];
        }
+7 −1
Original line number Diff line number Diff line
@@ -311,6 +311,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
                com.android.internal.R.integer.config_autoBrightnessDarkeningLightDebounce);
        boolean autoBrightnessResetAmbientLuxAfterWarmUp = resources.getBoolean(
                com.android.internal.R.bool.config_autoBrightnessResetAmbientLuxAfterWarmUp);
        int ambientLightHorizon = resources.getInteger(
                com.android.internal.R.integer.config_autoBrightnessAmbientLightHorizon);
        float autoBrightnessAdjustmentMaxGamma = resources.getFraction(
                com.android.internal.R.fraction.config_autoBrightnessAdjustmentMaxGamma,
                1, 1);

        if (mUseSoftwareAutoBrightnessConfig) {
            int[] lux = resources.getIntArray(
@@ -348,7 +353,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
                        lightSensorWarmUpTimeConfig, screenBrightnessRangeMinimum,
                        mScreenBrightnessRangeMaximum, dozeScaleFactor, lightSensorRate,
                        brighteningLightDebounce, darkeningLightDebounce,
                        autoBrightnessResetAmbientLuxAfterWarmUp);
                        autoBrightnessResetAmbientLuxAfterWarmUp,
                        ambientLightHorizon, autoBrightnessAdjustmentMaxGamma);
            }
        }