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. -->
|
to reduce it to preserve the battery. Value of 100% means no scaling. -->
|
||||||
<fraction name="config_screenAutoBrightnessDozeScaleFactor">100%</fraction>
|
<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
|
<!-- 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
|
the screen was turned off is restored and is used to determine the initial screen
|
||||||
brightness.
|
brightness.
|
||||||
|
|||||||
@@ -1736,8 +1736,10 @@
|
|||||||
<java-symbol type="dimen" name="default_minimal_size_resizable_task" />
|
<java-symbol type="dimen" name="default_minimal_size_resizable_task" />
|
||||||
<java-symbol type="fraction" name="config_screenAutoBrightnessDozeScaleFactor" />
|
<java-symbol type="fraction" name="config_screenAutoBrightnessDozeScaleFactor" />
|
||||||
<java-symbol type="fraction" name="config_autoBrightnessAdjustmentMaxGamma" />
|
<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_autoBrightnessAmbientLightHorizon"/>
|
||||||
<java-symbol type="integer" name="config_autoBrightnessBrighteningLightDebounce"/>
|
<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_autoBrightnessDarkeningLightDebounce"/>
|
||||||
<java-symbol type="integer" name="config_autoBrightnessInitialLightSensorRate"/>
|
<java-symbol type="integer" name="config_autoBrightnessInitialLightSensorRate"/>
|
||||||
<java-symbol type="integer" name="config_autoBrightnessLightSensorRate"/>
|
<java-symbol type="integer" name="config_autoBrightnessLightSensorRate"/>
|
||||||
|
|||||||
@@ -35,11 +35,13 @@ import android.os.SystemClock;
|
|||||||
import android.text.format.DateUtils;
|
import android.text.format.DateUtils;
|
||||||
import android.util.EventLog;
|
import android.util.EventLog;
|
||||||
import android.util.MathUtils;
|
import android.util.MathUtils;
|
||||||
|
import android.util.Pair;
|
||||||
import android.util.Spline;
|
import android.util.Spline;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.util.TimeUtils;
|
import android.util.TimeUtils;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
import java.util.ArrayDeque;
|
||||||
|
|
||||||
class AutomaticBrightnessController {
|
class AutomaticBrightnessController {
|
||||||
private static final String TAG = "AutomaticBrightnessController";
|
private static final String TAG = "AutomaticBrightnessController";
|
||||||
@@ -111,6 +113,9 @@ class AutomaticBrightnessController {
|
|||||||
// Period of time in which to consider light samples in milliseconds.
|
// Period of time in which to consider light samples in milliseconds.
|
||||||
private final int mAmbientLightHorizon;
|
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
|
// The intercept used for the weighting calculation. This is used in order to keep all possible
|
||||||
// weighting values positive.
|
// weighting values positive.
|
||||||
private final int mWeightingIntercept;
|
private final int mWeightingIntercept;
|
||||||
@@ -139,6 +144,10 @@ class AutomaticBrightnessController {
|
|||||||
private float mBrighteningLuxThreshold;
|
private float mBrighteningLuxThreshold;
|
||||||
private float mDarkeningLuxThreshold;
|
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.
|
// The most recent light sample.
|
||||||
private float mLastObservedLux;
|
private float mLastObservedLux;
|
||||||
|
|
||||||
@@ -148,6 +157,14 @@ class AutomaticBrightnessController {
|
|||||||
// The number of light samples collected since the light sensor was enabled.
|
// The number of light samples collected since the light sensor was enabled.
|
||||||
private int mRecentLightSamples;
|
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.
|
// A ring buffer containing all of the recent ambient light sensor readings.
|
||||||
private AmbientLightRingBuffer mAmbientLightRingBuffer;
|
private AmbientLightRingBuffer mAmbientLightRingBuffer;
|
||||||
|
|
||||||
@@ -203,7 +220,7 @@ class AutomaticBrightnessController {
|
|||||||
long darkeningLightDebounceConfig, boolean resetAmbientLuxAfterWarmUpConfig,
|
long darkeningLightDebounceConfig, boolean resetAmbientLuxAfterWarmUpConfig,
|
||||||
int ambientLightHorizon, float autoBrightnessAdjustmentMaxGamma,
|
int ambientLightHorizon, float autoBrightnessAdjustmentMaxGamma,
|
||||||
boolean activeDozeLightSensor, boolean useNewSensorSamplesForDoze,
|
boolean activeDozeLightSensor, boolean useNewSensorSamplesForDoze,
|
||||||
LuxLevels luxLevels) {
|
float darkHorizonThresholdFactor, int darkAmbientLightHorizon, LuxLevels luxLevels) {
|
||||||
mCallbacks = callbacks;
|
mCallbacks = callbacks;
|
||||||
mTwilight = LocalServices.getService(TwilightManager.class);
|
mTwilight = LocalServices.getService(TwilightManager.class);
|
||||||
mSensorManager = sensorManager;
|
mSensorManager = sensorManager;
|
||||||
@@ -223,6 +240,8 @@ class AutomaticBrightnessController {
|
|||||||
mScreenAutoBrightnessAdjustmentMaxGamma = autoBrightnessAdjustmentMaxGamma;
|
mScreenAutoBrightnessAdjustmentMaxGamma = autoBrightnessAdjustmentMaxGamma;
|
||||||
mUseNewSensorSamplesForDoze = useNewSensorSamplesForDoze;
|
mUseNewSensorSamplesForDoze = useNewSensorSamplesForDoze;
|
||||||
mUseActiveDozeLightSensorConfig = activeDozeLightSensor;
|
mUseActiveDozeLightSensorConfig = activeDozeLightSensor;
|
||||||
|
mDarkHorizonThresholdFactor = darkHorizonThresholdFactor;
|
||||||
|
mDarkAmbientLightHorizon = darkAmbientLightHorizon;
|
||||||
mLuxLevels = luxLevels;
|
mLuxLevels = luxLevels;
|
||||||
|
|
||||||
mHandler = new AutomaticBrightnessHandler(looper);
|
mHandler = new AutomaticBrightnessHandler(looper);
|
||||||
@@ -231,6 +250,10 @@ class AutomaticBrightnessController {
|
|||||||
mInitialHorizonAmbientLightRingBuffer =
|
mInitialHorizonAmbientLightRingBuffer =
|
||||||
new AmbientLightRingBuffer(mNormalLightSensorRate, mAmbientLightHorizon);
|
new AmbientLightRingBuffer(mNormalLightSensorRate, mAmbientLightHorizon);
|
||||||
|
|
||||||
|
mDarkAmbientLightSampleSize =
|
||||||
|
(int) Math.ceil(darkAmbientLightHorizon / mNormalLightSensorRate);
|
||||||
|
mDarkAmbientLightDeque = new ArrayDeque<>();
|
||||||
|
|
||||||
if (!DEBUG_PRETEND_LIGHT_SENSOR_ABSENT) {
|
if (!DEBUG_PRETEND_LIGHT_SENSOR_ABSENT) {
|
||||||
mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
|
mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
|
||||||
}
|
}
|
||||||
@@ -344,6 +367,7 @@ class AutomaticBrightnessController {
|
|||||||
mCurrentLightSensorRate = -1;
|
mCurrentLightSensorRate = -1;
|
||||||
mHandler.removeMessages(MSG_UPDATE_AMBIENT_LUX);
|
mHandler.removeMessages(MSG_UPDATE_AMBIENT_LUX);
|
||||||
mSensorManager.unregisterListener(mLightSensorListener);
|
mSensorManager.unregisterListener(mLightSensorListener);
|
||||||
|
mDarkAmbientLightDeque.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -375,12 +399,41 @@ class AutomaticBrightnessController {
|
|||||||
if (time <= mLightSensorEnableTime + mAmbientLightHorizon) {
|
if (time <= mLightSensorEnableTime + mAmbientLightHorizon) {
|
||||||
mInitialHorizonAmbientLightRingBuffer.push(time, lux);
|
mInitialHorizonAmbientLightRingBuffer.push(time, lux);
|
||||||
}
|
}
|
||||||
mAmbientLightRingBuffer.prune(time - mAmbientLightHorizon);
|
|
||||||
mAmbientLightRingBuffer.push(time, lux);
|
|
||||||
|
|
||||||
// Remember this sample value.
|
// Only consider light samples for the dark light deque when not dozing.
|
||||||
mLastObservedLux = lux;
|
// and once we've collected enough samples regularly.
|
||||||
mLastObservedLuxTime = time;
|
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) {
|
private void adjustLightSensorRate(int lightSensorRate) {
|
||||||
|
|||||||
@@ -363,6 +363,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
|||||||
final float dozeScaleFactor = resources.getFraction(
|
final float dozeScaleFactor = resources.getFraction(
|
||||||
com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor,
|
com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor,
|
||||||
1, 1);
|
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
|
// hysteresis configs
|
||||||
int[] brightHysteresisLevels = resources.getIntArray(
|
int[] brightHysteresisLevels = resources.getIntArray(
|
||||||
@@ -410,7 +415,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
|||||||
initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce,
|
initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce,
|
||||||
autoBrightnessResetAmbientLuxAfterWarmUp, ambientLightHorizon,
|
autoBrightnessResetAmbientLuxAfterWarmUp, ambientLightHorizon,
|
||||||
autoBrightnessAdjustmentMaxGamma, mUseActiveDozeLightSensorConfig,
|
autoBrightnessAdjustmentMaxGamma, mUseActiveDozeLightSensorConfig,
|
||||||
useNewSensorSamplesForDoze, luxLevels);
|
useNewSensorSamplesForDoze, darkHorizonThresholdFactor,
|
||||||
|
darkAmbientLightHorizon, luxLevels);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user