blob: 926009ebfbae49d43390076be819cd5efa5b22d5 [file] [log] [blame]
Kenny Guy22bd0442017-10-26 00:15:54 +01001/*
2 * Copyright 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.server.display;
18
19import static org.junit.Assert.assertArrayEquals;
20import static org.junit.Assert.assertEquals;
21import static org.junit.Assert.assertFalse;
22import static org.junit.Assert.assertNotNull;
23import static org.junit.Assert.assertNull;
24import static org.junit.Assert.assertTrue;
25
26import android.app.ActivityManager;
27import android.content.BroadcastReceiver;
28import android.content.ComponentName;
29import android.content.ContentResolver;
30import android.content.Context;
31import android.content.Intent;
32import android.content.IntentFilter;
33import android.database.ContentObserver;
34import android.hardware.SensorEvent;
35import android.hardware.SensorEventListener;
36import android.hardware.display.BrightnessChangeEvent;
37import android.os.BatteryManager;
38import android.os.Handler;
39import android.os.HandlerThread;
40import android.os.MessageQueue;
41import android.os.Parcel;
42import android.os.RemoteException;
43import android.os.SystemClock;
44import android.os.UserManager;
45import android.provider.Settings;
46import android.support.test.InstrumentationRegistry;
47import android.support.test.filters.SmallTest;
48import android.support.test.runner.AndroidJUnit4;
49import android.util.AtomicFile;
50
51import org.junit.Before;
52import org.junit.Test;
53import org.junit.runner.RunWith;
54
55import java.io.ByteArrayInputStream;
56import java.io.ByteArrayOutputStream;
57import java.io.IOException;
58import java.io.InputStream;
59import java.lang.reflect.Constructor;
60import java.nio.charset.StandardCharsets;
61import java.util.HashMap;
62import java.util.List;
63import java.util.Map;
64import java.util.concurrent.TimeUnit;
65
66@SmallTest
67@RunWith(AndroidJUnit4.class)
68public class BrightnessTrackerTest {
69
70 private BrightnessTracker mTracker;
71 private TestInjector mInjector;
72
73 private static Object sHandlerLock = new Object();
74 private static Handler sHandler;
75 private static HandlerThread sThread =
76 new HandlerThread("brightness.test", android.os.Process.THREAD_PRIORITY_BACKGROUND);
77
78 private static Handler ensureHandler() {
79 synchronized (sHandlerLock) {
80 if (sHandler == null) {
81 sThread.start();
82 sHandler = new Handler(sThread.getLooper());
83 }
84 return sHandler;
85 }
86 }
87
88
89 @Before
90 public void setUp() throws Exception {
91 mInjector = new TestInjector(ensureHandler());
92
93 mTracker = new BrightnessTracker(InstrumentationRegistry.getContext(), mInjector);
94 }
95
96 @Test
Kenny Guy689ab8f2017-11-29 12:12:06 +000097 public void testStartStopTrackerScreenOnOff() {
98 mInjector.mInteractive = false;
Kenny Guy22bd0442017-10-26 00:15:54 +010099 startTracker(mTracker);
Kenny Guy689ab8f2017-11-29 12:12:06 +0000100 assertNull(mInjector.mSensorListener);
Kenny Guy22bd0442017-10-26 00:15:54 +0100101 assertNotNull(mInjector.mSettingsObserver);
102 assertNotNull(mInjector.mBroadcastReceiver);
Kenny Guycfe7b702017-11-14 21:04:58 +0000103 assertTrue(mInjector.mIdleScheduled);
Kenny Guy689ab8f2017-11-29 12:12:06 +0000104 Intent onIntent = new Intent();
105 onIntent.setAction(Intent.ACTION_SCREEN_ON);
106 mInjector.mBroadcastReceiver.onReceive(InstrumentationRegistry.getContext(),
107 onIntent);
108 assertNotNull(mInjector.mSensorListener);
109
110 Intent offIntent = new Intent();
111 offIntent.setAction(Intent.ACTION_SCREEN_OFF);
112 mInjector.mBroadcastReceiver.onReceive(InstrumentationRegistry.getContext(),
113 offIntent);
114 assertNull(mInjector.mSensorListener);
115
116 mInjector.mBroadcastReceiver.onReceive(InstrumentationRegistry.getContext(),
117 onIntent);
118 assertNotNull(mInjector.mSensorListener);
119
Kenny Guy22bd0442017-10-26 00:15:54 +0100120 mTracker.stop();
121 assertNull(mInjector.mSensorListener);
122 assertNull(mInjector.mSettingsObserver);
123 assertNull(mInjector.mBroadcastReceiver);
Kenny Guycfe7b702017-11-14 21:04:58 +0000124 assertFalse(mInjector.mIdleScheduled);
Kenny Guy22bd0442017-10-26 00:15:54 +0100125 }
126
127 @Test
128 public void testBrightnessEvent() {
129 final int brightness = 20;
130
131 mInjector.mSystemIntSettings.put(Settings.System.SCREEN_BRIGHTNESS, brightness);
132 startTracker(mTracker);
133 mInjector.mSensorListener.onSensorChanged(createSensorEvent(1.0f));
134 mInjector.incrementTime(TimeUnit.SECONDS.toMillis(2));
135 mInjector.mSettingsObserver.onChange(false, Settings.System.getUriFor(
136 Settings.System.SCREEN_BRIGHTNESS));
Kenny Guy29aa30e2017-11-30 13:43:46 +0000137 List<BrightnessChangeEvent> events = mTracker.getEvents(0, true).getList();
Kenny Guy22bd0442017-10-26 00:15:54 +0100138 mTracker.stop();
139
140 assertEquals(1, events.size());
141 BrightnessChangeEvent event = events.get(0);
142 assertEquals(mInjector.currentTimeMillis(), event.timeStamp);
143 assertEquals(1, event.luxValues.length);
144 assertEquals(1.0f, event.luxValues[0], 0.1f);
145 assertEquals(mInjector.currentTimeMillis() - TimeUnit.SECONDS.toMillis(2),
146 event.luxTimestamps[0]);
147 assertEquals(brightness, event.brightness);
148
149 // System had no data so these should all be at defaults.
150 assertEquals(Float.NaN, event.batteryLevel, 0.0);
151 assertFalse(event.nightMode);
152 assertEquals(0, event.colorTemperature);
153 }
154
155 @Test
156 public void testBrightnessFullPopulatedEvent() {
157 final int lastBrightness = 230;
158 final int brightness = 130;
159
160 mInjector.mSystemIntSettings.put(Settings.System.SCREEN_BRIGHTNESS, lastBrightness);
161 mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_ACTIVATED, 1);
162 mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE, 3333);
163
164 startTracker(mTracker);
165 mInjector.mSystemIntSettings.put(Settings.System.SCREEN_BRIGHTNESS, brightness);
166 mInjector.mBroadcastReceiver.onReceive(InstrumentationRegistry.getContext(),
167 batteryChangeEvent(30, 60));
168 mInjector.mSensorListener.onSensorChanged(createSensorEvent(1000.0f));
169 final long sensorTime = mInjector.currentTimeMillis();
170 mInjector.mSettingsObserver.onChange(false, Settings.System.getUriFor(
171 Settings.System.SCREEN_BRIGHTNESS));
Kenny Guy29aa30e2017-11-30 13:43:46 +0000172 List<BrightnessChangeEvent> eventsNoPackage
173 = mTracker.getEvents(0, false).getList();
174 List<BrightnessChangeEvent> events = mTracker.getEvents(0, true).getList();
Kenny Guy22bd0442017-10-26 00:15:54 +0100175 mTracker.stop();
176
177 assertEquals(1, events.size());
178 BrightnessChangeEvent event = events.get(0);
179 assertEquals(event.timeStamp, mInjector.currentTimeMillis());
180 assertArrayEquals(new float[] {1000.0f}, event.luxValues, 0.01f);
181 assertArrayEquals(new long[] {sensorTime}, event.luxTimestamps);
182 assertEquals(brightness, event.brightness);
183 assertEquals(lastBrightness, event.lastBrightness);
184 assertEquals(0.5, event.batteryLevel, 0.01);
185 assertTrue(event.nightMode);
186 assertEquals(3333, event.colorTemperature);
187 assertEquals("a.package", event.packageName);
188 assertEquals(0, event.userId);
Kenny Guy29aa30e2017-11-30 13:43:46 +0000189
190 assertEquals(1, eventsNoPackage.size());
191 assertNull(eventsNoPackage.get(0).packageName);
Kenny Guy22bd0442017-10-26 00:15:54 +0100192 }
193
194 @Test
195 public void testIgnoreSelfChange() {
196 final int initialBrightness = 30;
197 mInjector.mSystemIntSettings.put(Settings.System.SCREEN_BRIGHTNESS, initialBrightness);
198 startTracker(mTracker);
199 mInjector.mSensorListener.onSensorChanged(createSensorEvent(1.0f));
200 mInjector.incrementTime(TimeUnit.SECONDS.toMillis(1));
201
202 final int systemUpdatedBrightness = 20;
203 mTracker.setBrightness(systemUpdatedBrightness, 0);
204 assertEquals(systemUpdatedBrightness,
205 (int) mInjector.mSystemIntSettings.get(Settings.System.SCREEN_BRIGHTNESS));
206 mInjector.mSettingsObserver.onChange(false, Settings.System.getUriFor(
207 Settings.System.SCREEN_BRIGHTNESS));
Kenny Guy29aa30e2017-11-30 13:43:46 +0000208 List<BrightnessChangeEvent> events = mTracker.getEvents(0, true).getList();
Kenny Guy22bd0442017-10-26 00:15:54 +0100209 // No events because we filtered out our change.
210 assertEquals(0, events.size());
211
212 final int firstUserUpdateBrightness = 20;
213 // Then change comes from somewhere else so we shouldn't filter.
214 mInjector.mSystemIntSettings.put(Settings.System.SCREEN_BRIGHTNESS,
215 firstUserUpdateBrightness);
216 mInjector.mSettingsObserver.onChange(false, Settings.System.getUriFor(
217 Settings.System.SCREEN_BRIGHTNESS));
218
219 // and with a different brightness value.
220 final int secondUserUpdateBrightness = 34;
221 mInjector.mSystemIntSettings.put(Settings.System.SCREEN_BRIGHTNESS,
222 secondUserUpdateBrightness);
223 mInjector.mSettingsObserver.onChange(false, Settings.System.getUriFor(
224 Settings.System.SCREEN_BRIGHTNESS));
Kenny Guy29aa30e2017-11-30 13:43:46 +0000225 events = mTracker.getEvents(0, true).getList();
Kenny Guy22bd0442017-10-26 00:15:54 +0100226
227 assertEquals(2, events.size());
228 // First event is change from system update (20) to first user update (20)
229 assertEquals(systemUpdatedBrightness, events.get(0).lastBrightness);
230 assertEquals(firstUserUpdateBrightness, events.get(0).brightness);
231 // Second event is from first to second user update.
232 assertEquals(firstUserUpdateBrightness, events.get(1).lastBrightness);
233 assertEquals(secondUserUpdateBrightness, events.get(1).brightness);
234
235 mTracker.stop();
236 }
237
238 @Test
239 public void testLimitedBufferSize() {
240 startTracker(mTracker);
241 mInjector.mSensorListener.onSensorChanged(createSensorEvent(1.0f));
242
243 for (int brightness = 0; brightness <= 255; ++brightness) {
244 mInjector.mSensorListener.onSensorChanged(createSensorEvent(1.0f));
245 mInjector.incrementTime(TimeUnit.SECONDS.toNanos(1));
246 mInjector.mSystemIntSettings.put(Settings.System.SCREEN_BRIGHTNESS, brightness);
247 mInjector.mSettingsObserver.onChange(false, Settings.System.getUriFor(
248 Settings.System.SCREEN_BRIGHTNESS));
249 }
Kenny Guy29aa30e2017-11-30 13:43:46 +0000250 List<BrightnessChangeEvent> events = mTracker.getEvents(0, true).getList();
Kenny Guy22bd0442017-10-26 00:15:54 +0100251 mTracker.stop();
252
253 // Should be capped at 100 events, and they should be the most recent 100.
254 assertEquals(100, events.size());
255 for (int i = 0; i < events.size(); i++) {
256 BrightnessChangeEvent event = events.get(i);
257 assertEquals(156 + i, event.brightness);
258 }
259 }
260
261 @Test
262 public void testLimitedSensorEvents() {
263 final int brightness = 20;
264 mInjector.mSystemIntSettings.put(Settings.System.SCREEN_BRIGHTNESS, brightness);
265
266 startTracker(mTracker);
267 // 20 Sensor events 1 second apart.
268 for (int i = 0; i < 20; ++i) {
269 mInjector.incrementTime(TimeUnit.SECONDS.toMillis(1));
270 mInjector.mSensorListener.onSensorChanged(createSensorEvent(i + 1.0f));
271 }
272 mInjector.mSettingsObserver.onChange(false, Settings.System.getUriFor(
273 Settings.System.SCREEN_BRIGHTNESS));
Kenny Guy29aa30e2017-11-30 13:43:46 +0000274 List<BrightnessChangeEvent> events = mTracker.getEvents(0, true).getList();
Kenny Guy22bd0442017-10-26 00:15:54 +0100275 mTracker.stop();
276
277 assertEquals(1, events.size());
278 BrightnessChangeEvent event = events.get(0);
279 assertEquals(mInjector.currentTimeMillis(), event.timeStamp);
280
281 // 12 sensor events, 11 for 0->10 seconds + 1 previous event.
282 assertEquals(12, event.luxValues.length);
283 for (int i = 0; i < 12; ++i) {
284 assertEquals(event.luxTimestamps[11 - i],
285 mInjector.currentTimeMillis() - i * TimeUnit.SECONDS.toMillis(1));
286 }
287 assertEquals(brightness, event.brightness);
288 }
289
290 @Test
291 public void testReadEvents() throws Exception {
292 BrightnessTracker tracker = new BrightnessTracker(InstrumentationRegistry.getContext(),
293 mInjector);
294 mInjector.mCurrentTimeMillis = System.currentTimeMillis();
295 long someTimeAgo = System.currentTimeMillis() - TimeUnit.HOURS.toMillis(12);
296 long twoMonthsAgo = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(60);
297 // 3 Events in the file but one too old to read.
298 String eventFile =
299 "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
300 + "<events>\n"
301 + "<event brightness=\"194\" timestamp=\""
302 + Long.toString(someTimeAgo) + "\" packageName=\""
303 + "com.example.app\" user=\"10\" "
304 + "lastBrightness=\"32\" "
305 + "batteryLevel=\"1.0\" nightMode=\"false\" colorTemperature=\"0\"\n"
306 + "lux=\"32.2,31.1\" luxTimestamps=\""
307 + Long.toString(someTimeAgo) + "," + Long.toString(someTimeAgo) + "\"/>"
308 + "<event brightness=\"71\" timestamp=\""
309 + Long.toString(someTimeAgo) + "\" packageName=\""
310 + "com.android.anapp\" user=\"11\" "
311 + "lastBrightness=\"32\" "
312 + "batteryLevel=\"0.5\" nightMode=\"true\" colorTemperature=\"3235\"\n"
313 + "lux=\"132.2,131.1\" luxTimestamps=\""
314 + Long.toString(someTimeAgo) + "," + Long.toString(someTimeAgo) + "\"/>"
315 // Event that is too old so shouldn't show up.
316 + "<event brightness=\"142\" timestamp=\""
317 + Long.toString(twoMonthsAgo) + "\" packageName=\""
318 + "com.example.app\" user=\"10\" "
319 + "lastBrightness=\"32\" "
320 + "batteryLevel=\"1.0\" nightMode=\"false\" colorTemperature=\"0\"\n"
321 + "lux=\"32.2,31.1\" luxTimestamps=\""
322 + Long.toString(twoMonthsAgo) + "," + Long.toString(twoMonthsAgo) + "\"/>"
323 + "</events>";
324 tracker.readEventsLocked(getInputStream(eventFile));
Kenny Guy29aa30e2017-11-30 13:43:46 +0000325 List<BrightnessChangeEvent> events = tracker.getEvents(0, true).getList();
Kenny Guy22bd0442017-10-26 00:15:54 +0100326 assertEquals(1, events.size());
327 BrightnessChangeEvent event = events.get(0);
328 assertEquals(someTimeAgo, event.timeStamp);
329 assertEquals(194, event.brightness);
330 assertArrayEquals(new float[] {32.2f, 31.1f}, event.luxValues, 0.01f);
331 assertArrayEquals(new long[] {someTimeAgo, someTimeAgo}, event.luxTimestamps);
332 assertEquals(32, event.lastBrightness);
333 assertEquals(0, event.userId);
334 assertFalse(event.nightMode);
335 assertEquals(1.0f, event.batteryLevel, 0.01);
336 assertEquals("com.example.app", event.packageName);
337
Kenny Guy29aa30e2017-11-30 13:43:46 +0000338 events = tracker.getEvents(1, true).getList();
Kenny Guy22bd0442017-10-26 00:15:54 +0100339 assertEquals(1, events.size());
340 event = events.get(0);
341 assertEquals(someTimeAgo, event.timeStamp);
342 assertEquals(71, event.brightness);
343 assertArrayEquals(new float[] {132.2f, 131.1f}, event.luxValues, 0.01f);
344 assertArrayEquals(new long[] {someTimeAgo, someTimeAgo}, event.luxTimestamps);
345 assertEquals(32, event.lastBrightness);
346 assertEquals(1, event.userId);
347 assertTrue(event.nightMode);
348 assertEquals(3235, event.colorTemperature);
349 assertEquals(0.5f, event.batteryLevel, 0.01);
350 assertEquals("com.android.anapp", event.packageName);
351 }
352
353 @Test
354 public void testFailedRead() {
355 String someTimeAgo =
356 Long.toString(System.currentTimeMillis() - TimeUnit.HOURS.toMillis(12));
357 mInjector.mCurrentTimeMillis = System.currentTimeMillis();
358
359 BrightnessTracker tracker = new BrightnessTracker(InstrumentationRegistry.getContext(),
360 mInjector);
361 String eventFile = "junk in the file";
362 try {
363 tracker.readEventsLocked(getInputStream(eventFile));
364 } catch (IOException e) {
365 // Expected;
366 }
Kenny Guy29aa30e2017-11-30 13:43:46 +0000367 assertEquals(0, tracker.getEvents(0, true).getList().size());
Kenny Guy22bd0442017-10-26 00:15:54 +0100368
369 // Missing lux value.
370 eventFile =
371 "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
372 + "<events>\n"
373 + "<event brightness=\"194\" timestamp=\"" + someTimeAgo + "\" packageName=\""
374 + "com.example.app\" user=\"10\" "
375 + "batteryLevel=\"0.7\" nightMode=\"false\" colorTemperature=\"0\" />\n"
376 + "</events>";
377 try {
378 tracker.readEventsLocked(getInputStream(eventFile));
379 } catch (IOException e) {
380 // Expected;
381 }
Kenny Guy29aa30e2017-11-30 13:43:46 +0000382 assertEquals(0, tracker.getEvents(0, true).getList().size());
Kenny Guy22bd0442017-10-26 00:15:54 +0100383 }
384
385 @Test
386 public void testWriteThenRead() throws Exception {
387 final int brightness = 20;
388
389 mInjector.mSystemIntSettings.put(Settings.System.SCREEN_BRIGHTNESS, brightness);
390 mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_ACTIVATED, 1);
391 mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE, 3339);
392
393 startTracker(mTracker);
394 mInjector.mBroadcastReceiver.onReceive(InstrumentationRegistry.getContext(),
395 batteryChangeEvent(30, 100));
396 mInjector.mSensorListener.onSensorChanged(createSensorEvent(2000.0f));
397 final long firstSensorTime = mInjector.currentTimeMillis();
398 mInjector.incrementTime(TimeUnit.SECONDS.toMillis(2));
399 mInjector.mSensorListener.onSensorChanged(createSensorEvent(3000.0f));
400 final long secondSensorTime = mInjector.currentTimeMillis();
401 mInjector.incrementTime(TimeUnit.SECONDS.toMillis(3));
402 mInjector.mSettingsObserver.onChange(false, Settings.System.getUriFor(
403 Settings.System.SCREEN_BRIGHTNESS));
404 ByteArrayOutputStream baos = new ByteArrayOutputStream();
405 mTracker.writeEventsLocked(baos);
406 mTracker.stop();
407
408 baos.flush();
409 ByteArrayInputStream input = new ByteArrayInputStream(baos.toByteArray());
410 BrightnessTracker tracker = new BrightnessTracker(InstrumentationRegistry.getContext(),
411 mInjector);
412 tracker.readEventsLocked(input);
Kenny Guy29aa30e2017-11-30 13:43:46 +0000413 List<BrightnessChangeEvent> events = tracker.getEvents(0, true).getList();
Kenny Guy22bd0442017-10-26 00:15:54 +0100414
415 assertEquals(1, events.size());
416 BrightnessChangeEvent event = events.get(0);
417 assertArrayEquals(new float[] {2000.0f, 3000.0f}, event.luxValues, 0.01f);
418 assertArrayEquals(new long[] {firstSensorTime, secondSensorTime}, event.luxTimestamps);
419 assertEquals(brightness, event.brightness);
420 assertEquals(0.3, event.batteryLevel, 0.01f);
421 assertTrue(event.nightMode);
422 assertEquals(3339, event.colorTemperature);
423 }
424
425 @Test
Kenny Guycfe7b702017-11-14 21:04:58 +0000426 public void testWritePrunesOldEvents() throws Exception {
427 final int brightness = 20;
428
429 mInjector.mSystemIntSettings.put(Settings.System.SCREEN_BRIGHTNESS, brightness);
430 mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_ACTIVATED, 1);
431 mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE, 3339);
432
433 startTracker(mTracker);
434 mInjector.mBroadcastReceiver.onReceive(InstrumentationRegistry.getContext(),
435 batteryChangeEvent(30, 100));
436 mInjector.mSensorListener.onSensorChanged(createSensorEvent(1000.0f));
437 mInjector.incrementTime(TimeUnit.SECONDS.toMillis(1));
438 mInjector.mSensorListener.onSensorChanged(createSensorEvent(2000.0f));
439 final long sensorTime = mInjector.currentTimeMillis();
440 mInjector.mSettingsObserver.onChange(false, Settings.System.getUriFor(
441 Settings.System.SCREEN_BRIGHTNESS));
442
443 // 31 days later
444 mInjector.incrementTime(TimeUnit.DAYS.toMillis(31));
445 mInjector.mSensorListener.onSensorChanged(createSensorEvent(3000.0f));
446 mInjector.mSettingsObserver.onChange(false, Settings.System.getUriFor(
447 Settings.System.SCREEN_BRIGHTNESS));
448 final long eventTime = mInjector.currentTimeMillis();
449
Kenny Guy29aa30e2017-11-30 13:43:46 +0000450 List<BrightnessChangeEvent> events = mTracker.getEvents(0, true).getList();
Kenny Guycfe7b702017-11-14 21:04:58 +0000451 assertEquals(2, events.size());
452
453 ByteArrayOutputStream baos = new ByteArrayOutputStream();
454 mTracker.writeEventsLocked(baos);
Kenny Guy29aa30e2017-11-30 13:43:46 +0000455 events = mTracker.getEvents(0, true).getList();
Kenny Guycfe7b702017-11-14 21:04:58 +0000456 mTracker.stop();
457
458 assertEquals(1, events.size());
459 BrightnessChangeEvent event = events.get(0);
460 assertEquals(eventTime, event.timeStamp);
461
462 // We will keep one of the old sensor events because we keep 1 event outside the window.
463 assertArrayEquals(new float[] {2000.0f, 3000.0f}, event.luxValues, 0.01f);
464 assertArrayEquals(new long[] {sensorTime, eventTime}, event.luxTimestamps);
465 assertEquals(brightness, event.brightness);
466 assertEquals(0.3, event.batteryLevel, 0.01f);
467 assertTrue(event.nightMode);
468 assertEquals(3339, event.colorTemperature);
469 }
470
471 @Test
Kenny Guy22bd0442017-10-26 00:15:54 +0100472 public void testParcelUnParcel() {
473 Parcel parcel = Parcel.obtain();
474 BrightnessChangeEvent event = new BrightnessChangeEvent();
475 event.brightness = 23;
476 event.timeStamp = 345L;
477 event.packageName = "com.example";
478 event.userId = 12;
479 event.luxValues = new float[2];
480 event.luxValues[0] = 3000.0f;
481 event.luxValues[1] = 4000.0f;
482 event.luxTimestamps = new long[2];
483 event.luxTimestamps[0] = 325L;
484 event.luxTimestamps[1] = 315L;
485 event.batteryLevel = 0.7f;
486 event.nightMode = false;
487 event.colorTemperature = 345;
488 event.lastBrightness = 50;
489
490 event.writeToParcel(parcel, 0);
491 byte[] parceled = parcel.marshall();
492 parcel.recycle();
493
494 parcel = Parcel.obtain();
495 parcel.unmarshall(parceled, 0, parceled.length);
496 parcel.setDataPosition(0);
497
498 BrightnessChangeEvent event2 = BrightnessChangeEvent.CREATOR.createFromParcel(parcel);
499 parcel.recycle();
500 assertEquals(event.brightness, event2.brightness);
501 assertEquals(event.timeStamp, event2.timeStamp);
502 assertEquals(event.packageName, event2.packageName);
503 assertEquals(event.userId, event2.userId);
504 assertArrayEquals(event.luxValues, event2.luxValues, 0.01f);
505 assertArrayEquals(event.luxTimestamps, event2.luxTimestamps);
506 assertEquals(event.batteryLevel, event2.batteryLevel, 0.01f);
507 assertEquals(event.nightMode, event2.nightMode);
508 assertEquals(event.colorTemperature, event2.colorTemperature);
509 assertEquals(event.lastBrightness, event2.lastBrightness);
510
511 parcel = Parcel.obtain();
512 event.batteryLevel = Float.NaN;
513 event.writeToParcel(parcel, 0);
514 parceled = parcel.marshall();
515 parcel.recycle();
516
517 parcel = Parcel.obtain();
518 parcel.unmarshall(parceled, 0, parceled.length);
519 parcel.setDataPosition(0);
520 event2 = BrightnessChangeEvent.CREATOR.createFromParcel(parcel);
521 assertEquals(event.batteryLevel, event2.batteryLevel, 0.01f);
522 }
523
524 private InputStream getInputStream(String data) {
525 return new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
526 }
527
528 private Intent batteryChangeEvent(int level, int scale) {
529 Intent intent = new Intent();
530 intent.setAction(Intent.ACTION_BATTERY_CHANGED);
531 intent.putExtra(BatteryManager.EXTRA_LEVEL, level);
532 intent.putExtra(BatteryManager.EXTRA_SCALE, scale);
533 return intent;
534 }
535
536 private SensorEvent createSensorEvent(float lux) {
537 SensorEvent event;
538 try {
539 Constructor<SensorEvent> constr =
540 SensorEvent.class.getDeclaredConstructor(Integer.TYPE);
541 constr.setAccessible(true);
542 event = constr.newInstance(1);
543 } catch (Exception e) {
544 throw new RuntimeException(e);
545 }
546 event.values[0] = lux;
547 event.timestamp = mInjector.mElapsedRealtimeNanos;
548
549 return event;
550 }
551
552 private void startTracker(BrightnessTracker tracker) {
553 tracker.start();
554 mInjector.waitForHandler();
555 }
556
Kenny Guy22bd0442017-10-26 00:15:54 +0100557 private static final class Idle implements MessageQueue.IdleHandler {
558 private boolean mIdle;
559
560 @Override
561 public boolean queueIdle() {
562 synchronized (this) {
563 mIdle = true;
564 notifyAll();
565 }
566 return false;
567 }
568
569 public synchronized void waitForIdle() {
570 while (!mIdle) {
571 try {
572 wait();
573 } catch (InterruptedException e) {
574 }
575 }
576 }
577 }
578
579 private class TestInjector extends BrightnessTracker.Injector {
580 SensorEventListener mSensorListener;
581 ContentObserver mSettingsObserver;
582 BroadcastReceiver mBroadcastReceiver;
583 Map<String, Integer> mSystemIntSettings = new HashMap<>();
584 Map<String, Integer> mSecureIntSettings = new HashMap<>();
585 long mCurrentTimeMillis = System.currentTimeMillis();
586 long mElapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos();
587 Handler mHandler;
Kenny Guycfe7b702017-11-14 21:04:58 +0000588 boolean mIdleScheduled;
Kenny Guy689ab8f2017-11-29 12:12:06 +0000589 boolean mInteractive = true;
Kenny Guy22bd0442017-10-26 00:15:54 +0100590
591 public TestInjector(Handler handler) {
592 mHandler = handler;
593 }
594
595 public void incrementTime(long timeMillis) {
596 mCurrentTimeMillis += timeMillis;
597 mElapsedRealtimeNanos += TimeUnit.MILLISECONDS.toNanos(timeMillis);
598 }
599
600 @Override
601 public void registerSensorListener(Context context,
Kenny Guy689ab8f2017-11-29 12:12:06 +0000602 SensorEventListener sensorListener, Handler handler) {
Kenny Guy22bd0442017-10-26 00:15:54 +0100603 mSensorListener = sensorListener;
604 }
605
606 @Override
607 public void unregisterSensorListener(Context context,
608 SensorEventListener sensorListener) {
609 mSensorListener = null;
610 }
611
612 @Override
613 public void registerBrightnessObserver(ContentResolver resolver,
614 ContentObserver settingsObserver) {
615 mSettingsObserver = settingsObserver;
616 }
617
618 @Override
619 public void unregisterBrightnessObserver(Context context,
620 ContentObserver settingsObserver) {
621 mSettingsObserver = null;
622 }
623
624 @Override
625 public void registerReceiver(Context context,
626 BroadcastReceiver shutdownReceiver, IntentFilter shutdownFilter) {
627 mBroadcastReceiver = shutdownReceiver;
628 }
629
630 @Override
631 public void unregisterReceiver(Context context,
632 BroadcastReceiver broadcastReceiver) {
633 assertEquals(mBroadcastReceiver, broadcastReceiver);
634 mBroadcastReceiver = null;
635 }
636
637 @Override
638 public Handler getBackgroundHandler() {
639 return mHandler;
640 }
641
642 public void waitForHandler() {
643 Idle idle = new Idle();
644 mHandler.getLooper().getQueue().addIdleHandler(idle);
645 mHandler.post(() -> {});
646 idle.waitForIdle();
647 }
648
649 @Override
650 public int getSystemIntForUser(ContentResolver resolver, String setting, int defaultValue,
651 int userId) {
652 Integer value = mSystemIntSettings.get(setting);
653 if (value == null) {
654 return defaultValue;
655 } else {
656 return value;
657 }
658 }
659
660 @Override
661 public void putSystemIntForUser(ContentResolver resolver, String setting, int value,
662 int userId) {
663 mSystemIntSettings.put(setting, value);
664 }
665
666 @Override
667 public int getSecureIntForUser(ContentResolver resolver, String setting, int defaultValue,
668 int userId) {
669 Integer value = mSecureIntSettings.get(setting);
670 if (value == null) {
671 return defaultValue;
672 } else {
673 return value;
674 }
675 }
676
677 @Override
678 public AtomicFile getFile() {
679 // Don't have the test write / read from anywhere.
680 return null;
681 }
682
683 @Override
684 public long currentTimeMillis() {
685 return mCurrentTimeMillis;
686 }
687
688 @Override
689 public long elapsedRealtimeNanos() {
690 return mElapsedRealtimeNanos;
691 }
692
693 @Override
694 public int getUserSerialNumber(UserManager userManager, int userId) {
695 return userId + 10;
696 }
697
698 @Override
699 public int getUserId(UserManager userManager, int userSerialNumber) {
700 return userSerialNumber - 10;
701 }
702
703 @Override
704 public ActivityManager.StackInfo getFocusedStack() throws RemoteException {
705 ActivityManager.StackInfo focusedStack = new ActivityManager.StackInfo();
706 focusedStack.userId = 0;
707 focusedStack.topActivity = new ComponentName("a.package", "a.class");
708 return focusedStack;
709 }
Kenny Guycfe7b702017-11-14 21:04:58 +0000710
711 public void scheduleIdleJob(Context context) {
712 // Don't actually schedule jobs during unit tests.
713 mIdleScheduled = true;
714 }
715
716 public void cancelIdleJob(Context context) {
717 mIdleScheduled = false;
718 }
Kenny Guy689ab8f2017-11-29 12:12:06 +0000719
720 public boolean isInteractive(Context context) {
721 return mInteractive;
722 }
Kenny Guy22bd0442017-10-26 00:15:54 +0100723 }
724}