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

Commit 529beb2c authored by Julius D'souza's avatar Julius D'souza Committed by Android (Google) Code Review
Browse files

Merge "DO NOT MERGE: Add dynamic illuminance hysteresis support" into cw-f-dev

parents b4e27c0d 043a5718
Loading
Loading
Loading
Loading
+34 −0
Original line number Diff line number Diff line
@@ -1132,6 +1132,40 @@
    <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>

    <!-- 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.

         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">
    </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 -->
+3 −0
Original line number Diff line number Diff line
@@ -1639,6 +1639,9 @@
  <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_protectedNetworks" />
  <java-symbol type="array" name="config_statusBarIcons" />
  <java-symbol type="array" name="config_tether_bluetooth_regexs" />
+10 −11
Original line number Diff line number Diff line
@@ -50,12 +50,6 @@ class AutomaticBrightnessController {
    // If true, enables the use of the screen auto-brightness adjustment setting.
    private static final boolean USE_SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT = true;

    // 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;

   // 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.
@@ -71,7 +65,7 @@ class AutomaticBrightnessController {
    private static final int MSG_UPDATE_AMBIENT_LUX = 1;
    private static final int MSG_BRIGHTNESS_ADJUSTMENT_SAMPLE = 2;

    // Callbacks for requesting updates to the the display's power state
    // Callbacks for requesting updates to the display's power state
    private final Callbacks mCallbacks;

    // The sensor manager.
@@ -115,6 +109,9 @@ class AutomaticBrightnessController {
    // weighting values positive.
    private final int mWeightingIntercept;

    // accessor object for determining thresholds to change brightness dynamically
    private final HysteresisLevels mDynamicHysteresis;

    // 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.
@@ -190,7 +187,8 @@ class AutomaticBrightnessController {
            int brightnessMin, int brightnessMax, float dozeScaleFactor,
            int lightSensorRate, long brighteningLightDebounceConfig,
            long darkeningLightDebounceConfig, boolean resetAmbientLuxAfterWarmUpConfig,
            int ambientLightHorizon, float autoBrightnessAdjustmentMaxGamma ) {
            int ambientLightHorizon, float autoBrightnessAdjustmentMaxGamma,
            HysteresisLevels dynamicHysteresis) {
        mCallbacks = callbacks;
        mTwilight = LocalServices.getService(TwilightManager.class);
        mSensorManager = sensorManager;
@@ -206,6 +204,7 @@ class AutomaticBrightnessController {
        mAmbientLightHorizon = ambientLightHorizon;
        mWeightingIntercept = ambientLightHorizon;
        mScreenAutoBrightnessAdjustmentMaxGamma = autoBrightnessAdjustmentMaxGamma;
        mDynamicHysteresis = dynamicHysteresis;

        mHandler = new AutomaticBrightnessHandler(looper);
        mAmbientLightRingBuffer =
@@ -344,8 +343,8 @@ class AutomaticBrightnessController {

    private void setAmbientLux(float lux) {
        mAmbientLux = lux;
        mBrighteningLuxThreshold = mAmbientLux * (1.0f + BRIGHTENING_LIGHT_HYSTERESIS);
        mDarkeningLuxThreshold = mAmbientLux * (1.0f - DARKENING_LIGHT_HYSTERESIS);
        mBrighteningLuxThreshold = mDynamicHysteresis.getBrighteningThreshold(lux);
        mDarkeningLuxThreshold = mDynamicHysteresis.getDarkeningThreshold(lux);
    }

    private float calculateAmbientLux(long now) {
+12 −3
Original line number Diff line number Diff line
@@ -72,7 +72,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
    private static final String TAG = "DisplayPowerController";
    private static final String SCREEN_ON_BLOCKED_TRACE_NAME = "Screen on blocked";

    private static boolean DEBUG = false;
    private static final boolean DEBUG = false;
    private static final boolean DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT = false;

    // If true, uses the color fade on animation.
@@ -322,6 +322,15 @@ 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);
@@ -358,8 +367,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
                        lightSensorWarmUpTimeConfig, screenBrightnessRangeMinimum,
                        mScreenBrightnessRangeMaximum, dozeScaleFactor, lightSensorRate,
                        brighteningLightDebounce, darkeningLightDebounce,
                        autoBrightnessResetAmbientLuxAfterWarmUp,
                        ambientLightHorizon, autoBrightnessAdjustmentMaxGamma);
                        autoBrightnessResetAmbientLuxAfterWarmUp, ambientLightHorizon,
                        autoBrightnessAdjustmentMaxGamma, dynamicHysteresis);
            }
        }

+104 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.display;

import android.util.Slog;

/**
 * A helper class for handling access to illuminance hysteresis level values.
 */
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.
    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;

  /**
   * 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
   */
    public HysteresisLevels(int[] brightLevels, int[] darkLevels, int[] luxLevels) {
        if (brightLevels.length != darkLevels.length || darkLevels.length != luxLevels.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);
    }

    /**
     * Return the brightening hysteresis threshold for the given lux level.
     */
    public float getBrighteningThreshold(float lux) {
        float brightConstant = getReferenceLevel(lux, mBrightLevels);
        float brightThreshold = lux * (1.0f + brightConstant);
        if (DEBUG) {
            Slog.d(TAG, "bright hysteresis constant=: " + brightConstant + ", threshold="
                + brightThreshold + ", lux=" + lux);
        }
        return brightThreshold;
    }

    /**
     * Return the darkening hysteresis threshold for the given lux level.
     */
    public float getDarkeningThreshold(float lux) {
        float darkConstant = getReferenceLevel(lux, mDarkLevels);
        float darkThreshold = lux * (1.0f - darkConstant);
        if (DEBUG) {
            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.
     */
    private float getReferenceLevel(float lux, float[] referenceLevels) {
        int index = 0;
        while (mLuxLevels.length > index && lux >= mLuxLevels[index]) {
            ++index;
        }
        return referenceLevels[index];
    }

    /**
     * Return a float array where each i-th element equals {@code configArray[i]/divideFactor}.
     */
    private float[] setArrayFormat(int[] configArray, float divideFactor) {
        float[] levelArray = new float[configArray.length];
        for (int index = 0; levelArray.length > index; ++index) {
            levelArray[index] = (float)configArray[index] / divideFactor;
        }
        return levelArray;
    }
}