1 /* 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 17 package com.android.server.display; 18 19 import static org.junit.Assert.assertArrayEquals; 20 import static org.junit.Assert.assertEquals; 21 import static org.junit.Assert.assertFalse; 22 import static org.junit.Assert.assertNotNull; 23 import static org.junit.Assert.assertNull; 24 import static org.junit.Assert.assertTrue; 25 import static org.junit.Assert.fail; 26 27 import android.app.ActivityTaskManager.RootTaskInfo; 28 import android.content.BroadcastReceiver; 29 import android.content.ComponentName; 30 import android.content.ContentResolver; 31 import android.content.Context; 32 import android.content.Intent; 33 import android.content.IntentFilter; 34 import android.content.pm.ParceledListSlice; 35 import android.database.ContentObserver; 36 import android.hardware.SensorEvent; 37 import android.hardware.SensorEventListener; 38 import android.hardware.display.AmbientBrightnessDayStats; 39 import android.hardware.display.BrightnessChangeEvent; 40 import android.hardware.display.BrightnessConfiguration; 41 import android.hardware.display.ColorDisplayManager; 42 import android.hardware.display.DisplayManager; 43 import android.hardware.display.DisplayedContentSample; 44 import android.hardware.display.DisplayedContentSamplingAttributes; 45 import android.os.BatteryManager; 46 import android.os.Handler; 47 import android.os.HandlerThread; 48 import android.os.MessageQueue; 49 import android.os.Parcel; 50 import android.os.RemoteException; 51 import android.os.SystemClock; 52 import android.os.UserManager; 53 import android.provider.Settings; 54 import android.util.AtomicFile; 55 import android.view.Display; 56 57 import androidx.test.InstrumentationRegistry; 58 import androidx.test.filters.SmallTest; 59 import androidx.test.runner.AndroidJUnit4; 60 61 import com.android.internal.R; 62 63 import org.junit.Before; 64 import org.junit.Test; 65 import org.junit.runner.RunWith; 66 67 import java.io.ByteArrayInputStream; 68 import java.io.ByteArrayOutputStream; 69 import java.io.IOException; 70 import java.io.InputStream; 71 import java.lang.reflect.Constructor; 72 import java.nio.charset.StandardCharsets; 73 import java.util.HashMap; 74 import java.util.List; 75 import java.util.Map; 76 import java.util.concurrent.CountDownLatch; 77 import java.util.concurrent.TimeUnit; 78 79 @SmallTest 80 @RunWith(AndroidJUnit4.class) 81 public class BrightnessTrackerTest { 82 private static final float DEFAULT_INITIAL_BRIGHTNESS = 2.5f; 83 private static final boolean DEFAULT_COLOR_SAMPLING_ENABLED = true; 84 private static final String DEFAULT_DISPLAY_ID = "123"; 85 private static final float FLOAT_DELTA = 0.01f; 86 87 private BrightnessTracker mTracker; 88 private TestInjector mInjector; 89 90 private static Object sHandlerLock = new Object(); 91 private static Handler sHandler; 92 private static HandlerThread sThread = 93 new HandlerThread("brightness.test", android.os.Process.THREAD_PRIORITY_BACKGROUND); 94 95 private int mDefaultNightModeColorTemperature; 96 private float mRbcOffsetFactor; 97 ensureHandler()98 private static Handler ensureHandler() { 99 synchronized (sHandlerLock) { 100 if (sHandler == null) { 101 sThread.start(); 102 sHandler = new Handler(sThread.getLooper()); 103 } 104 return sHandler; 105 } 106 } 107 108 109 @Before setUp()110 public void setUp() throws Exception { 111 mInjector = new TestInjector(ensureHandler()); 112 113 mTracker = new BrightnessTracker(InstrumentationRegistry.getContext(), mInjector); 114 mDefaultNightModeColorTemperature = 115 InstrumentationRegistry.getContext().getResources().getInteger( 116 R.integer.config_nightDisplayColorTemperatureDefault); 117 mRbcOffsetFactor = InstrumentationRegistry.getContext() 118 .getSystemService(ColorDisplayManager.class).getReduceBrightColorsOffsetFactor(); 119 } 120 121 @Test testStartStopTrackerScreenOnOff()122 public void testStartStopTrackerScreenOnOff() { 123 mInjector.mInteractive = false; 124 startTracker(mTracker); 125 assertNull(mInjector.mSensorListener); 126 assertNotNull(mInjector.mBroadcastReceiver); 127 assertTrue(mInjector.mIdleScheduled); 128 mInjector.sendScreenChange(/*screen on */ true); 129 assertNotNull(mInjector.mSensorListener); 130 assertTrue(mInjector.mColorSamplingEnabled); 131 132 mInjector.sendScreenChange(/*screen on */ false); 133 assertNull(mInjector.mSensorListener); 134 assertFalse(mInjector.mColorSamplingEnabled); 135 136 // Turn screen on while brightness mode is manual 137 mInjector.setBrightnessMode(/* isBrightnessModeAutomatic */ false); 138 mInjector.sendScreenChange(/*screen on */ true); 139 assertNull(mInjector.mSensorListener); 140 assertFalse(mInjector.mColorSamplingEnabled); 141 142 // Set brightness mode to automatic while screen is off. 143 mInjector.sendScreenChange(/*screen on */ false); 144 mInjector.setBrightnessMode(/* isBrightnessModeAutomatic */ true); 145 assertNull(mInjector.mSensorListener); 146 assertFalse(mInjector.mColorSamplingEnabled); 147 148 // Turn on screen while brightness mode is automatic. 149 mInjector.sendScreenChange(/*screen on */ true); 150 assertNotNull(mInjector.mSensorListener); 151 assertTrue(mInjector.mColorSamplingEnabled); 152 153 mTracker.stop(); 154 assertNull(mInjector.mSensorListener); 155 assertNull(mInjector.mBroadcastReceiver); 156 assertFalse(mInjector.mIdleScheduled); 157 assertFalse(mInjector.mColorSamplingEnabled); 158 } 159 160 @Test testModifyBrightnessConfiguration()161 public void testModifyBrightnessConfiguration() { 162 mInjector.mInteractive = true; 163 // Start with tracker not listening for color samples. 164 startTracker(mTracker, DEFAULT_INITIAL_BRIGHTNESS, /* collectColorSamples= */ false); 165 assertFalse(mInjector.mColorSamplingEnabled); 166 167 // Update brightness config to enabled color sampling. 168 mTracker.setBrightnessConfiguration(buildBrightnessConfiguration( 169 /* collectColorSamples= */ true)); 170 mInjector.waitForHandler(); 171 assertTrue(mInjector.mColorSamplingEnabled); 172 173 // Update brightness config to disable color sampling. 174 mTracker.setBrightnessConfiguration(buildBrightnessConfiguration( 175 /* collectColorSamples= */ false)); 176 mInjector.waitForHandler(); 177 assertFalse(mInjector.mColorSamplingEnabled); 178 179 // Pretend screen is off, update config to turn on color sampling. 180 mInjector.sendScreenChange(/*screen on */ false); 181 mTracker.setBrightnessConfiguration(buildBrightnessConfiguration( 182 /* collectColorSamples= */ true)); 183 mInjector.waitForHandler(); 184 assertFalse(mInjector.mColorSamplingEnabled); 185 186 // Pretend screen is on. 187 mInjector.sendScreenChange(/*screen on */ true); 188 assertTrue(mInjector.mColorSamplingEnabled); 189 190 mTracker.stop(); 191 assertFalse(mInjector.mColorSamplingEnabled); 192 } 193 194 @Test testNoColorSampling_WrongPixelFormat()195 public void testNoColorSampling_WrongPixelFormat() { 196 mInjector.mDefaultSamplingAttributes = 197 new DisplayedContentSamplingAttributes( 198 0x23, 199 mInjector.mDefaultSamplingAttributes.getDataspace(), 200 mInjector.mDefaultSamplingAttributes.getComponentMask()); 201 startTracker(mTracker); 202 assertFalse(mInjector.mColorSamplingEnabled); 203 assertNull(mInjector.mDisplayListener); 204 } 205 206 @Test testNoColorSampling_MissingComponent()207 public void testNoColorSampling_MissingComponent() { 208 mInjector.mDefaultSamplingAttributes = 209 new DisplayedContentSamplingAttributes( 210 mInjector.mDefaultSamplingAttributes.getPixelFormat(), 211 mInjector.mDefaultSamplingAttributes.getDataspace(), 212 0x2); 213 startTracker(mTracker); 214 assertFalse(mInjector.mColorSamplingEnabled); 215 assertNull(mInjector.mDisplayListener); 216 } 217 218 @Test testNoColorSampling_NoSupport()219 public void testNoColorSampling_NoSupport() { 220 mInjector.mDefaultSamplingAttributes = null; 221 startTracker(mTracker); 222 assertFalse(mInjector.mColorSamplingEnabled); 223 assertNull(mInjector.mDisplayListener); 224 } 225 226 @Test testColorSampling_FrameRateChange()227 public void testColorSampling_FrameRateChange() { 228 startTracker(mTracker); 229 assertTrue(mInjector.mColorSamplingEnabled); 230 assertNotNull(mInjector.mDisplayListener); 231 int noFramesSampled = mInjector.mNoColorSamplingFrames; 232 mInjector.mFrameRate = 120.0f; 233 // Wrong display 234 mInjector.mDisplayListener.onDisplayChanged(Display.DEFAULT_DISPLAY + 10); 235 assertEquals(noFramesSampled, mInjector.mNoColorSamplingFrames); 236 // Correct display 237 mInjector.mDisplayListener.onDisplayChanged(Display.DEFAULT_DISPLAY); 238 assertEquals(noFramesSampled * 2, mInjector.mNoColorSamplingFrames); 239 } 240 241 @Test testAdaptiveOnOff()242 public void testAdaptiveOnOff() { 243 mInjector.mInteractive = true; 244 mInjector.mIsBrightnessModeAutomatic = false; 245 startTracker(mTracker); 246 assertNull(mInjector.mSensorListener); 247 assertNotNull(mInjector.mBroadcastReceiver); 248 assertNotNull(mInjector.mContentObserver); 249 assertTrue(mInjector.mIdleScheduled); 250 assertFalse(mInjector.mColorSamplingEnabled); 251 assertNull(mInjector.mDisplayListener); 252 253 mInjector.setBrightnessMode(/*isBrightnessModeAutomatic*/ true); 254 assertNotNull(mInjector.mSensorListener); 255 assertTrue(mInjector.mColorSamplingEnabled); 256 assertNotNull(mInjector.mDisplayListener); 257 258 SensorEventListener listener = mInjector.mSensorListener; 259 DisplayManager.DisplayListener displayListener = mInjector.mDisplayListener; 260 mInjector.mSensorListener = null; 261 mInjector.mColorSamplingEnabled = false; 262 mInjector.mDisplayListener = null; 263 // Duplicate notification 264 mInjector.setBrightnessMode(/*isBrightnessModeAutomatic*/ true); 265 // Sensor shouldn't have been registered as it was already registered. 266 assertNull(mInjector.mSensorListener); 267 assertFalse(mInjector.mColorSamplingEnabled); 268 assertNull(mInjector.mDisplayListener); 269 mInjector.mSensorListener = listener; 270 mInjector.mDisplayListener = displayListener; 271 mInjector.mColorSamplingEnabled = true; 272 273 mInjector.setBrightnessMode(/*isBrightnessModeAutomatic*/ false); 274 assertNull(mInjector.mSensorListener); 275 assertFalse(mInjector.mColorSamplingEnabled); 276 assertNull(mInjector.mDisplayListener); 277 278 mTracker.stop(); 279 assertNull(mInjector.mSensorListener); 280 assertNull(mInjector.mBroadcastReceiver); 281 assertNull(mInjector.mContentObserver); 282 assertFalse(mInjector.mIdleScheduled); 283 assertFalse(mInjector.mColorSamplingEnabled); 284 assertNull(mInjector.mDisplayListener); 285 } 286 287 @Test testBrightnessEvent()288 public void testBrightnessEvent() { 289 final float brightness = 0.5f; 290 final String displayId = "1234"; 291 292 startTracker(mTracker); 293 mInjector.mSensorListener.onSensorChanged(createSensorEvent(1.0f)); 294 mInjector.incrementTime(TimeUnit.SECONDS.toMillis(2)); 295 notifyBrightnessChanged(mTracker, brightness, displayId); 296 List<BrightnessChangeEvent> events = mTracker.getEvents(0, true).getList(); 297 mTracker.stop(); 298 299 assertEquals(1, events.size()); 300 BrightnessChangeEvent event = events.get(0); 301 assertEquals(mInjector.currentTimeMillis(), event.timeStamp); 302 assertEquals(displayId, event.uniqueDisplayId); 303 assertEquals(1, event.luxValues.length); 304 assertEquals(1.0f, event.luxValues[0], FLOAT_DELTA); 305 assertEquals(mInjector.currentTimeMillis() - TimeUnit.SECONDS.toMillis(2), 306 event.luxTimestamps[0]); 307 assertEquals(brightness, event.brightness, FLOAT_DELTA); 308 assertEquals(DEFAULT_INITIAL_BRIGHTNESS, event.lastBrightness, FLOAT_DELTA); 309 310 // System had no data so these should all be at defaults. 311 assertEquals(Float.NaN, event.batteryLevel, 0.0); 312 assertFalse(event.nightMode); 313 assertEquals(mDefaultNightModeColorTemperature, event.colorTemperature); 314 } 315 316 @Test testBrightnessFullPopulatedEvent()317 public void testBrightnessFullPopulatedEvent() { 318 final int initialBrightness = 230; 319 final int brightness = 130; 320 final String displayId = "1234"; 321 322 mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_ACTIVATED, 1); 323 mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE, 3333); 324 325 mInjector.mSecureIntSettings.put(Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, 1); 326 mInjector.mSecureIntSettings.put(Settings.Secure.REDUCE_BRIGHT_COLORS_LEVEL, 40); 327 328 startTracker(mTracker, initialBrightness, DEFAULT_COLOR_SAMPLING_ENABLED); 329 mInjector.mBroadcastReceiver.onReceive(InstrumentationRegistry.getContext(), 330 batteryChangeEvent(30, 60)); 331 mInjector.mSensorListener.onSensorChanged(createSensorEvent(1000.0f)); 332 final long sensorTime = mInjector.currentTimeMillis(); 333 notifyBrightnessChanged(mTracker, brightness, displayId); 334 List<BrightnessChangeEvent> eventsNoPackage 335 = mTracker.getEvents(0, false).getList(); 336 List<BrightnessChangeEvent> events = mTracker.getEvents(0, true).getList(); 337 mTracker.stop(); 338 339 assertEquals(1, events.size()); 340 BrightnessChangeEvent event = events.get(0); 341 assertEquals(event.timeStamp, mInjector.currentTimeMillis()); 342 assertEquals(displayId, event.uniqueDisplayId); 343 assertArrayEquals(new float[] {1000.0f}, event.luxValues, 0.01f); 344 assertArrayEquals(new long[] {sensorTime}, event.luxTimestamps); 345 assertEquals(brightness, event.brightness, FLOAT_DELTA); 346 assertEquals(initialBrightness, event.lastBrightness, FLOAT_DELTA); 347 assertEquals(0.5, event.batteryLevel, FLOAT_DELTA); 348 assertTrue(event.nightMode); 349 assertEquals(3333, event.colorTemperature); 350 assertTrue(event.reduceBrightColors); 351 assertEquals(40, event.reduceBrightColorsStrength); 352 assertEquals(brightness * mRbcOffsetFactor, event.reduceBrightColorsOffset, FLOAT_DELTA); 353 assertEquals("a.package", event.packageName); 354 assertEquals(0, event.userId); 355 assertArrayEquals(new long[] {1, 10, 100, 1000, 300, 30, 10, 1}, event.colorValueBuckets); 356 assertEquals(10000, event.colorSampleDuration); 357 358 assertEquals(1, eventsNoPackage.size()); 359 assertNull(eventsNoPackage.get(0).packageName); 360 } 361 362 @Test testIgnoreAutomaticBrightnessChange()363 public void testIgnoreAutomaticBrightnessChange() { 364 final int initialBrightness = 30; 365 startTracker(mTracker, initialBrightness, DEFAULT_COLOR_SAMPLING_ENABLED); 366 mInjector.mSensorListener.onSensorChanged(createSensorEvent(1.0f)); 367 mInjector.incrementTime(TimeUnit.SECONDS.toMillis(1)); 368 369 final int systemUpdatedBrightness = 20; 370 notifyBrightnessChanged(mTracker, systemUpdatedBrightness, false /*userInitiated*/, 371 0.5f /*powerBrightnessFactor(*/, false /*isUserSetBrightness*/, 372 false /*isDefaultBrightnessConfig*/, DEFAULT_DISPLAY_ID); 373 List<BrightnessChangeEvent> events = mTracker.getEvents(0, true).getList(); 374 // No events because we filtered out our change. 375 assertEquals(0, events.size()); 376 377 final int firstUserUpdateBrightness = 20; 378 // Then change comes from somewhere else so we shouldn't filter. 379 notifyBrightnessChanged(mTracker, firstUserUpdateBrightness); 380 381 // and with a different brightness value. 382 final int secondUserUpdateBrightness = 34; 383 notifyBrightnessChanged(mTracker, secondUserUpdateBrightness); 384 events = mTracker.getEvents(0, true).getList(); 385 386 assertEquals(2, events.size()); 387 // First event is change from system update (20) to first user update (20) 388 assertEquals(systemUpdatedBrightness, events.get(0).lastBrightness, FLOAT_DELTA); 389 assertEquals(firstUserUpdateBrightness, events.get(0).brightness, FLOAT_DELTA); 390 // Second event is from first to second user update. 391 assertEquals(firstUserUpdateBrightness, events.get(1).lastBrightness, FLOAT_DELTA); 392 assertEquals(secondUserUpdateBrightness, events.get(1).brightness, FLOAT_DELTA); 393 394 mTracker.stop(); 395 } 396 397 @Test testLimitedBufferSize()398 public void testLimitedBufferSize() { 399 startTracker(mTracker); 400 mInjector.mSensorListener.onSensorChanged(createSensorEvent(1.0f)); 401 402 for (int brightness = 0; brightness <= 255; ++brightness) { 403 mInjector.mSensorListener.onSensorChanged(createSensorEvent(1.0f)); 404 mInjector.incrementTime(TimeUnit.SECONDS.toNanos(1)); 405 notifyBrightnessChanged(mTracker, brightness); 406 } 407 List<BrightnessChangeEvent> events = mTracker.getEvents(0, true).getList(); 408 mTracker.stop(); 409 410 // Should be capped at 100 events, and they should be the most recent 100. 411 assertEquals(100, events.size()); 412 for (int i = 0; i < events.size(); i++) { 413 BrightnessChangeEvent event = events.get(i); 414 assertEquals(156 + i, event.brightness, FLOAT_DELTA); 415 } 416 } 417 418 @Test testLimitedSensorEvents()419 public void testLimitedSensorEvents() { 420 final int brightness = 20; 421 422 startTracker(mTracker); 423 // 20 Sensor events 1 second apart. 424 for (int i = 0; i < 20; ++i) { 425 mInjector.incrementTime(TimeUnit.SECONDS.toMillis(1)); 426 mInjector.mSensorListener.onSensorChanged(createSensorEvent(i + 1.0f)); 427 } 428 notifyBrightnessChanged(mTracker, 20); 429 List<BrightnessChangeEvent> events = mTracker.getEvents(0, true).getList(); 430 mTracker.stop(); 431 432 assertEquals(1, events.size()); 433 BrightnessChangeEvent event = events.get(0); 434 assertEquals(mInjector.currentTimeMillis(), event.timeStamp); 435 436 // 12 sensor events, 11 for 0->10 seconds + 1 previous event. 437 assertEquals(12, event.luxValues.length); 438 for (int i = 0; i < 12; ++i) { 439 assertEquals(event.luxTimestamps[11 - i], 440 mInjector.currentTimeMillis() - i * TimeUnit.SECONDS.toMillis(1)); 441 } 442 assertEquals(brightness, event.brightness, FLOAT_DELTA); 443 } 444 445 @Test testReadEvents()446 public void testReadEvents() throws Exception { 447 BrightnessTracker tracker = new BrightnessTracker(InstrumentationRegistry.getContext(), 448 mInjector); 449 mInjector.mCurrentTimeMillis = System.currentTimeMillis(); 450 long someTimeAgo = System.currentTimeMillis() - TimeUnit.HOURS.toMillis(12); 451 long twoMonthsAgo = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(60); 452 // 3 Events in the file but one too old to read. 453 String eventFile = 454 "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" 455 + "<events>\n" 456 + "<event nits=\"194.2\" timestamp=\"" 457 + Long.toString(someTimeAgo) + "\" packageName=\"" 458 + "com.example.app\" user=\"10\" " 459 + "lastNits=\"32.333\" " 460 + "batteryLevel=\"1.0\" nightMode=\"false\" colorTemperature=\"0\" " 461 + "reduceBrightColors=\"false\" reduceBrightColorsStrength=\"40\" " 462 + "reduceBrightColorsOffset=\"0\"\n" 463 + "uniqueDisplayId=\"123\"" 464 + "lux=\"32.2,31.1\" luxTimestamps=\"" 465 + Long.toString(someTimeAgo) + "," + Long.toString(someTimeAgo) + "\"" 466 + "defaultConfig=\"true\" powerSaveFactor=\"0.5\" userPoint=\"true\" />" 467 + "<event nits=\"71\" timestamp=\"" 468 + Long.toString(someTimeAgo) + "\" packageName=\"" 469 + "com.android.anapp\" user=\"11\" " 470 + "lastNits=\"32\" " 471 + "batteryLevel=\"0.5\" nightMode=\"true\" colorTemperature=\"3235\" " 472 + "reduceBrightColors=\"true\" reduceBrightColorsStrength=\"40\" " 473 + "reduceBrightColorsOffset=\"0\"\n" 474 + "uniqueDisplayId=\"456\"" 475 + "lux=\"132.2,131.1\" luxTimestamps=\"" 476 + Long.toString(someTimeAgo) + "," + Long.toString(someTimeAgo) + "\"" 477 + "colorSampleDuration=\"3456\" colorValueBuckets=\"123,598,23,19\"/>" 478 // Event that is too old so shouldn't show up. 479 + "<event nits=\"142\" timestamp=\"" 480 + Long.toString(twoMonthsAgo) + "\" packageName=\"" 481 + "com.example.app\" user=\"10\" " 482 + "lastNits=\"32\" " 483 + "batteryLevel=\"1.0\" nightMode=\"false\" colorTemperature=\"0\" " 484 + "reduceBrightColors=\"false\" reduceBrightColorsStrength=\"40\" " 485 + "reduceBrightColorsOffset=\"0\"\n" 486 + "uniqueDisplayId=\"789\"" 487 + "lux=\"32.2,31.1\" luxTimestamps=\"" 488 + Long.toString(twoMonthsAgo) + "," + Long.toString(twoMonthsAgo) + "\"/>" 489 + "</events>"; 490 tracker.readEventsLocked(getInputStream(eventFile)); 491 List<BrightnessChangeEvent> events = tracker.getEvents(0, true).getList(); 492 assertEquals(1, events.size()); 493 BrightnessChangeEvent event = events.get(0); 494 assertEquals(someTimeAgo, event.timeStamp); 495 assertEquals(194.2, event.brightness, FLOAT_DELTA); 496 assertEquals("123", event.uniqueDisplayId); 497 assertArrayEquals(new float[] {32.2f, 31.1f}, event.luxValues, FLOAT_DELTA); 498 assertArrayEquals(new long[] {someTimeAgo, someTimeAgo}, event.luxTimestamps); 499 assertEquals(32.333, event.lastBrightness, FLOAT_DELTA); 500 assertEquals(0, event.userId); 501 assertFalse(event.nightMode); 502 assertFalse(event.reduceBrightColors); 503 assertEquals(1.0f, event.batteryLevel, FLOAT_DELTA); 504 assertEquals("com.example.app", event.packageName); 505 assertTrue(event.isDefaultBrightnessConfig); 506 assertEquals(0.5f, event.powerBrightnessFactor, FLOAT_DELTA); 507 assertTrue(event.isUserSetBrightness); 508 assertNull(event.colorValueBuckets); 509 510 events = tracker.getEvents(1, true).getList(); 511 assertEquals(1, events.size()); 512 event = events.get(0); 513 assertEquals(someTimeAgo, event.timeStamp); 514 assertEquals(71, event.brightness, FLOAT_DELTA); 515 assertEquals("456", event.uniqueDisplayId); 516 assertArrayEquals(new float[] {132.2f, 131.1f}, event.luxValues, FLOAT_DELTA); 517 assertArrayEquals(new long[] {someTimeAgo, someTimeAgo}, event.luxTimestamps); 518 assertEquals(32, event.lastBrightness, FLOAT_DELTA); 519 assertEquals(1, event.userId); 520 assertTrue(event.nightMode); 521 assertEquals(3235, event.colorTemperature); 522 assertTrue(event.reduceBrightColors); 523 assertEquals(0.5f, event.batteryLevel, FLOAT_DELTA); 524 assertEquals("com.android.anapp", event.packageName); 525 // Not present in the event so default to false. 526 assertFalse(event.isDefaultBrightnessConfig); 527 assertEquals(1.0, event.powerBrightnessFactor, FLOAT_DELTA); 528 assertFalse(event.isUserSetBrightness); 529 assertEquals(3456L, event.colorSampleDuration); 530 assertArrayEquals(new long[] {123L, 598L, 23L, 19L}, event.colorValueBuckets); 531 532 // Pretend user 1 is a profile of user 0. 533 mInjector.mProfiles = new int[]{0, 1}; 534 events = tracker.getEvents(0, true).getList(); 535 // Both events should now be returned. 536 assertEquals(2, events.size()); 537 BrightnessChangeEvent userZeroEvent; 538 BrightnessChangeEvent userOneEvent; 539 if (events.get(0).userId == 0) { 540 userZeroEvent = events.get(0); 541 userOneEvent = events.get(1); 542 } else { 543 userZeroEvent = events.get(1); 544 userOneEvent = events.get(0); 545 } 546 assertEquals(0, userZeroEvent.userId); 547 assertEquals("com.example.app", userZeroEvent.packageName); 548 assertEquals(1, userOneEvent.userId); 549 // Events from user 1 should have the package name redacted 550 assertNull(userOneEvent.packageName); 551 } 552 553 @Test testFailedRead()554 public void testFailedRead() { 555 String someTimeAgo = 556 Long.toString(System.currentTimeMillis() - TimeUnit.HOURS.toMillis(12)); 557 mInjector.mCurrentTimeMillis = System.currentTimeMillis(); 558 559 BrightnessTracker tracker = new BrightnessTracker(InstrumentationRegistry.getContext(), 560 mInjector); 561 String eventFile = "junk in the file"; 562 try { 563 tracker.readEventsLocked(getInputStream(eventFile)); 564 } catch (IOException e) { 565 // Expected; 566 } 567 assertEquals(0, tracker.getEvents(0, true).getList().size()); 568 569 // Missing lux value. 570 eventFile = 571 "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" 572 + "<events>\n" 573 + "<event nits=\"194\" timestamp=\"" + someTimeAgo + "\" packageName=\"" 574 + "com.example.app\" user=\"10\" " 575 + "batteryLevel=\"0.7\" nightMode=\"false\" colorTemperature=\"0\" />\n" 576 + "</events>"; 577 try { 578 tracker.readEventsLocked(getInputStream(eventFile)); 579 } catch (IOException e) { 580 // Expected; 581 } 582 assertEquals(0, tracker.getEvents(0, true).getList().size()); 583 } 584 585 @Test testWriteThenRead()586 public void testWriteThenRead() throws Exception { 587 final int brightness = 20; 588 final String displayId = "1234"; 589 590 mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_ACTIVATED, 1); 591 mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE, 3339); 592 593 mInjector.mSecureIntSettings.put(Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, 1); 594 mInjector.mSecureIntSettings.put(Settings.Secure.REDUCE_BRIGHT_COLORS_LEVEL, 40); 595 596 startTracker(mTracker); 597 mInjector.mBroadcastReceiver.onReceive(InstrumentationRegistry.getContext(), 598 batteryChangeEvent(30, 100)); 599 mInjector.mSensorListener.onSensorChanged(createSensorEvent(2000.0f)); 600 final long firstSensorTime = mInjector.currentTimeMillis(); 601 mInjector.incrementTime(TimeUnit.SECONDS.toMillis(2)); 602 mInjector.mSensorListener.onSensorChanged(createSensorEvent(3000.0f)); 603 final long secondSensorTime = mInjector.currentTimeMillis(); 604 mInjector.incrementTime(TimeUnit.SECONDS.toMillis(3)); 605 notifyBrightnessChanged(mTracker, brightness, true /*userInitiated*/, 606 0.5f /*powerBrightnessFactor*/, true /*hasUserBrightnessPoints*/, 607 false /*isDefaultBrightnessConfig*/, displayId); 608 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 609 mTracker.writeEventsLocked(baos); 610 mTracker.stop(); 611 612 baos.flush(); 613 ByteArrayInputStream input = new ByteArrayInputStream(baos.toByteArray()); 614 BrightnessTracker tracker = new BrightnessTracker(InstrumentationRegistry.getContext(), 615 mInjector); 616 tracker.readEventsLocked(input); 617 List<BrightnessChangeEvent> events = tracker.getEvents(0, true).getList(); 618 619 assertEquals(1, events.size()); 620 BrightnessChangeEvent event = events.get(0); 621 assertEquals(displayId, event.uniqueDisplayId); 622 assertArrayEquals(new float[] {2000.0f, 3000.0f}, event.luxValues, FLOAT_DELTA); 623 assertArrayEquals(new long[] {firstSensorTime, secondSensorTime}, event.luxTimestamps); 624 assertEquals(brightness, event.brightness, FLOAT_DELTA); 625 assertEquals(0.3, event.batteryLevel, FLOAT_DELTA); 626 assertTrue(event.nightMode); 627 assertEquals(3339, event.colorTemperature); 628 assertTrue(event.reduceBrightColors); 629 assertEquals(40, event.reduceBrightColorsStrength); 630 assertEquals(brightness * mRbcOffsetFactor, event.reduceBrightColorsOffset, FLOAT_DELTA); 631 assertEquals(0.5f, event.powerBrightnessFactor, FLOAT_DELTA); 632 assertTrue(event.isUserSetBrightness); 633 assertFalse(event.isDefaultBrightnessConfig); 634 assertArrayEquals(new long[] {1, 10, 100, 1000, 300, 30, 10, 1}, event.colorValueBuckets); 635 assertEquals(10000, event.colorSampleDuration); 636 } 637 638 @Test testWritePrunesOldEvents()639 public void testWritePrunesOldEvents() throws Exception { 640 final int brightness = 20; 641 642 mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_ACTIVATED, 1); 643 mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE, 3339); 644 645 mInjector.mSecureIntSettings.put(Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, 1); 646 mInjector.mSecureIntSettings.put(Settings.Secure.REDUCE_BRIGHT_COLORS_LEVEL, 40); 647 648 startTracker(mTracker); 649 mInjector.mBroadcastReceiver.onReceive(InstrumentationRegistry.getContext(), 650 batteryChangeEvent(30, 100)); 651 mInjector.mSensorListener.onSensorChanged(createSensorEvent(1000.0f)); 652 mInjector.incrementTime(TimeUnit.SECONDS.toMillis(1)); 653 mInjector.mSensorListener.onSensorChanged(createSensorEvent(2000.0f)); 654 final long sensorTime = mInjector.currentTimeMillis(); 655 notifyBrightnessChanged(mTracker, brightness); 656 657 // 31 days later 658 mInjector.incrementTime(TimeUnit.DAYS.toMillis(31)); 659 mInjector.mSensorListener.onSensorChanged(createSensorEvent(3000.0f)); 660 notifyBrightnessChanged(mTracker, brightness); 661 final long eventTime = mInjector.currentTimeMillis(); 662 663 List<BrightnessChangeEvent> events = mTracker.getEvents(0, true).getList(); 664 assertEquals(2, events.size()); 665 666 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 667 mTracker.writeEventsLocked(baos); 668 events = mTracker.getEvents(0, true).getList(); 669 mTracker.stop(); 670 671 assertEquals(1, events.size()); 672 BrightnessChangeEvent event = events.get(0); 673 assertEquals(eventTime, event.timeStamp); 674 675 // We will keep one of the old sensor events because we keep 1 event outside the window. 676 assertArrayEquals(new float[] {2000.0f, 3000.0f}, event.luxValues, FLOAT_DELTA); 677 assertArrayEquals(new long[] {sensorTime, eventTime}, event.luxTimestamps); 678 assertEquals(brightness, event.brightness, FLOAT_DELTA); 679 assertEquals(0.3, event.batteryLevel, FLOAT_DELTA); 680 assertTrue(event.nightMode); 681 assertTrue(event.reduceBrightColors); 682 assertEquals(3339, event.colorTemperature); 683 } 684 685 @Test testParcelUnParcel()686 public void testParcelUnParcel() { 687 Parcel parcel = Parcel.obtain(); 688 BrightnessChangeEvent.Builder builder = new BrightnessChangeEvent.Builder(); 689 builder.setBrightness(23f); 690 builder.setTimeStamp(345L); 691 builder.setPackageName("com.example"); 692 builder.setUserId(12); 693 builder.setUniqueDisplayId("9876"); 694 float[] luxValues = new float[2]; 695 luxValues[0] = 3000.0f; 696 luxValues[1] = 4000.0f; 697 builder.setLuxValues(luxValues); 698 long[] luxTimestamps = new long[2]; 699 luxTimestamps[0] = 325L; 700 luxTimestamps[1] = 315L; 701 builder.setLuxTimestamps(luxTimestamps); 702 builder.setBatteryLevel(0.7f); 703 builder.setNightMode(false); 704 builder.setColorTemperature(345); 705 builder.setReduceBrightColors(false); 706 builder.setReduceBrightColorsStrength(40); 707 builder.setReduceBrightColorsOffset(20f); 708 builder.setLastBrightness(50f); 709 builder.setColorValues(new long[] {23, 34, 45}, 1000L); 710 BrightnessChangeEvent event = builder.build(); 711 712 event.writeToParcel(parcel, 0); 713 byte[] parceled = parcel.marshall(); 714 parcel.recycle(); 715 716 parcel = Parcel.obtain(); 717 parcel.unmarshall(parceled, 0, parceled.length); 718 parcel.setDataPosition(0); 719 720 BrightnessChangeEvent event2 = BrightnessChangeEvent.CREATOR.createFromParcel(parcel); 721 parcel.recycle(); 722 assertEquals(event.brightness, event2.brightness, FLOAT_DELTA); 723 assertEquals(event.timeStamp, event2.timeStamp); 724 assertEquals(event.packageName, event2.packageName); 725 assertEquals(event.userId, event2.userId); 726 assertEquals(event.uniqueDisplayId, event2.uniqueDisplayId); 727 assertArrayEquals(event.luxValues, event2.luxValues, FLOAT_DELTA); 728 assertArrayEquals(event.luxTimestamps, event2.luxTimestamps); 729 assertEquals(event.batteryLevel, event2.batteryLevel, FLOAT_DELTA); 730 assertEquals(event.nightMode, event2.nightMode); 731 assertEquals(event.colorTemperature, event2.colorTemperature); 732 assertEquals(event.reduceBrightColors, event2.reduceBrightColors); 733 assertEquals(event.reduceBrightColorsStrength, event2.reduceBrightColorsStrength); 734 assertEquals(event.reduceBrightColorsOffset, event2.reduceBrightColorsOffset, FLOAT_DELTA); 735 assertEquals(event.lastBrightness, event2.lastBrightness, FLOAT_DELTA); 736 assertArrayEquals(event.colorValueBuckets, event2.colorValueBuckets); 737 assertEquals(event.colorSampleDuration, event2.colorSampleDuration); 738 739 parcel = Parcel.obtain(); 740 builder.setBatteryLevel(Float.NaN); 741 event = builder.build(); 742 event.writeToParcel(parcel, 0); 743 parceled = parcel.marshall(); 744 parcel.recycle(); 745 746 parcel = Parcel.obtain(); 747 parcel.unmarshall(parceled, 0, parceled.length); 748 parcel.setDataPosition(0); 749 event2 = BrightnessChangeEvent.CREATOR.createFromParcel(parcel); 750 assertEquals(event.batteryLevel, event2.batteryLevel, FLOAT_DELTA); 751 } 752 753 @Test testNonNullAmbientStats()754 public void testNonNullAmbientStats() { 755 // getAmbientBrightnessStats should return an empty list rather than null when 756 // tracker isn't started or hasn't collected any data. 757 ParceledListSlice<AmbientBrightnessDayStats> slice = mTracker.getAmbientBrightnessStats(0); 758 assertNotNull(slice); 759 assertTrue(slice.getList().isEmpty()); 760 startTracker(mTracker); 761 slice = mTracker.getAmbientBrightnessStats(0); 762 assertNotNull(slice); 763 assertTrue(slice.getList().isEmpty()); 764 } 765 766 @Test testBackgroundHandlerDelay()767 public void testBackgroundHandlerDelay() { 768 final int brightness = 20; 769 770 // Setup tracker. 771 startTracker(mTracker); 772 mInjector.mSensorListener.onSensorChanged(createSensorEvent(1.0f)); 773 mInjector.incrementTime(TimeUnit.SECONDS.toMillis(2)); 774 775 // Block handler from running. 776 final CountDownLatch latch = new CountDownLatch(1); 777 mInjector.mHandler.post( 778 () -> { 779 try { 780 latch.await(); 781 } catch (InterruptedException e) { 782 fail(e.getMessage()); 783 } 784 }); 785 786 // Send an event. 787 long eventTime = mInjector.currentTimeMillis(); 788 mTracker.notifyBrightnessChanged(brightness, true /*userInitiated*/, 789 1.0f /*powerBrightnessFactor*/, false /*isUserSetBrightness*/, 790 false /*isDefaultBrightnessConfig*/, DEFAULT_DISPLAY_ID); 791 792 // Time passes before handler can run. 793 mInjector.incrementTime(TimeUnit.SECONDS.toMillis(2)); 794 795 // Let the handler run. 796 latch.countDown(); 797 mInjector.waitForHandler(); 798 799 List<BrightnessChangeEvent> events = mTracker.getEvents(0, true).getList(); 800 mTracker.stop(); 801 802 // Check event was recorded with time it was sent rather than handler ran. 803 assertEquals(1, events.size()); 804 BrightnessChangeEvent event = events.get(0); 805 assertEquals(eventTime, event.timeStamp); 806 } 807 808 @Test testDisplayIdChange()809 public void testDisplayIdChange() { 810 float firstBrightness = 0.5f; 811 float secondBrightness = 0.75f; 812 String firstDisplayId = "123"; 813 String secondDisplayId = "456"; 814 815 startTracker(mTracker); 816 mInjector.mSensorListener.onSensorChanged(createSensorEvent(1000.0f)); 817 818 notifyBrightnessChanged(mTracker, firstBrightness, firstDisplayId); 819 mInjector.incrementTime(TimeUnit.SECONDS.toMillis(2)); 820 List<BrightnessChangeEvent> events = mTracker.getEvents(0, true).getList(); 821 assertEquals(1, events.size()); 822 BrightnessChangeEvent firstEvent = events.get(0); 823 assertEquals(firstDisplayId, firstEvent.uniqueDisplayId); 824 assertEquals(firstBrightness, firstEvent.brightness, 0.001f); 825 826 notifyBrightnessChanged(mTracker, secondBrightness, secondDisplayId); 827 mInjector.incrementTime(TimeUnit.SECONDS.toMillis(2)); 828 events = mTracker.getEvents(0, true).getList(); 829 assertEquals(2, events.size()); 830 BrightnessChangeEvent secondEvent = events.get(1); 831 assertEquals(secondDisplayId, secondEvent.uniqueDisplayId); 832 assertEquals(secondBrightness, secondEvent.brightness, 0.001f); 833 834 mTracker.stop(); 835 } 836 getInputStream(String data)837 private InputStream getInputStream(String data) { 838 return new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)); 839 } 840 batteryChangeEvent(int level, int scale)841 private Intent batteryChangeEvent(int level, int scale) { 842 Intent intent = new Intent(); 843 intent.setAction(Intent.ACTION_BATTERY_CHANGED); 844 intent.putExtra(BatteryManager.EXTRA_LEVEL, level); 845 intent.putExtra(BatteryManager.EXTRA_SCALE, scale); 846 return intent; 847 } 848 createSensorEvent(float lux)849 private SensorEvent createSensorEvent(float lux) { 850 SensorEvent event; 851 try { 852 Constructor<SensorEvent> constr = 853 SensorEvent.class.getDeclaredConstructor(Integer.TYPE); 854 constr.setAccessible(true); 855 event = constr.newInstance(1); 856 } catch (Exception e) { 857 throw new RuntimeException(e); 858 } 859 event.values[0] = lux; 860 event.timestamp = mInjector.mElapsedRealtimeNanos; 861 862 return event; 863 } 864 startTracker(BrightnessTracker tracker)865 private void startTracker(BrightnessTracker tracker) { 866 startTracker(tracker, DEFAULT_INITIAL_BRIGHTNESS, DEFAULT_COLOR_SAMPLING_ENABLED); 867 } 868 startTracker(BrightnessTracker tracker, float initialBrightness, boolean collectColorSamples)869 private void startTracker(BrightnessTracker tracker, float initialBrightness, 870 boolean collectColorSamples) { 871 tracker.start(initialBrightness); 872 tracker.setBrightnessConfiguration(buildBrightnessConfiguration(collectColorSamples)); 873 mInjector.waitForHandler(); 874 } 875 notifyBrightnessChanged(BrightnessTracker tracker, float brightness)876 private void notifyBrightnessChanged(BrightnessTracker tracker, float brightness) { 877 notifyBrightnessChanged(tracker, brightness, DEFAULT_DISPLAY_ID); 878 } 879 notifyBrightnessChanged(BrightnessTracker tracker, float brightness, String displayId)880 private void notifyBrightnessChanged(BrightnessTracker tracker, float brightness, 881 String displayId) { 882 notifyBrightnessChanged(tracker, brightness, true /*userInitiated*/, 883 1.0f /*powerBrightnessFactor*/, false /*isUserSetBrightness*/, 884 false /*isDefaultBrightnessConfig*/, displayId); 885 } 886 notifyBrightnessChanged(BrightnessTracker tracker, float brightness, boolean userInitiated, float powerBrightnessFactor, boolean isUserSetBrightness, boolean isDefaultBrightnessConfig, String displayId)887 private void notifyBrightnessChanged(BrightnessTracker tracker, float brightness, 888 boolean userInitiated, float powerBrightnessFactor, boolean isUserSetBrightness, 889 boolean isDefaultBrightnessConfig, String displayId) { 890 tracker.notifyBrightnessChanged(brightness, userInitiated, powerBrightnessFactor, 891 isUserSetBrightness, isDefaultBrightnessConfig, displayId); 892 mInjector.waitForHandler(); 893 } 894 buildBrightnessConfiguration(boolean collectColorSamples)895 private BrightnessConfiguration buildBrightnessConfiguration(boolean collectColorSamples) { 896 BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder( 897 /* lux = */ new float[] {0f, 10f, 100f}, 898 /* nits = */ new float[] {1f, 90f, 100f}); 899 builder.setShouldCollectColorSamples(collectColorSamples); 900 return builder.build(); 901 } 902 903 private static final class Idle implements MessageQueue.IdleHandler { 904 private boolean mIdle; 905 906 @Override queueIdle()907 public boolean queueIdle() { 908 synchronized (this) { 909 mIdle = true; 910 notifyAll(); 911 } 912 return false; 913 } 914 waitForIdle()915 public synchronized void waitForIdle() { 916 while (!mIdle) { 917 try { 918 wait(); 919 } catch (InterruptedException e) { 920 } 921 } 922 } 923 } 924 925 private class TestInjector extends BrightnessTracker.Injector { 926 SensorEventListener mSensorListener; 927 BroadcastReceiver mBroadcastReceiver; 928 DisplayManager.DisplayListener mDisplayListener; 929 Map<String, Integer> mSecureIntSettings = new HashMap<>(); 930 long mCurrentTimeMillis = System.currentTimeMillis(); 931 long mElapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos(); 932 Handler mHandler; 933 boolean mIdleScheduled; 934 boolean mInteractive = true; 935 int[] mProfiles; 936 ContentObserver mContentObserver; 937 boolean mIsBrightnessModeAutomatic = true; 938 boolean mColorSamplingEnabled = false; 939 DisplayedContentSamplingAttributes mDefaultSamplingAttributes = 940 new DisplayedContentSamplingAttributes(0x37, 0, 0x4); 941 float mFrameRate = 60.0f; 942 int mNoColorSamplingFrames; 943 944 TestInjector(Handler handler)945 public TestInjector(Handler handler) { 946 mHandler = handler; 947 } 948 incrementTime(long timeMillis)949 void incrementTime(long timeMillis) { 950 mCurrentTimeMillis += timeMillis; 951 mElapsedRealtimeNanos += TimeUnit.MILLISECONDS.toNanos(timeMillis); 952 } 953 setBrightnessMode(boolean isBrightnessModeAutomatic)954 void setBrightnessMode(boolean isBrightnessModeAutomatic) { 955 mIsBrightnessModeAutomatic = isBrightnessModeAutomatic; 956 mContentObserver.dispatchChange(false, null); 957 waitForHandler(); 958 } 959 sendScreenChange(boolean screenOn)960 void sendScreenChange(boolean screenOn) { 961 mInteractive = screenOn; 962 Intent intent = new Intent(); 963 intent.setAction(screenOn ? Intent.ACTION_SCREEN_ON : Intent.ACTION_SCREEN_OFF); 964 mBroadcastReceiver.onReceive(InstrumentationRegistry.getContext(), intent); 965 waitForHandler(); 966 } 967 waitForHandler()968 void waitForHandler() { 969 Idle idle = new Idle(); 970 mHandler.getLooper().getQueue().addIdleHandler(idle); 971 mHandler.post(() -> {}); 972 idle.waitForIdle(); 973 } 974 975 @Override registerSensorListener(Context context, SensorEventListener sensorListener, Handler handler)976 public void registerSensorListener(Context context, 977 SensorEventListener sensorListener, Handler handler) { 978 mSensorListener = sensorListener; 979 } 980 981 @Override unregisterSensorListener(Context context, SensorEventListener sensorListener)982 public void unregisterSensorListener(Context context, 983 SensorEventListener sensorListener) { 984 mSensorListener = null; 985 } 986 987 @Override registerBrightnessModeObserver(ContentResolver resolver, ContentObserver settingsObserver)988 public void registerBrightnessModeObserver(ContentResolver resolver, 989 ContentObserver settingsObserver) { 990 mContentObserver = settingsObserver; 991 } 992 993 @Override unregisterBrightnessModeObserver(Context context, ContentObserver settingsObserver)994 public void unregisterBrightnessModeObserver(Context context, 995 ContentObserver settingsObserver) { 996 mContentObserver = null; 997 } 998 999 @Override registerReceiver(Context context, BroadcastReceiver shutdownReceiver, IntentFilter shutdownFilter)1000 public void registerReceiver(Context context, 1001 BroadcastReceiver shutdownReceiver, IntentFilter shutdownFilter) { 1002 mBroadcastReceiver = shutdownReceiver; 1003 } 1004 1005 @Override unregisterReceiver(Context context, BroadcastReceiver broadcastReceiver)1006 public void unregisterReceiver(Context context, 1007 BroadcastReceiver broadcastReceiver) { 1008 assertEquals(mBroadcastReceiver, broadcastReceiver); 1009 mBroadcastReceiver = null; 1010 } 1011 1012 @Override getBackgroundHandler()1013 public Handler getBackgroundHandler() { 1014 return mHandler; 1015 } 1016 1017 @Override isBrightnessModeAutomatic(ContentResolver resolver)1018 public boolean isBrightnessModeAutomatic(ContentResolver resolver) { 1019 return mIsBrightnessModeAutomatic; 1020 } 1021 1022 @Override getSecureIntForUser(ContentResolver resolver, String setting, int defaultValue, int userId)1023 public int getSecureIntForUser(ContentResolver resolver, String setting, int defaultValue, 1024 int userId) { 1025 Integer value = mSecureIntSettings.get(setting); 1026 if (value == null) { 1027 return defaultValue; 1028 } else { 1029 return value; 1030 } 1031 } 1032 1033 @Override getFile(String filename)1034 public AtomicFile getFile(String filename) { 1035 // Don't have the test write / read from anywhere. 1036 return null; 1037 } 1038 1039 @Override currentTimeMillis()1040 public long currentTimeMillis() { 1041 return mCurrentTimeMillis; 1042 } 1043 1044 @Override elapsedRealtimeNanos()1045 public long elapsedRealtimeNanos() { 1046 return mElapsedRealtimeNanos; 1047 } 1048 1049 @Override getUserSerialNumber(UserManager userManager, int userId)1050 public int getUserSerialNumber(UserManager userManager, int userId) { 1051 return userId + 10; 1052 } 1053 1054 @Override getUserId(UserManager userManager, int userSerialNumber)1055 public int getUserId(UserManager userManager, int userSerialNumber) { 1056 return userSerialNumber - 10; 1057 } 1058 1059 @Override getProfileIds(UserManager userManager, int userId)1060 public int[] getProfileIds(UserManager userManager, int userId) { 1061 if (mProfiles != null) { 1062 return mProfiles; 1063 } else { 1064 return new int[]{userId}; 1065 } 1066 } 1067 1068 @Override getFocusedStack()1069 public RootTaskInfo getFocusedStack() throws RemoteException { 1070 RootTaskInfo focusedStack = new RootTaskInfo(); 1071 focusedStack.userId = 0; 1072 focusedStack.topActivity = new ComponentName("a.package", "a.class"); 1073 return focusedStack; 1074 } 1075 1076 @Override scheduleIdleJob(Context context)1077 public void scheduleIdleJob(Context context) { 1078 // Don't actually schedule jobs during unit tests. 1079 mIdleScheduled = true; 1080 } 1081 1082 @Override cancelIdleJob(Context context)1083 public void cancelIdleJob(Context context) { 1084 mIdleScheduled = false; 1085 } 1086 1087 @Override isInteractive(Context context)1088 public boolean isInteractive(Context context) { 1089 return mInteractive; 1090 } 1091 1092 @Override getNightDisplayColorTemperature(Context context)1093 public int getNightDisplayColorTemperature(Context context) { 1094 return mSecureIntSettings.getOrDefault(Settings.Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE, 1095 mDefaultNightModeColorTemperature); 1096 } 1097 1098 @Override isNightDisplayActivated(Context context)1099 public boolean isNightDisplayActivated(Context context) { 1100 return mSecureIntSettings.getOrDefault(Settings.Secure.NIGHT_DISPLAY_ACTIVATED, 1101 0) == 1; 1102 } 1103 1104 @Override getReduceBrightColorsStrength(Context context)1105 public int getReduceBrightColorsStrength(Context context) { 1106 return mSecureIntSettings.getOrDefault(Settings.Secure.REDUCE_BRIGHT_COLORS_LEVEL, 1107 0); 1108 } 1109 1110 @Override isReduceBrightColorsActivated(Context context)1111 public boolean isReduceBrightColorsActivated(Context context) { 1112 return mSecureIntSettings.getOrDefault(Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, 1113 0) == 1; 1114 } 1115 1116 @Override sampleColor(int noFramesToSample)1117 public DisplayedContentSample sampleColor(int noFramesToSample) { 1118 return new DisplayedContentSample(600L, 1119 null, 1120 null, 1121 new long[] {1, 10, 100, 1000, 300, 30, 10, 1}, 1122 null); 1123 } 1124 1125 @Override getFrameRate(Context context)1126 public float getFrameRate(Context context) { 1127 return mFrameRate; 1128 } 1129 1130 @Override getSamplingAttributes()1131 public DisplayedContentSamplingAttributes getSamplingAttributes() { 1132 return mDefaultSamplingAttributes; 1133 } 1134 1135 @Override enableColorSampling(boolean enable, int noFrames)1136 public boolean enableColorSampling(boolean enable, int noFrames) { 1137 mColorSamplingEnabled = enable; 1138 mNoColorSamplingFrames = noFrames; 1139 return true; 1140 } 1141 1142 @Override registerDisplayListener(Context context, DisplayManager.DisplayListener listener, Handler handler)1143 public void registerDisplayListener(Context context, 1144 DisplayManager.DisplayListener listener, Handler handler) { 1145 mDisplayListener = listener; 1146 } 1147 1148 @Override unRegisterDisplayListener(Context context, DisplayManager.DisplayListener listener)1149 public void unRegisterDisplayListener(Context context, 1150 DisplayManager.DisplayListener listener) { 1151 mDisplayListener = null; 1152 } 1153 } 1154 } 1155