BrightnessTracker should accomodate multiple ambient sensors
Refactor BrightnessTracker so that it receives an array of lux readings rather than listening to the light sensor Bug: 215100807 Test: atest BrightnessTrackerTest Test: atest AutomaticBrightnessControllerTest Change-Id: I9807ecb39ac8962d2dae9e53c68e6eadbba5c50f Merged-In: I9807ecb39ac8962d2dae9e53c68e6eadbba5c50f
This commit is contained in:
@@ -602,6 +602,14 @@ class AutomaticBrightnessController {
|
||||
mAmbientBrightnessThresholdsIdle.dump(pw);
|
||||
}
|
||||
|
||||
public float[] getLastSensorValues() {
|
||||
return mAmbientLightRingBuffer.getAllLuxValues();
|
||||
}
|
||||
|
||||
public long[] getLastSensorTimestamps() {
|
||||
return mAmbientLightRingBuffer.getAllTimestamps();
|
||||
}
|
||||
|
||||
private String configStateToString(int state) {
|
||||
switch (state) {
|
||||
case AUTO_BRIGHTNESS_ENABLED:
|
||||
@@ -1231,10 +1239,42 @@ class AutomaticBrightnessController {
|
||||
return mRingLux[offsetOf(index)];
|
||||
}
|
||||
|
||||
public float[] getAllLuxValues() {
|
||||
float[] values = new float[mCount];
|
||||
if (mCount == 0) {
|
||||
return values;
|
||||
}
|
||||
|
||||
if (mStart < mEnd) {
|
||||
System.arraycopy(mRingLux, mStart, values, 0, mCount);
|
||||
} else {
|
||||
System.arraycopy(mRingLux, mStart, values, 0, mCapacity - mStart);
|
||||
System.arraycopy(mRingLux, 0, values, mCapacity - mStart, mEnd);
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
public long getTime(int index) {
|
||||
return mRingTime[offsetOf(index)];
|
||||
}
|
||||
|
||||
public long[] getAllTimestamps() {
|
||||
long[] values = new long[mCount];
|
||||
if (mCount == 0) {
|
||||
return values;
|
||||
}
|
||||
|
||||
if (mStart < mEnd) {
|
||||
System.arraycopy(mRingTime, mStart, values, 0, mCount);
|
||||
} else {
|
||||
System.arraycopy(mRingTime, mStart, values, 0, mCapacity - mStart);
|
||||
System.arraycopy(mRingTime, 0, values, mCapacity - mStart, mEnd);
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
public void push(long time, float lux) {
|
||||
int next = mEnd;
|
||||
if (mCount == mCapacity) {
|
||||
|
||||
@@ -79,10 +79,8 @@ import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.Deque;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -101,8 +99,6 @@ public class BrightnessTracker {
|
||||
private static final int MAX_EVENTS = 100;
|
||||
// Discard events when reading or writing that are older than this.
|
||||
private static final long MAX_EVENT_AGE = TimeUnit.DAYS.toMillis(30);
|
||||
// Time over which we keep lux sensor readings.
|
||||
private static final long LUX_EVENT_HORIZON = TimeUnit.SECONDS.toNanos(10);
|
||||
|
||||
private static final String TAG_EVENTS = "events";
|
||||
private static final String TAG_EVENT = "event";
|
||||
@@ -174,8 +170,6 @@ public class BrightnessTracker {
|
||||
// Lock held while collecting data related to brightness changes.
|
||||
private final Object mDataCollectionLock = new Object();
|
||||
@GuardedBy("mDataCollectionLock")
|
||||
private Deque<LightData> mLastSensorReadings = new ArrayDeque<>();
|
||||
@GuardedBy("mDataCollectionLock")
|
||||
private float mLastBatteryLevel = Float.NaN;
|
||||
@GuardedBy("mDataCollectionLock")
|
||||
private float mLastBrightness = -1;
|
||||
@@ -327,7 +321,8 @@ public class BrightnessTracker {
|
||||
*/
|
||||
public void notifyBrightnessChanged(float brightness, boolean userInitiated,
|
||||
float powerBrightnessFactor, boolean isUserSetBrightness,
|
||||
boolean isDefaultBrightnessConfig, String uniqueDisplayId) {
|
||||
boolean isDefaultBrightnessConfig, String uniqueDisplayId, float[] luxValues,
|
||||
long[] luxTimestamps) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, String.format("notifyBrightnessChanged(brightness=%f, userInitiated=%b)",
|
||||
brightness, userInitiated));
|
||||
@@ -335,7 +330,7 @@ public class BrightnessTracker {
|
||||
Message m = mBgHandler.obtainMessage(MSG_BRIGHTNESS_CHANGED,
|
||||
userInitiated ? 1 : 0, 0 /*unused*/, new BrightnessChangeValues(brightness,
|
||||
powerBrightnessFactor, isUserSetBrightness, isDefaultBrightnessConfig,
|
||||
mInjector.currentTimeMillis(), uniqueDisplayId));
|
||||
mInjector.currentTimeMillis(), uniqueDisplayId, luxValues, luxTimestamps));
|
||||
m.sendToTarget();
|
||||
}
|
||||
|
||||
@@ -349,7 +344,8 @@ public class BrightnessTracker {
|
||||
|
||||
private void handleBrightnessChanged(float brightness, boolean userInitiated,
|
||||
float powerBrightnessFactor, boolean isUserSetBrightness,
|
||||
boolean isDefaultBrightnessConfig, long timestamp, String uniqueDisplayId) {
|
||||
boolean isDefaultBrightnessConfig, long timestamp, String uniqueDisplayId,
|
||||
float[] luxValues, long[] luxTimestamps) {
|
||||
BrightnessChangeEvent.Builder builder;
|
||||
|
||||
synchronized (mDataCollectionLock) {
|
||||
@@ -376,28 +372,22 @@ public class BrightnessTracker {
|
||||
builder.setIsDefaultBrightnessConfig(isDefaultBrightnessConfig);
|
||||
builder.setUniqueDisplayId(uniqueDisplayId);
|
||||
|
||||
final int readingCount = mLastSensorReadings.size();
|
||||
if (readingCount == 0) {
|
||||
if (luxValues.length == 0) {
|
||||
// No sensor data so ignore this.
|
||||
return;
|
||||
}
|
||||
|
||||
float[] luxValues = new float[readingCount];
|
||||
long[] luxTimestamps = new long[readingCount];
|
||||
long[] luxTimestampsMillis = new long[luxTimestamps.length];
|
||||
|
||||
int pos = 0;
|
||||
|
||||
// Convert sensor timestamp in elapsed time nanos to current time millis.
|
||||
// Convert lux timestamp in elapsed time to current time.
|
||||
long currentTimeMillis = mInjector.currentTimeMillis();
|
||||
long elapsedTimeNanos = mInjector.elapsedRealtimeNanos();
|
||||
for (LightData reading : mLastSensorReadings) {
|
||||
luxValues[pos] = reading.lux;
|
||||
luxTimestamps[pos] = currentTimeMillis -
|
||||
TimeUnit.NANOSECONDS.toMillis(elapsedTimeNanos - reading.timestamp);
|
||||
++pos;
|
||||
for (int i = 0; i < luxTimestamps.length; i++) {
|
||||
luxTimestampsMillis[i] = currentTimeMillis - (TimeUnit.NANOSECONDS.toMillis(
|
||||
elapsedTimeNanos) - luxTimestamps[i]);
|
||||
}
|
||||
builder.setLuxValues(luxValues);
|
||||
builder.setLuxTimestamps(luxTimestamps);
|
||||
builder.setLuxTimestamps(luxTimestampsMillis);
|
||||
|
||||
builder.setBatteryLevel(mLastBatteryLevel);
|
||||
builder.setLastBrightness(previousBrightness);
|
||||
@@ -452,9 +442,6 @@ public class BrightnessTracker {
|
||||
if (mLightSensor != lightSensor) {
|
||||
mLightSensor = lightSensor;
|
||||
stopSensorListener();
|
||||
synchronized (mDataCollectionLock) {
|
||||
mLastSensorReadings.clear();
|
||||
}
|
||||
// Attempt to restart the sensor listener. It will check to see if it should be running
|
||||
// so there is no need to also check here.
|
||||
startSensorListener();
|
||||
@@ -774,12 +761,6 @@ public class BrightnessTracker {
|
||||
pw.println(" mLightSensor=" + mLightSensor);
|
||||
pw.println(" mLastBatteryLevel=" + mLastBatteryLevel);
|
||||
pw.println(" mLastBrightness=" + mLastBrightness);
|
||||
pw.println(" mLastSensorReadings.size=" + mLastSensorReadings.size());
|
||||
if (!mLastSensorReadings.isEmpty()) {
|
||||
pw.println(" mLastSensorReadings time span "
|
||||
+ mLastSensorReadings.peekFirst().timestamp + "->"
|
||||
+ mLastSensorReadings.peekLast().timestamp);
|
||||
}
|
||||
}
|
||||
synchronized (mEventsLock) {
|
||||
pw.println(" mEventsDirty=" + mEventsDirty);
|
||||
@@ -895,43 +876,6 @@ public class BrightnessTracker {
|
||||
return ParceledListSlice.emptyList();
|
||||
}
|
||||
|
||||
// Not allowed to keep the SensorEvent so used to copy the data we care about.
|
||||
private static class LightData {
|
||||
public float lux;
|
||||
// Time in elapsedRealtimeNanos
|
||||
public long timestamp;
|
||||
}
|
||||
|
||||
private void recordSensorEvent(SensorEvent event) {
|
||||
long horizon = mInjector.elapsedRealtimeNanos() - LUX_EVENT_HORIZON;
|
||||
synchronized (mDataCollectionLock) {
|
||||
if (DEBUG) {
|
||||
Slog.v(TAG, "Sensor event " + event);
|
||||
}
|
||||
if (!mLastSensorReadings.isEmpty()
|
||||
&& event.timestamp < mLastSensorReadings.getLast().timestamp) {
|
||||
// Ignore event that came out of order.
|
||||
return;
|
||||
}
|
||||
LightData data = null;
|
||||
while (!mLastSensorReadings.isEmpty()
|
||||
&& mLastSensorReadings.getFirst().timestamp < horizon) {
|
||||
// Remove data that has fallen out of the window.
|
||||
data = mLastSensorReadings.removeFirst();
|
||||
}
|
||||
// We put back the last one we removed so we know how long
|
||||
// the first sensor reading was valid for.
|
||||
if (data != null) {
|
||||
mLastSensorReadings.addFirst(data);
|
||||
}
|
||||
|
||||
data = new LightData();
|
||||
data.timestamp = event.timestamp;
|
||||
data.lux = event.values[0];
|
||||
mLastSensorReadings.addLast(data);
|
||||
}
|
||||
}
|
||||
|
||||
private void recordAmbientBrightnessStats(SensorEvent event) {
|
||||
mAmbientBrightnessStatsTracker.add(mCurrentUserId, event.values[0]);
|
||||
}
|
||||
@@ -945,7 +889,6 @@ public class BrightnessTracker {
|
||||
private final class SensorListener implements SensorEventListener {
|
||||
@Override
|
||||
public void onSensorChanged(SensorEvent event) {
|
||||
recordSensorEvent(event);
|
||||
recordAmbientBrightnessStats(event);
|
||||
}
|
||||
|
||||
@@ -1032,7 +975,7 @@ public class BrightnessTracker {
|
||||
handleBrightnessChanged(values.brightness, userInitiatedChange,
|
||||
values.powerBrightnessFactor, values.isUserSetBrightness,
|
||||
values.isDefaultBrightnessConfig, values.timestamp,
|
||||
values.uniqueDisplayId);
|
||||
values.uniqueDisplayId, values.luxValues, values.luxTimestamps);
|
||||
break;
|
||||
case MSG_START_SENSOR_LISTENER:
|
||||
startSensorListener();
|
||||
@@ -1068,16 +1011,20 @@ public class BrightnessTracker {
|
||||
public final boolean isDefaultBrightnessConfig;
|
||||
public final long timestamp;
|
||||
public final String uniqueDisplayId;
|
||||
public final float[] luxValues;
|
||||
public final long[] luxTimestamps;
|
||||
|
||||
BrightnessChangeValues(float brightness, float powerBrightnessFactor,
|
||||
boolean isUserSetBrightness, boolean isDefaultBrightnessConfig,
|
||||
long timestamp, String uniqueDisplayId) {
|
||||
long timestamp, String uniqueDisplayId, float[] luxValues, long[] luxTimestamps) {
|
||||
this.brightness = brightness;
|
||||
this.powerBrightnessFactor = powerBrightnessFactor;
|
||||
this.isUserSetBrightness = isUserSetBrightness;
|
||||
this.isDefaultBrightnessConfig = isDefaultBrightnessConfig;
|
||||
this.timestamp = timestamp;
|
||||
this.uniqueDisplayId = uniqueDisplayId;
|
||||
this.luxValues = luxValues;
|
||||
this.luxTimestamps = luxTimestamps;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2458,7 +2458,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
|
||||
: 1.0f;
|
||||
mBrightnessTracker.notifyBrightnessChanged(brightnessInNits, userInitiated,
|
||||
powerFactor, hadUserDataPoint,
|
||||
mAutomaticBrightnessController.isDefaultConfig(), mUniqueDisplayId);
|
||||
mAutomaticBrightnessController.isDefaultConfig(), mUniqueDisplayId,
|
||||
mAutomaticBrightnessController.getLastSensorValues(),
|
||||
mAutomaticBrightnessController.getLastSensorTimestamps());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.server.display;
|
||||
|
||||
import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
@@ -178,7 +179,7 @@ public class AutomaticBrightnessControllerTest {
|
||||
|
||||
// Send new sensor value and verify
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, (int) lux1));
|
||||
assertEquals(normalizedBrightness1, mController.getAutomaticScreenBrightness(), 0.001f);
|
||||
assertEquals(normalizedBrightness1, mController.getAutomaticScreenBrightness(), EPSILON);
|
||||
|
||||
// Set up system to return 0.0f (minimum possible brightness) as a brightness value
|
||||
float lux2 = 10.0f;
|
||||
@@ -192,7 +193,7 @@ public class AutomaticBrightnessControllerTest {
|
||||
|
||||
// Send new sensor value and verify
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, (int) lux2));
|
||||
assertEquals(normalizedBrightness2, mController.getAutomaticScreenBrightness(), 0.001f);
|
||||
assertEquals(normalizedBrightness2, mController.getAutomaticScreenBrightness(), EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -221,7 +222,7 @@ public class AutomaticBrightnessControllerTest {
|
||||
|
||||
// Send new sensor value and verify
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, (int) lux1));
|
||||
assertEquals(normalizedBrightness1, mController.getAutomaticScreenBrightness(), 0.001f);
|
||||
assertEquals(normalizedBrightness1, mController.getAutomaticScreenBrightness(), EPSILON);
|
||||
|
||||
|
||||
// Set up system to return 1.0f as a brightness value (brightness_max)
|
||||
@@ -236,7 +237,7 @@ public class AutomaticBrightnessControllerTest {
|
||||
|
||||
// Send new sensor value and verify
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, (int) lux2));
|
||||
assertEquals(normalizedBrightness2, mController.getAutomaticScreenBrightness(), 0.001f);
|
||||
assertEquals(normalizedBrightness2, mController.getAutomaticScreenBrightness(), EPSILON);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -418,6 +419,12 @@ public class AutomaticBrightnessControllerTest {
|
||||
// ambient lux goes to 0
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, 0));
|
||||
assertEquals(0.0f, mController.getAmbientLux(), EPSILON);
|
||||
|
||||
// only the values within the horizon should be kept
|
||||
assertArrayEquals(new float[] {10000, 10000, 0, 0, 0}, mController.getLastSensorValues(),
|
||||
EPSILON);
|
||||
assertArrayEquals(new long[] {4000, 4500, 5000, 5500, 6000},
|
||||
mController.getLastSensorTimestamps());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -489,4 +496,92 @@ public class AutomaticBrightnessControllerTest {
|
||||
0 /* adjustment */, false /* userChanged */, DisplayPowerRequest.POLICY_BRIGHT);
|
||||
assertEquals(BRIGHTNESS_MAX_FLOAT, mController.getAutomaticScreenBrightness(), 0.0f);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSensorReadings() throws Exception {
|
||||
ArgumentCaptor<SensorEventListener> listenerCaptor =
|
||||
ArgumentCaptor.forClass(SensorEventListener.class);
|
||||
verify(mSensorManager).registerListener(listenerCaptor.capture(), eq(mLightSensor),
|
||||
eq(INITIAL_LIGHT_SENSOR_RATE * 1000), any(Handler.class));
|
||||
SensorEventListener listener = listenerCaptor.getValue();
|
||||
|
||||
// Choose values such that the ring buffer's capacity is extended and the buffer is pruned
|
||||
int increment = 11;
|
||||
int lux = 5000;
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
lux += increment;
|
||||
mClock.fastForward(increment);
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, lux));
|
||||
}
|
||||
|
||||
int valuesCount = (int) Math.ceil((double) AMBIENT_LIGHT_HORIZON_LONG / increment + 1);
|
||||
float[] sensorValues = mController.getLastSensorValues();
|
||||
long[] sensorTimestamps = mController.getLastSensorTimestamps();
|
||||
|
||||
// Only the values within the horizon should be kept
|
||||
assertEquals(valuesCount, sensorValues.length);
|
||||
assertEquals(valuesCount, sensorTimestamps.length);
|
||||
|
||||
long sensorTimestamp = mClock.now();
|
||||
for (int i = valuesCount - 1; i >= 1; i--) {
|
||||
assertEquals(lux, sensorValues[i], EPSILON);
|
||||
assertEquals(sensorTimestamp, sensorTimestamps[i]);
|
||||
lux -= increment;
|
||||
sensorTimestamp -= increment;
|
||||
}
|
||||
assertEquals(lux, sensorValues[0], EPSILON);
|
||||
assertEquals(mClock.now() - AMBIENT_LIGHT_HORIZON_LONG, sensorTimestamps[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSensorReadingsFullBuffer() throws Exception {
|
||||
ArgumentCaptor<SensorEventListener> listenerCaptor =
|
||||
ArgumentCaptor.forClass(SensorEventListener.class);
|
||||
verify(mSensorManager).registerListener(listenerCaptor.capture(), eq(mLightSensor),
|
||||
eq(INITIAL_LIGHT_SENSOR_RATE * 1000), any(Handler.class));
|
||||
SensorEventListener listener = listenerCaptor.getValue();
|
||||
int initialCapacity = 150;
|
||||
|
||||
// Choose values such that the ring buffer is pruned
|
||||
int increment1 = 200;
|
||||
int lux = 5000;
|
||||
for (int i = 0; i < 20; i++) {
|
||||
lux += increment1;
|
||||
mClock.fastForward(increment1);
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, lux));
|
||||
}
|
||||
|
||||
int valuesCount = (int) Math.ceil((double) AMBIENT_LIGHT_HORIZON_LONG / increment1 + 1);
|
||||
|
||||
// Choose values such that the buffer becomes full
|
||||
int increment2 = 1;
|
||||
for (int i = 0; i < initialCapacity - valuesCount; i++) {
|
||||
lux += increment2;
|
||||
mClock.fastForward(increment2);
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, lux));
|
||||
}
|
||||
|
||||
float[] sensorValues = mController.getLastSensorValues();
|
||||
long[] sensorTimestamps = mController.getLastSensorTimestamps();
|
||||
|
||||
// The buffer should be full
|
||||
assertEquals(initialCapacity, sensorValues.length);
|
||||
assertEquals(initialCapacity, sensorTimestamps.length);
|
||||
|
||||
long sensorTimestamp = mClock.now();
|
||||
for (int i = initialCapacity - 1; i >= 1; i--) {
|
||||
assertEquals(lux, sensorValues[i], EPSILON);
|
||||
assertEquals(sensorTimestamp, sensorTimestamps[i]);
|
||||
|
||||
if (i >= valuesCount) {
|
||||
lux -= increment2;
|
||||
sensorTimestamp -= increment2;
|
||||
} else {
|
||||
lux -= increment1;
|
||||
sensorTimestamp -= increment1;
|
||||
}
|
||||
}
|
||||
assertEquals(lux, sensorValues[0], EPSILON);
|
||||
assertEquals(mClock.now() - AMBIENT_LIGHT_HORIZON_LONG, sensorTimestamps[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,28 +136,28 @@ public class BrightnessTrackerTest {
|
||||
assertNull(mInjector.mSensorListener);
|
||||
assertNotNull(mInjector.mBroadcastReceiver);
|
||||
assertTrue(mInjector.mIdleScheduled);
|
||||
mInjector.sendScreenChange(/*screen on */ true);
|
||||
mInjector.sendScreenChange(/* screenOn= */ true);
|
||||
assertNotNull(mInjector.mSensorListener);
|
||||
assertTrue(mInjector.mColorSamplingEnabled);
|
||||
|
||||
mInjector.sendScreenChange(/*screen on */ false);
|
||||
mInjector.sendScreenChange(/* screenOn= */ false);
|
||||
assertNull(mInjector.mSensorListener);
|
||||
assertFalse(mInjector.mColorSamplingEnabled);
|
||||
|
||||
// Turn screen on while brightness mode is manual
|
||||
mInjector.setBrightnessMode(/* isBrightnessModeAutomatic */ false);
|
||||
mInjector.sendScreenChange(/*screen on */ true);
|
||||
mInjector.setBrightnessMode(/* isBrightnessModeAutomatic= */ false);
|
||||
mInjector.sendScreenChange(/* screenOn= */ true);
|
||||
assertNull(mInjector.mSensorListener);
|
||||
assertFalse(mInjector.mColorSamplingEnabled);
|
||||
|
||||
// Set brightness mode to automatic while screen is off.
|
||||
mInjector.sendScreenChange(/*screen on */ false);
|
||||
mInjector.setBrightnessMode(/* isBrightnessModeAutomatic */ true);
|
||||
mInjector.sendScreenChange(/* screenOn= */ false);
|
||||
mInjector.setBrightnessMode(/* isBrightnessModeAutomatic= */ true);
|
||||
assertNull(mInjector.mSensorListener);
|
||||
assertFalse(mInjector.mColorSamplingEnabled);
|
||||
|
||||
// Turn on screen while brightness mode is automatic.
|
||||
mInjector.sendScreenChange(/*screen on */ true);
|
||||
mInjector.sendScreenChange(/* screenOn= */ true);
|
||||
assertNotNull(mInjector.mSensorListener);
|
||||
assertTrue(mInjector.mColorSamplingEnabled);
|
||||
|
||||
@@ -188,14 +188,14 @@ public class BrightnessTrackerTest {
|
||||
assertFalse(mInjector.mColorSamplingEnabled);
|
||||
|
||||
// Pretend screen is off, update config to turn on color sampling.
|
||||
mInjector.sendScreenChange(/*screen on */ false);
|
||||
mInjector.sendScreenChange(/* screenOn= */ false);
|
||||
mTracker.setBrightnessConfiguration(buildBrightnessConfiguration(
|
||||
/* collectColorSamples= */ true));
|
||||
mInjector.waitForHandler();
|
||||
assertFalse(mInjector.mColorSamplingEnabled);
|
||||
|
||||
// Pretend screen is on.
|
||||
mInjector.sendScreenChange(/*screen on */ true);
|
||||
mInjector.sendScreenChange(/* screenOn= */ true);
|
||||
assertTrue(mInjector.mColorSamplingEnabled);
|
||||
|
||||
mTracker.stop();
|
||||
@@ -261,7 +261,7 @@ public class BrightnessTrackerTest {
|
||||
assertFalse(mInjector.mColorSamplingEnabled);
|
||||
assertNull(mInjector.mDisplayListener);
|
||||
|
||||
mInjector.setBrightnessMode(/*isBrightnessModeAutomatic*/ true);
|
||||
mInjector.setBrightnessMode(/* isBrightnessModeAutomatic= */ true);
|
||||
assertNotNull(mInjector.mSensorListener);
|
||||
assertTrue(mInjector.mColorSamplingEnabled);
|
||||
assertNotNull(mInjector.mDisplayListener);
|
||||
@@ -272,16 +272,15 @@ public class BrightnessTrackerTest {
|
||||
mInjector.mColorSamplingEnabled = false;
|
||||
mInjector.mDisplayListener = null;
|
||||
// Duplicate notification
|
||||
mInjector.setBrightnessMode(/*isBrightnessModeAutomatic*/ true);
|
||||
mInjector.setBrightnessMode(/* isBrightnessModeAutomatic= */ true);
|
||||
// Sensor shouldn't have been registered as it was already registered.
|
||||
assertNull(mInjector.mSensorListener);
|
||||
assertFalse(mInjector.mColorSamplingEnabled);
|
||||
assertNull(mInjector.mDisplayListener);
|
||||
mInjector.mSensorListener = listener;
|
||||
mInjector.mDisplayListener = displayListener;
|
||||
mInjector.mColorSamplingEnabled = true;
|
||||
|
||||
mInjector.setBrightnessMode(/*isBrightnessModeAutomatic*/ false);
|
||||
mInjector.setBrightnessMode(/* isBrightnessModeAutomatic= */ false);
|
||||
assertNull(mInjector.mSensorListener);
|
||||
assertFalse(mInjector.mColorSamplingEnabled);
|
||||
assertNull(mInjector.mDisplayListener);
|
||||
@@ -301,19 +300,21 @@ public class BrightnessTrackerTest {
|
||||
final String displayId = "1234";
|
||||
|
||||
startTracker(mTracker);
|
||||
mInjector.mSensorListener.onSensorChanged(createSensorEvent(1.0f));
|
||||
final long sensorTime = TimeUnit.NANOSECONDS.toMillis(mInjector.elapsedRealtimeNanos());
|
||||
mInjector.incrementTime(TimeUnit.SECONDS.toMillis(2));
|
||||
notifyBrightnessChanged(mTracker, brightness, displayId);
|
||||
final long currentTime = mInjector.currentTimeMillis();
|
||||
notifyBrightnessChanged(mTracker, brightness, displayId, new float[] {1.0f},
|
||||
new long[] {sensorTime});
|
||||
List<BrightnessChangeEvent> events = mTracker.getEvents(0, true).getList();
|
||||
mTracker.stop();
|
||||
|
||||
assertEquals(1, events.size());
|
||||
BrightnessChangeEvent event = events.get(0);
|
||||
assertEquals(mInjector.currentTimeMillis(), event.timeStamp);
|
||||
assertEquals(currentTime, event.timeStamp);
|
||||
assertEquals(displayId, event.uniqueDisplayId);
|
||||
assertEquals(1, event.luxValues.length);
|
||||
assertEquals(1.0f, event.luxValues[0], FLOAT_DELTA);
|
||||
assertEquals(mInjector.currentTimeMillis() - TimeUnit.SECONDS.toMillis(2),
|
||||
assertEquals(currentTime - TimeUnit.SECONDS.toMillis(2),
|
||||
event.luxTimestamps[0]);
|
||||
assertEquals(brightness, event.brightness, FLOAT_DELTA);
|
||||
assertEquals(DEFAULT_INITIAL_BRIGHTNESS, event.lastBrightness, FLOAT_DELTA);
|
||||
@@ -339,9 +340,9 @@ public class BrightnessTrackerTest {
|
||||
startTracker(mTracker, initialBrightness, DEFAULT_COLOR_SAMPLING_ENABLED);
|
||||
mInjector.mBroadcastReceiver.onReceive(InstrumentationRegistry.getContext(),
|
||||
batteryChangeEvent(30, 60));
|
||||
mInjector.mSensorListener.onSensorChanged(createSensorEvent(1000.0f));
|
||||
final long sensorTime = mInjector.currentTimeMillis();
|
||||
notifyBrightnessChanged(mTracker, brightness, displayId);
|
||||
final long currentTime = mInjector.currentTimeMillis();
|
||||
notifyBrightnessChanged(mTracker, brightness, displayId, new float[] {1000.0f},
|
||||
new long[] {TimeUnit.NANOSECONDS.toMillis(mInjector.elapsedRealtimeNanos())});
|
||||
List<BrightnessChangeEvent> eventsNoPackage
|
||||
= mTracker.getEvents(0, false).getList();
|
||||
List<BrightnessChangeEvent> events = mTracker.getEvents(0, true).getList();
|
||||
@@ -349,10 +350,10 @@ public class BrightnessTrackerTest {
|
||||
|
||||
assertEquals(1, events.size());
|
||||
BrightnessChangeEvent event = events.get(0);
|
||||
assertEquals(event.timeStamp, mInjector.currentTimeMillis());
|
||||
assertEquals(event.timeStamp, currentTime);
|
||||
assertEquals(displayId, event.uniqueDisplayId);
|
||||
assertArrayEquals(new float[] {1000.0f}, event.luxValues, 0.01f);
|
||||
assertArrayEquals(new long[] {sensorTime}, event.luxTimestamps);
|
||||
assertArrayEquals(new float[] {1000.0f}, event.luxValues, FLOAT_DELTA);
|
||||
assertArrayEquals(new long[] {currentTime}, event.luxTimestamps);
|
||||
assertEquals(brightness, event.brightness, FLOAT_DELTA);
|
||||
assertEquals(initialBrightness, event.lastBrightness, FLOAT_DELTA);
|
||||
assertEquals(0.5, event.batteryLevel, FLOAT_DELTA);
|
||||
@@ -374,13 +375,12 @@ public class BrightnessTrackerTest {
|
||||
public void testIgnoreAutomaticBrightnessChange() {
|
||||
final int initialBrightness = 30;
|
||||
startTracker(mTracker, initialBrightness, DEFAULT_COLOR_SAMPLING_ENABLED);
|
||||
mInjector.mSensorListener.onSensorChanged(createSensorEvent(1.0f));
|
||||
mInjector.incrementTime(TimeUnit.SECONDS.toMillis(1));
|
||||
|
||||
final int systemUpdatedBrightness = 20;
|
||||
notifyBrightnessChanged(mTracker, systemUpdatedBrightness, false /*userInitiated*/,
|
||||
0.5f /*powerBrightnessFactor(*/, false /*isUserSetBrightness*/,
|
||||
false /*isDefaultBrightnessConfig*/, DEFAULT_DISPLAY_ID);
|
||||
notifyBrightnessChanged(mTracker, systemUpdatedBrightness, /* userInitiated= */ false,
|
||||
/* powerBrightnessFactor= */ 0.5f, /* isUserSetBrightness= */ false,
|
||||
/* isDefaultBrightnessConfig= */ false, DEFAULT_DISPLAY_ID);
|
||||
List<BrightnessChangeEvent> events = mTracker.getEvents(0, true).getList();
|
||||
// No events because we filtered out our change.
|
||||
assertEquals(0, events.size());
|
||||
@@ -408,10 +408,8 @@ public class BrightnessTrackerTest {
|
||||
@Test
|
||||
public void testLimitedBufferSize() {
|
||||
startTracker(mTracker);
|
||||
mInjector.mSensorListener.onSensorChanged(createSensorEvent(1.0f));
|
||||
|
||||
for (int brightness = 0; brightness <= 255; ++brightness) {
|
||||
mInjector.mSensorListener.onSensorChanged(createSensorEvent(1.0f));
|
||||
mInjector.incrementTime(TimeUnit.SECONDS.toNanos(1));
|
||||
notifyBrightnessChanged(mTracker, brightness);
|
||||
}
|
||||
@@ -426,33 +424,6 @@ public class BrightnessTrackerTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLimitedSensorEvents() {
|
||||
final int brightness = 20;
|
||||
|
||||
startTracker(mTracker);
|
||||
// 20 Sensor events 1 second apart.
|
||||
for (int i = 0; i < 20; ++i) {
|
||||
mInjector.incrementTime(TimeUnit.SECONDS.toMillis(1));
|
||||
mInjector.mSensorListener.onSensorChanged(createSensorEvent(i + 1.0f));
|
||||
}
|
||||
notifyBrightnessChanged(mTracker, 20);
|
||||
List<BrightnessChangeEvent> events = mTracker.getEvents(0, true).getList();
|
||||
mTracker.stop();
|
||||
|
||||
assertEquals(1, events.size());
|
||||
BrightnessChangeEvent event = events.get(0);
|
||||
assertEquals(mInjector.currentTimeMillis(), event.timeStamp);
|
||||
|
||||
// 12 sensor events, 11 for 0->10 seconds + 1 previous event.
|
||||
assertEquals(12, event.luxValues.length);
|
||||
for (int i = 0; i < 12; ++i) {
|
||||
assertEquals(event.luxTimestamps[11 - i],
|
||||
mInjector.currentTimeMillis() - i * TimeUnit.SECONDS.toMillis(1));
|
||||
}
|
||||
assertEquals(brightness, event.brightness, FLOAT_DELTA);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadEvents() throws Exception {
|
||||
BrightnessTracker tracker = new BrightnessTracker(InstrumentationRegistry.getContext(),
|
||||
@@ -607,15 +578,16 @@ public class BrightnessTrackerTest {
|
||||
startTracker(mTracker);
|
||||
mInjector.mBroadcastReceiver.onReceive(InstrumentationRegistry.getContext(),
|
||||
batteryChangeEvent(30, 100));
|
||||
mInjector.mSensorListener.onSensorChanged(createSensorEvent(2000.0f));
|
||||
final long firstSensorTime = mInjector.currentTimeMillis();
|
||||
final long elapsedTime1 = TimeUnit.NANOSECONDS.toMillis(mInjector.elapsedRealtimeNanos());
|
||||
final long currentTime1 = mInjector.currentTimeMillis();
|
||||
mInjector.incrementTime(TimeUnit.SECONDS.toMillis(2));
|
||||
mInjector.mSensorListener.onSensorChanged(createSensorEvent(3000.0f));
|
||||
final long secondSensorTime = mInjector.currentTimeMillis();
|
||||
final long elapsedTime2 = TimeUnit.NANOSECONDS.toMillis(mInjector.elapsedRealtimeNanos());
|
||||
final long currentTime2 = mInjector.currentTimeMillis();
|
||||
mInjector.incrementTime(TimeUnit.SECONDS.toMillis(3));
|
||||
notifyBrightnessChanged(mTracker, brightness, true /*userInitiated*/,
|
||||
0.5f /*powerBrightnessFactor*/, true /*hasUserBrightnessPoints*/,
|
||||
false /*isDefaultBrightnessConfig*/, displayId);
|
||||
notifyBrightnessChanged(mTracker, brightness, /* userInitiated= */ true,
|
||||
/* powerBrightnessFactor= */ 0.5f, /* isUserSetBrightness= */ true,
|
||||
/* isDefaultBrightnessConfig= */ false, displayId, new float[] {2000.0f, 3000.0f},
|
||||
new long[] {elapsedTime1, elapsedTime2});
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
mTracker.writeEventsLocked(baos);
|
||||
mTracker.stop();
|
||||
@@ -631,7 +603,7 @@ public class BrightnessTrackerTest {
|
||||
BrightnessChangeEvent event = events.get(0);
|
||||
assertEquals(displayId, event.uniqueDisplayId);
|
||||
assertArrayEquals(new float[] {2000.0f, 3000.0f}, event.luxValues, FLOAT_DELTA);
|
||||
assertArrayEquals(new long[] {firstSensorTime, secondSensorTime}, event.luxTimestamps);
|
||||
assertArrayEquals(new long[] {currentTime1, currentTime2}, event.luxTimestamps);
|
||||
assertEquals(brightness, event.brightness, FLOAT_DELTA);
|
||||
assertEquals(0.3, event.batteryLevel, FLOAT_DELTA);
|
||||
assertTrue(event.nightMode);
|
||||
@@ -646,53 +618,6 @@ public class BrightnessTrackerTest {
|
||||
assertEquals(10000, event.colorSampleDuration);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWritePrunesOldEvents() throws Exception {
|
||||
final int brightness = 20;
|
||||
|
||||
mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_ACTIVATED, 1);
|
||||
mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE, 3339);
|
||||
|
||||
mInjector.mSecureIntSettings.put(Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, 1);
|
||||
mInjector.mSecureIntSettings.put(Settings.Secure.REDUCE_BRIGHT_COLORS_LEVEL, 40);
|
||||
|
||||
startTracker(mTracker);
|
||||
mInjector.mBroadcastReceiver.onReceive(InstrumentationRegistry.getContext(),
|
||||
batteryChangeEvent(30, 100));
|
||||
mInjector.mSensorListener.onSensorChanged(createSensorEvent(1000.0f));
|
||||
mInjector.incrementTime(TimeUnit.SECONDS.toMillis(1));
|
||||
mInjector.mSensorListener.onSensorChanged(createSensorEvent(2000.0f));
|
||||
final long sensorTime = mInjector.currentTimeMillis();
|
||||
notifyBrightnessChanged(mTracker, brightness);
|
||||
|
||||
// 31 days later
|
||||
mInjector.incrementTime(TimeUnit.DAYS.toMillis(31));
|
||||
mInjector.mSensorListener.onSensorChanged(createSensorEvent(3000.0f));
|
||||
notifyBrightnessChanged(mTracker, brightness);
|
||||
final long eventTime = mInjector.currentTimeMillis();
|
||||
|
||||
List<BrightnessChangeEvent> events = mTracker.getEvents(0, true).getList();
|
||||
assertEquals(2, events.size());
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
mTracker.writeEventsLocked(baos);
|
||||
events = mTracker.getEvents(0, true).getList();
|
||||
mTracker.stop();
|
||||
|
||||
assertEquals(1, events.size());
|
||||
BrightnessChangeEvent event = events.get(0);
|
||||
assertEquals(eventTime, event.timeStamp);
|
||||
|
||||
// We will keep one of the old sensor events because we keep 1 event outside the window.
|
||||
assertArrayEquals(new float[] {2000.0f, 3000.0f}, event.luxValues, FLOAT_DELTA);
|
||||
assertArrayEquals(new long[] {sensorTime, eventTime}, event.luxTimestamps);
|
||||
assertEquals(brightness, event.brightness, FLOAT_DELTA);
|
||||
assertEquals(0.3, event.batteryLevel, FLOAT_DELTA);
|
||||
assertTrue(event.nightMode);
|
||||
assertTrue(event.reduceBrightColors);
|
||||
assertEquals(3339, event.colorTemperature);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParcelUnParcel() {
|
||||
Parcel parcel = Parcel.obtain();
|
||||
@@ -796,9 +721,10 @@ public class BrightnessTrackerTest {
|
||||
|
||||
// Send an event.
|
||||
long eventTime = mInjector.currentTimeMillis();
|
||||
mTracker.notifyBrightnessChanged(brightness, true /*userInitiated*/,
|
||||
1.0f /*powerBrightnessFactor*/, false /*isUserSetBrightness*/,
|
||||
false /*isDefaultBrightnessConfig*/, DEFAULT_DISPLAY_ID);
|
||||
mTracker.notifyBrightnessChanged(brightness, /* userInitiated= */ true,
|
||||
/* powerBrightnessFactor= */ 1.0f, /* isUserSetBrightness= */ false,
|
||||
/* isDefaultBrightnessConfig= */ false, DEFAULT_DISPLAY_ID, new float[10],
|
||||
new long[10]);
|
||||
|
||||
// Time passes before handler can run.
|
||||
mInjector.incrementTime(TimeUnit.SECONDS.toMillis(2));
|
||||
@@ -890,20 +816,33 @@ public class BrightnessTrackerTest {
|
||||
public void testOnlyOneReceiverRegistered() {
|
||||
assertNull(mInjector.mLightSensor);
|
||||
assertNull(mInjector.mSensorListener);
|
||||
assertNull(mInjector.mContentObserver);
|
||||
assertNull(mInjector.mBroadcastReceiver);
|
||||
assertFalse(mInjector.mIdleScheduled);
|
||||
startTracker(mTracker, 0.3f, false);
|
||||
|
||||
assertNotNull(mInjector.mLightSensor);
|
||||
assertNotNull(mInjector.mSensorListener);
|
||||
assertNotNull(mInjector.mContentObserver);
|
||||
assertNotNull(mInjector.mBroadcastReceiver);
|
||||
assertTrue(mInjector.mIdleScheduled);
|
||||
Sensor registeredLightSensor = mInjector.mLightSensor;
|
||||
SensorEventListener registeredSensorListener = mInjector.mSensorListener;
|
||||
ContentObserver registeredContentObserver = mInjector.mContentObserver;
|
||||
BroadcastReceiver registeredBroadcastReceiver = mInjector.mBroadcastReceiver;
|
||||
|
||||
mTracker.start(0.3f);
|
||||
assertSame(registeredLightSensor, mInjector.mLightSensor);
|
||||
assertSame(registeredSensorListener, mInjector.mSensorListener);
|
||||
assertSame(registeredContentObserver, mInjector.mContentObserver);
|
||||
assertSame(registeredBroadcastReceiver, mInjector.mBroadcastReceiver);
|
||||
|
||||
mTracker.stop();
|
||||
assertNull(mInjector.mLightSensor);
|
||||
assertNull(mInjector.mSensorListener);
|
||||
assertNull(mInjector.mContentObserver);
|
||||
assertNull(mInjector.mBroadcastReceiver);
|
||||
assertFalse(mInjector.mIdleScheduled);
|
||||
|
||||
// mInjector asserts that we aren't removing a null receiver
|
||||
mTracker.stop();
|
||||
@@ -954,23 +893,41 @@ public class BrightnessTrackerTest {
|
||||
|
||||
private void notifyBrightnessChanged(BrightnessTracker tracker, float brightness,
|
||||
String displayId) {
|
||||
notifyBrightnessChanged(tracker, brightness, true /*userInitiated*/,
|
||||
1.0f /*powerBrightnessFactor*/, false /*isUserSetBrightness*/,
|
||||
false /*isDefaultBrightnessConfig*/, displayId);
|
||||
notifyBrightnessChanged(tracker, brightness, /* userInitiated= */ true,
|
||||
/* powerBrightnessFactor= */ 1.0f, /* isUserSetBrightness= */ false,
|
||||
/* isDefaultBrightnessConfig= */ false, displayId, new float[10], new long[10]);
|
||||
}
|
||||
|
||||
private void notifyBrightnessChanged(BrightnessTracker tracker, float brightness,
|
||||
String displayId, float[] luxValues, long[] luxTimestamps) {
|
||||
notifyBrightnessChanged(tracker, brightness, /* userInitiated= */ true,
|
||||
/* powerBrightnessFactor= */ 1.0f, /* isUserSetBrightness= */ false,
|
||||
/* isDefaultBrightnessConfig= */ false, displayId, luxValues, luxTimestamps);
|
||||
}
|
||||
|
||||
private void notifyBrightnessChanged(BrightnessTracker tracker, float brightness,
|
||||
boolean userInitiated, float powerBrightnessFactor, boolean isUserSetBrightness,
|
||||
boolean isDefaultBrightnessConfig, String displayId) {
|
||||
tracker.notifyBrightnessChanged(brightness, userInitiated, powerBrightnessFactor,
|
||||
isUserSetBrightness, isDefaultBrightnessConfig, displayId);
|
||||
isUserSetBrightness, isDefaultBrightnessConfig, displayId, new float[10],
|
||||
new long[10]);
|
||||
mInjector.waitForHandler();
|
||||
}
|
||||
|
||||
private void notifyBrightnessChanged(BrightnessTracker tracker, float brightness,
|
||||
boolean userInitiated, float powerBrightnessFactor, boolean isUserSetBrightness,
|
||||
boolean isDefaultBrightnessConfig, String displayId, float[] luxValues,
|
||||
long[] luxTimestamps) {
|
||||
tracker.notifyBrightnessChanged(brightness, userInitiated, powerBrightnessFactor,
|
||||
isUserSetBrightness, isDefaultBrightnessConfig, displayId, luxValues,
|
||||
luxTimestamps);
|
||||
mInjector.waitForHandler();
|
||||
}
|
||||
|
||||
private BrightnessConfiguration buildBrightnessConfiguration(boolean collectColorSamples) {
|
||||
BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder(
|
||||
/* lux = */ new float[] {0f, 10f, 100f},
|
||||
/* nits = */ new float[] {1f, 90f, 100f});
|
||||
/* lux= */ new float[] {0f, 10f, 100f},
|
||||
/* nits= */ new float[] {1f, 90f, 100f});
|
||||
builder.setShouldCollectColorSamples(collectColorSamples);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user