Loading services/core/java/com/android/server/display/AutomaticBrightnessController.java +40 −0 Original line number Diff line number Diff line Loading @@ -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: Loading Loading @@ -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) { Loading services/core/java/com/android/server/display/BrightnessTracker.java +18 −71 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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"; Loading Loading @@ -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; Loading Loading @@ -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)); Loading @@ -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(); } Loading @@ -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) { Loading @@ -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]; int pos = 0; long[] luxTimestampsMillis = new long[luxTimestamps.length]; // 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); Loading Loading @@ -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(); Loading Loading @@ -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); Loading Loading @@ -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]); } Loading @@ -945,7 +889,6 @@ public class BrightnessTracker { private final class SensorListener implements SensorEventListener { @Override public void onSensorChanged(SensorEvent event) { recordSensorEvent(event); recordAmbientBrightnessStats(event); } Loading Loading @@ -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(); Loading Loading @@ -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; } } Loading services/core/java/com/android/server/display/DisplayPowerController.java +3 −1 Original line number Diff line number Diff line Loading @@ -2471,7 +2471,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()); } } Loading services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java +99 −4 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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 Loading Loading @@ -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) Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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]); } } services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java +77 −120 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
services/core/java/com/android/server/display/AutomaticBrightnessController.java +40 −0 Original line number Diff line number Diff line Loading @@ -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: Loading Loading @@ -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) { Loading
services/core/java/com/android/server/display/BrightnessTracker.java +18 −71 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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"; Loading Loading @@ -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; Loading Loading @@ -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)); Loading @@ -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(); } Loading @@ -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) { Loading @@ -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]; int pos = 0; long[] luxTimestampsMillis = new long[luxTimestamps.length]; // 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); Loading Loading @@ -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(); Loading Loading @@ -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); Loading Loading @@ -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]); } Loading @@ -945,7 +889,6 @@ public class BrightnessTracker { private final class SensorListener implements SensorEventListener { @Override public void onSensorChanged(SensorEvent event) { recordSensorEvent(event); recordAmbientBrightnessStats(event); } Loading Loading @@ -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(); Loading Loading @@ -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; } } Loading
services/core/java/com/android/server/display/DisplayPowerController.java +3 −1 Original line number Diff line number Diff line Loading @@ -2471,7 +2471,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()); } } Loading
services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java +99 −4 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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 Loading Loading @@ -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) Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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]); } }
services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java +77 −120 File changed.Preview size limit exceeded, changes collapsed. Show changes