DO NOT MERGE: Add light sample filtering logic for devices with
ambient light sensors that can be regularly obstructed. Bug: 36869173 Change-Id: Ie2a1399c149c87df657b265911a7bb8417a1b8b9
This commit is contained in:
@@ -1079,6 +1079,27 @@
|
||||
to reduce it to preserve the battery. Value of 100% means no scaling. -->
|
||||
<fraction name="config_screenAutoBrightnessDozeScaleFactor">100%</fraction>
|
||||
|
||||
<!-- What percentage of possible ambient light sensor values below the current ambient lux
|
||||
calculation count count as valid samples. If a new lux sample is below
|
||||
(current ambient lux) * (threshold), the light sample is saved in a separate dark light
|
||||
buffer. When enough samples have accumulated continuously based off of the current light
|
||||
sensor rate and config_autoBrightnessDarkAmbientLightHorizon, the current ambient
|
||||
lux and screen brightness are recalculated; otherwise, the dark light buffer is cleared.
|
||||
This is useful for devices where the ambient light sensor can expect regular light
|
||||
obstruction, e.g. if the sensor is under the screen and a finger moves directly over the
|
||||
relevant area.
|
||||
|
||||
This should be used with config_autoBrightnessDarkAmbientLightHorizon set to greater
|
||||
than 0 and set to a value less than 100% to be enabled. -->
|
||||
<fraction name="config_autoBrightnessDarkHorizonThresholdFactor">100%</fraction>
|
||||
|
||||
<!-- The amount of time that the dark light buffer should hold samples for in milliseconds;
|
||||
see the description of config_autoBrightnessDarkHorizonThresholdFactor for details. This
|
||||
should be used with config_autoBrightnessDarkHorizonThresholdFactor.
|
||||
|
||||
Set this to 0 to disable this feature. -->
|
||||
<integer name="config_autoBrightnessDarkAmbientLightHorizon">0</integer>
|
||||
|
||||
<!-- When the screen is turned on, the previous estimate of the ambient light level at the time
|
||||
the screen was turned off is restored and is used to determine the initial screen
|
||||
brightness.
|
||||
|
||||
@@ -1736,8 +1736,10 @@
|
||||
<java-symbol type="dimen" name="default_minimal_size_resizable_task" />
|
||||
<java-symbol type="fraction" name="config_screenAutoBrightnessDozeScaleFactor" />
|
||||
<java-symbol type="fraction" name="config_autoBrightnessAdjustmentMaxGamma" />
|
||||
<java-symbol type="fraction" name="config_autoBrightnessDarkHorizonThresholdFactor" />
|
||||
<java-symbol type="integer" name="config_autoBrightnessAmbientLightHorizon"/>
|
||||
<java-symbol type="integer" name="config_autoBrightnessBrighteningLightDebounce"/>
|
||||
<java-symbol type="integer" name="config_autoBrightnessDarkAmbientLightHorizon"/>
|
||||
<java-symbol type="integer" name="config_autoBrightnessDarkeningLightDebounce"/>
|
||||
<java-symbol type="integer" name="config_autoBrightnessInitialLightSensorRate"/>
|
||||
<java-symbol type="integer" name="config_autoBrightnessLightSensorRate"/>
|
||||
|
||||
@@ -35,11 +35,13 @@ import android.os.SystemClock;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.EventLog;
|
||||
import android.util.MathUtils;
|
||||
import android.util.Pair;
|
||||
import android.util.Spline;
|
||||
import android.util.Slog;
|
||||
import android.util.TimeUtils;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayDeque;
|
||||
|
||||
class AutomaticBrightnessController {
|
||||
private static final String TAG = "AutomaticBrightnessController";
|
||||
@@ -111,6 +113,9 @@ class AutomaticBrightnessController {
|
||||
// Period of time in which to consider light samples in milliseconds.
|
||||
private final int mAmbientLightHorizon;
|
||||
|
||||
// Period of time in which to consider light samples below the current ambient lux threshold.
|
||||
private final int mDarkAmbientLightHorizon;
|
||||
|
||||
// The intercept used for the weighting calculation. This is used in order to keep all possible
|
||||
// weighting values positive.
|
||||
private final int mWeightingIntercept;
|
||||
@@ -139,6 +144,10 @@ class AutomaticBrightnessController {
|
||||
private float mBrighteningLuxThreshold;
|
||||
private float mDarkeningLuxThreshold;
|
||||
|
||||
// The percentage of possible values below the current ambient lux which we put in the dark
|
||||
// ambient light buffer.
|
||||
private final float mDarkHorizonThresholdFactor;
|
||||
|
||||
// The most recent light sample.
|
||||
private float mLastObservedLux;
|
||||
|
||||
@@ -148,6 +157,14 @@ class AutomaticBrightnessController {
|
||||
// The number of light samples collected since the light sensor was enabled.
|
||||
private int mRecentLightSamples;
|
||||
|
||||
// The number of light samples that will be held in the deque before being moved to the
|
||||
// light ring buffer.
|
||||
private int mDarkAmbientLightSampleSize;
|
||||
|
||||
// A deque containing the light sensor readings below the current ambient lux threshold
|
||||
// when the display is not dozing.
|
||||
private ArrayDeque<Pair<Long, Float>> mDarkAmbientLightDeque;
|
||||
|
||||
// A ring buffer containing all of the recent ambient light sensor readings.
|
||||
private AmbientLightRingBuffer mAmbientLightRingBuffer;
|
||||
|
||||
@@ -203,7 +220,7 @@ class AutomaticBrightnessController {
|
||||
long darkeningLightDebounceConfig, boolean resetAmbientLuxAfterWarmUpConfig,
|
||||
int ambientLightHorizon, float autoBrightnessAdjustmentMaxGamma,
|
||||
boolean activeDozeLightSensor, boolean useNewSensorSamplesForDoze,
|
||||
LuxLevels luxLevels) {
|
||||
float darkHorizonThresholdFactor, int darkAmbientLightHorizon, LuxLevels luxLevels) {
|
||||
mCallbacks = callbacks;
|
||||
mTwilight = LocalServices.getService(TwilightManager.class);
|
||||
mSensorManager = sensorManager;
|
||||
@@ -223,6 +240,8 @@ class AutomaticBrightnessController {
|
||||
mScreenAutoBrightnessAdjustmentMaxGamma = autoBrightnessAdjustmentMaxGamma;
|
||||
mUseNewSensorSamplesForDoze = useNewSensorSamplesForDoze;
|
||||
mUseActiveDozeLightSensorConfig = activeDozeLightSensor;
|
||||
mDarkHorizonThresholdFactor = darkHorizonThresholdFactor;
|
||||
mDarkAmbientLightHorizon = darkAmbientLightHorizon;
|
||||
mLuxLevels = luxLevels;
|
||||
|
||||
mHandler = new AutomaticBrightnessHandler(looper);
|
||||
@@ -231,6 +250,10 @@ class AutomaticBrightnessController {
|
||||
mInitialHorizonAmbientLightRingBuffer =
|
||||
new AmbientLightRingBuffer(mNormalLightSensorRate, mAmbientLightHorizon);
|
||||
|
||||
mDarkAmbientLightSampleSize =
|
||||
(int) Math.ceil(darkAmbientLightHorizon / mNormalLightSensorRate);
|
||||
mDarkAmbientLightDeque = new ArrayDeque<>();
|
||||
|
||||
if (!DEBUG_PRETEND_LIGHT_SENSOR_ABSENT) {
|
||||
mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
|
||||
}
|
||||
@@ -344,6 +367,7 @@ class AutomaticBrightnessController {
|
||||
mCurrentLightSensorRate = -1;
|
||||
mHandler.removeMessages(MSG_UPDATE_AMBIENT_LUX);
|
||||
mSensorManager.unregisterListener(mLightSensorListener);
|
||||
mDarkAmbientLightDeque.clear();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -375,12 +399,41 @@ class AutomaticBrightnessController {
|
||||
if (time <= mLightSensorEnableTime + mAmbientLightHorizon) {
|
||||
mInitialHorizonAmbientLightRingBuffer.push(time, lux);
|
||||
}
|
||||
mAmbientLightRingBuffer.prune(time - mAmbientLightHorizon);
|
||||
mAmbientLightRingBuffer.push(time, lux);
|
||||
|
||||
// Remember this sample value.
|
||||
mLastObservedLux = lux;
|
||||
mLastObservedLuxTime = time;
|
||||
// Only consider light samples for the dark light deque when not dozing.
|
||||
// and once we've collected enough samples regularly.
|
||||
if (mDarkAmbientLightHorizon > 0
|
||||
&& !mDozing
|
||||
&& mRecentLightSamples >= mDarkAmbientLightSampleSize
|
||||
&& mAmbientLux * mDarkHorizonThresholdFactor >= lux) {
|
||||
mDarkAmbientLightDeque.addLast(new Pair(time, lux));
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "applyLightSensorMeasurement: light sample filtered to deque: "
|
||||
+ mDarkAmbientLightDeque.size() + " / " + mDarkAmbientLightSampleSize);
|
||||
}
|
||||
if (mDarkAmbientLightSampleSize <= mDarkAmbientLightDeque.size()) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "applyLightSensorMeasurement: moving filtered samples from the "
|
||||
+ "deque to the light ring buffer.");
|
||||
}
|
||||
for (Pair<Long, Float> lightSample : mDarkAmbientLightDeque) {
|
||||
mAmbientLightRingBuffer.push(lightSample.first, lightSample.second);
|
||||
}
|
||||
mDarkAmbientLightDeque.clear();
|
||||
mLastObservedLux = lux;
|
||||
mLastObservedLuxTime = time;
|
||||
updateAmbientLux();
|
||||
}
|
||||
} else {
|
||||
mAmbientLightRingBuffer.prune(time - mAmbientLightHorizon);
|
||||
mAmbientLightRingBuffer.push(time, lux);
|
||||
mDarkAmbientLightDeque.clear();
|
||||
|
||||
// Remember this sample value.
|
||||
mLastObservedLux = lux;
|
||||
mLastObservedLuxTime = time;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void adjustLightSensorRate(int lightSensorRate) {
|
||||
|
||||
@@ -363,6 +363,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
final float dozeScaleFactor = resources.getFraction(
|
||||
com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor,
|
||||
1, 1);
|
||||
final float darkHorizonThresholdFactor = resources.getFraction(
|
||||
com.android.internal.R.fraction.config_autoBrightnessDarkHorizonThresholdFactor,
|
||||
1, 1);
|
||||
final int darkAmbientLightHorizon = resources.getInteger(
|
||||
com.android.internal.R.integer.config_autoBrightnessDarkAmbientLightHorizon);
|
||||
|
||||
// hysteresis configs
|
||||
int[] brightHysteresisLevels = resources.getIntArray(
|
||||
@@ -410,7 +415,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce,
|
||||
autoBrightnessResetAmbientLuxAfterWarmUp, ambientLightHorizon,
|
||||
autoBrightnessAdjustmentMaxGamma, mUseActiveDozeLightSensorConfig,
|
||||
useNewSensorSamplesForDoze, luxLevels);
|
||||
useNewSensorSamplesForDoze, darkHorizonThresholdFactor,
|
||||
darkAmbientLightHorizon, luxLevels);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user