DO NOT MERGE ANYWHERE: Add dynamic illuminance hysteresis support
Bug: 18572096 Change-Id: Ie0ff1990b8f4a3d435328834871f04a6e2bd5e97
This commit is contained in:
@@ -1082,6 +1082,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 -->
|
||||
|
||||
@@ -1607,6 +1607,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" />
|
||||
|
||||
@@ -56,12 +56,6 @@ class AutomaticBrightnessController {
|
||||
// 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;
|
||||
@@ -95,7 +89,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.
|
||||
@@ -132,6 +126,9 @@ class AutomaticBrightnessController {
|
||||
// and only then decide whether to change brightness.
|
||||
private final boolean mResetAmbientLuxAfterWarmUpConfig;
|
||||
|
||||
// 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.
|
||||
@@ -197,7 +194,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,
|
||||
HysteresisLevels dynamicHysteresis) {
|
||||
mCallbacks = callbacks;
|
||||
mTwilight = LocalServices.getService(TwilightManager.class);
|
||||
mSensorManager = sensorManager;
|
||||
@@ -210,6 +208,7 @@ class AutomaticBrightnessController {
|
||||
mBrighteningLightDebounceConfig = brighteningLightDebounceConfig;
|
||||
mDarkeningLightDebounceConfig = darkeningLightDebounceConfig;
|
||||
mResetAmbientLuxAfterWarmUpConfig = resetAmbientLuxAfterWarmUpConfig;
|
||||
mDynamicHysteresis = dynamicHysteresis;
|
||||
|
||||
mHandler = new AutomaticBrightnessHandler(looper);
|
||||
mAmbientLightRingBuffer = new AmbientLightRingBuffer(mLightSensorRate);
|
||||
@@ -327,8 +326,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) {
|
||||
|
||||
@@ -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.
|
||||
@@ -317,6 +317,15 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
boolean autoBrightnessResetAmbientLuxAfterWarmUp = resources.getBoolean(
|
||||
com.android.internal.R.bool.config_autoBrightnessResetAmbientLuxAfterWarmUp);
|
||||
|
||||
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);
|
||||
@@ -353,7 +362,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
lightSensorWarmUpTimeConfig, screenBrightnessRangeMinimum,
|
||||
mScreenBrightnessRangeMaximum, dozeScaleFactor, lightSensorRate,
|
||||
brighteningLightDebounce, darkeningLightDebounce,
|
||||
autoBrightnessResetAmbientLuxAfterWarmUp);
|
||||
autoBrightnessResetAmbientLuxAfterWarmUp, dynamicHysteresis);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user