1 /* 2 * Copyright (C) 2020 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.power; 18 19 import static android.os.PowerManager.SCREEN_TIMEOUT_KEEP_DISPLAY_ON; 20 import static android.os.PowerManager.SCREEN_TIMEOUT_ACTIVE; 21 import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP; 22 import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE; 23 24 import static com.google.common.truth.Truth.assertThat; 25 26 import static org.junit.Assert.assertEquals; 27 import static org.junit.Assert.assertNotNull; 28 import static org.junit.Assert.assertNull; 29 import static org.mockito.ArgumentMatchers.any; 30 import static org.mockito.ArgumentMatchers.anyInt; 31 import static org.mockito.ArgumentMatchers.anyString; 32 import static org.mockito.ArgumentMatchers.eq; 33 import static org.mockito.Mockito.atLeast; 34 import static org.mockito.Mockito.clearInvocations; 35 import static org.mockito.Mockito.doThrow; 36 import static org.mockito.Mockito.inOrder; 37 import static org.mockito.Mockito.never; 38 import static org.mockito.Mockito.spy; 39 import static org.mockito.Mockito.times; 40 import static org.mockito.Mockito.verify; 41 import static org.mockito.Mockito.verifyNoMoreInteractions; 42 import static org.mockito.Mockito.when; 43 44 import android.annotation.NonNull; 45 import android.app.ActivityManagerInternal; 46 import android.app.AppOpsManager; 47 import android.content.Context; 48 import android.content.res.Resources; 49 import android.hardware.SensorManager; 50 import android.hardware.display.AmbientDisplayConfiguration; 51 import android.hardware.display.DisplayManagerInternal; 52 import android.os.BatteryStats; 53 import android.os.BatteryStatsInternal; 54 import android.os.Handler; 55 import android.os.IBinder; 56 import android.os.IScreenTimeoutPolicyListener; 57 import android.os.IWakeLockCallback; 58 import android.os.Looper; 59 import android.os.PowerManager; 60 import android.os.RemoteException; 61 import android.os.VibrationAttributes; 62 import android.os.Vibrator; 63 import android.os.WorkSource; 64 import android.os.WorkSource.WorkChain; 65 import android.os.test.TestLooper; 66 import android.provider.Settings; 67 import android.testing.TestableContext; 68 import android.util.IntArray; 69 import android.util.SparseArray; 70 import android.util.SparseBooleanArray; 71 import android.view.Display; 72 import android.view.DisplayAddress; 73 import android.view.DisplayInfo; 74 75 import androidx.test.InstrumentationRegistry; 76 77 import com.android.internal.app.IBatteryStats; 78 import com.android.server.LocalServices; 79 import com.android.server.input.InputManagerInternal; 80 import com.android.server.inputmethod.InputMethodManagerInternal; 81 import com.android.server.policy.WindowManagerPolicy; 82 import com.android.server.power.FrameworkStatsLogger.WakelockEventType; 83 import com.android.server.power.batterysaver.BatterySaverStateMachine; 84 import com.android.server.power.feature.PowerManagerFlags; 85 import com.android.server.statusbar.StatusBarManagerInternal; 86 87 import org.junit.Before; 88 import org.junit.Test; 89 import org.mockito.ArgumentCaptor; 90 import org.mockito.InOrder; 91 import org.mockito.Mock; 92 import org.mockito.Mockito; 93 import org.mockito.MockitoAnnotations; 94 95 import java.util.concurrent.Executor; 96 97 /** 98 * Tests for {@link com.android.server.power.Notifier} 99 */ 100 public class NotifierTest { 101 private static final String SYSTEM_PROPERTY_QUIESCENT = "ro.boot.quiescent"; 102 private static final int USER_ID = 0; 103 private static final int DISPLAY_PORT = 0xFF; 104 private static final long DISPLAY_MODEL = 0xEEEEEEEEL; 105 106 private static final int UID = 1234; 107 private static final int OWNER_UID = 1235; 108 private static final int WORK_SOURCE_UID_1 = 2345; 109 private static final int WORK_SOURCE_UID_2 = 2346; 110 private static final int OWNER_WORK_SOURCE_UID_1 = 3456; 111 private static final int OWNER_WORK_SOURCE_UID_2 = 3457; 112 private static final int PID = 5678; 113 114 @Mock private BatterySaverStateMachine mBatterySaverStateMachineMock; 115 @Mock private PowerManagerService.NativeWrapper mNativeWrapperMock; 116 @Mock private Notifier mNotifierMock; 117 @Mock private WirelessChargerDetector mWirelessChargerDetectorMock; 118 @Mock private AmbientDisplayConfiguration mAmbientDisplayConfigurationMock; 119 @Mock private SystemPropertiesWrapper mSystemPropertiesMock; 120 @Mock private InattentiveSleepWarningController mInattentiveSleepWarningControllerMock; 121 @Mock private Vibrator mVibrator; 122 @Mock private StatusBarManagerInternal mStatusBarManagerInternal; 123 @Mock private InputManagerInternal mInputManagerInternal; 124 @Mock private InputMethodManagerInternal mInputMethodManagerInternal; 125 @Mock private DisplayManagerInternal mDisplayManagerInternal; 126 @Mock private ActivityManagerInternal mActivityManagerInternal; 127 @Mock private WakeLockLog mWakeLockLog; 128 129 @Mock private IBatteryStats mBatteryStats; 130 131 @Mock private WindowManagerPolicy mPolicy; 132 133 @Mock private PowerManagerFlags mPowerManagerFlags; 134 135 @Mock private AppOpsManager mAppOpsManager; 136 137 @Mock private BatteryStatsInternal mBatteryStatsInternal; 138 @Mock private FrameworkStatsLogger mLogger; 139 140 private PowerManagerService mService; 141 private Context mContextSpy; 142 private Resources mResourcesSpy; 143 private TestLooper mTestLooper = new TestLooper(); 144 private FakeExecutor mTestExecutor = new FakeExecutor(); 145 private Notifier mNotifier; 146 private DisplayInfo mDefaultDisplayInfo = new DisplayInfo(); 147 148 @Before setUp()149 public void setUp() { 150 MockitoAnnotations.initMocks(this); 151 152 LocalServices.removeServiceForTest(StatusBarManagerInternal.class); 153 LocalServices.addService(StatusBarManagerInternal.class, mStatusBarManagerInternal); 154 155 LocalServices.removeServiceForTest(InputManagerInternal.class); 156 LocalServices.addService(InputManagerInternal.class, mInputManagerInternal); 157 LocalServices.removeServiceForTest(InputMethodManagerInternal.class); 158 LocalServices.addService(InputMethodManagerInternal.class, mInputMethodManagerInternal); 159 160 LocalServices.removeServiceForTest(ActivityManagerInternal.class); 161 LocalServices.addService(ActivityManagerInternal.class, mActivityManagerInternal); 162 163 mDefaultDisplayInfo.address = DisplayAddress.fromPortAndModel(DISPLAY_PORT, DISPLAY_MODEL); 164 LocalServices.removeServiceForTest(DisplayManagerInternal.class); 165 LocalServices.addService(DisplayManagerInternal.class, mDisplayManagerInternal); 166 167 mContextSpy = spy(new TestableContext(InstrumentationRegistry.getContext())); 168 mResourcesSpy = spy(mContextSpy.getResources()); 169 when(mContextSpy.getResources()).thenReturn(mResourcesSpy); 170 when(mSystemPropertiesMock.get(eq(SYSTEM_PROPERTY_QUIESCENT), anyString())).thenReturn(""); 171 when(mContextSpy.getSystemService(Vibrator.class)).thenReturn(mVibrator); 172 when(mDisplayManagerInternal.getDisplayInfo(Display.DEFAULT_DISPLAY)).thenReturn( 173 mDefaultDisplayInfo); 174 175 mService = new PowerManagerService(mContextSpy, mInjector); 176 } 177 178 @Test testVibrateEnabled_wiredCharging()179 public void testVibrateEnabled_wiredCharging() { 180 createNotifier(); 181 182 // GIVEN the charging vibration is enabled 183 enableChargingVibration(true); 184 185 // WHEN wired charging starts 186 mNotifier.onWiredChargingStarted(USER_ID); 187 mTestLooper.dispatchAll(); 188 mTestExecutor.simulateAsyncExecutionOfLastCommand(); 189 190 // THEN the device vibrates once 191 verify(mVibrator, times(1)).vibrate(anyInt(), any(), any(), any(), 192 any(VibrationAttributes.class)); 193 } 194 195 @Test testVibrateDisabled_wiredCharging()196 public void testVibrateDisabled_wiredCharging() { 197 createNotifier(); 198 199 // GIVEN the charging vibration is disabled 200 enableChargingVibration(false); 201 202 // WHEN wired charging starts 203 mNotifier.onWiredChargingStarted(USER_ID); 204 mTestLooper.dispatchAll(); 205 mTestExecutor.simulateAsyncExecutionOfLastCommand(); 206 207 // THEN the device doesn't vibrate 208 verifyNoMoreInteractions(mVibrator); 209 } 210 211 @Test testVibrateEnabled_wirelessCharging()212 public void testVibrateEnabled_wirelessCharging() { 213 createNotifier(); 214 215 // GIVEN the charging vibration is enabled 216 enableChargingVibration(true); 217 218 // WHEN wireless charging starts 219 mNotifier.onWirelessChargingStarted(5, USER_ID); 220 mTestLooper.dispatchAll(); 221 mTestExecutor.simulateAsyncExecutionOfLastCommand(); 222 223 // THEN the device vibrates once 224 verify(mVibrator, times(1)).vibrate(anyInt(), any(), any(), any(), 225 any(VibrationAttributes.class)); 226 } 227 228 @Test testVibrateDisabled_wirelessCharging()229 public void testVibrateDisabled_wirelessCharging() { 230 createNotifier(); 231 232 // GIVEN the charging vibration is disabled 233 enableChargingVibration(false); 234 235 // WHEN wireless charging starts 236 mNotifier.onWirelessChargingStarted(5, USER_ID); 237 mTestLooper.dispatchAll(); 238 mTestExecutor.simulateAsyncExecutionOfLastCommand(); 239 240 // THEN the device doesn't vibrate 241 verifyNoMoreInteractions(mVibrator); 242 } 243 244 @Test testVibrateEnabled_dndOn()245 public void testVibrateEnabled_dndOn() { 246 createNotifier(); 247 248 // GIVEN the charging vibration is enabled but dnd is on 249 enableChargingVibration(true); 250 enableChargingFeedback( 251 /* chargingFeedbackEnabled */ true, 252 /* dndOn */ true); 253 254 // WHEN wired charging starts 255 mNotifier.onWiredChargingStarted(USER_ID); 256 mTestLooper.dispatchAll(); 257 mTestExecutor.simulateAsyncExecutionOfLastCommand(); 258 259 // THEN the device doesn't vibrate 260 verify(mVibrator, never()).vibrate(any(), any(VibrationAttributes.class)); 261 } 262 263 @Test testWirelessAnimationEnabled()264 public void testWirelessAnimationEnabled() { 265 // GIVEN the wireless charging animation is enabled 266 when(mResourcesSpy.getBoolean( 267 com.android.internal.R.bool.config_showBuiltinWirelessChargingAnim)) 268 .thenReturn(true); 269 createNotifier(); 270 271 // WHEN wireless charging starts 272 mNotifier.onWirelessChargingStarted(5, USER_ID); 273 mTestLooper.dispatchAll(); 274 mTestExecutor.simulateAsyncExecutionOfLastCommand(); 275 276 // THEN the charging animation is triggered 277 verify(mStatusBarManagerInternal, times(1)).showChargingAnimation(5); 278 } 279 280 @Test testWirelessAnimationDisabled()281 public void testWirelessAnimationDisabled() { 282 // GIVEN the wireless charging animation is disabled 283 when(mResourcesSpy.getBoolean( 284 com.android.internal.R.bool.config_showBuiltinWirelessChargingAnim)) 285 .thenReturn(false); 286 createNotifier(); 287 288 // WHEN wireless charging starts 289 mNotifier.onWirelessChargingStarted(5, USER_ID); 290 mTestLooper.dispatchAll(); 291 mTestExecutor.simulateAsyncExecutionOfLastCommand(); 292 293 // THEN the charging animation never gets called 294 verify(mStatusBarManagerInternal, never()).showChargingAnimation(anyInt()); 295 } 296 297 @Test testOnGlobalWakefulnessChangeStarted()298 public void testOnGlobalWakefulnessChangeStarted() { 299 createNotifier(); 300 // GIVEN system is currently non-interactive 301 when(mPowerManagerFlags.isPerDisplayWakeByTouchEnabled()).thenReturn(false); 302 final int displayId1 = 101; 303 final int displayId2 = 102; 304 final int[] displayIds = new int[]{displayId1, displayId2}; 305 when(mDisplayManagerInternal.getDisplayIds()).thenReturn(IntArray.wrap(displayIds)); 306 mNotifier.onGlobalWakefulnessChangeStarted(WAKEFULNESS_ASLEEP, 307 PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, /* eventTime= */ 1000); 308 mTestLooper.dispatchAll(); 309 310 // WHEN a global wakefulness change to interactive starts 311 mNotifier.onGlobalWakefulnessChangeStarted(WAKEFULNESS_AWAKE, 312 PowerManager.WAKE_REASON_TAP, /* eventTime= */ 2000); 313 mTestLooper.dispatchAll(); 314 315 // THEN input is notified of all displays being interactive 316 final SparseBooleanArray expectedDisplayInteractivities = new SparseBooleanArray(); 317 expectedDisplayInteractivities.put(displayId1, true); 318 expectedDisplayInteractivities.put(displayId2, true); 319 verify(mInputManagerInternal).setDisplayInteractivities(expectedDisplayInteractivities); 320 verify(mInputMethodManagerInternal).setInteractive(/* interactive= */ true); 321 } 322 323 @Test testOnGroupWakefulnessChangeStarted_newPowerGroup_perDisplayWakeDisabled()324 public void testOnGroupWakefulnessChangeStarted_newPowerGroup_perDisplayWakeDisabled() { 325 createNotifier(); 326 // GIVEN power group is not yet known to Notifier and per-display wake by touch is disabled 327 final int groupId = 123; 328 final int changeReason = PowerManager.WAKE_REASON_TAP; 329 when(mPowerManagerFlags.isPerDisplayWakeByTouchEnabled()).thenReturn(false); 330 331 // WHEN a power group wakefulness change starts 332 mNotifier.onGroupWakefulnessChangeStarted( 333 groupId, WAKEFULNESS_AWAKE, changeReason, /* eventTime= */ 999); 334 mTestLooper.dispatchAll(); 335 336 // THEN window manager policy is informed that device has started waking up 337 verify(mPolicy).startedWakingUp(groupId, changeReason); 338 verify(mDisplayManagerInternal, never()).getDisplayIds(); 339 verify(mInputManagerInternal, never()).setDisplayInteractivities(any()); 340 } 341 342 @Test testOnGroupWakefulnessChangeStarted_interactivityNoChange_perDisplayWakeDisabled()343 public void testOnGroupWakefulnessChangeStarted_interactivityNoChange_perDisplayWakeDisabled() { 344 createNotifier(); 345 // GIVEN power group is not interactive and per-display wake by touch is disabled 346 final int groupId = 234; 347 final int changeReason = PowerManager.GO_TO_SLEEP_REASON_TIMEOUT; 348 when(mPowerManagerFlags.isPerDisplayWakeByTouchEnabled()).thenReturn(false); 349 mNotifier.onGroupWakefulnessChangeStarted( 350 groupId, WAKEFULNESS_ASLEEP, changeReason, /* eventTime= */ 999); 351 mTestLooper.dispatchAll(); 352 verify(mPolicy, times(1)).startedGoingToSleep(groupId, changeReason); 353 354 // WHEN a power wakefulness change to not interactive starts 355 mNotifier.onGroupWakefulnessChangeStarted( 356 groupId, WAKEFULNESS_ASLEEP, changeReason, /* eventTime= */ 999); 357 mTestLooper.dispatchAll(); 358 359 // THEN policy is only informed once of non-interactive wakefulness change 360 verify(mPolicy, times(1)).startedGoingToSleep(groupId, changeReason); 361 verify(mDisplayManagerInternal, never()).getDisplayIds(); 362 verify(mInputManagerInternal, never()).setDisplayInteractivities(any()); 363 } 364 365 @Test testOnGroupWakefulnessChangeStarted_interactivityChange_perDisplayWakeDisabled()366 public void testOnGroupWakefulnessChangeStarted_interactivityChange_perDisplayWakeDisabled() { 367 createNotifier(); 368 // GIVEN power group is not interactive and per-display wake by touch is disabled 369 final int groupId = 345; 370 final int firstChangeReason = PowerManager.GO_TO_SLEEP_REASON_TIMEOUT; 371 when(mPowerManagerFlags.isPerDisplayWakeByTouchEnabled()).thenReturn(false); 372 mNotifier.onGroupWakefulnessChangeStarted( 373 groupId, WAKEFULNESS_ASLEEP, firstChangeReason, /* eventTime= */ 999); 374 mTestLooper.dispatchAll(); 375 376 // WHEN a power wakefulness change to interactive starts 377 final int secondChangeReason = PowerManager.WAKE_REASON_TAP; 378 mNotifier.onGroupWakefulnessChangeStarted( 379 groupId, WAKEFULNESS_AWAKE, secondChangeReason, /* eventTime= */ 999); 380 mTestLooper.dispatchAll(); 381 382 // THEN policy is informed of the change 383 verify(mPolicy).startedWakingUp(groupId, secondChangeReason); 384 verify(mDisplayManagerInternal, never()).getDisplayIds(); 385 verify(mInputManagerInternal, never()).setDisplayInteractivities(any()); 386 } 387 388 @Test testOnGroupWakefulnessChangeStarted_perDisplayWakeByTouchEnabled()389 public void testOnGroupWakefulnessChangeStarted_perDisplayWakeByTouchEnabled() { 390 createNotifier(); 391 // GIVEN per-display wake by touch flag is enabled 392 when(mPowerManagerFlags.isPerDisplayWakeByTouchEnabled()).thenReturn(true); 393 final int groupId = 456; 394 final int displayId1 = 1001; 395 final int displayId2 = 1002; 396 final int[] displays = new int[]{displayId1, displayId2}; 397 when(mDisplayManagerInternal.getDisplayIds()).thenReturn(IntArray.wrap(displays)); 398 when(mDisplayManagerInternal.getDisplayIdsForGroup(groupId)).thenReturn(displays); 399 final int changeReason = PowerManager.WAKE_REASON_TAP; 400 401 // WHEN power group wakefulness change started 402 mNotifier.onGroupWakefulnessChangeStarted( 403 groupId, WAKEFULNESS_AWAKE, changeReason, /* eventTime= */ 999); 404 mTestLooper.dispatchAll(); 405 406 // THEN native input manager is updated that the displays are interactive 407 final SparseBooleanArray expectedDisplayInteractivities = new SparseBooleanArray(); 408 expectedDisplayInteractivities.put(displayId1, true); 409 expectedDisplayInteractivities.put(displayId2, true); 410 verify(mInputManagerInternal).setDisplayInteractivities(expectedDisplayInteractivities); 411 } 412 413 @Test testOnGroupRemoved_perDisplayWakeByTouchEnabled()414 public void testOnGroupRemoved_perDisplayWakeByTouchEnabled() { 415 createNotifier(); 416 // GIVEN per-display wake by touch is enabled and one display group has been defined 417 when(mPowerManagerFlags.isPerDisplayWakeByTouchEnabled()).thenReturn(true); 418 final int groupId = 313; 419 final int displayId1 = 3113; 420 final int displayId2 = 4114; 421 final int[] displays = new int[]{displayId1, displayId2}; 422 when(mDisplayManagerInternal.getDisplayIds()).thenReturn(IntArray.wrap(displays)); 423 when(mDisplayManagerInternal.getDisplayIdsForGroup(groupId)).thenReturn(displays); 424 mNotifier.onGroupWakefulnessChangeStarted( 425 groupId, WAKEFULNESS_AWAKE, PowerManager.WAKE_REASON_TAP, /* eventTime= */ 1000); 426 final SparseBooleanArray expectedDisplayInteractivities = new SparseBooleanArray(); 427 expectedDisplayInteractivities.put(displayId1, true); 428 expectedDisplayInteractivities.put(displayId2, true); 429 verify(mInputManagerInternal).setDisplayInteractivities(expectedDisplayInteractivities); 430 431 // WHEN display group is removed 432 when(mDisplayManagerInternal.getDisplayIdsByGroupsIds()).thenReturn(new SparseArray<>()); 433 mNotifier.onGroupRemoved(groupId); 434 435 // THEN native input manager is informed that displays in that group no longer exist 436 verify(mInputManagerInternal).setDisplayInteractivities(new SparseBooleanArray()); 437 } 438 439 @Test testOnGroupChanged_perDisplayWakeByTouchEnabled()440 public void testOnGroupChanged_perDisplayWakeByTouchEnabled() { 441 createNotifier(); 442 // GIVEN per-display wake by touch is enabled and one display group has been defined with 443 // two displays 444 when(mPowerManagerFlags.isPerDisplayWakeByTouchEnabled()).thenReturn(true); 445 final int groupId = 121; 446 final int displayId1 = 1221; 447 final int displayId2 = 1222; 448 final int[] displays = new int[]{displayId1, displayId2}; 449 when(mDisplayManagerInternal.getDisplayIds()).thenReturn(IntArray.wrap(displays)); 450 when(mDisplayManagerInternal.getDisplayIdsForGroup(groupId)).thenReturn(displays); 451 SparseArray<int[]> displayIdsByGroupId = new SparseArray<>(); 452 displayIdsByGroupId.put(groupId, displays); 453 when(mDisplayManagerInternal.getDisplayIdsByGroupsIds()).thenReturn(displayIdsByGroupId); 454 mNotifier.onGroupWakefulnessChangeStarted( 455 groupId, WAKEFULNESS_AWAKE, PowerManager.WAKE_REASON_TAP, /* eventTime= */ 1000); 456 final SparseBooleanArray expectedDisplayInteractivities = new SparseBooleanArray(); 457 expectedDisplayInteractivities.put(displayId1, true); 458 expectedDisplayInteractivities.put(displayId2, true); 459 verify(mInputManagerInternal).setDisplayInteractivities(expectedDisplayInteractivities); 460 461 // WHEN display group is changed to only contain one display 462 SparseArray<int[]> newDisplayIdsByGroupId = new SparseArray<>(); 463 newDisplayIdsByGroupId.put(groupId, new int[]{displayId1}); 464 when(mDisplayManagerInternal.getDisplayIdsByGroupsIds()).thenReturn(newDisplayIdsByGroupId); 465 mNotifier.onGroupChanged(); 466 467 // THEN native input manager is informed that the displays in the group have changed 468 final SparseBooleanArray expectedDisplayInteractivitiesAfterChange = 469 new SparseBooleanArray(); 470 expectedDisplayInteractivitiesAfterChange.put(displayId1, true); 471 verify(mInputManagerInternal).setDisplayInteractivities( 472 expectedDisplayInteractivitiesAfterChange); 473 } 474 475 @Test testOnWakeLockReleased_FrameworkStatsLogged_NoChains()476 public void testOnWakeLockReleased_FrameworkStatsLogged_NoChains() { 477 when(mPowerManagerFlags.isMoveWscLoggingToNotifierEnabled()).thenReturn(true); 478 createNotifier(); 479 480 clearInvocations(mLogger, mWakeLockLog, mBatteryStats, mAppOpsManager); 481 482 when(mBatteryStatsInternal.getOwnerUid(UID)).thenReturn(OWNER_UID); 483 when(mBatteryStatsInternal.getOwnerUid(WORK_SOURCE_UID_1)) 484 .thenReturn(OWNER_WORK_SOURCE_UID_1); 485 486 mNotifier.onWakeLockAcquired( 487 PowerManager.PARTIAL_WAKE_LOCK, 488 "wakelockTag", 489 "my.package.name", 490 UID, 491 PID, 492 /* workSource= */ null, 493 /* historyTag= */ null, 494 /* callback= */ null); 495 496 WorkSource ws = new WorkSource(WORK_SOURCE_UID_1); 497 498 mNotifier.onWakeLockChanging( 499 /* existing WakeLock params */ 500 PowerManager.PARTIAL_WAKE_LOCK, 501 "wakelockTag", 502 "my.package.name", 503 UID, 504 PID, 505 /* workSource= */ null, 506 /* historyTag= */ null, 507 /* callback= */ null, 508 /* updated WakeLock params */ 509 PowerManager.PARTIAL_WAKE_LOCK, 510 "wakelockTag", 511 "my.package.name", 512 UID, 513 PID, 514 ws, 515 /* historyTag= */ null, 516 /* callback= */ null); 517 518 mNotifier.onWakeLockReleased( 519 PowerManager.PARTIAL_WAKE_LOCK, 520 "wakelockTag", 521 "my.package.name", 522 UID, 523 PID, 524 ws, 525 /* historyTag= */ null, 526 /* callback= */ null); 527 528 verify(mBatteryStatsInternal, atLeast(1)).getOwnerUid(eq(UID)); 529 verify(mBatteryStatsInternal, atLeast(1)).getOwnerUid(eq(WORK_SOURCE_UID_1)); 530 531 // ACQUIRE before RELEASE 532 InOrder inOrder1 = inOrder(mLogger); 533 inOrder1.verify(mLogger) 534 .wakelockStateChanged( 535 eq(OWNER_UID), 536 eq("wakelockTag"), 537 eq(PowerManager.PARTIAL_WAKE_LOCK), 538 eq(WakelockEventType.ACQUIRE)); 539 inOrder1.verify(mLogger) 540 .wakelockStateChanged( 541 eq(OWNER_UID), 542 eq("wakelockTag"), 543 eq(PowerManager.PARTIAL_WAKE_LOCK), 544 eq(WakelockEventType.RELEASE)); 545 546 InOrder inOrder2 = inOrder(mLogger); 547 inOrder2.verify(mLogger) 548 .wakelockStateChanged( 549 eq(OWNER_WORK_SOURCE_UID_1), 550 eq("wakelockTag"), 551 eq(PowerManager.PARTIAL_WAKE_LOCK), 552 eq(WakelockEventType.ACQUIRE)); 553 inOrder2.verify(mLogger) 554 .wakelockStateChanged( 555 eq(OWNER_WORK_SOURCE_UID_1), 556 eq("wakelockTag"), 557 eq(PowerManager.PARTIAL_WAKE_LOCK), 558 eq(WakelockEventType.RELEASE)); 559 } 560 561 @Test testOnWakeLockReleased_FrameworkStatsLogged_MultipleWorkSourceUids()562 public void testOnWakeLockReleased_FrameworkStatsLogged_MultipleWorkSourceUids() { 563 // UIDs stored directly in WorkSource 564 WorkSource ws = new WorkSource(WORK_SOURCE_UID_1); 565 ws.add(WORK_SOURCE_UID_2); 566 testWorkSource(ws); 567 568 InOrder inOrder = inOrder(mLogger); 569 ArgumentCaptor<Integer> captorInt = ArgumentCaptor.forClass(int.class); 570 571 // ACQUIRE 572 inOrder.verify(mLogger, times(2)) 573 .wakelockStateChanged( 574 /* uid= */ captorInt.capture(), 575 eq("wakelockTag"), 576 eq(PowerManager.PARTIAL_WAKE_LOCK), 577 eq(WakelockEventType.ACQUIRE)); 578 assertThat(captorInt.getAllValues()) 579 .containsExactly(OWNER_WORK_SOURCE_UID_1, OWNER_WORK_SOURCE_UID_2); 580 581 // RELEASE 582 captorInt = ArgumentCaptor.forClass(int.class); 583 inOrder.verify(mLogger, times(2)) 584 .wakelockStateChanged( 585 /* uid= */ captorInt.capture(), 586 eq("wakelockTag"), 587 eq(PowerManager.PARTIAL_WAKE_LOCK), 588 eq(WakelockEventType.RELEASE)); 589 assertThat(captorInt.getAllValues()) 590 .containsExactly(OWNER_WORK_SOURCE_UID_1, OWNER_WORK_SOURCE_UID_2); 591 } 592 593 @Test testOnWakeLockReleased_FrameworkStatsLogged_OneChain()594 public void testOnWakeLockReleased_FrameworkStatsLogged_OneChain() { 595 // UIDs stored in a WorkChain of the WorkSource 596 WorkSource ws = new WorkSource(); 597 WorkChain wc = ws.createWorkChain(); 598 wc.addNode(WORK_SOURCE_UID_1, "tag1"); 599 wc.addNode(WORK_SOURCE_UID_2, "tag2"); 600 testWorkSource(ws); 601 602 WorkChain expectedWorkChain = new WorkChain(); 603 expectedWorkChain.addNode(OWNER_WORK_SOURCE_UID_1, "tag1"); 604 expectedWorkChain.addNode(OWNER_WORK_SOURCE_UID_2, "tag2"); 605 606 InOrder inOrder = inOrder(mLogger); 607 608 // ACQUIRE 609 inOrder.verify(mLogger) 610 .wakelockStateChanged( 611 eq("wakelockTag"), 612 eq(expectedWorkChain), 613 eq(PowerManager.PARTIAL_WAKE_LOCK), 614 eq(WakelockEventType.ACQUIRE)); 615 // RELEASE 616 inOrder.verify(mLogger) 617 .wakelockStateChanged( 618 eq("wakelockTag"), 619 eq(expectedWorkChain), 620 eq(PowerManager.PARTIAL_WAKE_LOCK), 621 eq(WakelockEventType.RELEASE)); 622 } 623 624 @Test testOnWakeLockReleased_FrameworkStatsLogged_OneUid_OneChain()625 public void testOnWakeLockReleased_FrameworkStatsLogged_OneUid_OneChain() { 626 WorkSource ws = new WorkSource(WORK_SOURCE_UID_1); 627 WorkChain wc = ws.createWorkChain(); 628 wc.addNode(WORK_SOURCE_UID_2, "someTag"); 629 testWorkSource(ws); 630 631 WorkChain expectedWorkChain = new WorkChain(); 632 expectedWorkChain.addNode(OWNER_WORK_SOURCE_UID_2, "someTag"); 633 634 InOrder inOrder1 = inOrder(mLogger); 635 InOrder inOrder2 = inOrder(mLogger); 636 637 // ACQUIRE 638 inOrder1.verify(mLogger) 639 .wakelockStateChanged( 640 eq(OWNER_WORK_SOURCE_UID_1), 641 eq("wakelockTag"), 642 eq(PowerManager.PARTIAL_WAKE_LOCK), 643 eq(WakelockEventType.ACQUIRE)); 644 inOrder2.verify(mLogger) 645 .wakelockStateChanged( 646 eq("wakelockTag"), 647 eq(expectedWorkChain), 648 eq(PowerManager.PARTIAL_WAKE_LOCK), 649 eq(WakelockEventType.ACQUIRE)); 650 // RELEASE 651 inOrder1.verify(mLogger) 652 .wakelockStateChanged( 653 eq(OWNER_WORK_SOURCE_UID_1), 654 eq("wakelockTag"), 655 eq(PowerManager.PARTIAL_WAKE_LOCK), 656 eq(WakelockEventType.RELEASE)); 657 inOrder2.verify(mLogger) 658 .wakelockStateChanged( 659 eq("wakelockTag"), 660 eq(expectedWorkChain), 661 eq(PowerManager.PARTIAL_WAKE_LOCK), 662 eq(WakelockEventType.RELEASE)); 663 } 664 665 @Test testOnWakeLockReleased_FrameworkStatsLogged_TwoChains()666 public void testOnWakeLockReleased_FrameworkStatsLogged_TwoChains() { 667 // UIDs stored in a WorkChain of the WorkSource 668 WorkSource ws = new WorkSource(); 669 WorkChain wc1 = ws.createWorkChain(); 670 wc1.addNode(WORK_SOURCE_UID_1, "tag1"); 671 672 WorkChain wc2 = ws.createWorkChain(); 673 wc2.addNode(WORK_SOURCE_UID_2, "tag2"); 674 675 testWorkSource(ws); 676 677 WorkChain expectedWorkChain1 = new WorkChain(); 678 expectedWorkChain1.addNode(OWNER_WORK_SOURCE_UID_1, "tag1"); 679 680 WorkChain expectedWorkChain2 = new WorkChain(); 681 expectedWorkChain2.addNode(OWNER_WORK_SOURCE_UID_2, "tag2"); 682 683 InOrder inOrder1 = inOrder(mLogger); 684 InOrder inOrder2 = inOrder(mLogger); 685 686 // ACQUIRE 687 inOrder1.verify(mLogger) 688 .wakelockStateChanged( 689 eq("wakelockTag"), 690 eq(expectedWorkChain1), 691 eq(PowerManager.PARTIAL_WAKE_LOCK), 692 eq(WakelockEventType.ACQUIRE)); 693 inOrder2.verify(mLogger) 694 .wakelockStateChanged( 695 eq("wakelockTag"), 696 eq(expectedWorkChain2), 697 eq(PowerManager.PARTIAL_WAKE_LOCK), 698 eq(WakelockEventType.ACQUIRE)); 699 700 // RELEASE 701 inOrder1.verify(mLogger) 702 .wakelockStateChanged( 703 eq("wakelockTag"), 704 eq(expectedWorkChain1), 705 eq(PowerManager.PARTIAL_WAKE_LOCK), 706 eq(WakelockEventType.RELEASE)); 707 inOrder2.verify(mLogger) 708 .wakelockStateChanged( 709 eq("wakelockTag"), 710 eq(expectedWorkChain2), 711 eq(PowerManager.PARTIAL_WAKE_LOCK), 712 eq(WakelockEventType.RELEASE)); 713 } 714 715 @Test testOnWakeLockListener_RemoteException_NoRethrow()716 public void testOnWakeLockListener_RemoteException_NoRethrow() throws RemoteException { 717 when(mPowerManagerFlags.improveWakelockLatency()).thenReturn(true); 718 createNotifier(); 719 clearInvocations(mWakeLockLog, mBatteryStats, mAppOpsManager); 720 IWakeLockCallback exceptingCallback = new IWakeLockCallback.Stub() { 721 @Override public void onStateChanged(boolean enabled) throws RemoteException { 722 throw new RemoteException("Just testing"); 723 } 724 }; 725 726 final int uid = 1234; 727 final int pid = 5678; 728 729 mNotifier.onWakeLockReleased(PowerManager.PARTIAL_WAKE_LOCK, "wakelockTag", 730 "my.package.name", uid, pid, /* workSource= */ null, /* historyTag= */ null, 731 exceptingCallback); 732 verifyNoMoreInteractions(mWakeLockLog); 733 mTestLooper.dispatchAll(); 734 verify(mWakeLockLog).onWakeLockReleased("wakelockTag", uid, 1); 735 clearInvocations(mBatteryStats); 736 mNotifier.onWakeLockAcquired(PowerManager.PARTIAL_WAKE_LOCK, "wakelockTag", 737 "my.package.name", uid, pid, /* workSource= */ null, /* historyTag= */ null, 738 exceptingCallback); 739 740 verifyNoMoreInteractions(mWakeLockLog, mBatteryStats); 741 mTestLooper.dispatchAll(); 742 verify(mWakeLockLog).onWakeLockAcquired("wakelockTag", uid, 743 PowerManager.PARTIAL_WAKE_LOCK, 1); 744 verify(mBatteryStats).noteStartWakelock(uid, pid, "wakelockTag", /* historyTag= */ null, 745 BatteryStats.WAKE_TYPE_PARTIAL, false); 746 747 verifyNoMoreInteractions(mWakeLockLog, mBatteryStats); 748 WorkSource worksourceOld = new WorkSource(/*uid=*/ 1); 749 WorkSource worksourceNew = new WorkSource(/*uid=*/ 2); 750 751 mNotifier.onWakeLockChanging(PowerManager.PARTIAL_WAKE_LOCK, "wakelockTag", 752 "my.package.name", uid, pid, worksourceOld, /* historyTag= */ null, 753 exceptingCallback, 754 PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "wakelockTag", 755 "my.package.name", uid, pid, worksourceNew, /* newHistoryTag= */ null, 756 exceptingCallback); 757 mTestLooper.dispatchAll(); 758 verify(mBatteryStats).noteChangeWakelockFromSource(worksourceOld, pid, "wakelockTag", 759 null, BatteryStats.WAKE_TYPE_PARTIAL, worksourceNew, pid, "wakelockTag", 760 null, BatteryStats.WAKE_TYPE_FULL, false); 761 // If we didn't throw, we're good! 762 763 // Test with improveWakelockLatency flag false, hence the wakelock log will run on the same 764 // thread 765 clearInvocations(mWakeLockLog, mBatteryStats); 766 when(mPowerManagerFlags.improveWakelockLatency()).thenReturn(false); 767 768 // Acquire the wakelock 769 mNotifier.onWakeLockAcquired(PowerManager.PARTIAL_WAKE_LOCK, "wakelockTag", 770 "my.package.name", uid, pid, /* workSource= */ null, /* historyTag= */ null, 771 exceptingCallback); 772 verify(mWakeLockLog).onWakeLockAcquired("wakelockTag", uid, 773 PowerManager.PARTIAL_WAKE_LOCK, -1); 774 775 // Update the wakelock 776 mNotifier.onWakeLockChanging(PowerManager.PARTIAL_WAKE_LOCK, "wakelockTag", 777 "my.package.name", uid, pid, worksourceOld, /* historyTag= */ null, 778 exceptingCallback, 779 PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "wakelockTag", 780 "my.package.name", uid, pid, worksourceNew, /* newHistoryTag= */ null, 781 exceptingCallback); 782 verify(mBatteryStats).noteChangeWakelockFromSource(worksourceOld, pid, "wakelockTag", 783 null, BatteryStats.WAKE_TYPE_PARTIAL, worksourceNew, pid, "wakelockTag", 784 null, BatteryStats.WAKE_TYPE_FULL, false); 785 786 // Release the wakelock 787 mNotifier.onWakeLockReleased(PowerManager.PARTIAL_WAKE_LOCK, "wakelockTag", 788 "my.package.name", uid, pid, /* workSource= */ null, /* historyTag= */ null, 789 exceptingCallback); 790 verify(mWakeLockLog).onWakeLockReleased("wakelockTag", uid, -1); 791 } 792 793 @Test test_wakeLockLogUsesWorkSource()794 public void test_wakeLockLogUsesWorkSource() { 795 createNotifier(); 796 clearInvocations(mWakeLockLog); 797 IWakeLockCallback exceptingCallback = new IWakeLockCallback.Stub() { 798 @Override public void onStateChanged(boolean enabled) throws RemoteException { 799 throw new RemoteException("Just testing"); 800 } 801 }; 802 803 final int uid = 1234; 804 final int pid = 5678; 805 WorkSource worksource = new WorkSource(1212); 806 WorkSource worksource2 = new WorkSource(3131); 807 808 mNotifier.onWakeLockAcquired(PowerManager.PARTIAL_WAKE_LOCK, "wakelockTag", 809 "my.package.name", uid, pid, worksource, /* historyTag= */ null, 810 exceptingCallback); 811 verify(mWakeLockLog).onWakeLockAcquired("wakelockTag", 1212, 812 PowerManager.PARTIAL_WAKE_LOCK, -1); 813 814 // Release the wakelock 815 mNotifier.onWakeLockReleased(PowerManager.FULL_WAKE_LOCK, "wakelockTag2", 816 "my.package.name", uid, pid, worksource2, /* historyTag= */ null, 817 exceptingCallback); 818 verify(mWakeLockLog).onWakeLockReleased("wakelockTag2", 3131, -1); 819 820 // clear the handler 821 mTestLooper.dispatchAll(); 822 823 // Now test with improveWakelockLatency flag true 824 clearInvocations(mWakeLockLog); 825 when(mPowerManagerFlags.improveWakelockLatency()).thenReturn(true); 826 827 mNotifier.onWakeLockAcquired(PowerManager.PARTIAL_WAKE_LOCK, "wakelockTag", 828 "my.package.name", uid, pid, worksource, /* historyTag= */ null, 829 exceptingCallback); 830 mTestLooper.dispatchAll(); 831 verify(mWakeLockLog).onWakeLockAcquired("wakelockTag", 1212, 832 PowerManager.PARTIAL_WAKE_LOCK, 1); 833 834 // Release the wakelock 835 mNotifier.onWakeLockReleased(PowerManager.FULL_WAKE_LOCK, "wakelockTag2", 836 "my.package.name", uid, pid, worksource2, /* historyTag= */ null, 837 exceptingCallback); 838 mTestLooper.dispatchAll(); 839 verify(mWakeLockLog).onWakeLockReleased("wakelockTag2", 3131, 1); 840 } 841 842 @Test 843 public void test_notifierProcessesWorkSourceDeepCopy_OnWakelockChanging()844 test_notifierProcessesWorkSourceDeepCopy_OnWakelockChanging() throws RemoteException { 845 when(mPowerManagerFlags.improveWakelockLatency()).thenReturn(true); 846 createNotifier(); 847 clearInvocations(mWakeLockLog, mBatteryStats, mAppOpsManager); 848 IWakeLockCallback exceptingCallback = new IWakeLockCallback.Stub() { 849 @Override public void onStateChanged(boolean enabled) throws RemoteException { 850 throw new RemoteException("Just testing"); 851 } 852 }; 853 854 final int uid = 1234; 855 final int pid = 5678; 856 mTestLooper.dispatchAll(); 857 WorkSource worksourceOld = new WorkSource(/*uid=*/ 1); 858 WorkSource worksourceNew = new WorkSource(/*uid=*/ 2); 859 860 mNotifier.onWakeLockChanging(PowerManager.PARTIAL_WAKE_LOCK, "wakelockTag", 861 "my.package.name", uid, pid, worksourceOld, /* historyTag= */ null, 862 exceptingCallback, 863 PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "wakelockTag", 864 "my.package.name", uid, pid, worksourceNew, /* newHistoryTag= */ null, 865 exceptingCallback); 866 // The newWorksource is modified before notifier could process it. 867 worksourceNew.set(/*uid=*/ 3); 868 869 mTestLooper.dispatchAll(); 870 verify(mBatteryStats).noteChangeWakelockFromSource(worksourceOld, pid, 871 "wakelockTag", null, BatteryStats.WAKE_TYPE_PARTIAL, 872 new WorkSource(/*uid=*/ 2), pid, "wakelockTag", null, 873 BatteryStats.WAKE_TYPE_FULL, false); 874 } 875 876 877 @Test testOnWakeLockListener_FullWakeLock_ProcessesOnHandler()878 public void testOnWakeLockListener_FullWakeLock_ProcessesOnHandler() throws RemoteException { 879 when(mPowerManagerFlags.improveWakelockLatency()).thenReturn(true); 880 createNotifier(); 881 882 IWakeLockCallback exceptingCallback = new IWakeLockCallback.Stub() { 883 @Override public void onStateChanged(boolean enabled) throws RemoteException { 884 throw new RemoteException("Just testing"); 885 } 886 }; 887 clearInvocations(mWakeLockLog, mBatteryStats, mAppOpsManager); 888 889 final int uid = 1234; 890 final int pid = 5678; 891 892 // Release the wakelock 893 mNotifier.onWakeLockReleased(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "wakelockTag", 894 "my.package.name", uid, pid, /* workSource= */ null, /* historyTag= */ null, 895 exceptingCallback); 896 897 // No interaction because we expect that to happen in async 898 verifyNoMoreInteractions(mWakeLockLog, mBatteryStats, mAppOpsManager); 899 900 // Progressing the looper, and validating all the interactions 901 mTestLooper.dispatchAll(); 902 verify(mWakeLockLog).onWakeLockReleased("wakelockTag", uid, 1); 903 verify(mBatteryStats).noteStopWakelock(uid, pid, "wakelockTag", /* historyTag= */ null, 904 BatteryStats.WAKE_TYPE_FULL); 905 verify(mAppOpsManager).finishOp(AppOpsManager.OP_WAKE_LOCK, uid, 906 "my.package.name", null); 907 908 clearInvocations(mWakeLockLog, mBatteryStats, mAppOpsManager); 909 910 // Acquire the wakelock 911 mNotifier.onWakeLockAcquired(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "wakelockTag", 912 "my.package.name", uid, pid, /* workSource= */ null, /* historyTag= */ null, 913 exceptingCallback); 914 915 // No interaction because we expect that to happen in async 916 verifyNoMoreInteractions(mWakeLockLog, mBatteryStats, mAppOpsManager); 917 918 // Progressing the looper, and validating all the interactions 919 mTestLooper.dispatchAll(); 920 verify(mWakeLockLog).onWakeLockAcquired("wakelockTag", uid, 921 PowerManager.SCREEN_BRIGHT_WAKE_LOCK, 1); 922 verify(mBatteryStats).noteStartWakelock(uid, pid, "wakelockTag", /* historyTag= */ null, 923 BatteryStats.WAKE_TYPE_FULL, false); 924 verify(mAppOpsManager).startOpNoThrow(AppOpsManager.OP_WAKE_LOCK, uid, 925 "my.package.name", false, null, null); 926 927 // Test with improveWakelockLatency flag false, hence the wakelock log will run on the same 928 // thread 929 clearInvocations(mWakeLockLog, mBatteryStats, mAppOpsManager); 930 when(mPowerManagerFlags.improveWakelockLatency()).thenReturn(false); 931 932 mNotifier.onWakeLockAcquired(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "wakelockTag", 933 "my.package.name", uid, pid, /* workSource= */ null, /* historyTag= */ null, 934 exceptingCallback); 935 verify(mWakeLockLog).onWakeLockAcquired("wakelockTag", uid, 936 PowerManager.SCREEN_BRIGHT_WAKE_LOCK, -1); 937 938 mNotifier.onWakeLockReleased(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "wakelockTag", 939 "my.package.name", uid, pid, /* workSource= */ null, /* historyTag= */ null, 940 exceptingCallback); 941 verify(mWakeLockLog).onWakeLockReleased("wakelockTag", uid, -1); 942 } 943 944 @Test testOnWakeLockListener_FullWakeLock_ProcessesInSync()945 public void testOnWakeLockListener_FullWakeLock_ProcessesInSync() throws RemoteException { 946 createNotifier(); 947 948 IWakeLockCallback exceptingCallback = new IWakeLockCallback.Stub() { 949 @Override public void onStateChanged(boolean enabled) throws RemoteException { 950 throw new RemoteException("Just testing"); 951 } 952 }; 953 clearInvocations(mWakeLockLog, mBatteryStats, mAppOpsManager); 954 955 final int uid = 1234; 956 final int pid = 5678; 957 958 // Release the wakelock 959 mNotifier.onWakeLockReleased(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "wakelockTag", 960 "my.package.name", uid, pid, /* workSource= */ null, /* historyTag= */ null, 961 exceptingCallback); 962 963 verify(mWakeLockLog).onWakeLockReleased("wakelockTag", uid, -1); 964 verify(mBatteryStats).noteStopWakelock(uid, pid, "wakelockTag", /* historyTag= */ null, 965 BatteryStats.WAKE_TYPE_FULL); 966 verify(mAppOpsManager).finishOp(AppOpsManager.OP_WAKE_LOCK, uid, 967 "my.package.name", null); 968 969 clearInvocations(mWakeLockLog, mBatteryStats, mAppOpsManager); 970 971 // Acquire the wakelock 972 mNotifier.onWakeLockAcquired(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "wakelockTag", 973 "my.package.name", uid, pid, /* workSource= */ null, /* historyTag= */ null, 974 exceptingCallback); 975 976 mTestLooper.dispatchAll(); 977 verify(mWakeLockLog).onWakeLockAcquired("wakelockTag", uid, 978 PowerManager.SCREEN_BRIGHT_WAKE_LOCK, -1); 979 verify(mBatteryStats).noteStartWakelock(uid, pid, "wakelockTag", /* historyTag= */ null, 980 BatteryStats.WAKE_TYPE_FULL, false); 981 verify(mAppOpsManager).startOpNoThrow(AppOpsManager.OP_WAKE_LOCK, uid, 982 "my.package.name", false, null, null); 983 } 984 985 @Test getWakelockMonitorTypeForLogging_evaluatesWakelockLevel()986 public void getWakelockMonitorTypeForLogging_evaluatesWakelockLevel() { 987 createNotifier(); 988 assertEquals(mNotifier.getWakelockMonitorTypeForLogging(PowerManager.SCREEN_DIM_WAKE_LOCK), 989 PowerManager.FULL_WAKE_LOCK); 990 assertEquals(mNotifier.getWakelockMonitorTypeForLogging( 991 PowerManager.SCREEN_BRIGHT_WAKE_LOCK), PowerManager.FULL_WAKE_LOCK); 992 assertEquals(mNotifier.getWakelockMonitorTypeForLogging(PowerManager.DRAW_WAKE_LOCK), 993 PowerManager.DRAW_WAKE_LOCK); 994 assertEquals(mNotifier.getWakelockMonitorTypeForLogging(PowerManager.PARTIAL_WAKE_LOCK), 995 PowerManager.PARTIAL_WAKE_LOCK); 996 assertEquals(mNotifier.getWakelockMonitorTypeForLogging( 997 PowerManager.DOZE_WAKE_LOCK), -1); 998 } 999 1000 @Test getWakelockMonitorTypeForLogging_evaluateProximityLevel()1001 public void getWakelockMonitorTypeForLogging_evaluateProximityLevel() { 1002 // How proximity wakelock is evaluated depends on boolean configuration. Test both. 1003 when(mResourcesSpy.getBoolean( 1004 com.android.internal.R.bool.config_suspendWhenScreenOffDueToProximity)) 1005 .thenReturn(false); 1006 createNotifier(); 1007 assertEquals(mNotifier.getWakelockMonitorTypeForLogging( 1008 PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK), 1009 PowerManager.PARTIAL_WAKE_LOCK); 1010 1011 when(mResourcesSpy.getBoolean( 1012 com.android.internal.R.bool.config_suspendWhenScreenOffDueToProximity)) 1013 .thenReturn(true); 1014 createNotifier(); 1015 assertEquals(mNotifier.getWakelockMonitorTypeForLogging( 1016 PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK), -1); 1017 } 1018 1019 @Test testScreenTimeoutListener_reportsScreenTimeoutPolicyChange()1020 public void testScreenTimeoutListener_reportsScreenTimeoutPolicyChange() throws Exception { 1021 createNotifier(); 1022 final IScreenTimeoutPolicyListener listener = Mockito.mock( 1023 IScreenTimeoutPolicyListener.class); 1024 final IBinder listenerBinder = Mockito.mock(IBinder.class); 1025 when(listener.asBinder()).thenReturn(listenerBinder); 1026 mNotifier.addScreenTimeoutPolicyListener(Display.DEFAULT_DISPLAY, 1027 SCREEN_TIMEOUT_ACTIVE, listener); 1028 mTestLooper.dispatchAll(); 1029 clearInvocations(listener); 1030 1031 mNotifier.notifyScreenTimeoutPolicyChanges(Display.DEFAULT_DISPLAY_GROUP, 1032 /* hasScreenWakeLock= */ SCREEN_TIMEOUT_KEEP_DISPLAY_ON); 1033 1034 // Verify that the event is sent asynchronously on a handler 1035 verify(listener, never()).onScreenTimeoutPolicyChanged(anyInt()); 1036 mTestLooper.dispatchAll(); 1037 verify(listener).onScreenTimeoutPolicyChanged(SCREEN_TIMEOUT_KEEP_DISPLAY_ON); 1038 } 1039 1040 @Test testScreenTimeoutListener_addAndRemoveListener_doesNotInvokeListener()1041 public void testScreenTimeoutListener_addAndRemoveListener_doesNotInvokeListener() 1042 throws Exception { 1043 createNotifier(); 1044 final IScreenTimeoutPolicyListener listener = Mockito.mock( 1045 IScreenTimeoutPolicyListener.class); 1046 final IBinder listenerBinder = Mockito.mock(IBinder.class); 1047 when(listener.asBinder()).thenReturn(listenerBinder); 1048 mNotifier.addScreenTimeoutPolicyListener(Display.DEFAULT_DISPLAY, 1049 SCREEN_TIMEOUT_ACTIVE, listener); 1050 mTestLooper.dispatchAll(); 1051 clearInvocations(listener); 1052 mNotifier.removeScreenTimeoutPolicyListener(Display.DEFAULT_DISPLAY, listener); 1053 1054 mNotifier.notifyScreenTimeoutPolicyChanges(Display.DEFAULT_DISPLAY_GROUP, 1055 SCREEN_TIMEOUT_KEEP_DISPLAY_ON); 1056 mTestLooper.dispatchAll(); 1057 1058 // Callback should not be fired as listener is removed 1059 verify(listener, never()).onScreenTimeoutPolicyChanged(anyInt()); 1060 } 1061 1062 @Test testScreenTimeoutListener_addAndClearListeners_doesNotInvokeListener()1063 public void testScreenTimeoutListener_addAndClearListeners_doesNotInvokeListener() 1064 throws Exception { 1065 createNotifier(); 1066 final IScreenTimeoutPolicyListener listener = Mockito.mock( 1067 IScreenTimeoutPolicyListener.class); 1068 final IBinder listenerBinder = Mockito.mock(IBinder.class); 1069 when(listener.asBinder()).thenReturn(listenerBinder); 1070 mNotifier.addScreenTimeoutPolicyListener(Display.DEFAULT_DISPLAY, 1071 SCREEN_TIMEOUT_ACTIVE, listener); 1072 mTestLooper.dispatchAll(); 1073 clearInvocations(listener); 1074 mNotifier.clearScreenTimeoutPolicyListeners(Display.DEFAULT_DISPLAY); 1075 1076 mNotifier.notifyScreenTimeoutPolicyChanges(Display.DEFAULT_DISPLAY_GROUP, 1077 SCREEN_TIMEOUT_KEEP_DISPLAY_ON); 1078 mTestLooper.dispatchAll(); 1079 1080 // Callback should not be fired as listener is removed 1081 verify(listener, never()).onScreenTimeoutPolicyChanged(anyInt()); 1082 } 1083 1084 @Test testScreenTimeoutListener_subscribedToAnotherDisplay_listenerNotFired()1085 public void testScreenTimeoutListener_subscribedToAnotherDisplay_listenerNotFired() 1086 throws Exception { 1087 createNotifier(); 1088 1089 final IScreenTimeoutPolicyListener listener = Mockito.mock( 1090 IScreenTimeoutPolicyListener.class); 1091 final IBinder listenerBinder = Mockito.mock(IBinder.class); 1092 when(listener.asBinder()).thenReturn(listenerBinder); 1093 mNotifier.addScreenTimeoutPolicyListener(Display.DEFAULT_DISPLAY, 1094 SCREEN_TIMEOUT_ACTIVE, listener); 1095 mTestLooper.dispatchAll(); 1096 clearInvocations(listener); 1097 1098 mNotifier.notifyScreenTimeoutPolicyChanges(/* displayGroupId= */ 123, 1099 SCREEN_TIMEOUT_KEEP_DISPLAY_ON); 1100 mTestLooper.dispatchAll(); 1101 1102 // Callback should not be fired as we subscribed only to the DEFAULT_DISPLAY 1103 verify(listener, never()).onScreenTimeoutPolicyChanged(anyInt()); 1104 } 1105 1106 @Test testScreenTimeoutListener_listenerDied_listenerNotFired()1107 public void testScreenTimeoutListener_listenerDied_listenerNotFired() 1108 throws Exception { 1109 createNotifier(); 1110 1111 final IScreenTimeoutPolicyListener listener = Mockito.mock( 1112 IScreenTimeoutPolicyListener.class); 1113 final IBinder listenerBinder = Mockito.mock(IBinder.class); 1114 when(listener.asBinder()).thenReturn(listenerBinder); 1115 1116 mNotifier.addScreenTimeoutPolicyListener(Display.DEFAULT_DISPLAY, 1117 SCREEN_TIMEOUT_ACTIVE, listener); 1118 mTestLooper.dispatchAll(); 1119 1120 ArgumentCaptor<IBinder.DeathRecipient> captor = 1121 ArgumentCaptor.forClass(IBinder.DeathRecipient.class); 1122 verify(listenerBinder).linkToDeath(captor.capture(), anyInt()); 1123 mTestLooper.dispatchAll(); 1124 captor.getValue().binderDied(); 1125 clearInvocations(listener); 1126 1127 mNotifier.notifyScreenTimeoutPolicyChanges(Display.DEFAULT_DISPLAY, 1128 SCREEN_TIMEOUT_KEEP_DISPLAY_ON); 1129 mTestLooper.dispatchAll(); 1130 1131 // Callback should not be fired as binder died 1132 verify(listener, never()).onScreenTimeoutPolicyChanged(anyInt()); 1133 } 1134 1135 @Test testScreenTimeoutListener_listenerThrowsException_listenerNotFiredSecondTime()1136 public void testScreenTimeoutListener_listenerThrowsException_listenerNotFiredSecondTime() 1137 throws Exception { 1138 createNotifier(); 1139 1140 final IScreenTimeoutPolicyListener listener = Mockito.mock( 1141 IScreenTimeoutPolicyListener.class); 1142 final IBinder listenerBinder = Mockito.mock(IBinder.class); 1143 when(listener.asBinder()).thenReturn(listenerBinder); 1144 doThrow(RuntimeException.class).when(listener).onScreenTimeoutPolicyChanged(anyInt()); 1145 mNotifier.addScreenTimeoutPolicyListener(Display.DEFAULT_DISPLAY_GROUP, 1146 SCREEN_TIMEOUT_ACTIVE, listener); 1147 mTestLooper.dispatchAll(); 1148 clearInvocations(listener); 1149 1150 mNotifier.notifyScreenTimeoutPolicyChanges(Display.DEFAULT_DISPLAY, 1151 SCREEN_TIMEOUT_KEEP_DISPLAY_ON); 1152 mTestLooper.dispatchAll(); 1153 1154 // Callback should not be fired as it has thrown an exception once 1155 verify(listener, never()).onScreenTimeoutPolicyChanged(anyInt()); 1156 } 1157 1158 @Test testScreenTimeoutListener_nonDefaultDisplay_stillReportsPolicyCorrectly()1159 public void testScreenTimeoutListener_nonDefaultDisplay_stillReportsPolicyCorrectly() 1160 throws Exception { 1161 createNotifier(); 1162 final int otherDisplayId = 123; 1163 final int otherDisplayGroupId = 123_00; 1164 when(mDisplayManagerInternal.getGroupIdForDisplay(otherDisplayId)).thenReturn( 1165 otherDisplayGroupId); 1166 final IScreenTimeoutPolicyListener listener = Mockito.mock( 1167 IScreenTimeoutPolicyListener.class); 1168 final IBinder listenerBinder = Mockito.mock(IBinder.class); 1169 when(listener.asBinder()).thenReturn(listenerBinder); 1170 mNotifier.addScreenTimeoutPolicyListener(otherDisplayId, 1171 SCREEN_TIMEOUT_ACTIVE, listener); 1172 mTestLooper.dispatchAll(); 1173 clearInvocations(listener); 1174 1175 mNotifier.notifyScreenTimeoutPolicyChanges(otherDisplayGroupId, 1176 SCREEN_TIMEOUT_KEEP_DISPLAY_ON); 1177 mTestLooper.dispatchAll(); 1178 1179 verify(listener).onScreenTimeoutPolicyChanged(SCREEN_TIMEOUT_KEEP_DISPLAY_ON); 1180 } 1181 1182 @Test testScreenTimeoutListener_timeoutPolicyTimeout_reportsTimeoutOnSubscription()1183 public void testScreenTimeoutListener_timeoutPolicyTimeout_reportsTimeoutOnSubscription() 1184 throws Exception { 1185 createNotifier(); 1186 final IScreenTimeoutPolicyListener listener = Mockito.mock( 1187 IScreenTimeoutPolicyListener.class); 1188 final IBinder listenerBinder = Mockito.mock(IBinder.class); 1189 when(listener.asBinder()).thenReturn(listenerBinder); 1190 1191 mNotifier.addScreenTimeoutPolicyListener(Display.DEFAULT_DISPLAY, 1192 SCREEN_TIMEOUT_ACTIVE, listener); 1193 mTestLooper.dispatchAll(); 1194 1195 verify(listener).onScreenTimeoutPolicyChanged(SCREEN_TIMEOUT_ACTIVE); 1196 } 1197 1198 @Test testScreenTimeoutListener_policyHeld_reportsHeldOnSubscription()1199 public void testScreenTimeoutListener_policyHeld_reportsHeldOnSubscription() 1200 throws Exception { 1201 createNotifier(); 1202 final IScreenTimeoutPolicyListener listener = Mockito.mock( 1203 IScreenTimeoutPolicyListener.class); 1204 final IBinder listenerBinder = Mockito.mock(IBinder.class); 1205 when(listener.asBinder()).thenReturn(listenerBinder); 1206 1207 mNotifier.addScreenTimeoutPolicyListener(Display.DEFAULT_DISPLAY, 1208 SCREEN_TIMEOUT_KEEP_DISPLAY_ON, listener); 1209 mTestLooper.dispatchAll(); 1210 1211 verify(listener).onScreenTimeoutPolicyChanged(SCREEN_TIMEOUT_KEEP_DISPLAY_ON); 1212 } 1213 1214 private final PowerManagerService.Injector mInjector = new PowerManagerService.Injector() { 1215 @Override 1216 Notifier createNotifier(Looper looper, Context context, IBatteryStats batteryStats, 1217 SuspendBlocker suspendBlocker, WindowManagerPolicy policy, 1218 FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector, 1219 Executor backgroundExecutor, PowerManagerFlags powerManagerFlags) { 1220 return mNotifierMock; 1221 } 1222 1223 @Override 1224 SuspendBlocker createSuspendBlocker(PowerManagerService service, String name) { 1225 return super.createSuspendBlocker(service, name); 1226 } 1227 1228 @Override 1229 BatterySaverStateMachine createBatterySaverStateMachine(Object lock, Context context) { 1230 return mBatterySaverStateMachineMock; 1231 } 1232 1233 @Override 1234 PowerManagerService.NativeWrapper createNativeWrapper() { 1235 return mNativeWrapperMock; 1236 } 1237 1238 @Override 1239 WirelessChargerDetector createWirelessChargerDetector( 1240 SensorManager sensorManager, SuspendBlocker suspendBlocker, Handler handler) { 1241 return mWirelessChargerDetectorMock; 1242 } 1243 1244 @Override 1245 AmbientDisplayConfiguration createAmbientDisplayConfiguration(Context context) { 1246 return mAmbientDisplayConfigurationMock; 1247 } 1248 1249 @Override 1250 InattentiveSleepWarningController createInattentiveSleepWarningController() { 1251 return mInattentiveSleepWarningControllerMock; 1252 } 1253 1254 @Override 1255 public SystemPropertiesWrapper createSystemPropertiesWrapper() { 1256 return mSystemPropertiesMock; 1257 } 1258 1259 @Override 1260 void invalidateIsInteractiveCaches() { 1261 // Avoids an SELinux denial. 1262 } 1263 }; 1264 enableChargingFeedback(boolean chargingFeedbackEnabled, boolean dndOn)1265 private void enableChargingFeedback(boolean chargingFeedbackEnabled, boolean dndOn) { 1266 // enable/disable charging feedback 1267 Settings.Secure.putIntForUser( 1268 mContextSpy.getContentResolver(), 1269 Settings.Secure.CHARGING_SOUNDS_ENABLED, 1270 chargingFeedbackEnabled ? 1 : 0, 1271 USER_ID); 1272 1273 // toggle on/off dnd 1274 Settings.Global.putInt( 1275 mContextSpy.getContentResolver(), 1276 Settings.Global.ZEN_MODE, 1277 dndOn ? Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS 1278 : Settings.Global.ZEN_MODE_OFF); 1279 } 1280 enableChargingVibration(boolean enable)1281 private void enableChargingVibration(boolean enable) { 1282 enableChargingFeedback(true, false); 1283 1284 Settings.Secure.putIntForUser( 1285 mContextSpy.getContentResolver(), 1286 Settings.Secure.CHARGING_VIBRATION_ENABLED, 1287 enable ? 1 : 0, 1288 USER_ID); 1289 } 1290 createNotifier()1291 private void createNotifier() { 1292 Notifier.Injector injector = 1293 new Notifier.Injector() { 1294 @Override 1295 public long currentTimeMillis() { 1296 return 1; 1297 } 1298 1299 @Override 1300 public @NonNull WakeLockLog getWakeLockLog(Context context) { 1301 return mWakeLockLog; 1302 } 1303 1304 @Override 1305 public AppOpsManager getAppOpsManager(Context context) { 1306 return mAppOpsManager; 1307 } 1308 1309 @Override 1310 public FrameworkStatsLogger getFrameworkStatsLogger() { 1311 return mLogger; 1312 } 1313 1314 @Override 1315 public BatteryStatsInternal getBatteryStatsInternal() { 1316 return mBatteryStatsInternal; 1317 } 1318 }; 1319 1320 mNotifier = new Notifier( 1321 mTestLooper.getLooper(), 1322 mContextSpy, 1323 mBatteryStats, 1324 mInjector.createSuspendBlocker(mService, "testBlocker"), 1325 mPolicy, 1326 null, 1327 null, 1328 mTestExecutor, mPowerManagerFlags, injector); 1329 } 1330 1331 private static class FakeExecutor implements Executor { 1332 private Runnable mLastCommand; 1333 1334 @Override execute(Runnable command)1335 public void execute(Runnable command) { 1336 assertNull(mLastCommand); 1337 assertNotNull(command); 1338 mLastCommand = command; 1339 } 1340 getAndResetLastCommand()1341 public Runnable getAndResetLastCommand() { 1342 Runnable toReturn = mLastCommand; 1343 mLastCommand = null; 1344 return toReturn; 1345 } 1346 simulateAsyncExecutionOfLastCommand()1347 public void simulateAsyncExecutionOfLastCommand() { 1348 Runnable toRun = getAndResetLastCommand(); 1349 if (toRun != null) { 1350 toRun.run(); 1351 } 1352 } 1353 } 1354 testWorkSource(WorkSource ws)1355 private void testWorkSource(WorkSource ws) { 1356 when(mPowerManagerFlags.isMoveWscLoggingToNotifierEnabled()).thenReturn(true); 1357 createNotifier(); 1358 clearInvocations( 1359 mBatteryStatsInternal, mLogger, mWakeLockLog, mBatteryStats, mAppOpsManager); 1360 1361 when(mBatteryStatsInternal.getOwnerUid(WORK_SOURCE_UID_1)) 1362 .thenReturn(OWNER_WORK_SOURCE_UID_1); 1363 when(mBatteryStatsInternal.getOwnerUid(WORK_SOURCE_UID_2)) 1364 .thenReturn(OWNER_WORK_SOURCE_UID_2); 1365 1366 mNotifier.onWakeLockAcquired( 1367 PowerManager.PARTIAL_WAKE_LOCK, 1368 "wakelockTag", 1369 "my.package.name", 1370 UID, 1371 PID, 1372 ws, 1373 /* historyTag= */ null, 1374 /* callback= */ null); 1375 1376 mNotifier.onWakeLockReleased( 1377 PowerManager.PARTIAL_WAKE_LOCK, 1378 "wakelockTag", 1379 "my.package.name", 1380 UID, 1381 PID, 1382 ws, 1383 /* historyTag= */ null, 1384 /* callback= */ null); 1385 1386 verify(mBatteryStatsInternal, atLeast(1)).getOwnerUid(eq(WORK_SOURCE_UID_1)); 1387 verify(mBatteryStatsInternal, atLeast(1)).getOwnerUid(eq(WORK_SOURCE_UID_2)); 1388 } 1389 } 1390