Use a brightness sensor to determine the screen's initial brightness
- Create a controller to listen to a brightness sensor when the screen is off - Estimate the ambient lux based on the sensor reading - Determine the brightness using the ambient lux estimate - Specify the sensor and the sensor value to lux mapping in the config Bug: 193224604 Test: Use the device in a bright room, turn the screen off, go to a dark room, turn the screen on, see that the screen doesn't start as too bright. Test: atest ScreenOffBrightnessSensorControllerTest Test: atest DisplayDeviceConfigTest Change-Id: Ib4c4d9e0d6b385b0d309be6b8c27b71af72d4ecc
This commit is contained in:
@@ -46,6 +46,7 @@ import com.android.server.display.config.DisplayConfiguration;
|
|||||||
import com.android.server.display.config.DisplayQuirks;
|
import com.android.server.display.config.DisplayQuirks;
|
||||||
import com.android.server.display.config.HbmTiming;
|
import com.android.server.display.config.HbmTiming;
|
||||||
import com.android.server.display.config.HighBrightnessMode;
|
import com.android.server.display.config.HighBrightnessMode;
|
||||||
|
import com.android.server.display.config.IntegerArray;
|
||||||
import com.android.server.display.config.NitsMap;
|
import com.android.server.display.config.NitsMap;
|
||||||
import com.android.server.display.config.Point;
|
import com.android.server.display.config.Point;
|
||||||
import com.android.server.display.config.RefreshRateConfigs;
|
import com.android.server.display.config.RefreshRateConfigs;
|
||||||
@@ -213,6 +214,10 @@ import javax.xml.datatype.DatatypeConfigurationException;
|
|||||||
* <type>android.sensor.light</type>
|
* <type>android.sensor.light</type>
|
||||||
* <name>1234 Ambient Light Sensor</name>
|
* <name>1234 Ambient Light Sensor</name>
|
||||||
* </lightSensor>
|
* </lightSensor>
|
||||||
|
* <screenOffBrightnessSensor>
|
||||||
|
* <type>com.google.sensor.binned_brightness</type>
|
||||||
|
* <name>Binned Brightness 0 (wake-up)</name>
|
||||||
|
* </screenOffBrightnessSensor>
|
||||||
* <proxSensor>
|
* <proxSensor>
|
||||||
* <type>android.sensor.proximity</type>
|
* <type>android.sensor.proximity</type>
|
||||||
* <name>1234 Proximity Sensor</name>
|
* <name>1234 Proximity Sensor</name>
|
||||||
@@ -368,6 +373,13 @@ import javax.xml.datatype.DatatypeConfigurationException;
|
|||||||
* </brightnessThresholdPoints>
|
* </brightnessThresholdPoints>
|
||||||
* </darkeningThresholds>
|
* </darkeningThresholds>
|
||||||
* </displayBrightnessChangeThresholdsIdle>
|
* </displayBrightnessChangeThresholdsIdle>
|
||||||
|
* <screenOffBrightnessSensorValueToLux>
|
||||||
|
* <item>-1</item>
|
||||||
|
* <item>0</item>
|
||||||
|
* <item>5</item>
|
||||||
|
* <item>80</item>
|
||||||
|
* <item>1500</item>
|
||||||
|
* </screenOffBrightnessSensorValueToLux>
|
||||||
* </displayConfiguration>
|
* </displayConfiguration>
|
||||||
* }
|
* }
|
||||||
* </pre>
|
* </pre>
|
||||||
@@ -428,6 +440,9 @@ public class DisplayDeviceConfig {
|
|||||||
// The details of the ambient light sensor associated with this display.
|
// The details of the ambient light sensor associated with this display.
|
||||||
private final SensorData mAmbientLightSensor = new SensorData();
|
private final SensorData mAmbientLightSensor = new SensorData();
|
||||||
|
|
||||||
|
// The details of the doze brightness sensor associated with this display.
|
||||||
|
private final SensorData mScreenOffBrightnessSensor = new SensorData();
|
||||||
|
|
||||||
// The details of the proximity sensor associated with this display.
|
// The details of the proximity sensor associated with this display.
|
||||||
private final SensorData mProximitySensor = new SensorData();
|
private final SensorData mProximitySensor = new SensorData();
|
||||||
|
|
||||||
@@ -523,6 +538,9 @@ public class DisplayDeviceConfig {
|
|||||||
private float[] mAmbientDarkeningLevelsIdle = DEFAULT_AMBIENT_THRESHOLD_LEVELS;
|
private float[] mAmbientDarkeningLevelsIdle = DEFAULT_AMBIENT_THRESHOLD_LEVELS;
|
||||||
private float[] mAmbientDarkeningPercentagesIdle = DEFAULT_AMBIENT_DARKENING_THRESHOLDS;
|
private float[] mAmbientDarkeningPercentagesIdle = DEFAULT_AMBIENT_DARKENING_THRESHOLDS;
|
||||||
|
|
||||||
|
// A mapping between screen off sensor values and lux values
|
||||||
|
private int[] mScreenOffBrightnessSensorValueToLux;
|
||||||
|
|
||||||
private Spline mBrightnessToBacklightSpline;
|
private Spline mBrightnessToBacklightSpline;
|
||||||
private Spline mBacklightToBrightnessSpline;
|
private Spline mBacklightToBrightnessSpline;
|
||||||
private Spline mBacklightToNitsSpline;
|
private Spline mBacklightToNitsSpline;
|
||||||
@@ -1197,6 +1215,10 @@ public class DisplayDeviceConfig {
|
|||||||
return mAmbientLightSensor;
|
return mAmbientLightSensor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SensorData getScreenOffBrightnessSensor() {
|
||||||
|
return mScreenOffBrightnessSensor;
|
||||||
|
}
|
||||||
|
|
||||||
SensorData getProximitySensor() {
|
SensorData getProximitySensor() {
|
||||||
return mProximitySensor;
|
return mProximitySensor;
|
||||||
}
|
}
|
||||||
@@ -1320,6 +1342,14 @@ public class DisplayDeviceConfig {
|
|||||||
return mHighAmbientBrightnessThresholds;
|
return mHighAmbientBrightnessThresholds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return A mapping from screen off brightness sensor readings to lux values. This estimates
|
||||||
|
* the ambient lux when the screen is off to determine the initial brightness
|
||||||
|
*/
|
||||||
|
public int[] getScreenOffBrightnessSensorValueToLux() {
|
||||||
|
return mScreenOffBrightnessSensorValueToLux;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "DisplayDeviceConfig{"
|
return "DisplayDeviceConfig{"
|
||||||
@@ -1398,6 +1428,7 @@ public class DisplayDeviceConfig {
|
|||||||
mScreenDarkeningPercentagesIdle)
|
mScreenDarkeningPercentagesIdle)
|
||||||
+ "\n"
|
+ "\n"
|
||||||
+ ", mAmbientLightSensor=" + mAmbientLightSensor
|
+ ", mAmbientLightSensor=" + mAmbientLightSensor
|
||||||
|
+ ", mScreenOffBrightnessSensor=" + mScreenOffBrightnessSensor
|
||||||
+ ", mProximitySensor=" + mProximitySensor
|
+ ", mProximitySensor=" + mProximitySensor
|
||||||
+ ", mRefreshRateLimitations= " + Arrays.toString(mRefreshRateLimitations.toArray())
|
+ ", mRefreshRateLimitations= " + Arrays.toString(mRefreshRateLimitations.toArray())
|
||||||
+ ", mDensityMapping= " + mDensityMapping
|
+ ", mDensityMapping= " + mDensityMapping
|
||||||
@@ -1420,6 +1451,9 @@ public class DisplayDeviceConfig {
|
|||||||
+ Arrays.toString(mHighDisplayBrightnessThresholds)
|
+ Arrays.toString(mHighDisplayBrightnessThresholds)
|
||||||
+ ", mHighAmbientBrightnessThresholds= "
|
+ ", mHighAmbientBrightnessThresholds= "
|
||||||
+ Arrays.toString(mHighAmbientBrightnessThresholds)
|
+ Arrays.toString(mHighAmbientBrightnessThresholds)
|
||||||
|
+ "\n"
|
||||||
|
+ ", mScreenOffBrightnessSensorValueToLux=" + Arrays.toString(
|
||||||
|
mScreenOffBrightnessSensorValueToLux)
|
||||||
+ "}";
|
+ "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1473,11 +1507,13 @@ public class DisplayDeviceConfig {
|
|||||||
loadQuirks(config);
|
loadQuirks(config);
|
||||||
loadBrightnessRamps(config);
|
loadBrightnessRamps(config);
|
||||||
loadAmbientLightSensorFromDdc(config);
|
loadAmbientLightSensorFromDdc(config);
|
||||||
|
loadScreenOffBrightnessSensorFromDdc(config);
|
||||||
loadProxSensorFromDdc(config);
|
loadProxSensorFromDdc(config);
|
||||||
loadAmbientHorizonFromDdc(config);
|
loadAmbientHorizonFromDdc(config);
|
||||||
loadBrightnessChangeThresholds(config);
|
loadBrightnessChangeThresholds(config);
|
||||||
loadAutoBrightnessConfigValues(config);
|
loadAutoBrightnessConfigValues(config);
|
||||||
loadRefreshRateSetting(config);
|
loadRefreshRateSetting(config);
|
||||||
|
loadScreenOffBrightnessSensorValueToLuxFromDdc(config);
|
||||||
} else {
|
} else {
|
||||||
Slog.w(TAG, "DisplayDeviceConfig file is null");
|
Slog.w(TAG, "DisplayDeviceConfig file is null");
|
||||||
}
|
}
|
||||||
@@ -2169,6 +2205,14 @@ public class DisplayDeviceConfig {
|
|||||||
mProximitySensor.type = null;
|
mProximitySensor.type = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void loadScreenOffBrightnessSensorFromDdc(DisplayConfiguration config) {
|
||||||
|
final SensorDetails sensorDetails = config.getScreenOffBrightnessSensor();
|
||||||
|
if (sensorDetails != null) {
|
||||||
|
mScreenOffBrightnessSensor.type = sensorDetails.getType();
|
||||||
|
mScreenOffBrightnessSensor.name = sensorDetails.getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void loadProxSensorFromDdc(DisplayConfiguration config) {
|
private void loadProxSensorFromDdc(DisplayConfiguration config) {
|
||||||
SensorDetails sensorDetails = config.getProxSensor();
|
SensorDetails sensorDetails = config.getProxSensor();
|
||||||
if (sensorDetails != null) {
|
if (sensorDetails != null) {
|
||||||
@@ -2573,6 +2617,19 @@ public class DisplayDeviceConfig {
|
|||||||
&& mDdcAutoBrightnessAvailable;
|
&& mDdcAutoBrightnessAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void loadScreenOffBrightnessSensorValueToLuxFromDdc(DisplayConfiguration config) {
|
||||||
|
IntegerArray sensorValueToLux = config.getScreenOffBrightnessSensorValueToLux();
|
||||||
|
if (sensorValueToLux == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<BigInteger> items = sensorValueToLux.getItem();
|
||||||
|
mScreenOffBrightnessSensorValueToLux = new int[items.size()];
|
||||||
|
for (int i = 0; i < items.size(); i++) {
|
||||||
|
mScreenOffBrightnessSensorValueToLux[i] = items.get(i).intValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static class SensorData {
|
static class SensorData {
|
||||||
public String type;
|
public String type;
|
||||||
public String name;
|
public String name;
|
||||||
|
|||||||
@@ -408,7 +408,12 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
|||||||
@Nullable
|
@Nullable
|
||||||
private AutomaticBrightnessController mAutomaticBrightnessController;
|
private AutomaticBrightnessController mAutomaticBrightnessController;
|
||||||
|
|
||||||
|
// The controller for the sensor used to estimate ambient lux while the display is off.
|
||||||
|
@Nullable
|
||||||
|
private ScreenOffBrightnessSensorController mScreenOffBrightnessSensorController;
|
||||||
|
|
||||||
private Sensor mLightSensor;
|
private Sensor mLightSensor;
|
||||||
|
private Sensor mScreenOffBrightnessSensor;
|
||||||
|
|
||||||
// The mappers between ambient lux, display backlight values, and display brightness.
|
// The mappers between ambient lux, display backlight values, and display brightness.
|
||||||
// We will switch between the idle mapper and active mapper in AutomaticBrightnessController.
|
// We will switch between the idle mapper and active mapper in AutomaticBrightnessController.
|
||||||
@@ -1077,6 +1082,19 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
|||||||
|
|
||||||
mBrightnessEventRingBuffer =
|
mBrightnessEventRingBuffer =
|
||||||
new RingBuffer<>(BrightnessEvent.class, RINGBUFFER_MAX);
|
new RingBuffer<>(BrightnessEvent.class, RINGBUFFER_MAX);
|
||||||
|
|
||||||
|
loadScreenOffBrightnessSensor();
|
||||||
|
int[] sensorValueToLux = mDisplayDeviceConfig.getScreenOffBrightnessSensorValueToLux();
|
||||||
|
if (mScreenOffBrightnessSensor != null && sensorValueToLux != null) {
|
||||||
|
mScreenOffBrightnessSensorController = new ScreenOffBrightnessSensorController(
|
||||||
|
mSensorManager,
|
||||||
|
mScreenOffBrightnessSensor,
|
||||||
|
mHandler,
|
||||||
|
SystemClock::uptimeMillis,
|
||||||
|
sensorValueToLux,
|
||||||
|
mInteractiveModeBrightnessMapper
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
mUseSoftwareAutoBrightnessConfig = false;
|
mUseSoftwareAutoBrightnessConfig = false;
|
||||||
}
|
}
|
||||||
@@ -1262,6 +1280,12 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
|||||||
}
|
}
|
||||||
assert (state != Display.STATE_UNKNOWN);
|
assert (state != Display.STATE_UNKNOWN);
|
||||||
|
|
||||||
|
if (mScreenOffBrightnessSensorController != null) {
|
||||||
|
mScreenOffBrightnessSensorController.setLightSensorEnabled(mUseAutoBrightness
|
||||||
|
&& (state == Display.STATE_OFF || (state == Display.STATE_DOZE
|
||||||
|
&& !mAllowAutoBrightnessWhileDozingConfig)));
|
||||||
|
}
|
||||||
|
|
||||||
boolean skipRampBecauseOfProximityChangeToNegative = false;
|
boolean skipRampBecauseOfProximityChangeToNegative = false;
|
||||||
// Apply the proximity sensor.
|
// Apply the proximity sensor.
|
||||||
if (mProximitySensor != null) {
|
if (mProximitySensor != null) {
|
||||||
@@ -1433,6 +1457,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
|||||||
updateScreenBrightnessSetting = mCurrentScreenBrightnessSetting != brightnessState;
|
updateScreenBrightnessSetting = mCurrentScreenBrightnessSetting != brightnessState;
|
||||||
mAppliedAutoBrightness = true;
|
mAppliedAutoBrightness = true;
|
||||||
mBrightnessReasonTemp.setReason(BrightnessReason.REASON_AUTOMATIC);
|
mBrightnessReasonTemp.setReason(BrightnessReason.REASON_AUTOMATIC);
|
||||||
|
if (mScreenOffBrightnessSensorController != null) {
|
||||||
|
mScreenOffBrightnessSensorController.setLightSensorEnabled(false);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
mAppliedAutoBrightness = false;
|
mAppliedAutoBrightness = false;
|
||||||
}
|
}
|
||||||
@@ -1460,6 +1487,19 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
|||||||
mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE_DEFAULT);
|
mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The ALS is not available yet - use the screen off sensor to determine the initial
|
||||||
|
// brightness
|
||||||
|
if (Float.isNaN(brightnessState) && autoBrightnessEnabled
|
||||||
|
&& mScreenOffBrightnessSensorController != null) {
|
||||||
|
brightnessState = mScreenOffBrightnessSensorController.getAutomaticScreenBrightness();
|
||||||
|
if (isValidBrightnessValue(brightnessState)) {
|
||||||
|
brightnessState = clampScreenBrightness(brightnessState);
|
||||||
|
updateScreenBrightnessSetting = mCurrentScreenBrightnessSetting != brightnessState;
|
||||||
|
mBrightnessReasonTemp.setReason(
|
||||||
|
BrightnessReason.REASON_SCREEN_OFF_BRIGHTNESS_SENSOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Apply manual brightness.
|
// Apply manual brightness.
|
||||||
if (Float.isNaN(brightnessState)) {
|
if (Float.isNaN(brightnessState)) {
|
||||||
brightnessState = clampScreenBrightness(mCurrentScreenBrightnessSetting);
|
brightnessState = clampScreenBrightness(mCurrentScreenBrightnessSetting);
|
||||||
@@ -2034,6 +2074,14 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
|||||||
fallbackType);
|
fallbackType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void loadScreenOffBrightnessSensor() {
|
||||||
|
DisplayDeviceConfig.SensorData screenOffBrightnessSensor =
|
||||||
|
mDisplayDeviceConfig.getScreenOffBrightnessSensor();
|
||||||
|
mScreenOffBrightnessSensor = SensorUtils.findSensor(mSensorManager,
|
||||||
|
screenOffBrightnessSensor.type, screenOffBrightnessSensor.name,
|
||||||
|
SensorUtils.NO_FALLBACK);
|
||||||
|
}
|
||||||
|
|
||||||
private void loadProximitySensor() {
|
private void loadProximitySensor() {
|
||||||
if (DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) {
|
if (DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -360,7 +360,12 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
|||||||
@Nullable
|
@Nullable
|
||||||
private AutomaticBrightnessController mAutomaticBrightnessController;
|
private AutomaticBrightnessController mAutomaticBrightnessController;
|
||||||
|
|
||||||
|
// The controller for the sensor used to estimate ambient lux while the display is off.
|
||||||
|
@Nullable
|
||||||
|
private ScreenOffBrightnessSensorController mScreenOffBrightnessSensorController;
|
||||||
|
|
||||||
private Sensor mLightSensor;
|
private Sensor mLightSensor;
|
||||||
|
private Sensor mScreenOffBrightnessSensor;
|
||||||
|
|
||||||
// The mappers between ambient lux, display backlight values, and display brightness.
|
// The mappers between ambient lux, display backlight values, and display brightness.
|
||||||
// We will switch between the idle mapper and active mapper in AutomaticBrightnessController.
|
// We will switch between the idle mapper and active mapper in AutomaticBrightnessController.
|
||||||
@@ -994,6 +999,19 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
|||||||
|
|
||||||
mBrightnessEventRingBuffer =
|
mBrightnessEventRingBuffer =
|
||||||
new RingBuffer<>(BrightnessEvent.class, RINGBUFFER_MAX);
|
new RingBuffer<>(BrightnessEvent.class, RINGBUFFER_MAX);
|
||||||
|
|
||||||
|
loadScreenOffBrightnessSensor();
|
||||||
|
int[] sensorValueToLux = mDisplayDeviceConfig.getScreenOffBrightnessSensorValueToLux();
|
||||||
|
if (mScreenOffBrightnessSensor != null && sensorValueToLux != null) {
|
||||||
|
mScreenOffBrightnessSensorController = new ScreenOffBrightnessSensorController(
|
||||||
|
mSensorManager,
|
||||||
|
mScreenOffBrightnessSensor,
|
||||||
|
mHandler,
|
||||||
|
SystemClock::uptimeMillis,
|
||||||
|
sensorValueToLux,
|
||||||
|
mInteractiveModeBrightnessMapper
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
mUseSoftwareAutoBrightnessConfig = false;
|
mUseSoftwareAutoBrightnessConfig = false;
|
||||||
}
|
}
|
||||||
@@ -1135,6 +1153,13 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
|||||||
|
|
||||||
int state = mDisplayStateController
|
int state = mDisplayStateController
|
||||||
.updateDisplayState(mPowerRequest, mIsEnabled, mIsInTransition);
|
.updateDisplayState(mPowerRequest, mIsEnabled, mIsInTransition);
|
||||||
|
|
||||||
|
if (mScreenOffBrightnessSensorController != null) {
|
||||||
|
mScreenOffBrightnessSensorController.setLightSensorEnabled(mUseAutoBrightness
|
||||||
|
&& (state == Display.STATE_OFF || (state == Display.STATE_DOZE
|
||||||
|
&& !mDisplayBrightnessController.isAllowAutoBrightnessWhileDozingConfig())));
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize things the first time the power state is changed.
|
// Initialize things the first time the power state is changed.
|
||||||
if (mustInitialize) {
|
if (mustInitialize) {
|
||||||
initialize(state);
|
initialize(state);
|
||||||
@@ -1224,6 +1249,9 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
|||||||
updateScreenBrightnessSetting = mCurrentScreenBrightnessSetting != brightnessState;
|
updateScreenBrightnessSetting = mCurrentScreenBrightnessSetting != brightnessState;
|
||||||
mAppliedAutoBrightness = true;
|
mAppliedAutoBrightness = true;
|
||||||
mBrightnessReasonTemp.setReason(BrightnessReason.REASON_AUTOMATIC);
|
mBrightnessReasonTemp.setReason(BrightnessReason.REASON_AUTOMATIC);
|
||||||
|
if (mScreenOffBrightnessSensorController != null) {
|
||||||
|
mScreenOffBrightnessSensorController.setLightSensorEnabled(false);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
mAppliedAutoBrightness = false;
|
mAppliedAutoBrightness = false;
|
||||||
}
|
}
|
||||||
@@ -1251,6 +1279,19 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
|||||||
mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE_DEFAULT);
|
mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The ALS is not available yet - use the screen off sensor to determine the initial
|
||||||
|
// brightness
|
||||||
|
if (Float.isNaN(brightnessState) && autoBrightnessEnabled
|
||||||
|
&& mScreenOffBrightnessSensorController != null) {
|
||||||
|
brightnessState = mScreenOffBrightnessSensorController.getAutomaticScreenBrightness();
|
||||||
|
if (isValidBrightnessValue(brightnessState)) {
|
||||||
|
brightnessState = clampScreenBrightness(brightnessState);
|
||||||
|
updateScreenBrightnessSetting = mCurrentScreenBrightnessSetting != brightnessState;
|
||||||
|
mBrightnessReasonTemp.setReason(
|
||||||
|
BrightnessReason.REASON_SCREEN_OFF_BRIGHTNESS_SENSOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Apply manual brightness.
|
// Apply manual brightness.
|
||||||
if (Float.isNaN(brightnessState)) {
|
if (Float.isNaN(brightnessState)) {
|
||||||
brightnessState = clampScreenBrightness(mCurrentScreenBrightnessSetting);
|
brightnessState = clampScreenBrightness(mCurrentScreenBrightnessSetting);
|
||||||
@@ -1819,6 +1860,14 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
|
|||||||
fallbackType);
|
fallbackType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void loadScreenOffBrightnessSensor() {
|
||||||
|
DisplayDeviceConfig.SensorData screenOffBrightnessSensor =
|
||||||
|
mDisplayDeviceConfig.getScreenOffBrightnessSensor();
|
||||||
|
mScreenOffBrightnessSensor = SensorUtils.findSensor(mSensorManager,
|
||||||
|
screenOffBrightnessSensor.type, screenOffBrightnessSensor.name,
|
||||||
|
SensorUtils.NO_FALLBACK);
|
||||||
|
}
|
||||||
|
|
||||||
private float clampScreenBrightness(float value) {
|
private float clampScreenBrightness(float value) {
|
||||||
if (Float.isNaN(value)) {
|
if (Float.isNaN(value)) {
|
||||||
value = PowerManager.BRIGHTNESS_MIN;
|
value = PowerManager.BRIGHTNESS_MIN;
|
||||||
|
|||||||
@@ -0,0 +1,127 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2022 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.annotation.Nullable;
|
||||||
|
import android.hardware.Sensor;
|
||||||
|
import android.hardware.SensorEvent;
|
||||||
|
import android.hardware.SensorEventListener;
|
||||||
|
import android.hardware.SensorManager;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.PowerManager;
|
||||||
|
import android.util.IndentingPrintWriter;
|
||||||
|
|
||||||
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controls the light sensor when the screen is off. The sensor used here does not report lux values
|
||||||
|
* but an index that needs to be mapped to a lux value.
|
||||||
|
*/
|
||||||
|
public class ScreenOffBrightnessSensorController implements SensorEventListener {
|
||||||
|
private static final String TAG = "ScreenOffBrightnessSensorController";
|
||||||
|
|
||||||
|
private static final int SENSOR_INVALID_VALUE = -1;
|
||||||
|
private static final long SENSOR_VALUE_VALID_TIME_MILLIS = 1500;
|
||||||
|
|
||||||
|
private final Handler mHandler;
|
||||||
|
private final Clock mClock;
|
||||||
|
private final SensorManager mSensorManager;
|
||||||
|
private final Sensor mLightSensor;
|
||||||
|
private final int[] mSensorValueToLux;
|
||||||
|
|
||||||
|
private boolean mRegistered;
|
||||||
|
private int mLastSensorValue = SENSOR_INVALID_VALUE;
|
||||||
|
private long mSensorDisableTime = -1;
|
||||||
|
|
||||||
|
// The mapper to translate ambient lux to screen brightness in the range [0, 1.0].
|
||||||
|
@Nullable
|
||||||
|
private final BrightnessMappingStrategy mBrightnessMapper;
|
||||||
|
|
||||||
|
public ScreenOffBrightnessSensorController(
|
||||||
|
SensorManager sensorManager,
|
||||||
|
Sensor lightSensor,
|
||||||
|
Handler handler,
|
||||||
|
Clock clock,
|
||||||
|
int[] sensorValueToLux,
|
||||||
|
BrightnessMappingStrategy brightnessMapper) {
|
||||||
|
mSensorManager = sensorManager;
|
||||||
|
mLightSensor = lightSensor;
|
||||||
|
mHandler = handler;
|
||||||
|
mClock = clock;
|
||||||
|
mSensorValueToLux = sensorValueToLux;
|
||||||
|
mBrightnessMapper = brightnessMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSensorChanged(SensorEvent event) {
|
||||||
|
if (mRegistered) {
|
||||||
|
mLastSensorValue = (int) event.values[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void setLightSensorEnabled(boolean enabled) {
|
||||||
|
if (enabled && !mRegistered) {
|
||||||
|
// Wait until we get an event from the sensor indicating ready.
|
||||||
|
mRegistered = mSensorManager.registerListener(this, mLightSensor,
|
||||||
|
SensorManager.SENSOR_DELAY_NORMAL, mHandler);
|
||||||
|
mLastSensorValue = SENSOR_INVALID_VALUE;
|
||||||
|
} else if (!enabled && mRegistered) {
|
||||||
|
mSensorManager.unregisterListener(this);
|
||||||
|
mRegistered = false;
|
||||||
|
mSensorDisableTime = mClock.uptimeMillis();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float getAutomaticScreenBrightness() {
|
||||||
|
if (mLastSensorValue < 0 || mLastSensorValue >= mSensorValueToLux.length
|
||||||
|
|| (!mRegistered
|
||||||
|
&& mClock.uptimeMillis() - mSensorDisableTime > SENSOR_VALUE_VALID_TIME_MILLIS)) {
|
||||||
|
return PowerManager.BRIGHTNESS_INVALID_FLOAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lux = mSensorValueToLux[mLastSensorValue];
|
||||||
|
if (lux < 0) {
|
||||||
|
return PowerManager.BRIGHTNESS_INVALID_FLOAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mBrightnessMapper.getBrightness(lux);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Dump current state */
|
||||||
|
public void dump(PrintWriter pw) {
|
||||||
|
pw.println("ScreenOffBrightnessSensorController:");
|
||||||
|
IndentingPrintWriter idpw = new IndentingPrintWriter(pw);
|
||||||
|
idpw.increaseIndent();
|
||||||
|
idpw.println("registered=" + mRegistered);
|
||||||
|
idpw.println("lastSensorValue=" + mLastSensorValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Functional interface for providing time. */
|
||||||
|
@VisibleForTesting
|
||||||
|
interface Clock {
|
||||||
|
/**
|
||||||
|
* Returns current time in milliseconds since boot, not counting time spent in deep sleep.
|
||||||
|
*/
|
||||||
|
long uptimeMillis();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -37,7 +37,8 @@ public final class BrightnessReason {
|
|||||||
public static final int REASON_OVERRIDE = 6;
|
public static final int REASON_OVERRIDE = 6;
|
||||||
public static final int REASON_TEMPORARY = 7;
|
public static final int REASON_TEMPORARY = 7;
|
||||||
public static final int REASON_BOOST = 8;
|
public static final int REASON_BOOST = 8;
|
||||||
public static final int REASON_MAX = REASON_BOOST;
|
public static final int REASON_SCREEN_OFF_BRIGHTNESS_SENSOR = 9;
|
||||||
|
public static final int REASON_MAX = REASON_SCREEN_OFF_BRIGHTNESS_SENSOR;
|
||||||
|
|
||||||
public static final int MODIFIER_DIMMED = 0x1;
|
public static final int MODIFIER_DIMMED = 0x1;
|
||||||
public static final int MODIFIER_LOW_POWER = 0x2;
|
public static final int MODIFIER_LOW_POWER = 0x2;
|
||||||
@@ -190,6 +191,8 @@ public final class BrightnessReason {
|
|||||||
return "temporary";
|
return "temporary";
|
||||||
case REASON_BOOST:
|
case REASON_BOOST:
|
||||||
return "boost";
|
return "boost";
|
||||||
|
case REASON_SCREEN_OFF_BRIGHTNESS_SENSOR:
|
||||||
|
return "screen_off_brightness_sensor";
|
||||||
default:
|
default:
|
||||||
return Integer.toString(reason);
|
return Integer.toString(reason);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,6 +74,9 @@
|
|||||||
<xs:element type="sensorDetails" name="lightSensor">
|
<xs:element type="sensorDetails" name="lightSensor">
|
||||||
<xs:annotation name="final"/>
|
<xs:annotation name="final"/>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
|
<xs:element type="sensorDetails" name="screenOffBrightnessSensor">
|
||||||
|
<xs:annotation name="final"/>
|
||||||
|
</xs:element>
|
||||||
<xs:element type="sensorDetails" name="proxSensor">
|
<xs:element type="sensorDetails" name="proxSensor">
|
||||||
<xs:annotation name="final"/>
|
<xs:annotation name="final"/>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
@@ -109,6 +112,11 @@
|
|||||||
<xs:element type="thresholds" name="ambientBrightnessChangeThresholdsIdle" minOccurs="0" maxOccurs="1">
|
<xs:element type="thresholds" name="ambientBrightnessChangeThresholdsIdle" minOccurs="0" maxOccurs="1">
|
||||||
<xs:annotation name="final"/>
|
<xs:annotation name="final"/>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
|
<!-- Table that translates sensor values from the screenOffBrightnessSensor
|
||||||
|
to lux values; -1 means the lux reading is not available. -->
|
||||||
|
<xs:element type="integer-array" name="screenOffBrightnessSensorValueToLux">
|
||||||
|
<xs:annotation name="final"/>
|
||||||
|
</xs:element>
|
||||||
</xs:sequence>
|
</xs:sequence>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
@@ -485,4 +493,10 @@
|
|||||||
</xs:element>
|
</xs:element>
|
||||||
</xs:sequence>
|
</xs:sequence>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
|
|
||||||
|
<xs:complexType name="integer-array">
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element name="item" type="xs:nonNegativeInteger" minOccurs="0" maxOccurs="unbounded"/>
|
||||||
|
</xs:sequence>
|
||||||
|
</xs:complexType>
|
||||||
</xs:schema>
|
</xs:schema>
|
||||||
|
|||||||
@@ -98,6 +98,8 @@ package com.android.server.display.config {
|
|||||||
method public final java.math.BigInteger getScreenBrightnessRampIncreaseMaxMillis();
|
method public final java.math.BigInteger getScreenBrightnessRampIncreaseMaxMillis();
|
||||||
method public final java.math.BigDecimal getScreenBrightnessRampSlowDecrease();
|
method public final java.math.BigDecimal getScreenBrightnessRampSlowDecrease();
|
||||||
method public final java.math.BigDecimal getScreenBrightnessRampSlowIncrease();
|
method public final java.math.BigDecimal getScreenBrightnessRampSlowIncrease();
|
||||||
|
method public final com.android.server.display.config.SensorDetails getScreenOffBrightnessSensor();
|
||||||
|
method public final com.android.server.display.config.IntegerArray getScreenOffBrightnessSensorValueToLux();
|
||||||
method @NonNull public final com.android.server.display.config.ThermalThrottling getThermalThrottling();
|
method @NonNull public final com.android.server.display.config.ThermalThrottling getThermalThrottling();
|
||||||
method public final void setAmbientBrightnessChangeThresholds(@NonNull com.android.server.display.config.Thresholds);
|
method public final void setAmbientBrightnessChangeThresholds(@NonNull com.android.server.display.config.Thresholds);
|
||||||
method public final void setAmbientBrightnessChangeThresholdsIdle(com.android.server.display.config.Thresholds);
|
method public final void setAmbientBrightnessChangeThresholdsIdle(com.android.server.display.config.Thresholds);
|
||||||
@@ -120,6 +122,8 @@ package com.android.server.display.config {
|
|||||||
method public final void setScreenBrightnessRampIncreaseMaxMillis(java.math.BigInteger);
|
method public final void setScreenBrightnessRampIncreaseMaxMillis(java.math.BigInteger);
|
||||||
method public final void setScreenBrightnessRampSlowDecrease(java.math.BigDecimal);
|
method public final void setScreenBrightnessRampSlowDecrease(java.math.BigDecimal);
|
||||||
method public final void setScreenBrightnessRampSlowIncrease(java.math.BigDecimal);
|
method public final void setScreenBrightnessRampSlowIncrease(java.math.BigDecimal);
|
||||||
|
method public final void setScreenOffBrightnessSensor(com.android.server.display.config.SensorDetails);
|
||||||
|
method public final void setScreenOffBrightnessSensorValueToLux(com.android.server.display.config.IntegerArray);
|
||||||
method public final void setThermalThrottling(@NonNull com.android.server.display.config.ThermalThrottling);
|
method public final void setThermalThrottling(@NonNull com.android.server.display.config.ThermalThrottling);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,6 +164,11 @@ package com.android.server.display.config {
|
|||||||
method public final void setTransitionPoint_all(@NonNull java.math.BigDecimal);
|
method public final void setTransitionPoint_all(@NonNull java.math.BigDecimal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class IntegerArray {
|
||||||
|
ctor public IntegerArray();
|
||||||
|
method public java.util.List<java.math.BigInteger> getItem();
|
||||||
|
}
|
||||||
|
|
||||||
public class NitsMap {
|
public class NitsMap {
|
||||||
ctor public NitsMap();
|
ctor public NitsMap();
|
||||||
method public String getInterpolation();
|
method public String getInterpolation();
|
||||||
|
|||||||
@@ -156,6 +156,14 @@ public final class DisplayDeviceConfigTest {
|
|||||||
assertArrayEquals(new int[]{70, 80},
|
assertArrayEquals(new int[]{70, 80},
|
||||||
mDisplayDeviceConfig.getHighAmbientBrightnessThresholds());
|
mDisplayDeviceConfig.getHighAmbientBrightnessThresholds());
|
||||||
|
|
||||||
|
assertEquals("sensor_12345",
|
||||||
|
mDisplayDeviceConfig.getScreenOffBrightnessSensor().type);
|
||||||
|
assertEquals("Sensor 12345",
|
||||||
|
mDisplayDeviceConfig.getScreenOffBrightnessSensor().name);
|
||||||
|
|
||||||
|
assertArrayEquals(new int[]{-1, 10, 20, 30, 40},
|
||||||
|
mDisplayDeviceConfig.getScreenOffBrightnessSensorValueToLux());
|
||||||
|
|
||||||
// Todo(brup): Add asserts for BrightnessThrottlingData, DensityMapping,
|
// Todo(brup): Add asserts for BrightnessThrottlingData, DensityMapping,
|
||||||
// HighBrightnessModeData AmbientLightSensor, RefreshRateLimitations and ProximitySensor.
|
// HighBrightnessModeData AmbientLightSensor, RefreshRateLimitations and ProximitySensor.
|
||||||
}
|
}
|
||||||
@@ -227,6 +235,7 @@ public final class DisplayDeviceConfigTest {
|
|||||||
HIGH_BRIGHTNESS_THRESHOLD_OF_PEAK_REFRESH_RATE);
|
HIGH_BRIGHTNESS_THRESHOLD_OF_PEAK_REFRESH_RATE);
|
||||||
assertArrayEquals(mDisplayDeviceConfig.getHighAmbientBrightnessThresholds(),
|
assertArrayEquals(mDisplayDeviceConfig.getHighAmbientBrightnessThresholds(),
|
||||||
HIGH_AMBIENT_THRESHOLD_OF_PEAK_REFRESH_RATE);
|
HIGH_AMBIENT_THRESHOLD_OF_PEAK_REFRESH_RATE);
|
||||||
|
|
||||||
// Todo(brup): Add asserts for BrightnessThrottlingData, DensityMapping,
|
// Todo(brup): Add asserts for BrightnessThrottlingData, DensityMapping,
|
||||||
// HighBrightnessModeData AmbientLightSensor, RefreshRateLimitations and ProximitySensor.
|
// HighBrightnessModeData AmbientLightSensor, RefreshRateLimitations and ProximitySensor.
|
||||||
}
|
}
|
||||||
@@ -278,6 +287,10 @@ public final class DisplayDeviceConfigTest {
|
|||||||
+ "<thermalStatusLimit>light</thermalStatusLimit>\n"
|
+ "<thermalStatusLimit>light</thermalStatusLimit>\n"
|
||||||
+ "<allowInLowPowerMode>false</allowInLowPowerMode>\n"
|
+ "<allowInLowPowerMode>false</allowInLowPowerMode>\n"
|
||||||
+ "</highBrightnessMode>\n"
|
+ "</highBrightnessMode>\n"
|
||||||
|
+ "<screenOffBrightnessSensor>\n"
|
||||||
|
+ "<type>sensor_12345</type>\n"
|
||||||
|
+ "<name>Sensor 12345</name>\n"
|
||||||
|
+ "</screenOffBrightnessSensor>\n"
|
||||||
+ "<ambientBrightnessChangeThresholds>\n"
|
+ "<ambientBrightnessChangeThresholds>\n"
|
||||||
+ "<brighteningThresholds>\n"
|
+ "<brighteningThresholds>\n"
|
||||||
+ "<minimum>10</minimum>\n"
|
+ "<minimum>10</minimum>\n"
|
||||||
@@ -458,6 +471,13 @@ public final class DisplayDeviceConfigTest {
|
|||||||
+ "</blockingZoneThreshold>\n"
|
+ "</blockingZoneThreshold>\n"
|
||||||
+ "</higherBlockingZoneConfigs>\n"
|
+ "</higherBlockingZoneConfigs>\n"
|
||||||
+ "</refreshRate>\n"
|
+ "</refreshRate>\n"
|
||||||
|
+ "<screenOffBrightnessSensorValueToLux>\n"
|
||||||
|
+ "<item>-1</item>\n"
|
||||||
|
+ "<item>10</item>\n"
|
||||||
|
+ "<item>20</item>\n"
|
||||||
|
+ "<item>30</item>\n"
|
||||||
|
+ "<item>40</item>\n"
|
||||||
|
+ "</screenOffBrightnessSensorValueToLux>\n"
|
||||||
+ "</displayConfiguration>\n";
|
+ "</displayConfiguration>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -535,6 +555,7 @@ public final class DisplayDeviceConfigTest {
|
|||||||
when(mResources.getIntArray(
|
when(mResources.getIntArray(
|
||||||
R.array.config_highAmbientBrightnessThresholdsOfFixedRefreshRate))
|
R.array.config_highAmbientBrightnessThresholdsOfFixedRefreshRate))
|
||||||
.thenReturn(HIGH_AMBIENT_THRESHOLD_OF_PEAK_REFRESH_RATE);
|
.thenReturn(HIGH_AMBIENT_THRESHOLD_OF_PEAK_REFRESH_RATE);
|
||||||
|
|
||||||
mDisplayDeviceConfig = DisplayDeviceConfig.create(mContext, true);
|
mDisplayDeviceConfig = DisplayDeviceConfig.create(mContext, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,148 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2022 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 static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotEquals;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import android.hardware.Sensor;
|
||||||
|
import android.hardware.SensorEventListener;
|
||||||
|
import android.hardware.SensorManager;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.PowerManager;
|
||||||
|
import android.platform.test.annotations.Presubmit;
|
||||||
|
|
||||||
|
import androidx.test.filters.SmallTest;
|
||||||
|
import androidx.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
|
import com.android.server.testutils.OffsettableClock;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
@SmallTest
|
||||||
|
@Presubmit
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
public class ScreenOffBrightnessSensorControllerTest {
|
||||||
|
|
||||||
|
private static final int[] SENSOR_TO_LUX = new int[]{-1, 10, 20, 30, 40};
|
||||||
|
|
||||||
|
private ScreenOffBrightnessSensorController mController;
|
||||||
|
private OffsettableClock mClock;
|
||||||
|
private Sensor mLightSensor;
|
||||||
|
|
||||||
|
@Mock SensorManager mSensorManager;
|
||||||
|
@Mock Handler mNoOpHandler;
|
||||||
|
@Mock BrightnessMappingStrategy mBrightnessMappingStrategy;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
|
mClock = new OffsettableClock.Stopped();
|
||||||
|
mLightSensor = TestUtils.createSensor(Sensor.TYPE_LIGHT, "Light Sensor");
|
||||||
|
mController = new ScreenOffBrightnessSensorController(
|
||||||
|
mSensorManager,
|
||||||
|
mLightSensor,
|
||||||
|
mNoOpHandler,
|
||||||
|
mClock::now,
|
||||||
|
SENSOR_TO_LUX,
|
||||||
|
mBrightnessMappingStrategy
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBrightness() throws Exception {
|
||||||
|
when(mSensorManager.registerListener(any(SensorEventListener.class), eq(mLightSensor),
|
||||||
|
eq(SensorManager.SENSOR_DELAY_NORMAL), any(Handler.class)))
|
||||||
|
.thenReturn(true);
|
||||||
|
mController.setLightSensorEnabled(true);
|
||||||
|
ArgumentCaptor<SensorEventListener> listenerCaptor =
|
||||||
|
ArgumentCaptor.forClass(SensorEventListener.class);
|
||||||
|
verify(mSensorManager).registerListener(listenerCaptor.capture(), eq(mLightSensor),
|
||||||
|
eq(SensorManager.SENSOR_DELAY_NORMAL), any(Handler.class));
|
||||||
|
SensorEventListener listener = listenerCaptor.getValue();
|
||||||
|
|
||||||
|
listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, 0));
|
||||||
|
assertEquals(PowerManager.BRIGHTNESS_INVALID_FLOAT,
|
||||||
|
mController.getAutomaticScreenBrightness(), 0);
|
||||||
|
|
||||||
|
int sensorValue = 1;
|
||||||
|
float brightness = 0.2f;
|
||||||
|
listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, sensorValue));
|
||||||
|
when(mBrightnessMappingStrategy.getBrightness(SENSOR_TO_LUX[sensorValue]))
|
||||||
|
.thenReturn(brightness);
|
||||||
|
assertEquals(brightness, mController.getAutomaticScreenBrightness(), 0);
|
||||||
|
|
||||||
|
sensorValue = 2;
|
||||||
|
brightness = 0.4f;
|
||||||
|
listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, sensorValue));
|
||||||
|
when(mBrightnessMappingStrategy.getBrightness(SENSOR_TO_LUX[sensorValue]))
|
||||||
|
.thenReturn(brightness);
|
||||||
|
assertEquals(brightness, mController.getAutomaticScreenBrightness(), 0);
|
||||||
|
|
||||||
|
sensorValue = 3;
|
||||||
|
brightness = 0.6f;
|
||||||
|
listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, sensorValue));
|
||||||
|
when(mBrightnessMappingStrategy.getBrightness(SENSOR_TO_LUX[sensorValue]))
|
||||||
|
.thenReturn(brightness);
|
||||||
|
assertEquals(brightness, mController.getAutomaticScreenBrightness(), 0);
|
||||||
|
|
||||||
|
sensorValue = 4;
|
||||||
|
brightness = 0.8f;
|
||||||
|
listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, sensorValue));
|
||||||
|
when(mBrightnessMappingStrategy.getBrightness(SENSOR_TO_LUX[sensorValue]))
|
||||||
|
.thenReturn(brightness);
|
||||||
|
assertEquals(brightness, mController.getAutomaticScreenBrightness(), 0);
|
||||||
|
|
||||||
|
sensorValue = 5;
|
||||||
|
listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, sensorValue));
|
||||||
|
assertEquals(PowerManager.BRIGHTNESS_INVALID_FLOAT,
|
||||||
|
mController.getAutomaticScreenBrightness(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSensorValueValidTime() throws Exception {
|
||||||
|
when(mSensorManager.registerListener(any(SensorEventListener.class), eq(mLightSensor),
|
||||||
|
eq(SensorManager.SENSOR_DELAY_NORMAL), any(Handler.class)))
|
||||||
|
.thenReturn(true);
|
||||||
|
mController.setLightSensorEnabled(true);
|
||||||
|
ArgumentCaptor<SensorEventListener> listenerCaptor =
|
||||||
|
ArgumentCaptor.forClass(SensorEventListener.class);
|
||||||
|
verify(mSensorManager).registerListener(listenerCaptor.capture(), eq(mLightSensor),
|
||||||
|
eq(SensorManager.SENSOR_DELAY_NORMAL), any(Handler.class));
|
||||||
|
SensorEventListener listener = listenerCaptor.getValue();
|
||||||
|
|
||||||
|
listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, 1));
|
||||||
|
mController.setLightSensorEnabled(false);
|
||||||
|
assertNotEquals(PowerManager.BRIGHTNESS_INVALID_FLOAT,
|
||||||
|
mController.getAutomaticScreenBrightness(), 0);
|
||||||
|
|
||||||
|
mClock.fastForward(2000);
|
||||||
|
mController.setLightSensorEnabled(false);
|
||||||
|
assertEquals(PowerManager.BRIGHTNESS_INVALID_FLOAT,
|
||||||
|
mController.getAutomaticScreenBrightness(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,13 +28,13 @@ import java.lang.reflect.Method;
|
|||||||
|
|
||||||
public final class TestUtils {
|
public final class TestUtils {
|
||||||
|
|
||||||
public static SensorEvent createSensorEvent(Sensor sensor, int lux) throws Exception {
|
public static SensorEvent createSensorEvent(Sensor sensor, int value) throws Exception {
|
||||||
final Constructor<SensorEvent> constructor =
|
final Constructor<SensorEvent> constructor =
|
||||||
SensorEvent.class.getDeclaredConstructor(int.class);
|
SensorEvent.class.getDeclaredConstructor(int.class);
|
||||||
constructor.setAccessible(true);
|
constructor.setAccessible(true);
|
||||||
final SensorEvent event = constructor.newInstance(1);
|
final SensorEvent event = constructor.newInstance(1);
|
||||||
event.sensor = sensor;
|
event.sensor = sensor;
|
||||||
event.values[0] = lux;
|
event.values[0] = value;
|
||||||
event.timestamp = SystemClock.elapsedRealtimeNanos();
|
event.timestamp = SystemClock.elapsedRealtimeNanos();
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user