Merge "Use a brightness sensor to determine the screen's initial brightness" into tm-qpr-dev am: 7cd5d000d8

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20105810

Change-Id: I7c2a2240412fc8923b0262e321deda960a97f7c4
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Piotr Wilczyński
2022-12-20 18:15:23 +00:00
committed by Automerger Merge Worker
8 changed files with 429 additions and 3 deletions

View File

@@ -46,6 +46,7 @@ import com.android.server.display.config.DisplayConfiguration;
import com.android.server.display.config.DisplayQuirks;
import com.android.server.display.config.HbmTiming;
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.Point;
import com.android.server.display.config.RefreshRateConfigs;
@@ -213,6 +214,10 @@ import javax.xml.datatype.DatatypeConfigurationException;
* <type>android.sensor.light</type>
* <name>1234 Ambient Light Sensor</name>
* </lightSensor>
* <screenOffBrightnessSensor>
* <type>com.google.sensor.binned_brightness</type>
* <name>Binned Brightness 0 (wake-up)</name>
* </screenOffBrightnessSensor>
* <proxSensor>
* <type>android.sensor.proximity</type>
* <name>1234 Proximity Sensor</name>
@@ -368,6 +373,13 @@ import javax.xml.datatype.DatatypeConfigurationException;
* </brightnessThresholdPoints>
* </darkeningThresholds>
* </displayBrightnessChangeThresholdsIdle>
* <screenOffBrightnessSensorValueToLux>
* <item>-1</item>
* <item>0</item>
* <item>5</item>
* <item>80</item>
* <item>1500</item>
* </screenOffBrightnessSensorValueToLux>
* </displayConfiguration>
* }
* </pre>
@@ -428,6 +440,9 @@ public class DisplayDeviceConfig {
// The details of the ambient light sensor associated with this display.
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.
private final SensorData mProximitySensor = new SensorData();
@@ -523,6 +538,9 @@ public class DisplayDeviceConfig {
private float[] mAmbientDarkeningLevelsIdle = DEFAULT_AMBIENT_THRESHOLD_LEVELS;
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 mBacklightToBrightnessSpline;
private Spline mBacklightToNitsSpline;
@@ -1197,6 +1215,10 @@ public class DisplayDeviceConfig {
return mAmbientLightSensor;
}
SensorData getScreenOffBrightnessSensor() {
return mScreenOffBrightnessSensor;
}
SensorData getProximitySensor() {
return mProximitySensor;
}
@@ -1320,6 +1342,14 @@ public class DisplayDeviceConfig {
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
public String toString() {
return "DisplayDeviceConfig{"
@@ -1398,6 +1428,7 @@ public class DisplayDeviceConfig {
mScreenDarkeningPercentagesIdle)
+ "\n"
+ ", mAmbientLightSensor=" + mAmbientLightSensor
+ ", mScreenOffBrightnessSensor=" + mScreenOffBrightnessSensor
+ ", mProximitySensor=" + mProximitySensor
+ ", mRefreshRateLimitations= " + Arrays.toString(mRefreshRateLimitations.toArray())
+ ", mDensityMapping= " + mDensityMapping
@@ -1420,6 +1451,9 @@ public class DisplayDeviceConfig {
+ Arrays.toString(mHighDisplayBrightnessThresholds)
+ ", mHighAmbientBrightnessThresholds= "
+ Arrays.toString(mHighAmbientBrightnessThresholds)
+ "\n"
+ ", mScreenOffBrightnessSensorValueToLux=" + Arrays.toString(
mScreenOffBrightnessSensorValueToLux)
+ "}";
}
@@ -1473,11 +1507,13 @@ public class DisplayDeviceConfig {
loadQuirks(config);
loadBrightnessRamps(config);
loadAmbientLightSensorFromDdc(config);
loadScreenOffBrightnessSensorFromDdc(config);
loadProxSensorFromDdc(config);
loadAmbientHorizonFromDdc(config);
loadBrightnessChangeThresholds(config);
loadAutoBrightnessConfigValues(config);
loadRefreshRateSetting(config);
loadScreenOffBrightnessSensorValueToLuxFromDdc(config);
} else {
Slog.w(TAG, "DisplayDeviceConfig file is null");
}
@@ -2174,6 +2210,14 @@ public class DisplayDeviceConfig {
mProximitySensor.type = "";
}
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) {
SensorDetails sensorDetails = config.getProxSensor();
if (sensorDetails != null) {
@@ -2586,6 +2630,19 @@ public class DisplayDeviceConfig {
&& 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 {
public String type;
public String name;

View File

@@ -414,7 +414,12 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
@Nullable
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 mScreenOffBrightnessSensor;
// The mappers between ambient lux, display backlight values, and display brightness.
// We will switch between the idle mapper and active mapper in AutomaticBrightnessController.
@@ -1098,6 +1103,19 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mBrightnessEventRingBuffer =
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 {
mUseSoftwareAutoBrightnessConfig = false;
}
@@ -1275,6 +1293,12 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
}
assert(state != Display.STATE_UNKNOWN);
if (mScreenOffBrightnessSensorController != null) {
mScreenOffBrightnessSensorController.setLightSensorEnabled(mUseAutoBrightness
&& (state == Display.STATE_OFF || (state == Display.STATE_DOZE
&& !mAllowAutoBrightnessWhileDozingConfig)));
}
boolean skipRampBecauseOfProximityChangeToNegative = false;
// Apply the proximity sensor.
if (mProximitySensor != null) {
@@ -1454,6 +1478,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
updateScreenBrightnessSetting = mCurrentScreenBrightnessSetting != brightnessState;
mAppliedAutoBrightness = true;
mBrightnessReasonTemp.setReason(BrightnessReason.REASON_AUTOMATIC);
if (mScreenOffBrightnessSensorController != null) {
mScreenOffBrightnessSensorController.setLightSensorEnabled(false);
}
} else {
mAppliedAutoBrightness = false;
}
@@ -1481,6 +1508,19 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
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.
if (Float.isNaN(brightnessState)) {
brightnessState = clampScreenBrightness(mCurrentScreenBrightnessSetting);
@@ -2052,6 +2092,14 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
fallbackType);
}
private void loadScreenOffBrightnessSensor() {
DisplayDeviceConfig.SensorData screenOffBrightnessSensor =
mDisplayDeviceConfig.getScreenOffBrightnessSensor();
mScreenOffBrightnessSensor = SensorUtils.findSensor(mSensorManager,
screenOffBrightnessSensor.type, screenOffBrightnessSensor.name,
SensorUtils.NO_FALLBACK);
}
private void loadProximitySensor() {
if (DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) {
return;
@@ -3201,7 +3249,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
static final int REASON_OVERRIDE = 7;
static final int REASON_TEMPORARY = 8;
static final int REASON_BOOST = 9;
static final int REASON_MAX = REASON_BOOST;
static final int REASON_SCREEN_OFF_BRIGHTNESS_SENSOR = 10;
static final int REASON_MAX = REASON_SCREEN_OFF_BRIGHTNESS_SENSOR;
static final int MODIFIER_DIMMED = 0x1;
static final int MODIFIER_LOW_POWER = 0x2;
@@ -3311,6 +3360,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
case REASON_OVERRIDE: return "override";
case REASON_TEMPORARY: return "temporary";
case REASON_BOOST: return "boost";
case REASON_SCREEN_OFF_BRIGHTNESS_SENSOR: return "screen_off_brightness_sensor";
default: return Integer.toString(reason);
}
}

View File

@@ -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();
}
}

View File

@@ -74,6 +74,9 @@
<xs:element type="sensorDetails" name="lightSensor">
<xs:annotation name="final"/>
</xs:element>
<xs:element type="sensorDetails" name="screenOffBrightnessSensor">
<xs:annotation name="final"/>
</xs:element>
<xs:element type="sensorDetails" name="proxSensor">
<xs:annotation name="final"/>
</xs:element>
@@ -109,6 +112,11 @@
<xs:element type="thresholds" name="ambientBrightnessChangeThresholdsIdle" minOccurs="0" maxOccurs="1">
<xs:annotation name="final"/>
</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:complexType>
</xs:element>
@@ -485,4 +493,10 @@
</xs:element>
</xs:sequence>
</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>

View File

@@ -98,6 +98,8 @@ package com.android.server.display.config {
method public final java.math.BigInteger getScreenBrightnessRampIncreaseMaxMillis();
method public final java.math.BigDecimal getScreenBrightnessRampSlowDecrease();
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 public final void setAmbientBrightnessChangeThresholds(@NonNull 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 setScreenBrightnessRampSlowDecrease(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);
}
@@ -160,6 +164,11 @@ package com.android.server.display.config {
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 {
ctor public NitsMap();
method public String getInterpolation();

View File

@@ -161,6 +161,14 @@ public final class DisplayDeviceConfigTest {
assertArrayEquals(new int[]{70, 80},
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,
// HighBrightnessModeData AmbientLightSensor, RefreshRateLimitations and ProximitySensor.
}
@@ -232,6 +240,7 @@ public final class DisplayDeviceConfigTest {
HIGH_BRIGHTNESS_THRESHOLD_OF_PEAK_REFRESH_RATE);
assertArrayEquals(mDisplayDeviceConfig.getHighAmbientBrightnessThresholds(),
HIGH_AMBIENT_THRESHOLD_OF_PEAK_REFRESH_RATE);
// Todo(brup): Add asserts for BrightnessThrottlingData, DensityMapping,
// HighBrightnessModeData AmbientLightSensor, RefreshRateLimitations and ProximitySensor.
}
@@ -283,6 +292,10 @@ public final class DisplayDeviceConfigTest {
+ "<thermalStatusLimit>light</thermalStatusLimit>\n"
+ "<allowInLowPowerMode>false</allowInLowPowerMode>\n"
+ "</highBrightnessMode>\n"
+ "<screenOffBrightnessSensor>\n"
+ "<type>sensor_12345</type>\n"
+ "<name>Sensor 12345</name>\n"
+ "</screenOffBrightnessSensor>\n"
+ "<ambientBrightnessChangeThresholds>\n"
+ "<brighteningThresholds>\n"
+ "<minimum>10</minimum>\n"
@@ -467,6 +480,13 @@ public final class DisplayDeviceConfigTest {
+ "</blockingZoneThreshold>\n"
+ "</higherBlockingZoneConfigs>\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";
}
@@ -544,6 +564,7 @@ public final class DisplayDeviceConfigTest {
when(mResources.getIntArray(
R.array.config_highAmbientBrightnessThresholdsOfFixedRefreshRate))
.thenReturn(HIGH_AMBIENT_THRESHOLD_OF_PEAK_REFRESH_RATE);
mDisplayDeviceConfig = DisplayDeviceConfig.create(mContext, true);
}

View File

@@ -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);
}
}

View File

@@ -28,13 +28,13 @@ import java.lang.reflect.Method;
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 =
SensorEvent.class.getDeclaredConstructor(int.class);
constructor.setAccessible(true);
final SensorEvent event = constructor.newInstance(1);
event.sensor = sensor;
event.values[0] = lux;
event.values[0] = value;
event.timestamp = SystemClock.elapsedRealtimeNanos();
return event;
}