1 /* 2 * Copyright (C) 2022 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 com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; 20 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; 21 22 import static org.junit.Assert.assertNotNull; 23 import static org.mockito.ArgumentMatchers.any; 24 import static org.mockito.ArgumentMatchers.anyBoolean; 25 import static org.mockito.ArgumentMatchers.anyFloat; 26 import static org.mockito.ArgumentMatchers.anyInt; 27 import static org.mockito.ArgumentMatchers.anyLong; 28 import static org.mockito.ArgumentMatchers.anyString; 29 import static org.mockito.ArgumentMatchers.eq; 30 import static org.mockito.ArgumentMatchers.isA; 31 import static org.mockito.ArgumentMatchers.isNull; 32 import static org.mockito.Mockito.atLeastOnce; 33 import static org.mockito.Mockito.clearInvocations; 34 import static org.mockito.Mockito.mock; 35 import static org.mockito.Mockito.never; 36 import static org.mockito.Mockito.reset; 37 import static org.mockito.Mockito.spy; 38 import static org.mockito.Mockito.times; 39 import static org.mockito.Mockito.when; 40 41 import android.content.Context; 42 import android.content.res.Resources; 43 import android.hardware.Sensor; 44 import android.hardware.SensorEventListener; 45 import android.hardware.SensorManager; 46 import android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks; 47 import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest; 48 import android.os.Handler; 49 import android.os.IBinder; 50 import android.os.Looper; 51 import android.os.PowerManager; 52 import android.os.SystemProperties; 53 import android.os.UserHandle; 54 import android.os.test.TestLooper; 55 import android.provider.Settings; 56 import android.testing.TestableContext; 57 import android.util.FloatProperty; 58 import android.view.Display; 59 import android.view.DisplayInfo; 60 61 import androidx.test.ext.junit.runners.AndroidJUnit4; 62 import androidx.test.filters.SmallTest; 63 import androidx.test.platform.app.InstrumentationRegistry; 64 65 import com.android.server.ExtendedMockitoRule; 66 import com.android.server.LocalServices; 67 import com.android.server.am.BatteryStatsService; 68 import com.android.server.display.RampAnimator.DualRampAnimator; 69 import com.android.server.display.brightness.BrightnessEvent; 70 import com.android.server.display.color.ColorDisplayService; 71 import com.android.server.display.layout.Layout; 72 import com.android.server.display.whitebalance.DisplayWhiteBalanceController; 73 import com.android.server.policy.WindowManagerPolicy; 74 import com.android.server.testutils.OffsettableClock; 75 76 import org.junit.After; 77 import org.junit.Before; 78 import org.junit.Rule; 79 import org.junit.Test; 80 import org.junit.runner.RunWith; 81 import org.mockito.ArgumentCaptor; 82 import org.mockito.Captor; 83 import org.mockito.Mock; 84 import org.mockito.quality.Strictness; 85 import org.mockito.stubbing.Answer; 86 87 import java.util.List; 88 89 90 @SmallTest 91 @RunWith(AndroidJUnit4.class) 92 public final class DisplayPowerControllerTest { 93 private static final int DISPLAY_ID = Display.DEFAULT_DISPLAY; 94 private static final String UNIQUE_ID = "unique_id_test123"; 95 private static final int FOLLOWER_DISPLAY_ID = DISPLAY_ID + 1; 96 private static final String FOLLOWER_UNIQUE_ID = "unique_id_456"; 97 private static final int SECOND_FOLLOWER_DISPLAY_ID = FOLLOWER_DISPLAY_ID + 1; 98 private static final String SECOND_FOLLOWER_UNIQUE_DISPLAY_ID = "unique_id_789"; 99 private static final float PROX_SENSOR_MAX_RANGE = 5; 100 private static final float BRIGHTNESS_RAMP_RATE_FAST_DECREASE = 0.3f; 101 private static final float BRIGHTNESS_RAMP_RATE_FAST_INCREASE = 0.4f; 102 private static final float BRIGHTNESS_RAMP_RATE_SLOW_DECREASE = 0.1f; 103 private static final float BRIGHTNESS_RAMP_RATE_SLOW_INCREASE = 0.2f; 104 105 private OffsettableClock mClock; 106 private TestLooper mTestLooper; 107 private Handler mHandler; 108 private DisplayPowerControllerHolder mHolder; 109 private Sensor mProxSensor; 110 111 @Mock 112 private DisplayPowerCallbacks mDisplayPowerCallbacksMock; 113 @Mock 114 private SensorManager mSensorManagerMock; 115 @Mock 116 private DisplayBlanker mDisplayBlankerMock; 117 @Mock 118 private BrightnessTracker mBrightnessTrackerMock; 119 @Mock 120 private WindowManagerPolicy mWindowManagerPolicyMock; 121 @Mock 122 private PowerManager mPowerManagerMock; 123 @Mock 124 private ColorDisplayService.ColorDisplayServiceInternal mCdsiMock; 125 @Mock 126 private DisplayWhiteBalanceController mDisplayWhiteBalanceControllerMock; 127 @Captor 128 private ArgumentCaptor<SensorEventListener> mSensorEventListenerCaptor; 129 130 @Rule 131 public final TestableContext mContext = new TestableContext( 132 InstrumentationRegistry.getInstrumentation().getContext()); 133 134 @Rule 135 public final ExtendedMockitoRule mExtendedMockitoRule = 136 new ExtendedMockitoRule.Builder(this) 137 .setStrictness(Strictness.LENIENT) 138 .spyStatic(SystemProperties.class) 139 .spyStatic(BatteryStatsService.class) 140 .build(); 141 142 @Before setUp()143 public void setUp() throws Exception { 144 mClock = new OffsettableClock.Stopped(); 145 mTestLooper = new TestLooper(mClock::now); 146 mHandler = new Handler(mTestLooper.getLooper()); 147 148 // Set some settings to minimize unexpected events and have a consistent starting state 149 Settings.System.putInt(mContext.getContentResolver(), 150 Settings.System.SCREEN_BRIGHTNESS_MODE, 151 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL); 152 Settings.System.putFloatForUser(mContext.getContentResolver(), 153 Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0, UserHandle.USER_CURRENT); 154 155 addLocalServiceMock(WindowManagerPolicy.class, mWindowManagerPolicyMock); 156 addLocalServiceMock(ColorDisplayService.ColorDisplayServiceInternal.class, 157 mCdsiMock); 158 159 mContext.addMockSystemService(PowerManager.class, mPowerManagerMock); 160 161 doAnswer((Answer<Void>) invocationOnMock -> null).when(() -> 162 SystemProperties.set(anyString(), any())); 163 doAnswer((Answer<Void>) invocationOnMock -> null).when(BatteryStatsService::getService); 164 165 setUpSensors(); 166 mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID); 167 } 168 169 @After tearDown()170 public void tearDown() { 171 LocalServices.removeServiceForTest(WindowManagerPolicy.class); 172 LocalServices.removeServiceForTest(ColorDisplayService.ColorDisplayServiceInternal.class); 173 } 174 175 @Test testReleaseProxSuspendBlockersOnExit()176 public void testReleaseProxSuspendBlockersOnExit() throws Exception { 177 when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON); 178 // Send a display power request 179 DisplayPowerRequest dpr = new DisplayPowerRequest(); 180 dpr.policy = DisplayPowerRequest.POLICY_BRIGHT; 181 dpr.useProximitySensor = true; 182 mHolder.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */); 183 184 // Run updatePowerState to start listener for the prox sensor 185 advanceTime(1); 186 187 SensorEventListener listener = getSensorEventListener(mProxSensor); 188 assertNotNull(listener); 189 190 listener.onSensorChanged(TestUtils.createSensorEvent(mProxSensor, /* value= */ 5)); 191 advanceTime(1); 192 193 // two times, one for unfinished business and one for proximity 194 verify(mDisplayPowerCallbacksMock).acquireSuspendBlocker( 195 mHolder.dpc.getSuspendBlockerUnfinishedBusinessId(DISPLAY_ID)); 196 verify(mDisplayPowerCallbacksMock).acquireSuspendBlocker( 197 mHolder.dpc.getSuspendBlockerProxDebounceId(DISPLAY_ID)); 198 199 mHolder.dpc.stop(); 200 advanceTime(1); 201 202 // two times, one for unfinished business and one for proximity 203 verify(mDisplayPowerCallbacksMock).releaseSuspendBlocker( 204 mHolder.dpc.getSuspendBlockerUnfinishedBusinessId(DISPLAY_ID)); 205 verify(mDisplayPowerCallbacksMock).releaseSuspendBlocker( 206 mHolder.dpc.getSuspendBlockerProxDebounceId(DISPLAY_ID)); 207 } 208 209 @Test testScreenOffBecauseOfProximity()210 public void testScreenOffBecauseOfProximity() throws Exception { 211 when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON); 212 // Send a display power request 213 DisplayPowerRequest dpr = new DisplayPowerRequest(); 214 dpr.policy = DisplayPowerRequest.POLICY_BRIGHT; 215 dpr.useProximitySensor = true; 216 mHolder.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */); 217 218 // Run updatePowerState to start listener for the prox sensor 219 advanceTime(1); 220 221 SensorEventListener listener = getSensorEventListener(mProxSensor); 222 assertNotNull(listener); 223 224 // Send a positive proximity event 225 listener.onSensorChanged(TestUtils.createSensorEvent(mProxSensor, /* value= */ 1)); 226 advanceTime(1); 227 228 // The display should have been turned off 229 verify(mHolder.displayPowerState).setScreenState(Display.STATE_OFF); 230 231 clearInvocations(mHolder.displayPowerState); 232 when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_OFF); 233 // Send a negative proximity event 234 listener.onSensorChanged(TestUtils.createSensorEvent(mProxSensor, 235 (int) PROX_SENSOR_MAX_RANGE + 1)); 236 // Advance time by less than PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY 237 advanceTime(1); 238 239 // The prox sensor is debounced so the display should not have been turned back on yet 240 verify(mHolder.displayPowerState, never()).setScreenState(Display.STATE_ON); 241 242 // Advance time by more than PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY 243 advanceTime(1000); 244 245 // The display should have been turned back on 246 verify(mHolder.displayPowerState).setScreenState(Display.STATE_ON); 247 } 248 249 @Test testScreenOffBecauseOfProximity_ProxSensorGone()250 public void testScreenOffBecauseOfProximity_ProxSensorGone() throws Exception { 251 when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON); 252 // Send a display power request 253 DisplayPowerRequest dpr = new DisplayPowerRequest(); 254 dpr.policy = DisplayPowerRequest.POLICY_BRIGHT; 255 dpr.useProximitySensor = true; 256 mHolder.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */); 257 258 // Run updatePowerState to start listener for the prox sensor 259 advanceTime(1); 260 261 SensorEventListener listener = getSensorEventListener(mProxSensor); 262 assertNotNull(listener); 263 264 // Send a positive proximity event 265 listener.onSensorChanged(TestUtils.createSensorEvent(mProxSensor, /* value= */ 1)); 266 advanceTime(1); 267 268 // The display should have been turned off 269 verify(mHolder.displayPowerState).setScreenState(Display.STATE_OFF); 270 271 when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_OFF); 272 // The display device changes and we no longer have a prox sensor 273 reset(mSensorManagerMock); 274 setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class), 275 mock(DisplayDeviceConfig.class), /* isEnabled= */ true); 276 mHolder.dpc.onDisplayChanged(mHolder.hbmMetadata, Layout.NO_LEAD_DISPLAY); 277 278 advanceTime(1); // Run updatePowerState 279 280 // The display should have been turned back on and the listener should have been 281 // unregistered 282 verify(mHolder.displayPowerState).setScreenState(Display.STATE_ON); 283 verify(mSensorManagerMock).unregisterListener(listener); 284 } 285 286 @Test testProximitySensorListenerNotRegisteredForNonDefaultDisplay()287 public void testProximitySensorListenerNotRegisteredForNonDefaultDisplay() { 288 DisplayPowerControllerHolder followerDpc = 289 createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_ID); 290 291 when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON); 292 // send a display power request 293 DisplayPowerRequest dpr = new DisplayPowerRequest(); 294 dpr.policy = DisplayPowerRequest.POLICY_BRIGHT; 295 dpr.useProximitySensor = true; 296 followerDpc.dpc.requestPowerState(dpr, false /* waitForNegativeProximity */); 297 298 // Run updatePowerState 299 advanceTime(1); 300 301 verify(mSensorManagerMock, never()).registerListener(any(SensorEventListener.class), 302 eq(mProxSensor), anyInt(), any(Handler.class)); 303 } 304 305 @Test testDisplayBrightnessFollowers_BothDpcsSupportNits()306 public void testDisplayBrightnessFollowers_BothDpcsSupportNits() { 307 DisplayPowerControllerHolder followerDpc = 308 createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_ID); 309 when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f); 310 when(followerDpc.displayPowerState.getColorFadeLevel()).thenReturn(1.0f); 311 312 DisplayPowerRequest dpr = new DisplayPowerRequest(); 313 mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 314 followerDpc.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 315 advanceTime(1); // Run updatePowerState 316 317 ArgumentCaptor<BrightnessSetting.BrightnessSettingListener> listenerCaptor = 318 ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class); 319 verify(mHolder.brightnessSetting).registerListener(listenerCaptor.capture()); 320 BrightnessSetting.BrightnessSettingListener listener = listenerCaptor.getValue(); 321 322 mHolder.dpc.addDisplayBrightnessFollower(followerDpc.dpc); 323 324 // Test different float scale values 325 float leadBrightness = 0.3f; 326 float followerBrightness = 0.4f; 327 float nits = 300; 328 when(mHolder.automaticBrightnessController.convertToNits(leadBrightness)).thenReturn(nits); 329 when(followerDpc.automaticBrightnessController.convertToFloatScale(nits)) 330 .thenReturn(followerBrightness); 331 when(mHolder.brightnessSetting.getBrightness()).thenReturn(leadBrightness); 332 listener.onBrightnessChanged(leadBrightness); 333 advanceTime(1); // Send messages, run updatePowerState 334 verify(mHolder.animator).animateTo(eq(leadBrightness), anyFloat(), 335 eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); 336 verify(followerDpc.animator).animateTo(eq(followerBrightness), anyFloat(), 337 eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); 338 339 when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(leadBrightness); 340 when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(followerBrightness); 341 clearInvocations(mHolder.animator, followerDpc.animator); 342 343 // Test the same float scale value 344 float brightness = 0.6f; 345 nits = 600; 346 when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits); 347 when(followerDpc.automaticBrightnessController.convertToFloatScale(nits)) 348 .thenReturn(brightness); 349 when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness); 350 listener.onBrightnessChanged(brightness); 351 advanceTime(1); // Send messages, run updatePowerState 352 verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), 353 eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); 354 verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), 355 eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); 356 } 357 358 @Test testDisplayBrightnessFollowers_FollowerDoesNotSupportNits()359 public void testDisplayBrightnessFollowers_FollowerDoesNotSupportNits() { 360 DisplayPowerControllerHolder followerDpc = 361 createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_ID); 362 when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f); 363 when(followerDpc.displayPowerState.getColorFadeLevel()).thenReturn(1.0f); 364 365 DisplayPowerRequest dpr = new DisplayPowerRequest(); 366 mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 367 followerDpc.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 368 advanceTime(1); // Run updatePowerState 369 370 ArgumentCaptor<BrightnessSetting.BrightnessSettingListener> listenerCaptor = 371 ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class); 372 verify(mHolder.brightnessSetting).registerListener(listenerCaptor.capture()); 373 BrightnessSetting.BrightnessSettingListener listener = listenerCaptor.getValue(); 374 375 mHolder.dpc.addDisplayBrightnessFollower(followerDpc.dpc); 376 377 float brightness = 0.3f; 378 when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(300f); 379 when(followerDpc.automaticBrightnessController.convertToFloatScale(anyFloat())) 380 .thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT); 381 when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness); 382 listener.onBrightnessChanged(brightness); 383 advanceTime(1); // Send messages, run updatePowerState 384 verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), 385 eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); 386 verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), 387 eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); 388 } 389 390 @Test testDisplayBrightnessFollowers_LeadDpcDoesNotSupportNits()391 public void testDisplayBrightnessFollowers_LeadDpcDoesNotSupportNits() { 392 DisplayPowerControllerHolder followerDpc = 393 createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_ID); 394 when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f); 395 when(followerDpc.displayPowerState.getColorFadeLevel()).thenReturn(1.0f); 396 397 DisplayPowerRequest dpr = new DisplayPowerRequest(); 398 mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 399 followerDpc.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 400 advanceTime(1); // Run updatePowerState 401 402 ArgumentCaptor<BrightnessSetting.BrightnessSettingListener> listenerCaptor = 403 ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class); 404 verify(mHolder.brightnessSetting).registerListener(listenerCaptor.capture()); 405 BrightnessSetting.BrightnessSettingListener listener = listenerCaptor.getValue(); 406 407 mHolder.dpc.addDisplayBrightnessFollower(followerDpc.dpc); 408 409 float brightness = 0.3f; 410 when(mHolder.automaticBrightnessController.convertToNits(anyFloat())).thenReturn(-1f); 411 when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness); 412 listener.onBrightnessChanged(brightness); 413 advanceTime(1); // Send messages, run updatePowerState 414 verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), 415 eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); 416 verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), 417 eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); 418 } 419 420 @Test testDisplayBrightnessFollowers_NeitherDpcSupportsNits()421 public void testDisplayBrightnessFollowers_NeitherDpcSupportsNits() { 422 DisplayPowerControllerHolder followerDpc = 423 createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_ID); 424 when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f); 425 when(followerDpc.displayPowerState.getColorFadeLevel()).thenReturn(1.0f); 426 427 DisplayPowerRequest dpr = new DisplayPowerRequest(); 428 mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 429 followerDpc.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 430 advanceTime(1); // Run updatePowerState 431 432 ArgumentCaptor<BrightnessSetting.BrightnessSettingListener> listenerCaptor = 433 ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class); 434 verify(mHolder.brightnessSetting).registerListener(listenerCaptor.capture()); 435 BrightnessSetting.BrightnessSettingListener listener = listenerCaptor.getValue(); 436 437 mHolder.dpc.addDisplayBrightnessFollower(followerDpc.dpc); 438 439 float brightness = 0.3f; 440 when(mHolder.automaticBrightnessController.convertToNits(anyFloat())).thenReturn(-1f); 441 when(followerDpc.automaticBrightnessController.convertToFloatScale(anyFloat())) 442 .thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT); 443 when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness); 444 listener.onBrightnessChanged(brightness); 445 advanceTime(1); // Send messages, run updatePowerState 446 verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), 447 eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); 448 verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), 449 eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); 450 } 451 452 @Test testDisplayBrightnessFollowers_AutomaticBrightness()453 public void testDisplayBrightnessFollowers_AutomaticBrightness() { 454 Settings.System.putInt(mContext.getContentResolver(), 455 Settings.System.SCREEN_BRIGHTNESS_MODE, 456 Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC); 457 DisplayPowerControllerHolder followerDpc = 458 createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_ID); 459 when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON); 460 when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f); 461 when(followerDpc.displayPowerState.getColorFadeLevel()).thenReturn(1.0f); 462 float leadBrightness = 0.1f; 463 float rawLeadBrightness = 0.3f; 464 float followerBrightness = 0.4f; 465 float nits = 300; 466 float ambientLux = 3000; 467 when(mHolder.automaticBrightnessController.getRawAutomaticScreenBrightness()) 468 .thenReturn(rawLeadBrightness); 469 when(mHolder.automaticBrightnessController 470 .getAutomaticScreenBrightness(any(BrightnessEvent.class))) 471 .thenReturn(leadBrightness); 472 when(mHolder.automaticBrightnessController.convertToNits(rawLeadBrightness)) 473 .thenReturn(nits); 474 when(mHolder.automaticBrightnessController.getAmbientLux()).thenReturn(ambientLux); 475 when(followerDpc.automaticBrightnessController.convertToFloatScale(nits)) 476 .thenReturn(followerBrightness); 477 478 mHolder.dpc.addDisplayBrightnessFollower(followerDpc.dpc); 479 480 DisplayPowerRequest dpr = new DisplayPowerRequest(); 481 mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 482 followerDpc.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 483 advanceTime(1); // Run updatePowerState 484 485 verify(mHolder.animator).animateTo(eq(leadBrightness), anyFloat(), 486 eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); 487 // One triggered by handleBrightnessModeChange, another triggered by setBrightnessToFollow 488 verify(followerDpc.hbmController, times(2)).onAmbientLuxChange(ambientLux); 489 verify(followerDpc.animator, times(2)).animateTo(eq(followerBrightness), anyFloat(), 490 eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); 491 492 when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(leadBrightness); 493 when(followerDpc.displayPowerState.getScreenBrightness()).thenReturn(followerBrightness); 494 clearInvocations(mHolder.animator, followerDpc.animator); 495 496 leadBrightness = 0.05f; 497 rawLeadBrightness = 0.2f; 498 followerBrightness = 0.3f; 499 nits = 200; 500 ambientLux = 2000; 501 when(mHolder.automaticBrightnessController.getRawAutomaticScreenBrightness()) 502 .thenReturn(rawLeadBrightness); 503 when(mHolder.automaticBrightnessController 504 .getAutomaticScreenBrightness(any(BrightnessEvent.class))) 505 .thenReturn(leadBrightness); 506 when(mHolder.automaticBrightnessController.convertToNits(rawLeadBrightness)) 507 .thenReturn(nits); 508 when(mHolder.automaticBrightnessController.getAmbientLux()).thenReturn(ambientLux); 509 when(followerDpc.automaticBrightnessController.convertToFloatScale(nits)) 510 .thenReturn(followerBrightness); 511 512 mHolder.dpc.updateBrightness(); 513 advanceTime(1); // Run updatePowerState 514 515 // The second time, the animation rate should be slow 516 verify(mHolder.animator).animateTo(eq(leadBrightness), anyFloat(), 517 eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE)); 518 verify(followerDpc.hbmController).onAmbientLuxChange(ambientLux); 519 verify(followerDpc.animator).animateTo(eq(followerBrightness), anyFloat(), 520 eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE)); 521 } 522 523 @Test testDisplayBrightnessFollowersRemoval_RemoveSingleFollower()524 public void testDisplayBrightnessFollowersRemoval_RemoveSingleFollower() { 525 DisplayPowerControllerHolder followerDpc = createDisplayPowerController(FOLLOWER_DISPLAY_ID, 526 FOLLOWER_UNIQUE_ID); 527 DisplayPowerControllerHolder secondFollowerDpc = createDisplayPowerController( 528 SECOND_FOLLOWER_DISPLAY_ID, SECOND_FOLLOWER_UNIQUE_DISPLAY_ID); 529 when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f); 530 when(followerDpc.displayPowerState.getColorFadeLevel()).thenReturn(1.0f); 531 when(secondFollowerDpc.displayPowerState.getColorFadeLevel()).thenReturn(1.0f); 532 533 DisplayPowerRequest dpr = new DisplayPowerRequest(); 534 mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 535 followerDpc.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 536 secondFollowerDpc.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 537 advanceTime(1); // Run updatePowerState 538 539 ArgumentCaptor<BrightnessSetting.BrightnessSettingListener> listenerCaptor = 540 ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class); 541 verify(mHolder.brightnessSetting).registerListener(listenerCaptor.capture()); 542 BrightnessSetting.BrightnessSettingListener listener = listenerCaptor.getValue(); 543 544 // Set the initial brightness on the DPC we're going to remove so we have a fixed value for 545 // it to return to. 546 listenerCaptor = ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class); 547 verify(followerDpc.brightnessSetting).registerListener(listenerCaptor.capture()); 548 BrightnessSetting.BrightnessSettingListener followerListener = listenerCaptor.getValue(); 549 final float initialFollowerBrightness = 0.3f; 550 when(followerDpc.brightnessSetting.getBrightness()).thenReturn(initialFollowerBrightness); 551 followerListener.onBrightnessChanged(initialFollowerBrightness); 552 advanceTime(1); 553 verify(followerDpc.animator).animateTo(eq(initialFollowerBrightness), anyFloat(), 554 eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); 555 556 when(followerDpc.displayPowerState.getScreenBrightness()) 557 .thenReturn(initialFollowerBrightness); 558 559 mHolder.dpc.addDisplayBrightnessFollower(followerDpc.dpc); 560 mHolder.dpc.addDisplayBrightnessFollower(secondFollowerDpc.dpc); 561 clearInvocations(followerDpc.animator); 562 563 // Validate both followers are correctly registered and receiving brightness updates 564 float brightness = 0.6f; 565 float nits = 600; 566 when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits); 567 when(followerDpc.automaticBrightnessController.convertToFloatScale(nits)) 568 .thenReturn(brightness); 569 when(secondFollowerDpc.automaticBrightnessController.convertToFloatScale(nits)) 570 .thenReturn(brightness); 571 when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness); 572 listener.onBrightnessChanged(brightness); 573 advanceTime(1); // Send messages, run updatePowerState 574 verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), 575 eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); 576 verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), 577 eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); 578 verify(secondFollowerDpc.animator).animateTo(eq(brightness), anyFloat(), 579 eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); 580 581 when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness); 582 when(followerDpc.displayPowerState.getScreenBrightness()).thenReturn(brightness); 583 when(secondFollowerDpc.displayPowerState.getScreenBrightness()).thenReturn(brightness); 584 clearInvocations(mHolder.animator, followerDpc.animator, secondFollowerDpc.animator); 585 586 // Remove the first follower and validate it goes back to its original brightness. 587 mHolder.dpc.removeDisplayBrightnessFollower(followerDpc.dpc); 588 advanceTime(1); 589 verify(followerDpc.animator).animateTo(eq(initialFollowerBrightness), anyFloat(), 590 eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE)); 591 592 when(followerDpc.displayPowerState.getScreenBrightness()) 593 .thenReturn(initialFollowerBrightness); 594 clearInvocations(followerDpc.animator); 595 596 // Change the brightness of the lead display and validate only the second follower responds 597 brightness = 0.7f; 598 nits = 700; 599 when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits); 600 when(followerDpc.automaticBrightnessController.convertToFloatScale(nits)) 601 .thenReturn(brightness); 602 when(secondFollowerDpc.automaticBrightnessController.convertToFloatScale(nits)) 603 .thenReturn(brightness); 604 when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness); 605 listener.onBrightnessChanged(brightness); 606 advanceTime(1); // Send messages, run updatePowerState 607 verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), 608 eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); 609 verify(followerDpc.animator, never()).animateTo(anyFloat(), anyFloat(), anyFloat()); 610 verify(secondFollowerDpc.animator).animateTo(eq(brightness), anyFloat(), 611 eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); 612 } 613 614 @Test testDisplayBrightnessFollowersRemoval_RemoveAllFollowers()615 public void testDisplayBrightnessFollowersRemoval_RemoveAllFollowers() { 616 DisplayPowerControllerHolder followerHolder = 617 createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_ID); 618 DisplayPowerControllerHolder secondFollowerHolder = 619 createDisplayPowerController(SECOND_FOLLOWER_DISPLAY_ID, 620 SECOND_FOLLOWER_UNIQUE_DISPLAY_ID); 621 when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f); 622 when(followerHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f); 623 when(secondFollowerHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f); 624 625 DisplayPowerRequest dpr = new DisplayPowerRequest(); 626 mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 627 followerHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 628 secondFollowerHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 629 advanceTime(1); // Run updatePowerState 630 631 ArgumentCaptor<BrightnessSetting.BrightnessSettingListener> listenerCaptor = 632 ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class); 633 verify(mHolder.brightnessSetting).registerListener(listenerCaptor.capture()); 634 BrightnessSetting.BrightnessSettingListener listener = listenerCaptor.getValue(); 635 636 // Set the initial brightness on the DPCs we're going to remove so we have a fixed value for 637 // it to return to. 638 listenerCaptor = ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class); 639 verify(followerHolder.brightnessSetting).registerListener(listenerCaptor.capture()); 640 BrightnessSetting.BrightnessSettingListener followerListener = listenerCaptor.getValue(); 641 listenerCaptor = ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class); 642 verify(secondFollowerHolder.brightnessSetting).registerListener(listenerCaptor.capture()); 643 BrightnessSetting.BrightnessSettingListener secondFollowerListener = 644 listenerCaptor.getValue(); 645 final float initialFollowerBrightness = 0.3f; 646 when(followerHolder.brightnessSetting.getBrightness()).thenReturn( 647 initialFollowerBrightness); 648 when(secondFollowerHolder.brightnessSetting.getBrightness()).thenReturn( 649 initialFollowerBrightness); 650 followerListener.onBrightnessChanged(initialFollowerBrightness); 651 secondFollowerListener.onBrightnessChanged(initialFollowerBrightness); 652 advanceTime(1); 653 verify(followerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(), 654 eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); 655 verify(secondFollowerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(), 656 eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); 657 658 when(followerHolder.displayPowerState.getScreenBrightness()) 659 .thenReturn(initialFollowerBrightness); 660 when(secondFollowerHolder.displayPowerState.getScreenBrightness()) 661 .thenReturn(initialFollowerBrightness); 662 663 mHolder.dpc.addDisplayBrightnessFollower(followerHolder.dpc); 664 mHolder.dpc.addDisplayBrightnessFollower(secondFollowerHolder.dpc); 665 clearInvocations(followerHolder.animator, secondFollowerHolder.animator); 666 667 // Validate both followers are correctly registered and receiving brightness updates 668 float brightness = 0.6f; 669 float nits = 600; 670 when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits); 671 when(followerHolder.automaticBrightnessController.convertToFloatScale(nits)) 672 .thenReturn(brightness); 673 when(secondFollowerHolder.automaticBrightnessController.convertToFloatScale(nits)) 674 .thenReturn(brightness); 675 when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness); 676 listener.onBrightnessChanged(brightness); 677 advanceTime(1); // Send messages, run updatePowerState 678 verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), 679 eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); 680 verify(followerHolder.animator).animateTo(eq(brightness), anyFloat(), 681 eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); 682 verify(secondFollowerHolder.animator).animateTo(eq(brightness), anyFloat(), 683 eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); 684 685 when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness); 686 when(followerHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness); 687 when(secondFollowerHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness); 688 clearInvocations(mHolder.animator, followerHolder.animator, secondFollowerHolder.animator); 689 690 // Stop the lead DPC and validate that the followers go back to their original brightness. 691 mHolder.dpc.stop(); 692 advanceTime(1); 693 verify(followerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(), 694 eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE)); 695 verify(secondFollowerHolder.animator).animateTo(eq(initialFollowerBrightness), anyFloat(), 696 eq(BRIGHTNESS_RAMP_RATE_FAST_DECREASE)); 697 clearInvocations(followerHolder.animator, secondFollowerHolder.animator); 698 } 699 700 @Test testDoesNotSetScreenStateForNonDefaultDisplayUntilBootCompleted()701 public void testDoesNotSetScreenStateForNonDefaultDisplayUntilBootCompleted() { 702 // We should still set screen state for the default display 703 DisplayPowerRequest dpr = new DisplayPowerRequest(); 704 mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 705 advanceTime(1); // Run updatePowerState 706 verify(mHolder.displayPowerState, times(2)).setScreenState(anyInt()); 707 708 mHolder = createDisplayPowerController(42, UNIQUE_ID); 709 710 mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 711 advanceTime(1); // Run updatePowerState 712 verify(mHolder.displayPowerState, never()).setScreenState(anyInt()); 713 714 mHolder.dpc.onBootCompleted(); 715 advanceTime(1); // Run updatePowerState 716 verify(mHolder.displayPowerState).setScreenState(anyInt()); 717 } 718 719 @Test testSetScreenOffBrightnessSensorEnabled_DisplayIsOff()720 public void testSetScreenOffBrightnessSensorEnabled_DisplayIsOff() { 721 Settings.System.putInt(mContext.getContentResolver(), 722 Settings.System.SCREEN_BRIGHTNESS_MODE, 723 Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC); 724 725 DisplayPowerRequest dpr = new DisplayPowerRequest(); 726 dpr.policy = DisplayPowerRequest.POLICY_OFF; 727 mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 728 advanceTime(1); // Run updatePowerState 729 730 verify(mHolder.screenOffBrightnessSensorController, atLeastOnce()) 731 .setLightSensorEnabled(true); 732 733 // The display turns on and we use the brightness value recommended by 734 // ScreenOffBrightnessSensorController 735 clearInvocations(mHolder.screenOffBrightnessSensorController); 736 float brightness = 0.14f; 737 when(mHolder.screenOffBrightnessSensorController.getAutomaticScreenBrightness()) 738 .thenReturn(brightness); 739 dpr.policy = DisplayPowerRequest.POLICY_BRIGHT; 740 when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON); 741 when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness( 742 any(BrightnessEvent.class))).thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT); 743 744 mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 745 advanceTime(1); // Run updatePowerState 746 747 verify(mHolder.screenOffBrightnessSensorController, atLeastOnce()) 748 .getAutomaticScreenBrightness(); 749 verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat()); 750 } 751 752 @Test testSetScreenOffBrightnessSensorEnabled_DisplayIsInDoze()753 public void testSetScreenOffBrightnessSensorEnabled_DisplayIsInDoze() { 754 Settings.System.putInt(mContext.getContentResolver(), 755 Settings.System.SCREEN_BRIGHTNESS_MODE, 756 Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC); 757 758 DisplayPowerRequest dpr = new DisplayPowerRequest(); 759 dpr.policy = DisplayPowerRequest.POLICY_DOZE; 760 mContext.getOrCreateTestableResources().addOverride( 761 com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing, true); 762 mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 763 advanceTime(1); // Run updatePowerState 764 765 verify(mHolder.screenOffBrightnessSensorController, atLeastOnce()) 766 .setLightSensorEnabled(true); 767 768 // The display turns on and we use the brightness value recommended by 769 // ScreenOffBrightnessSensorController 770 clearInvocations(mHolder.screenOffBrightnessSensorController); 771 float brightness = 0.14f; 772 when(mHolder.screenOffBrightnessSensorController.getAutomaticScreenBrightness()) 773 .thenReturn(brightness); 774 dpr.policy = DisplayPowerRequest.POLICY_BRIGHT; 775 when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON); 776 when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness( 777 any(BrightnessEvent.class))).thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT); 778 779 mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 780 advanceTime(1); // Run updatePowerState 781 782 verify(mHolder.screenOffBrightnessSensorController, atLeastOnce()) 783 .getAutomaticScreenBrightness(); 784 verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat()); 785 } 786 787 @Test testSetScreenOffBrightnessSensorDisabled_AutoBrightnessIsDisabled()788 public void testSetScreenOffBrightnessSensorDisabled_AutoBrightnessIsDisabled() { 789 // Tests are set up with manual brightness by default, so no need to set it here. 790 DisplayPowerRequest dpr = new DisplayPowerRequest(); 791 dpr.policy = DisplayPowerRequest.POLICY_OFF; 792 mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 793 advanceTime(1); // Run updatePowerState 794 795 verify(mHolder.screenOffBrightnessSensorController, atLeastOnce()) 796 .setLightSensorEnabled(false); 797 } 798 799 @Test testSetScreenOffBrightnessSensorDisabled_DisplayIsDisabled()800 public void testSetScreenOffBrightnessSensorDisabled_DisplayIsDisabled() { 801 Settings.System.putInt(mContext.getContentResolver(), 802 Settings.System.SCREEN_BRIGHTNESS_MODE, 803 Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC); 804 805 mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID, /* isEnabled= */ false); 806 807 DisplayPowerRequest dpr = new DisplayPowerRequest(); 808 mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 809 advanceTime(1); // Run updatePowerState 810 811 verify(mHolder.screenOffBrightnessSensorController, atLeastOnce()) 812 .setLightSensorEnabled(false); 813 } 814 815 @Test testSetScreenOffBrightnessSensorDisabled_DisplayIsOn()816 public void testSetScreenOffBrightnessSensorDisabled_DisplayIsOn() { 817 DisplayPowerRequest dpr = new DisplayPowerRequest(); 818 dpr.policy = DisplayPowerRequest.POLICY_BRIGHT; 819 820 mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 821 advanceTime(1); // Run updatePowerState 822 823 verify(mHolder.screenOffBrightnessSensorController, atLeastOnce()) 824 .setLightSensorEnabled(false); 825 } 826 827 @Test testSetScreenOffBrightnessSensorDisabled_DisplayIsAFollower()828 public void testSetScreenOffBrightnessSensorDisabled_DisplayIsAFollower() { 829 DisplayPowerRequest dpr = new DisplayPowerRequest(); 830 dpr.policy = DisplayPowerRequest.POLICY_OFF; 831 832 mHolder.dpc.onDisplayChanged(mHolder.hbmMetadata, /* leadDisplayId= */ 42); 833 mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 834 advanceTime(1); // Run updatePowerState 835 836 verify(mHolder.screenOffBrightnessSensorController, atLeastOnce()) 837 .setLightSensorEnabled(false); 838 } 839 840 @Test testStopScreenOffBrightnessSensorControllerWhenDisplayDeviceChanges()841 public void testStopScreenOffBrightnessSensorControllerWhenDisplayDeviceChanges() { 842 // New display device 843 setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class), 844 mock(DisplayDeviceConfig.class), /* isEnabled= */ true); 845 846 mHolder.dpc.onDisplayChanged(mHolder.hbmMetadata, Layout.NO_LEAD_DISPLAY); 847 DisplayPowerRequest dpr = new DisplayPowerRequest(); 848 mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 849 advanceTime(1); // Run updatePowerState 850 851 verify(mHolder.screenOffBrightnessSensorController).stop(); 852 } 853 854 @Test testAutoBrightnessEnabled_DisplayIsOn()855 public void testAutoBrightnessEnabled_DisplayIsOn() { 856 Settings.System.putInt(mContext.getContentResolver(), 857 Settings.System.SCREEN_BRIGHTNESS_MODE, 858 Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC); 859 860 DisplayPowerRequest dpr = new DisplayPowerRequest(); 861 dpr.policy = DisplayPowerRequest.POLICY_BRIGHT; 862 when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON); 863 mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 864 advanceTime(1); // Run updatePowerState 865 866 verify(mHolder.automaticBrightnessController).configure( 867 AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED, 868 /* configuration= */ null, PowerManager.BRIGHTNESS_INVALID_FLOAT, 869 /* userChangedBrightness= */ false, /* adjustment= */ 0, 870 /* userChangedAutoBrightnessAdjustment= */ false, DisplayPowerRequest.POLICY_BRIGHT, 871 /* shouldResetShortTermModel= */ false 872 ); 873 verify(mHolder.hbmController) 874 .setAutoBrightnessEnabled(AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED); 875 } 876 877 @Test testAutoBrightnessEnabled_DisplayIsInDoze()878 public void testAutoBrightnessEnabled_DisplayIsInDoze() { 879 Settings.System.putInt(mContext.getContentResolver(), 880 Settings.System.SCREEN_BRIGHTNESS_MODE, 881 Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC); 882 mContext.getOrCreateTestableResources().addOverride( 883 com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing, true); 884 mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID); 885 886 DisplayPowerRequest dpr = new DisplayPowerRequest(); 887 dpr.policy = DisplayPowerRequest.POLICY_DOZE; 888 when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_DOZE); 889 mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 890 advanceTime(1); // Run updatePowerState 891 892 verify(mHolder.automaticBrightnessController).configure( 893 AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED, 894 /* configuration= */ null, PowerManager.BRIGHTNESS_INVALID_FLOAT, 895 /* userChangedBrightness= */ false, /* adjustment= */ 0, 896 /* userChangedAutoBrightnessAdjustment= */ false, DisplayPowerRequest.POLICY_DOZE, 897 /* shouldResetShortTermModel= */ false 898 ); 899 verify(mHolder.hbmController) 900 .setAutoBrightnessEnabled(AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED); 901 } 902 903 @Test testAutoBrightnessDisabled_ManualBrightnessMode()904 public void testAutoBrightnessDisabled_ManualBrightnessMode() { 905 Settings.System.putInt(mContext.getContentResolver(), 906 Settings.System.SCREEN_BRIGHTNESS_MODE, 907 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL); 908 909 DisplayPowerRequest dpr = new DisplayPowerRequest(); 910 dpr.policy = DisplayPowerRequest.POLICY_BRIGHT; 911 when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON); 912 mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 913 advanceTime(1); // Run updatePowerState 914 915 // One triggered by the test, the other by handleBrightnessModeChange 916 verify(mHolder.automaticBrightnessController, times(2)).configure( 917 AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED, 918 /* configuration= */ null, PowerManager.BRIGHTNESS_INVALID_FLOAT, 919 /* userChangedBrightness= */ false, /* adjustment= */ 0, 920 /* userChangedAutoBrightnessAdjustment= */ false, DisplayPowerRequest.POLICY_BRIGHT, 921 /* shouldResetShortTermModel= */ false 922 ); 923 verify(mHolder.hbmController, times(2)) 924 .setAutoBrightnessEnabled(AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED); 925 } 926 927 @Test testAutoBrightnessDisabled_DisplayIsOff()928 public void testAutoBrightnessDisabled_DisplayIsOff() { 929 Settings.System.putInt(mContext.getContentResolver(), 930 Settings.System.SCREEN_BRIGHTNESS_MODE, 931 Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC); 932 933 DisplayPowerRequest dpr = new DisplayPowerRequest(); 934 dpr.policy = DisplayPowerRequest.POLICY_OFF; 935 when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_OFF); 936 mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 937 advanceTime(1); // Run updatePowerState 938 939 verify(mHolder.automaticBrightnessController).configure( 940 AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE, 941 /* configuration= */ null, PowerManager.BRIGHTNESS_INVALID_FLOAT, 942 /* userChangedBrightness= */ false, /* adjustment= */ 0, 943 /* userChangedAutoBrightnessAdjustment= */ false, DisplayPowerRequest.POLICY_OFF, 944 /* shouldResetShortTermModel= */ false 945 ); 946 verify(mHolder.hbmController).setAutoBrightnessEnabled( 947 AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE); 948 } 949 950 @Test testAutoBrightnessDisabled_DisplayIsInDoze()951 public void testAutoBrightnessDisabled_DisplayIsInDoze() { 952 Settings.System.putInt(mContext.getContentResolver(), 953 Settings.System.SCREEN_BRIGHTNESS_MODE, 954 Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC); 955 mContext.getOrCreateTestableResources().addOverride( 956 com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing, false); 957 mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID); 958 959 DisplayPowerRequest dpr = new DisplayPowerRequest(); 960 dpr.policy = DisplayPowerRequest.POLICY_DOZE; 961 when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_DOZE); 962 mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 963 advanceTime(1); // Run updatePowerState 964 965 verify(mHolder.automaticBrightnessController).configure( 966 AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE, 967 /* configuration= */ null, PowerManager.BRIGHTNESS_INVALID_FLOAT, 968 /* userChangedBrightness= */ false, /* adjustment= */ 0, 969 /* userChangedAutoBrightnessAdjustment= */ false, DisplayPowerRequest.POLICY_DOZE, 970 /* shouldResetShortTermModel= */ false 971 ); 972 verify(mHolder.hbmController).setAutoBrightnessEnabled( 973 AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE); 974 } 975 976 @Test testAutoBrightnessDisabled_FollowerDisplay()977 public void testAutoBrightnessDisabled_FollowerDisplay() { 978 Settings.System.putInt(mContext.getContentResolver(), 979 Settings.System.SCREEN_BRIGHTNESS_MODE, 980 Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC); 981 mHolder.dpc.setBrightnessToFollow(0.3f, -1, 0, /* slowChange= */ false); 982 983 DisplayPowerRequest dpr = new DisplayPowerRequest(); 984 dpr.policy = DisplayPowerRequest.POLICY_BRIGHT; 985 when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON); 986 mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 987 advanceTime(1); // Run updatePowerState 988 989 // One triggered by the test, the other by handleBrightnessModeChange 990 verify(mHolder.automaticBrightnessController, times(2)).configure( 991 AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED, 992 /* configuration= */ null, PowerManager.BRIGHTNESS_INVALID_FLOAT, 993 /* userChangedBrightness= */ false, /* adjustment= */ 0, 994 /* userChangedAutoBrightnessAdjustment= */ false, DisplayPowerRequest.POLICY_BRIGHT, 995 /* shouldResetShortTermModel= */ false 996 ); 997 998 // HBM should be allowed for the follower display 999 verify(mHolder.hbmController) 1000 .setAutoBrightnessEnabled(AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED); 1001 } 1002 1003 @Test testBrightnessNitsPersistWhenDisplayDeviceChanges()1004 public void testBrightnessNitsPersistWhenDisplayDeviceChanges() { 1005 float brightness = 0.3f; 1006 float nits = 500; 1007 mContext.getOrCreateTestableResources().addOverride( 1008 com.android.internal.R.bool.config_persistBrightnessNitsForDefaultDisplay, 1009 true); 1010 1011 mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID); 1012 when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits); 1013 1014 mHolder.dpc.setBrightness(brightness); 1015 verify(mHolder.brightnessSetting).setBrightnessNitsForDefaultDisplay(nits); 1016 1017 float newBrightness = 0.4f; 1018 when(mHolder.brightnessSetting.getBrightnessNitsForDefaultDisplay()).thenReturn(nits); 1019 when(mHolder.automaticBrightnessController.convertToFloatScale(nits)) 1020 .thenReturn(newBrightness); 1021 // New display device 1022 setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class), 1023 mock(DisplayDeviceConfig.class), /* isEnabled= */ true); 1024 mHolder.dpc.onDisplayChanged(mHolder.hbmMetadata, Layout.NO_LEAD_DISPLAY); 1025 DisplayPowerRequest dpr = new DisplayPowerRequest(); 1026 mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 1027 advanceTime(1); // Run updatePowerState 1028 // One triggered by handleBrightnessModeChange, another triggered by onDisplayChanged 1029 verify(mHolder.animator, times(2)).animateTo(eq(newBrightness), anyFloat(), anyFloat()); 1030 } 1031 1032 @Test testShortTermModelPersistsWhenDisplayDeviceChanges()1033 public void testShortTermModelPersistsWhenDisplayDeviceChanges() { 1034 float lux = 2000; 1035 float brightness = 0.4f; 1036 float nits = 500; 1037 when(mHolder.brightnessMappingStrategy.getUserLux()).thenReturn(lux); 1038 when(mHolder.brightnessMappingStrategy.getUserBrightness()).thenReturn(brightness); 1039 when(mHolder.brightnessMappingStrategy.convertToNits(brightness)).thenReturn(nits); 1040 when(mHolder.brightnessMappingStrategy.convertToFloatScale(nits)).thenReturn(brightness); 1041 DisplayPowerRequest dpr = new DisplayPowerRequest(); 1042 mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 1043 advanceTime(1); 1044 clearInvocations(mHolder.injector); 1045 1046 // New display device 1047 setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class), 1048 mock(DisplayDeviceConfig.class), /* isEnabled= */ true); 1049 mHolder.dpc.onDisplayChanged(mHolder.hbmMetadata, Layout.NO_LEAD_DISPLAY); 1050 advanceTime(1); 1051 1052 verify(mHolder.injector).getAutomaticBrightnessController( 1053 any(AutomaticBrightnessController.Callbacks.class), 1054 any(Looper.class), 1055 eq(mSensorManagerMock), 1056 any(), 1057 eq(mHolder.brightnessMappingStrategy), 1058 anyInt(), 1059 anyFloat(), 1060 anyFloat(), 1061 anyFloat(), 1062 anyInt(), 1063 anyInt(), 1064 anyLong(), 1065 anyLong(), 1066 anyBoolean(), 1067 any(HysteresisLevels.class), 1068 any(HysteresisLevels.class), 1069 any(HysteresisLevels.class), 1070 any(HysteresisLevels.class), 1071 eq(mContext), 1072 any(BrightnessRangeController.class), 1073 any(BrightnessThrottler.class), 1074 isNull(), 1075 anyInt(), 1076 anyInt(), 1077 eq(lux), 1078 eq(brightness) 1079 ); 1080 } 1081 1082 @Test testUpdateBrightnessThrottlingDataId()1083 public void testUpdateBrightnessThrottlingDataId() { 1084 mHolder.display.getDisplayInfoLocked().thermalBrightnessThrottlingDataId = 1085 "throttling-data-id"; 1086 clearInvocations(mHolder.display.getPrimaryDisplayDeviceLocked().getDisplayDeviceConfig()); 1087 1088 mHolder.dpc.onDisplayChanged(mHolder.hbmMetadata, Layout.NO_LEAD_DISPLAY); 1089 DisplayPowerRequest dpr = new DisplayPowerRequest(); 1090 mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); 1091 advanceTime(1); // Run updatePowerState 1092 1093 verify(mHolder.display.getPrimaryDisplayDeviceLocked().getDisplayDeviceConfig()) 1094 .getThermalBrightnessThrottlingDataMapByThrottlingId(); 1095 } 1096 1097 @Test testDwbcCallsHappenOnHandler()1098 public void testDwbcCallsHappenOnHandler() { 1099 mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID); 1100 1101 mHolder.dpc.setAutomaticScreenBrightnessMode(true); 1102 verify(mDisplayWhiteBalanceControllerMock, never()).setStrongModeEnabled(true); 1103 1104 // dispatch handler looper 1105 advanceTime(1); 1106 verify(mDisplayWhiteBalanceControllerMock, times(1)).setStrongModeEnabled(true); 1107 } 1108 1109 /** 1110 * Creates a mock and registers it to {@link LocalServices}. 1111 */ addLocalServiceMock(Class<T> clazz, T mock)1112 private static <T> void addLocalServiceMock(Class<T> clazz, T mock) { 1113 LocalServices.removeServiceForTest(clazz); 1114 LocalServices.addService(clazz, mock); 1115 } 1116 advanceTime(long timeMs)1117 private void advanceTime(long timeMs) { 1118 mClock.fastForward(timeMs); 1119 mTestLooper.dispatchAll(); 1120 } 1121 setUpSensors()1122 private void setUpSensors() throws Exception { 1123 mProxSensor = TestUtils.createSensor(Sensor.TYPE_PROXIMITY, Sensor.STRING_TYPE_PROXIMITY, 1124 PROX_SENSOR_MAX_RANGE); 1125 Sensor screenOffBrightnessSensor = TestUtils.createSensor( 1126 Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT); 1127 when(mSensorManagerMock.getSensorList(eq(Sensor.TYPE_ALL))) 1128 .thenReturn(List.of(mProxSensor, screenOffBrightnessSensor)); 1129 } 1130 getSensorEventListener(Sensor sensor)1131 private SensorEventListener getSensorEventListener(Sensor sensor) { 1132 verify(mSensorManagerMock).registerListener(mSensorEventListenerCaptor.capture(), 1133 eq(sensor), eq(SensorManager.SENSOR_DELAY_NORMAL), isA(Handler.class)); 1134 return mSensorEventListenerCaptor.getValue(); 1135 } 1136 setUpDisplay(int displayId, String uniqueId, LogicalDisplay logicalDisplayMock, DisplayDevice displayDeviceMock, DisplayDeviceConfig displayDeviceConfigMock, boolean isEnabled)1137 private void setUpDisplay(int displayId, String uniqueId, LogicalDisplay logicalDisplayMock, 1138 DisplayDevice displayDeviceMock, DisplayDeviceConfig displayDeviceConfigMock, 1139 boolean isEnabled) { 1140 DisplayInfo info = new DisplayInfo(); 1141 DisplayDeviceInfo deviceInfo = new DisplayDeviceInfo(); 1142 deviceInfo.uniqueId = uniqueId; 1143 1144 when(logicalDisplayMock.getDisplayIdLocked()).thenReturn(displayId); 1145 when(logicalDisplayMock.getPrimaryDisplayDeviceLocked()).thenReturn(displayDeviceMock); 1146 when(logicalDisplayMock.getDisplayInfoLocked()).thenReturn(info); 1147 when(logicalDisplayMock.isEnabledLocked()).thenReturn(isEnabled); 1148 when(logicalDisplayMock.isInTransitionLocked()).thenReturn(false); 1149 when(displayDeviceMock.getDisplayDeviceInfoLocked()).thenReturn(deviceInfo); 1150 when(displayDeviceMock.getUniqueId()).thenReturn(uniqueId); 1151 when(displayDeviceMock.getDisplayDeviceConfig()).thenReturn(displayDeviceConfigMock); 1152 when(displayDeviceConfigMock.getProximitySensor()).thenReturn( 1153 new DisplayDeviceConfig.SensorData() { 1154 { 1155 type = Sensor.STRING_TYPE_PROXIMITY; 1156 name = null; 1157 } 1158 }); 1159 when(displayDeviceConfigMock.getNits()).thenReturn(new float[]{2, 500}); 1160 when(displayDeviceConfigMock.isAutoBrightnessAvailable()).thenReturn(true); 1161 when(displayDeviceConfigMock.getAmbientLightSensor()).thenReturn( 1162 new DisplayDeviceConfig.SensorData()); 1163 when(displayDeviceConfigMock.getScreenOffBrightnessSensor()).thenReturn( 1164 new DisplayDeviceConfig.SensorData() { 1165 { 1166 type = Sensor.STRING_TYPE_LIGHT; 1167 name = null; 1168 } 1169 }); 1170 when(displayDeviceConfigMock.getScreenOffBrightnessSensorValueToLux()) 1171 .thenReturn(new int[0]); 1172 when(displayDeviceConfigMock.getBrightnessRampFastDecrease()) 1173 .thenReturn(BRIGHTNESS_RAMP_RATE_FAST_DECREASE); 1174 when(displayDeviceConfigMock.getBrightnessRampFastIncrease()) 1175 .thenReturn(BRIGHTNESS_RAMP_RATE_FAST_INCREASE); 1176 when(displayDeviceConfigMock.getBrightnessRampSlowDecrease()) 1177 .thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE); 1178 when(displayDeviceConfigMock.getBrightnessRampSlowIncrease()) 1179 .thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_INCREASE); 1180 } 1181 createDisplayPowerController(int displayId, String uniqueId)1182 private DisplayPowerControllerHolder createDisplayPowerController(int displayId, 1183 String uniqueId) { 1184 return createDisplayPowerController(displayId, uniqueId, /* isEnabled= */ true); 1185 } 1186 createDisplayPowerController(int displayId, String uniqueId, boolean isEnabled)1187 private DisplayPowerControllerHolder createDisplayPowerController(int displayId, 1188 String uniqueId, boolean isEnabled) { 1189 final DisplayPowerState displayPowerState = mock(DisplayPowerState.class); 1190 final DualRampAnimator<DisplayPowerState> animator = mock(DualRampAnimator.class); 1191 final AutomaticBrightnessController automaticBrightnessController = 1192 mock(AutomaticBrightnessController.class); 1193 final BrightnessMappingStrategy brightnessMappingStrategy = 1194 mock(BrightnessMappingStrategy.class); 1195 final HysteresisLevels hysteresisLevels = mock(HysteresisLevels.class); 1196 final ScreenOffBrightnessSensorController screenOffBrightnessSensorController = 1197 mock(ScreenOffBrightnessSensorController.class); 1198 final HighBrightnessModeController hbmController = mock(HighBrightnessModeController.class); 1199 1200 when(hbmController.getCurrentBrightnessMax()).thenReturn(PowerManager.BRIGHTNESS_MAX); 1201 1202 DisplayPowerController.Injector injector = spy(new TestInjector(displayPowerState, animator, 1203 automaticBrightnessController, brightnessMappingStrategy, hysteresisLevels, 1204 screenOffBrightnessSensorController, hbmController)); 1205 1206 final LogicalDisplay display = mock(LogicalDisplay.class); 1207 final DisplayDevice device = mock(DisplayDevice.class); 1208 final HighBrightnessModeMetadata hbmMetadata = mock(HighBrightnessModeMetadata.class); 1209 final BrightnessSetting brightnessSetting = mock(BrightnessSetting.class); 1210 final DisplayDeviceConfig config = mock(DisplayDeviceConfig.class); 1211 1212 setUpDisplay(displayId, uniqueId, display, device, config, isEnabled); 1213 1214 final DisplayPowerController dpc = new DisplayPowerController( 1215 mContext, injector, mDisplayPowerCallbacksMock, mHandler, 1216 mSensorManagerMock, mDisplayBlankerMock, display, 1217 mBrightnessTrackerMock, brightnessSetting, () -> {}, 1218 hbmMetadata, /* bootCompleted= */ false); 1219 1220 return new DisplayPowerControllerHolder(dpc, display, displayPowerState, brightnessSetting, 1221 animator, automaticBrightnessController, screenOffBrightnessSensorController, 1222 hbmController, hbmMetadata, brightnessMappingStrategy, injector); 1223 } 1224 1225 /** 1226 * A class for holding a DisplayPowerController under test and all the mocks specifically 1227 * related to it. 1228 */ 1229 private static class DisplayPowerControllerHolder { 1230 public final DisplayPowerController dpc; 1231 public final LogicalDisplay display; 1232 public final DisplayPowerState displayPowerState; 1233 public final BrightnessSetting brightnessSetting; 1234 public final DualRampAnimator<DisplayPowerState> animator; 1235 public final AutomaticBrightnessController automaticBrightnessController; 1236 public final ScreenOffBrightnessSensorController screenOffBrightnessSensorController; 1237 public final HighBrightnessModeController hbmController; 1238 public final HighBrightnessModeMetadata hbmMetadata; 1239 public final BrightnessMappingStrategy brightnessMappingStrategy; 1240 public final DisplayPowerController.Injector injector; 1241 DisplayPowerControllerHolder(DisplayPowerController dpc, LogicalDisplay display, DisplayPowerState displayPowerState, BrightnessSetting brightnessSetting, DualRampAnimator<DisplayPowerState> animator, AutomaticBrightnessController automaticBrightnessController, ScreenOffBrightnessSensorController screenOffBrightnessSensorController, HighBrightnessModeController hbmController, HighBrightnessModeMetadata hbmMetadata, BrightnessMappingStrategy brightnessMappingStrategy, DisplayPowerController.Injector injector)1242 DisplayPowerControllerHolder(DisplayPowerController dpc, LogicalDisplay display, 1243 DisplayPowerState displayPowerState, BrightnessSetting brightnessSetting, 1244 DualRampAnimator<DisplayPowerState> animator, 1245 AutomaticBrightnessController automaticBrightnessController, 1246 ScreenOffBrightnessSensorController screenOffBrightnessSensorController, 1247 HighBrightnessModeController hbmController, 1248 HighBrightnessModeMetadata hbmMetadata, 1249 BrightnessMappingStrategy brightnessMappingStrategy, 1250 DisplayPowerController.Injector injector) { 1251 this.dpc = dpc; 1252 this.display = display; 1253 this.displayPowerState = displayPowerState; 1254 this.brightnessSetting = brightnessSetting; 1255 this.animator = animator; 1256 this.automaticBrightnessController = automaticBrightnessController; 1257 this.screenOffBrightnessSensorController = screenOffBrightnessSensorController; 1258 this.hbmController = hbmController; 1259 this.hbmMetadata = hbmMetadata; 1260 this.brightnessMappingStrategy = brightnessMappingStrategy; 1261 this.injector = injector; 1262 } 1263 } 1264 1265 private class TestInjector extends DisplayPowerController.Injector { 1266 private final DisplayPowerState mDisplayPowerState; 1267 private final DualRampAnimator<DisplayPowerState> mAnimator; 1268 private final AutomaticBrightnessController mAutomaticBrightnessController; 1269 private final BrightnessMappingStrategy mBrightnessMappingStrategy; 1270 private final HysteresisLevels mHysteresisLevels; 1271 private final ScreenOffBrightnessSensorController mScreenOffBrightnessSensorController; 1272 private final HighBrightnessModeController mHighBrightnessModeController; 1273 TestInjector(DisplayPowerState dps, DualRampAnimator<DisplayPowerState> animator, AutomaticBrightnessController automaticBrightnessController, BrightnessMappingStrategy brightnessMappingStrategy, HysteresisLevels hysteresisLevels, ScreenOffBrightnessSensorController screenOffBrightnessSensorController, HighBrightnessModeController highBrightnessModeController)1274 TestInjector(DisplayPowerState dps, DualRampAnimator<DisplayPowerState> animator, 1275 AutomaticBrightnessController automaticBrightnessController, 1276 BrightnessMappingStrategy brightnessMappingStrategy, 1277 HysteresisLevels hysteresisLevels, 1278 ScreenOffBrightnessSensorController screenOffBrightnessSensorController, 1279 HighBrightnessModeController highBrightnessModeController) { 1280 mDisplayPowerState = dps; 1281 mAnimator = animator; 1282 mAutomaticBrightnessController = automaticBrightnessController; 1283 mBrightnessMappingStrategy = brightnessMappingStrategy; 1284 mHysteresisLevels = hysteresisLevels; 1285 mScreenOffBrightnessSensorController = screenOffBrightnessSensorController; 1286 mHighBrightnessModeController = highBrightnessModeController; 1287 } 1288 1289 @Override getClock()1290 DisplayPowerController.Clock getClock() { 1291 return mClock::now; 1292 } 1293 1294 @Override getDisplayPowerState(DisplayBlanker blanker, ColorFade colorFade, int displayId, int displayState)1295 DisplayPowerState getDisplayPowerState(DisplayBlanker blanker, ColorFade colorFade, 1296 int displayId, int displayState) { 1297 return mDisplayPowerState; 1298 } 1299 1300 @Override getDualRampAnimator(DisplayPowerState dps, FloatProperty<DisplayPowerState> firstProperty, FloatProperty<DisplayPowerState> secondProperty)1301 DualRampAnimator<DisplayPowerState> getDualRampAnimator(DisplayPowerState dps, 1302 FloatProperty<DisplayPowerState> firstProperty, 1303 FloatProperty<DisplayPowerState> secondProperty) { 1304 return mAnimator; 1305 } 1306 1307 @Override getAutomaticBrightnessController( AutomaticBrightnessController.Callbacks callbacks, Looper looper, SensorManager sensorManager, Sensor lightSensor, BrightnessMappingStrategy interactiveModeBrightnessMapper, int lightSensorWarmUpTime, float brightnessMin, float brightnessMax, float dozeScaleFactor, int lightSensorRate, int initialLightSensorRate, long brighteningLightDebounceConfig, long darkeningLightDebounceConfig, boolean resetAmbientLuxAfterWarmUpConfig, HysteresisLevels ambientBrightnessThresholds, HysteresisLevels screenBrightnessThresholds, HysteresisLevels ambientBrightnessThresholdsIdle, HysteresisLevels screenBrightnessThresholdsIdle, Context context, BrightnessRangeController brightnessRangeController, BrightnessThrottler brightnessThrottler, BrightnessMappingStrategy idleModeBrightnessMapper, int ambientLightHorizonShort, int ambientLightHorizonLong, float userLux, float userBrightness)1308 AutomaticBrightnessController getAutomaticBrightnessController( 1309 AutomaticBrightnessController.Callbacks callbacks, Looper looper, 1310 SensorManager sensorManager, Sensor lightSensor, 1311 BrightnessMappingStrategy interactiveModeBrightnessMapper, 1312 int lightSensorWarmUpTime, float brightnessMin, float brightnessMax, 1313 float dozeScaleFactor, int lightSensorRate, int initialLightSensorRate, 1314 long brighteningLightDebounceConfig, long darkeningLightDebounceConfig, 1315 boolean resetAmbientLuxAfterWarmUpConfig, 1316 HysteresisLevels ambientBrightnessThresholds, 1317 HysteresisLevels screenBrightnessThresholds, 1318 HysteresisLevels ambientBrightnessThresholdsIdle, 1319 HysteresisLevels screenBrightnessThresholdsIdle, Context context, 1320 BrightnessRangeController brightnessRangeController, 1321 BrightnessThrottler brightnessThrottler, 1322 BrightnessMappingStrategy idleModeBrightnessMapper, 1323 int ambientLightHorizonShort, int ambientLightHorizonLong, float userLux, 1324 float userBrightness) { 1325 return mAutomaticBrightnessController; 1326 } 1327 1328 @Override getInteractiveModeBrightnessMapper(Resources resources, DisplayDeviceConfig displayDeviceConfig, DisplayWhiteBalanceController displayWhiteBalanceController)1329 BrightnessMappingStrategy getInteractiveModeBrightnessMapper(Resources resources, 1330 DisplayDeviceConfig displayDeviceConfig, 1331 DisplayWhiteBalanceController displayWhiteBalanceController) { 1332 return mBrightnessMappingStrategy; 1333 } 1334 1335 @Override getHysteresisLevels(float[] brighteningThresholdsPercentages, float[] darkeningThresholdsPercentages, float[] brighteningThresholdLevels, float[] darkeningThresholdLevels, float minDarkeningThreshold, float minBrighteningThreshold)1336 HysteresisLevels getHysteresisLevels(float[] brighteningThresholdsPercentages, 1337 float[] darkeningThresholdsPercentages, float[] brighteningThresholdLevels, 1338 float[] darkeningThresholdLevels, float minDarkeningThreshold, 1339 float minBrighteningThreshold) { 1340 return mHysteresisLevels; 1341 } 1342 1343 @Override getHysteresisLevels(float[] brighteningThresholdsPercentages, float[] darkeningThresholdsPercentages, float[] brighteningThresholdLevels, float[] darkeningThresholdLevels, float minDarkeningThreshold, float minBrighteningThreshold, boolean potentialOldBrightnessRange)1344 HysteresisLevels getHysteresisLevels(float[] brighteningThresholdsPercentages, 1345 float[] darkeningThresholdsPercentages, float[] brighteningThresholdLevels, 1346 float[] darkeningThresholdLevels, float minDarkeningThreshold, 1347 float minBrighteningThreshold, boolean potentialOldBrightnessRange) { 1348 return mHysteresisLevels; 1349 } 1350 1351 @Override getScreenOffBrightnessSensorController( SensorManager sensorManager, Sensor lightSensor, Handler handler, ScreenOffBrightnessSensorController.Clock clock, int[] sensorValueToLux, BrightnessMappingStrategy brightnessMapper)1352 ScreenOffBrightnessSensorController getScreenOffBrightnessSensorController( 1353 SensorManager sensorManager, Sensor lightSensor, Handler handler, 1354 ScreenOffBrightnessSensorController.Clock clock, int[] sensorValueToLux, 1355 BrightnessMappingStrategy brightnessMapper) { 1356 return mScreenOffBrightnessSensorController; 1357 } 1358 1359 @Override getHighBrightnessModeController(Handler handler, int width, int height, IBinder displayToken, String displayUniqueId, float brightnessMin, float brightnessMax, DisplayDeviceConfig.HighBrightnessModeData hbmData, HighBrightnessModeController.HdrBrightnessDeviceConfig hdrBrightnessCfg, Runnable hbmChangeCallback, HighBrightnessModeMetadata hbmMetadata, Context context)1360 HighBrightnessModeController getHighBrightnessModeController(Handler handler, int width, 1361 int height, IBinder displayToken, String displayUniqueId, float brightnessMin, 1362 float brightnessMax, DisplayDeviceConfig.HighBrightnessModeData hbmData, 1363 HighBrightnessModeController.HdrBrightnessDeviceConfig hdrBrightnessCfg, 1364 Runnable hbmChangeCallback, HighBrightnessModeMetadata hbmMetadata, 1365 Context context) { 1366 return mHighBrightnessModeController; 1367 } 1368 1369 @Override getDisplayWhiteBalanceController(Handler handler, SensorManager sensorManager, Resources resources)1370 DisplayWhiteBalanceController getDisplayWhiteBalanceController(Handler handler, 1371 SensorManager sensorManager, Resources resources) { 1372 return mDisplayWhiteBalanceControllerMock; 1373 } 1374 } 1375 } 1376