Add ambientLightHorizon to DDC
Add ambientLightHorizonLong and ambientLightHorizonShort to the DisplayDeviceConfig. These values were previously hardcoded, we can now adjust them per display. The fallback is still the original hardcoded value. Bug: 204251622 Test: adb shell dumpsys display | grep -i horizon Test: atest AutomaticBrightnessControllerTest Change-Id: Id6960c8117c4c981f74f883af35b2f8fbf171367
This commit is contained in:
@@ -70,13 +70,6 @@ class AutomaticBrightnessController {
|
||||
private static final int MSG_UPDATE_FOREGROUND_APP_SYNC = 5;
|
||||
private static final int MSG_RUN_UPDATE = 6;
|
||||
|
||||
// Length of the ambient light horizon used to calculate the long term estimate of ambient
|
||||
// light.
|
||||
private static final int AMBIENT_LIGHT_LONG_HORIZON_MILLIS = 10000;
|
||||
|
||||
// Length of the ambient light horizon used to calculate short-term estimate of ambient light.
|
||||
private static final int AMBIENT_LIGHT_SHORT_HORIZON_MILLIS = 2000;
|
||||
|
||||
// Callbacks for requesting updates to the display's power state
|
||||
private final Callbacks mCallbacks;
|
||||
|
||||
@@ -121,8 +114,10 @@ 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;
|
||||
// Period of time in which to consider light samples for a short/long-term estimate of ambient
|
||||
// light in milliseconds.
|
||||
private final int mAmbientLightHorizonLong;
|
||||
private final int mAmbientLightHorizonShort;
|
||||
|
||||
// The intercept used for the weighting calculation. This is used in order to keep all possible
|
||||
// weighting values positive.
|
||||
@@ -215,6 +210,7 @@ class AutomaticBrightnessController {
|
||||
private PackageManager mPackageManager;
|
||||
private Context mContext;
|
||||
|
||||
private Clock mClock;
|
||||
private final Injector mInjector;
|
||||
|
||||
AutomaticBrightnessController(Callbacks callbacks, Looper looper,
|
||||
@@ -226,14 +222,16 @@ class AutomaticBrightnessController {
|
||||
boolean resetAmbientLuxAfterWarmUpConfig, HysteresisLevels ambientBrightnessThresholds,
|
||||
HysteresisLevels screenBrightnessThresholds, Context context,
|
||||
HighBrightnessModeController hbmController,
|
||||
BrightnessMappingStrategy idleModeBrightnessMapper) {
|
||||
BrightnessMappingStrategy idleModeBrightnessMapper, int ambientLightHorizonShort,
|
||||
int ambientLightHorizonLong) {
|
||||
this(new Injector(), callbacks, looper, sensorManager, lightSensor,
|
||||
interactiveModeBrightnessMapper,
|
||||
lightSensorWarmUpTime, brightnessMin, brightnessMax, dozeScaleFactor,
|
||||
lightSensorRate, initialLightSensorRate, brighteningLightDebounceConfig,
|
||||
darkeningLightDebounceConfig, resetAmbientLuxAfterWarmUpConfig,
|
||||
ambientBrightnessThresholds, screenBrightnessThresholds, context,
|
||||
hbmController, idleModeBrightnessMapper
|
||||
hbmController, idleModeBrightnessMapper, ambientLightHorizonShort,
|
||||
ambientLightHorizonLong
|
||||
);
|
||||
}
|
||||
|
||||
@@ -247,8 +245,10 @@ class AutomaticBrightnessController {
|
||||
boolean resetAmbientLuxAfterWarmUpConfig, HysteresisLevels ambientBrightnessThresholds,
|
||||
HysteresisLevels screenBrightnessThresholds, Context context,
|
||||
HighBrightnessModeController hbmController,
|
||||
BrightnessMappingStrategy idleModeBrightnessMapper) {
|
||||
BrightnessMappingStrategy idleModeBrightnessMapper, int ambientLightHorizonShort,
|
||||
int ambientLightHorizonLong) {
|
||||
mInjector = injector;
|
||||
mClock = injector.createClock();
|
||||
mContext = context;
|
||||
mCallbacks = callbacks;
|
||||
mSensorManager = sensorManager;
|
||||
@@ -263,15 +263,16 @@ class AutomaticBrightnessController {
|
||||
mBrighteningLightDebounceConfig = brighteningLightDebounceConfig;
|
||||
mDarkeningLightDebounceConfig = darkeningLightDebounceConfig;
|
||||
mResetAmbientLuxAfterWarmUpConfig = resetAmbientLuxAfterWarmUpConfig;
|
||||
mAmbientLightHorizon = AMBIENT_LIGHT_LONG_HORIZON_MILLIS;
|
||||
mWeightingIntercept = AMBIENT_LIGHT_LONG_HORIZON_MILLIS;
|
||||
mAmbientLightHorizonLong = ambientLightHorizonLong;
|
||||
mAmbientLightHorizonShort = ambientLightHorizonShort;
|
||||
mWeightingIntercept = ambientLightHorizonLong;
|
||||
mAmbientBrightnessThresholds = ambientBrightnessThresholds;
|
||||
mScreenBrightnessThresholds = screenBrightnessThresholds;
|
||||
mShortTermModelValid = true;
|
||||
mShortTermModelAnchor = -1;
|
||||
mHandler = new AutomaticBrightnessHandler(looper);
|
||||
mAmbientLightRingBuffer =
|
||||
new AmbientLightRingBuffer(mNormalLightSensorRate, mAmbientLightHorizon);
|
||||
new AmbientLightRingBuffer(mNormalLightSensorRate, mAmbientLightHorizonLong, mClock);
|
||||
|
||||
if (!DEBUG_PRETEND_LIGHT_SENSOR_ABSENT) {
|
||||
mLightSensor = lightSensor;
|
||||
@@ -390,6 +391,11 @@ class AutomaticBrightnessController {
|
||||
mHandler.sendEmptyMessage(MSG_RUN_UPDATE);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
float getAmbientLux() {
|
||||
return mAmbientLux;
|
||||
}
|
||||
|
||||
private boolean setDisplayPolicy(int policy) {
|
||||
if (mDisplayPolicy == policy) {
|
||||
return false;
|
||||
@@ -468,7 +474,8 @@ class AutomaticBrightnessController {
|
||||
pw.println(" mBrighteningLightDebounceConfig=" + mBrighteningLightDebounceConfig);
|
||||
pw.println(" mDarkeningLightDebounceConfig=" + mDarkeningLightDebounceConfig);
|
||||
pw.println(" mResetAmbientLuxAfterWarmUpConfig=" + mResetAmbientLuxAfterWarmUpConfig);
|
||||
pw.println(" mAmbientLightHorizon=" + mAmbientLightHorizon);
|
||||
pw.println(" mAmbientLightHorizonLong=" + mAmbientLightHorizonLong);
|
||||
pw.println(" mAmbientLightHorizonShort=" + mAmbientLightHorizonShort);
|
||||
pw.println(" mWeightingIntercept=" + mWeightingIntercept);
|
||||
|
||||
pw.println();
|
||||
@@ -524,7 +531,7 @@ class AutomaticBrightnessController {
|
||||
if (enable) {
|
||||
if (!mLightSensorEnabled) {
|
||||
mLightSensorEnabled = true;
|
||||
mLightSensorEnableTime = SystemClock.uptimeMillis();
|
||||
mLightSensorEnableTime = mClock.uptimeMillis();
|
||||
mCurrentLightSensorRate = mInitialLightSensorRate;
|
||||
registerForegroundAppUpdater();
|
||||
mSensorManager.registerListener(mLightSensorListener, mLightSensor,
|
||||
@@ -559,7 +566,7 @@ class AutomaticBrightnessController {
|
||||
|
||||
private void applyLightSensorMeasurement(long time, float lux) {
|
||||
mRecentLightSamples++;
|
||||
mAmbientLightRingBuffer.prune(time - mAmbientLightHorizon);
|
||||
mAmbientLightRingBuffer.prune(time - mAmbientLightHorizonLong);
|
||||
mAmbientLightRingBuffer.push(time, lux);
|
||||
|
||||
// Remember this sample value.
|
||||
@@ -700,8 +707,8 @@ class AutomaticBrightnessController {
|
||||
}
|
||||
|
||||
private void updateAmbientLux() {
|
||||
long time = SystemClock.uptimeMillis();
|
||||
mAmbientLightRingBuffer.prune(time - mAmbientLightHorizon);
|
||||
long time = mClock.uptimeMillis();
|
||||
mAmbientLightRingBuffer.prune(time - mAmbientLightHorizonLong);
|
||||
updateAmbientLux(time);
|
||||
}
|
||||
|
||||
@@ -721,7 +728,7 @@ class AutomaticBrightnessController {
|
||||
timeWhenSensorWarmedUp);
|
||||
return;
|
||||
}
|
||||
setAmbientLux(calculateAmbientLux(time, AMBIENT_LIGHT_SHORT_HORIZON_MILLIS));
|
||||
setAmbientLux(calculateAmbientLux(time, mAmbientLightHorizonShort));
|
||||
mAmbientLuxValid = true;
|
||||
if (mLoggingEnabled) {
|
||||
Slog.d(TAG, "updateAmbientLux: Initializing: " +
|
||||
@@ -741,8 +748,8 @@ class AutomaticBrightnessController {
|
||||
// proposed ambient light value since the slow value might be sufficiently far enough away
|
||||
// from the fast value to cause a recalculation while its actually just converging on
|
||||
// the fast value still.
|
||||
float slowAmbientLux = calculateAmbientLux(time, AMBIENT_LIGHT_LONG_HORIZON_MILLIS);
|
||||
float fastAmbientLux = calculateAmbientLux(time, AMBIENT_LIGHT_SHORT_HORIZON_MILLIS);
|
||||
float slowAmbientLux = calculateAmbientLux(time, mAmbientLightHorizonLong);
|
||||
float fastAmbientLux = calculateAmbientLux(time, mAmbientLightHorizonShort);
|
||||
|
||||
if ((slowAmbientLux >= mAmbientBrighteningThreshold
|
||||
&& fastAmbientLux >= mAmbientBrighteningThreshold
|
||||
@@ -1023,7 +1030,7 @@ class AutomaticBrightnessController {
|
||||
@Override
|
||||
public void onSensorChanged(SensorEvent event) {
|
||||
if (mLightSensorEnabled) {
|
||||
final long time = SystemClock.uptimeMillis();
|
||||
final long time = mClock.uptimeMillis();
|
||||
final float lux = event.values[0];
|
||||
handleLightSensorEvent(time, lux);
|
||||
}
|
||||
@@ -1049,6 +1056,15 @@ class AutomaticBrightnessController {
|
||||
void updateBrightness();
|
||||
}
|
||||
|
||||
/** Functional interface for providing time. */
|
||||
@VisibleForTesting
|
||||
interface Clock {
|
||||
/**
|
||||
* Returns current time in milliseconds since boot, not counting time spent in deep sleep.
|
||||
*/
|
||||
long uptimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* A ring buffer of ambient light measurements sorted by time.
|
||||
*
|
||||
@@ -1068,14 +1084,16 @@ class AutomaticBrightnessController {
|
||||
private int mStart;
|
||||
private int mEnd;
|
||||
private int mCount;
|
||||
Clock mClock;
|
||||
|
||||
public AmbientLightRingBuffer(long lightSensorRate, int ambientLightHorizon) {
|
||||
public AmbientLightRingBuffer(long lightSensorRate, int ambientLightHorizon, Clock clock) {
|
||||
if (lightSensorRate <= 0) {
|
||||
throw new IllegalArgumentException("lightSensorRate must be above 0");
|
||||
}
|
||||
mCapacity = (int) Math.ceil(ambientLightHorizon * BUFFER_SLACK / lightSensorRate);
|
||||
mRingLux = new float[mCapacity];
|
||||
mRingTime = new long[mCapacity];
|
||||
mClock = clock;
|
||||
}
|
||||
|
||||
public float getLux(int index) {
|
||||
@@ -1160,7 +1178,7 @@ class AutomaticBrightnessController {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append('[');
|
||||
for (int i = 0; i < mCount; i++) {
|
||||
final long next = i + 1 < mCount ? getTime(i + 1) : SystemClock.uptimeMillis();
|
||||
final long next = i + 1 < mCount ? getTime(i + 1) : mClock.uptimeMillis();
|
||||
if (i != 0) {
|
||||
buf.append(", ");
|
||||
}
|
||||
@@ -1189,5 +1207,9 @@ class AutomaticBrightnessController {
|
||||
public Handler getBackgroundThreadHandler() {
|
||||
return BackgroundThread.getHandler();
|
||||
}
|
||||
|
||||
Clock createClock() {
|
||||
return SystemClock::uptimeMillis;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
@@ -86,6 +87,13 @@ public class DisplayDeviceConfig {
|
||||
|
||||
private static final float NITS_INVALID = -1;
|
||||
|
||||
// Length of the ambient light horizon used to calculate the long term estimate of ambient
|
||||
// light.
|
||||
private static final int AMBIENT_LIGHT_LONG_HORIZON_MILLIS = 10000;
|
||||
|
||||
// Length of the ambient light horizon used to calculate short-term estimate of ambient light.
|
||||
private static final int AMBIENT_LIGHT_SHORT_HORIZON_MILLIS = 2000;
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
// The details of the ambient light sensor associated with this display.
|
||||
@@ -120,6 +128,8 @@ public class DisplayDeviceConfig {
|
||||
private float mBrightnessRampFastIncrease = Float.NaN;
|
||||
private float mBrightnessRampSlowDecrease = Float.NaN;
|
||||
private float mBrightnessRampSlowIncrease = Float.NaN;
|
||||
private int mAmbientHorizonLong = AMBIENT_LIGHT_LONG_HORIZON_MILLIS;
|
||||
private int mAmbientHorizonShort = AMBIENT_LIGHT_SHORT_HORIZON_MILLIS;
|
||||
private Spline mBrightnessToBacklightSpline;
|
||||
private Spline mBacklightToBrightnessSpline;
|
||||
private Spline mBacklightToNitsSpline;
|
||||
@@ -346,6 +356,14 @@ public class DisplayDeviceConfig {
|
||||
return mBrightnessRampSlowIncrease;
|
||||
}
|
||||
|
||||
public int getAmbientHorizonLong() {
|
||||
return mAmbientHorizonLong;
|
||||
}
|
||||
|
||||
public int getAmbientHorizonShort() {
|
||||
return mAmbientHorizonShort;
|
||||
}
|
||||
|
||||
SensorData getAmbientLightSensor() {
|
||||
return mAmbientLightSensor;
|
||||
}
|
||||
@@ -405,6 +423,8 @@ public class DisplayDeviceConfig {
|
||||
+ ", mBrightnessRampFastIncrease=" + mBrightnessRampFastIncrease
|
||||
+ ", mBrightnessRampSlowDecrease=" + mBrightnessRampSlowDecrease
|
||||
+ ", mBrightnessRampSlowIncrease=" + mBrightnessRampSlowIncrease
|
||||
+ ", mAmbientHorizonLong=" + mAmbientHorizonLong
|
||||
+ ", mAmbientHorizonShort=" + mAmbientHorizonShort
|
||||
+ ", mAmbientLightSensor=" + mAmbientLightSensor
|
||||
+ ", mProximitySensor=" + mProximitySensor
|
||||
+ ", mRefreshRateLimitations= " + Arrays.toString(mRefreshRateLimitations.toArray())
|
||||
@@ -461,6 +481,7 @@ public class DisplayDeviceConfig {
|
||||
loadBrightnessRamps(config);
|
||||
loadAmbientLightSensorFromDdc(config);
|
||||
loadProxSensorFromDdc(config);
|
||||
loadAmbientHorizonFromDdc(config);
|
||||
} else {
|
||||
Slog.w(TAG, "DisplayDeviceConfig file is null");
|
||||
}
|
||||
@@ -869,6 +890,17 @@ public class DisplayDeviceConfig {
|
||||
}
|
||||
}
|
||||
|
||||
private void loadAmbientHorizonFromDdc(DisplayConfiguration config) {
|
||||
final BigInteger configLongHorizon = config.getAmbientLightHorizonLong();
|
||||
if (configLongHorizon != null) {
|
||||
mAmbientHorizonLong = configLongHorizon.intValue();
|
||||
}
|
||||
final BigInteger configShortHorizon = config.getAmbientLightHorizonShort();
|
||||
if (configShortHorizon != null) {
|
||||
mAmbientHorizonShort = configShortHorizon.intValue();
|
||||
}
|
||||
}
|
||||
|
||||
static class SensorData {
|
||||
public String type;
|
||||
public String name;
|
||||
|
||||
@@ -946,7 +946,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
lightSensorRate, initialLightSensorRate, brighteningLightDebounce,
|
||||
darkeningLightDebounce, autoBrightnessResetAmbientLuxAfterWarmUp,
|
||||
ambientBrightnessThresholds, screenBrightnessThresholds, mContext,
|
||||
mHbmController, mIdleModeBrightnessMapper);
|
||||
mHbmController, mIdleModeBrightnessMapper,
|
||||
mDisplayDeviceConfig.getAmbientHorizonShort(),
|
||||
mDisplayDeviceConfig.getAmbientHorizonLong());
|
||||
} else {
|
||||
mUseSoftwareAutoBrightnessConfig = false;
|
||||
}
|
||||
|
||||
@@ -58,6 +58,15 @@
|
||||
<xs:element type="sensorDetails" name="proxSensor">
|
||||
<xs:annotation name="final"/>
|
||||
</xs:element>
|
||||
|
||||
<!-- Length of the ambient light horizon used to calculate the long & short term
|
||||
estimates of ambient light in milliseconds.-->
|
||||
<xs:element type="xs:nonNegativeInteger" name="ambientLightHorizonLong">
|
||||
<xs:annotation name="final"/>
|
||||
</xs:element>
|
||||
<xs:element type="xs:nonNegativeInteger" name="ambientLightHorizonShort">
|
||||
<xs:annotation name="final"/>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
@@ -18,6 +18,8 @@ package com.android.server.display.config {
|
||||
|
||||
public class DisplayConfiguration {
|
||||
ctor public DisplayConfiguration();
|
||||
method public final java.math.BigInteger getAmbientLightHorizonLong();
|
||||
method public final java.math.BigInteger getAmbientLightHorizonShort();
|
||||
method @Nullable public final com.android.server.display.config.DensityMap getDensityMap();
|
||||
method public com.android.server.display.config.HighBrightnessMode getHighBrightnessMode();
|
||||
method public final com.android.server.display.config.SensorDetails getLightSensor();
|
||||
@@ -29,6 +31,8 @@ package com.android.server.display.config {
|
||||
method public final java.math.BigDecimal getScreenBrightnessRampFastIncrease();
|
||||
method public final java.math.BigDecimal getScreenBrightnessRampSlowDecrease();
|
||||
method public final java.math.BigDecimal getScreenBrightnessRampSlowIncrease();
|
||||
method public final void setAmbientLightHorizonLong(java.math.BigInteger);
|
||||
method public final void setAmbientLightHorizonShort(java.math.BigInteger);
|
||||
method public final void setDensityMap(@Nullable com.android.server.display.config.DensityMap);
|
||||
method public void setHighBrightnessMode(com.android.server.display.config.HighBrightnessMode);
|
||||
method public final void setLightSensor(com.android.server.display.config.SensorDetails);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.server.display;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.anyFloat;
|
||||
@@ -32,18 +33,22 @@ import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
|
||||
import android.os.Handler;
|
||||
import android.os.test.TestLooper;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.server.testutils.OffsettableClock;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@SmallTest
|
||||
@@ -59,7 +64,11 @@ public class AutomaticBrightnessControllerTest {
|
||||
private static final float DOZE_SCALE_FACTOR = 0.0f;
|
||||
private static final boolean RESET_AMBIENT_LUX_AFTER_WARMUP_CONFIG = false;
|
||||
private static final int LIGHT_SENSOR_WARMUP_TIME = 0;
|
||||
|
||||
private static final int AMBIENT_LIGHT_HORIZON_SHORT = 1000;
|
||||
private static final int AMBIENT_LIGHT_HORIZON_LONG = 2000;
|
||||
private static final float EPSILON = 0.001f;
|
||||
private OffsettableClock mClock = new OffsettableClock();
|
||||
private TestLooper mTestLooper;
|
||||
private Context mContext;
|
||||
private AutomaticBrightnessController mController;
|
||||
|
||||
@@ -89,21 +98,36 @@ public class AutomaticBrightnessControllerTest {
|
||||
}
|
||||
}
|
||||
|
||||
private void advanceTime(long timeMs) {
|
||||
mClock.fastForward(timeMs);
|
||||
mTestLooper.dispatchAll();
|
||||
}
|
||||
|
||||
private AutomaticBrightnessController setupController(Sensor lightSensor) {
|
||||
mClock = new OffsettableClock.Stopped();
|
||||
mTestLooper = new TestLooper(mClock::now);
|
||||
|
||||
AutomaticBrightnessController controller = new AutomaticBrightnessController(
|
||||
new AutomaticBrightnessController.Injector() {
|
||||
@Override
|
||||
public Handler getBackgroundThreadHandler() {
|
||||
return mNoOpHandler;
|
||||
}
|
||||
},
|
||||
() -> { }, mContext.getMainLooper(), mSensorManager, lightSensor,
|
||||
|
||||
@Override
|
||||
AutomaticBrightnessController.Clock createClock() {
|
||||
return mClock::now;
|
||||
}
|
||||
|
||||
}, // pass in test looper instead, pass in offsetable clock
|
||||
() -> { }, mTestLooper.getLooper(), mSensorManager, lightSensor,
|
||||
mBrightnessMappingStrategy, LIGHT_SENSOR_WARMUP_TIME, BRIGHTNESS_MIN_FLOAT,
|
||||
BRIGHTNESS_MAX_FLOAT, DOZE_SCALE_FACTOR, LIGHT_SENSOR_RATE,
|
||||
INITIAL_LIGHT_SENSOR_RATE, BRIGHTENING_LIGHT_DEBOUNCE_CONFIG,
|
||||
DARKENING_LIGHT_DEBOUNCE_CONFIG, RESET_AMBIENT_LUX_AFTER_WARMUP_CONFIG,
|
||||
mAmbientBrightnessThresholds, mScreenBrightnessThresholds,
|
||||
mContext, mHbmController, mIdleBrightnessMappingStrategy
|
||||
mContext, mHbmController, mIdleBrightnessMappingStrategy,
|
||||
AMBIENT_LIGHT_HORIZON_SHORT, AMBIENT_LIGHT_HORIZON_LONG
|
||||
);
|
||||
|
||||
when(mHbmController.getCurrentBrightnessMax()).thenReturn(BRIGHTNESS_MAX_FLOAT);
|
||||
@@ -274,4 +298,95 @@ public class AutomaticBrightnessControllerTest {
|
||||
// Ensure we use the correct mapping strategy
|
||||
verify(mIdleBrightnessMappingStrategy, times(1)).addUserDataPoint(1000f, 0.5f);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAmbientLightHorizon() throws Exception {
|
||||
// create abc
|
||||
Sensor lightSensor = TestUtils.createSensor(Sensor.TYPE_LIGHT, "Light Sensor");
|
||||
mController = setupController(lightSensor);
|
||||
ArgumentCaptor<SensorEventListener> listenerCaptor =
|
||||
ArgumentCaptor.forClass(SensorEventListener.class);
|
||||
verify(mSensorManager).registerListener(listenerCaptor.capture(), eq(lightSensor),
|
||||
eq(INITIAL_LIGHT_SENSOR_RATE * 1000), any(Handler.class));
|
||||
SensorEventListener listener = listenerCaptor.getValue();
|
||||
|
||||
long increment = 500;
|
||||
// set autobrightness to low
|
||||
// t = 0
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 0));
|
||||
|
||||
// t = 500
|
||||
mClock.fastForward(increment);
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 0));
|
||||
|
||||
// t = 1000
|
||||
mClock.fastForward(increment);
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 0));
|
||||
assertEquals(0.0f, mController.getAmbientLux(), EPSILON);
|
||||
|
||||
// t = 1500
|
||||
mClock.fastForward(increment);
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 0));
|
||||
assertEquals(0.0f, mController.getAmbientLux(), EPSILON);
|
||||
|
||||
// t = 2000
|
||||
// ensure that our reading is at 0.
|
||||
mClock.fastForward(increment);
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 0));
|
||||
assertEquals(0.0f, mController.getAmbientLux(), EPSILON);
|
||||
|
||||
// t = 2500
|
||||
// first 10000 lux sensor event reading
|
||||
mClock.fastForward(increment);
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 10000));
|
||||
assertTrue(mController.getAmbientLux() > 0.0f);
|
||||
assertTrue(mController.getAmbientLux() < 10000.0f);
|
||||
|
||||
// t = 3000
|
||||
// lux reading should still not yet be 10000.
|
||||
mClock.fastForward(increment);
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 10000));
|
||||
assertTrue(mController.getAmbientLux() > 0.0f);
|
||||
assertTrue(mController.getAmbientLux() < 10000.0f);
|
||||
|
||||
// t = 3500
|
||||
mClock.fastForward(increment);
|
||||
// lux has been high (10000) for 1000ms.
|
||||
// lux reading should be 10000
|
||||
// short horizon (ambient lux) is high, long horizon is still not high
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 10000));
|
||||
assertEquals(10000.0f, mController.getAmbientLux(), EPSILON);
|
||||
|
||||
// t = 4000
|
||||
// stay high
|
||||
mClock.fastForward(increment);
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 10000));
|
||||
assertEquals(10000.0f, mController.getAmbientLux(), EPSILON);
|
||||
|
||||
// t = 4500
|
||||
Mockito.clearInvocations(mBrightnessMappingStrategy);
|
||||
mClock.fastForward(increment);
|
||||
// short horizon is high, long horizon is high too
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 10000));
|
||||
verify(mBrightnessMappingStrategy, times(1)).getBrightness(10000, null, -1);
|
||||
assertEquals(10000.0f, mController.getAmbientLux(), EPSILON);
|
||||
|
||||
// t = 5000
|
||||
mClock.fastForward(increment);
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 0));
|
||||
assertTrue(mController.getAmbientLux() > 0.0f);
|
||||
assertTrue(mController.getAmbientLux() < 10000.0f);
|
||||
|
||||
// t = 5500
|
||||
mClock.fastForward(increment);
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 0));
|
||||
assertTrue(mController.getAmbientLux() > 0.0f);
|
||||
assertTrue(mController.getAmbientLux() < 10000.0f);
|
||||
|
||||
// t = 6000
|
||||
mClock.fastForward(increment);
|
||||
// ambient lux goes to 0
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, 0));
|
||||
assertEquals(0.0f, mController.getAmbientLux(), EPSILON);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user