1 /* 2 * Copyright (C) 2016 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.systemui.statusbar; 18 19 import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED; 20 import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE; 21 import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_DARK; 22 import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_LOCKOUT_PERMANENT; 23 import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_TIMEOUT; 24 25 import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_AVAILABLE; 26 import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED; 27 import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED; 28 import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_ALIGNMENT; 29 import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BATTERY; 30 import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BIOMETRIC_MESSAGE; 31 import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP; 32 import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_DISCLOSURE; 33 import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_LOGOUT; 34 import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_OWNER_INFO; 35 import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_PERSISTENT_UNLOCK_MESSAGE; 36 import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_TRANSIENT; 37 import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_TRUST; 38 import static com.android.systemui.keyguard.ScreenLifecycle.SCREEN_OFF; 39 import static com.android.systemui.keyguard.ScreenLifecycle.SCREEN_TURNING_ON; 40 41 import static com.google.common.truth.Truth.assertThat; 42 43 import static org.junit.Assert.assertFalse; 44 import static org.junit.Assert.assertTrue; 45 import static org.mockito.ArgumentMatchers.any; 46 import static org.mockito.ArgumentMatchers.anyBoolean; 47 import static org.mockito.ArgumentMatchers.anyInt; 48 import static org.mockito.ArgumentMatchers.anyObject; 49 import static org.mockito.ArgumentMatchers.anyString; 50 import static org.mockito.ArgumentMatchers.eq; 51 import static org.mockito.Mockito.clearInvocations; 52 import static org.mockito.Mockito.mock; 53 import static org.mockito.Mockito.never; 54 import static org.mockito.Mockito.reset; 55 import static org.mockito.Mockito.times; 56 import static org.mockito.Mockito.verify; 57 import static org.mockito.Mockito.verifyNoMoreInteractions; 58 import static org.mockito.Mockito.when; 59 60 import android.content.Intent; 61 import android.content.pm.UserInfo; 62 import android.graphics.Color; 63 import android.hardware.biometrics.BiometricFaceConstants; 64 import android.hardware.biometrics.BiometricFingerprintConstants; 65 import android.hardware.biometrics.BiometricSourceType; 66 import android.os.BatteryManager; 67 import android.os.RemoteException; 68 import android.testing.AndroidTestingRunner; 69 import android.testing.TestableLooper; 70 71 import androidx.test.filters.SmallTest; 72 73 import com.android.keyguard.TrustGrantFlags; 74 import com.android.settingslib.fuelgauge.BatteryStatus; 75 import com.android.systemui.R; 76 import com.android.systemui.dock.DockManager; 77 import com.android.systemui.keyguard.KeyguardIndication; 78 import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController; 79 80 import org.junit.Test; 81 import org.junit.runner.RunWith; 82 83 import java.text.NumberFormat; 84 import java.util.Collections; 85 import java.util.HashSet; 86 import java.util.List; 87 import java.util.Set; 88 89 @SmallTest 90 @RunWith(AndroidTestingRunner.class) 91 @TestableLooper.RunWithLooper 92 public class KeyguardIndicationControllerTest extends KeyguardIndicationControllerBaseTest { 93 @Test createController_setIndicationAreaAgain_destroysPreviousRotateTextViewController()94 public void createController_setIndicationAreaAgain_destroysPreviousRotateTextViewController() { 95 // GIVEN a controller with a mocked rotate text view controlller 96 final KeyguardIndicationRotateTextViewController mockedRotateTextViewController = 97 mock(KeyguardIndicationRotateTextViewController.class); 98 createController(); 99 mController.mRotateTextViewController = mockedRotateTextViewController; 100 101 // WHEN a new indication area is set 102 mController.setIndicationArea(mIndicationArea); 103 104 // THEN the previous rotateTextViewController is destroyed 105 verify(mockedRotateTextViewController).destroy(); 106 } 107 108 @Test createController_addsAlignmentListener()109 public void createController_addsAlignmentListener() { 110 createController(); 111 112 verify(mDockManager).addAlignmentStateListener( 113 any(DockManager.AlignmentStateListener.class)); 114 } 115 116 @Test onAlignmentStateChanged_showsSlowChargingIndication()117 public void onAlignmentStateChanged_showsSlowChargingIndication() { 118 mInstrumentation.runOnMainSync(() -> { 119 createController(); 120 verify(mDockManager).addAlignmentStateListener(mAlignmentListener.capture()); 121 mController.setVisible(true); 122 123 mAlignmentListener.getValue().onAlignmentStateChanged(DockManager.ALIGN_STATE_POOR); 124 }); 125 mInstrumentation.waitForIdleSync(); 126 mTestableLooper.processAllMessages(); 127 128 verifyIndicationMessage(INDICATION_TYPE_ALIGNMENT, 129 mContext.getResources().getString(R.string.dock_alignment_slow_charging)); 130 assertThat(mKeyguardIndicationCaptor.getValue().getTextColor().getDefaultColor()) 131 .isEqualTo(mContext.getColor(R.color.misalignment_text_color)); 132 } 133 134 @Test onAlignmentStateChanged_showsNotChargingIndication()135 public void onAlignmentStateChanged_showsNotChargingIndication() { 136 mInstrumentation.runOnMainSync(() -> { 137 createController(); 138 verify(mDockManager).addAlignmentStateListener(mAlignmentListener.capture()); 139 mController.setVisible(true); 140 141 mAlignmentListener.getValue().onAlignmentStateChanged(DockManager.ALIGN_STATE_TERRIBLE); 142 }); 143 mInstrumentation.waitForIdleSync(); 144 mTestableLooper.processAllMessages(); 145 146 verifyIndicationMessage(INDICATION_TYPE_ALIGNMENT, 147 mContext.getResources().getString(R.string.dock_alignment_not_charging)); 148 assertThat(mKeyguardIndicationCaptor.getValue().getTextColor().getDefaultColor()) 149 .isEqualTo(mContext.getColor(R.color.misalignment_text_color)); 150 } 151 152 @Test onAlignmentStateChanged_whileDozing_showsSlowChargingIndication()153 public void onAlignmentStateChanged_whileDozing_showsSlowChargingIndication() { 154 mInstrumentation.runOnMainSync(() -> { 155 createController(); 156 verify(mDockManager).addAlignmentStateListener(mAlignmentListener.capture()); 157 mController.setVisible(true); 158 mStatusBarStateListener.onDozingChanged(true); 159 160 mAlignmentListener.getValue().onAlignmentStateChanged(DockManager.ALIGN_STATE_POOR); 161 }); 162 mInstrumentation.waitForIdleSync(); 163 mTestableLooper.processAllMessages(); 164 165 assertThat(mTextView.getText()).isEqualTo( 166 mContext.getResources().getString(R.string.dock_alignment_slow_charging)); 167 assertThat(mTextView.getCurrentTextColor()).isEqualTo( 168 mContext.getColor(R.color.misalignment_text_color)); 169 } 170 171 @Test onAlignmentStateChanged_whileDozing_showsNotChargingIndication()172 public void onAlignmentStateChanged_whileDozing_showsNotChargingIndication() { 173 mInstrumentation.runOnMainSync(() -> { 174 createController(); 175 verify(mDockManager).addAlignmentStateListener(mAlignmentListener.capture()); 176 mController.setVisible(true); 177 mStatusBarStateListener.onDozingChanged(true); 178 179 mAlignmentListener.getValue().onAlignmentStateChanged(DockManager.ALIGN_STATE_TERRIBLE); 180 }); 181 mInstrumentation.waitForIdleSync(); 182 mTestableLooper.processAllMessages(); 183 184 assertThat(mTextView.getText()).isEqualTo( 185 mContext.getResources().getString(R.string.dock_alignment_not_charging)); 186 assertThat(mTextView.getCurrentTextColor()).isEqualTo( 187 mContext.getColor(R.color.misalignment_text_color)); 188 } 189 190 @Test disclosure_unmanaged()191 public void disclosure_unmanaged() { 192 createController(); 193 mController.setVisible(true); 194 when(mKeyguardStateController.isShowing()).thenReturn(true); 195 when(mDevicePolicyManager.isDeviceManaged()).thenReturn(false); 196 when(mDevicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile()).thenReturn(false); 197 reset(mRotateTextViewController); 198 199 sendUpdateDisclosureBroadcast(); 200 mExecutor.runAllReady(); 201 202 verifyHideIndication(INDICATION_TYPE_DISCLOSURE); 203 } 204 205 @Test disclosure_deviceOwner_noOrganizationName()206 public void disclosure_deviceOwner_noOrganizationName() { 207 createController(); 208 when(mKeyguardStateController.isShowing()).thenReturn(true); 209 when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true); 210 when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(null); 211 sendUpdateDisclosureBroadcast(); 212 mController.setVisible(true); 213 mExecutor.runAllReady(); 214 215 verifyIndicationMessage(INDICATION_TYPE_DISCLOSURE, mDisclosureGeneric); 216 } 217 218 @Test disclosure_orgOwnedDeviceWithManagedProfile_noOrganizationName()219 public void disclosure_orgOwnedDeviceWithManagedProfile_noOrganizationName() { 220 createController(); 221 mController.setVisible(true); 222 when(mKeyguardStateController.isShowing()).thenReturn(true); 223 when(mDevicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile()).thenReturn(true); 224 when(mUserManager.getProfiles(anyInt())).thenReturn(Collections.singletonList( 225 new UserInfo(10, /* name */ null, /* flags */ FLAG_MANAGED_PROFILE))); 226 when(mDevicePolicyManager.getOrganizationNameForUser(eq(10))).thenReturn(null); 227 sendUpdateDisclosureBroadcast(); 228 mExecutor.runAllReady(); 229 230 verifyIndicationMessage(INDICATION_TYPE_DISCLOSURE, mDisclosureGeneric); 231 } 232 233 @Test disclosure_deviceOwner_withOrganizationName()234 public void disclosure_deviceOwner_withOrganizationName() { 235 createController(); 236 mController.setVisible(true); 237 when(mKeyguardStateController.isShowing()).thenReturn(true); 238 when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true); 239 when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(ORGANIZATION_NAME); 240 sendUpdateDisclosureBroadcast(); 241 mExecutor.runAllReady(); 242 243 verifyIndicationMessage(INDICATION_TYPE_DISCLOSURE, mDisclosureWithOrganization); 244 } 245 246 @Test disclosure_orgOwnedDeviceWithManagedProfile_withOrganizationName()247 public void disclosure_orgOwnedDeviceWithManagedProfile_withOrganizationName() { 248 createController(); 249 mController.setVisible(true); 250 when(mKeyguardStateController.isShowing()).thenReturn(true); 251 when(mDevicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile()).thenReturn(true); 252 when(mUserManager.getProfiles(anyInt())).thenReturn(Collections.singletonList( 253 new UserInfo(10, /* name */ null, FLAG_MANAGED_PROFILE))); 254 when(mDevicePolicyManager.getOrganizationNameForUser(eq(10))).thenReturn(ORGANIZATION_NAME); 255 sendUpdateDisclosureBroadcast(); 256 mExecutor.runAllReady(); 257 258 verifyIndicationMessage(INDICATION_TYPE_DISCLOSURE, mDisclosureWithOrganization); 259 } 260 261 @Test disclosure_updateOnTheFly()262 public void disclosure_updateOnTheFly() { 263 when(mKeyguardStateController.isShowing()).thenReturn(true); 264 when(mDevicePolicyManager.isDeviceManaged()).thenReturn(false); 265 createController(); 266 mController.setVisible(true); 267 268 when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true); 269 when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(null); 270 sendUpdateDisclosureBroadcast(); 271 mExecutor.runAllReady(); 272 273 verifyIndicationMessage(INDICATION_TYPE_DISCLOSURE, mDisclosureGeneric); 274 reset(mRotateTextViewController); 275 276 when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true); 277 when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(ORGANIZATION_NAME); 278 sendUpdateDisclosureBroadcast(); 279 mExecutor.runAllReady(); 280 281 verifyIndicationMessage(INDICATION_TYPE_DISCLOSURE, mDisclosureWithOrganization); 282 reset(mRotateTextViewController); 283 284 when(mDevicePolicyManager.isDeviceManaged()).thenReturn(false); 285 sendUpdateDisclosureBroadcast(); 286 mExecutor.runAllReady(); 287 288 verifyHideIndication(INDICATION_TYPE_DISCLOSURE); 289 } 290 291 @Test disclosure_deviceOwner_financedDeviceWithOrganizationName()292 public void disclosure_deviceOwner_financedDeviceWithOrganizationName() { 293 createController(); 294 mController.setVisible(true); 295 when(mKeyguardStateController.isShowing()).thenReturn(true); 296 when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true); 297 when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(ORGANIZATION_NAME); 298 when(mDevicePolicyManager.isFinancedDevice()).thenReturn(true); 299 // TODO(b/259908270): remove 300 when(mDevicePolicyManager.getDeviceOwnerType(DEVICE_OWNER_COMPONENT)) 301 .thenReturn(DEVICE_OWNER_TYPE_FINANCED); 302 sendUpdateDisclosureBroadcast(); 303 mExecutor.runAllReady(); 304 mController.setVisible(true); 305 306 verifyIndicationMessage(INDICATION_TYPE_DISCLOSURE, mFinancedDisclosureWithOrganization); 307 } 308 309 @Test transientIndication_holdsWakeLock_whenDozing()310 public void transientIndication_holdsWakeLock_whenDozing() { 311 // GIVEN animations are enabled and text is visible 312 mTextView.setAnimationsEnabled(true); 313 createController(); 314 mController.setVisible(true); 315 316 // WHEN transient text is shown 317 mStatusBarStateListener.onDozingChanged(true); 318 mController.showTransientIndication(TEST_STRING_RES); 319 320 // THEN wake lock is held while the animation is running 321 assertTrue("WakeLock expected: HELD, was: RELEASED", mWakeLock.isHeld()); 322 } 323 324 @Test transientIndication_releasesWakeLock_whenDozing()325 public void transientIndication_releasesWakeLock_whenDozing() { 326 // GIVEN animations aren't enabled 327 mTextView.setAnimationsEnabled(false); 328 createController(); 329 mController.setVisible(true); 330 331 // WHEN we show the transient indication 332 mStatusBarStateListener.onDozingChanged(true); 333 mController.showTransientIndication(TEST_STRING_RES); 334 335 // THEN wake lock is RELEASED, not held 336 assertFalse("WakeLock expected: RELEASED, was: HELD", mWakeLock.isHeld()); 337 } 338 339 @Test transientIndication_visibleWhenDozing()340 public void transientIndication_visibleWhenDozing() { 341 createController(); 342 mController.setVisible(true); 343 344 mStatusBarStateListener.onDozingChanged(true); 345 mController.showTransientIndication(TEST_STRING_RES); 346 347 assertThat(mTextView.getText()).isEqualTo( 348 mContext.getResources().getString(TEST_STRING_RES)); 349 assertThat(mTextView.getCurrentTextColor()).isEqualTo(Color.WHITE); 350 assertThat(mTextView.getAlpha()).isEqualTo(1f); 351 } 352 353 @Test transientIndication_visibleWhenDozing_unlessSwipeUp_fromHelp()354 public void transientIndication_visibleWhenDozing_unlessSwipeUp_fromHelp() { 355 createController(); 356 String message = "A message"; 357 358 mController.setVisible(true); 359 mController.getKeyguardCallback().onBiometricHelp( 360 BIOMETRIC_HELP_FACE_NOT_RECOGNIZED, message, 361 BiometricSourceType.FACE); 362 verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, message); 363 reset(mRotateTextViewController); 364 mStatusBarStateListener.onDozingChanged(true); 365 366 assertThat(mTextView.getText()).isNotEqualTo(message); 367 } 368 369 @Test transientIndication_visibleWhenWokenUp()370 public void transientIndication_visibleWhenWokenUp() { 371 createController(); 372 when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false); 373 final String message = "helpMsg"; 374 375 // GIVEN screen is off 376 when(mScreenLifecycle.getScreenState()).thenReturn(SCREEN_OFF); 377 378 // WHEN fingeprint help message received 379 mController.setVisible(true); 380 mController.getKeyguardCallback().onBiometricHelp(BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED, 381 message, BiometricSourceType.FINGERPRINT); 382 383 // THEN message isn't shown right away 384 verifyNoMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE); 385 386 // WHEN the screen turns on 387 mScreenObserver.onScreenTurnedOn(); 388 mTestableLooper.processAllMessages(); 389 390 // THEN the message is shown 391 verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, message); 392 } 393 394 @Test onBiometricHelp_coEx_faceFailure()395 public void onBiometricHelp_coEx_faceFailure() { 396 createController(); 397 398 // GIVEN unlocking with fingerprint is possible and allowed 399 fingerprintUnlockIsPossibleAndAllowed(); 400 401 String message = "A message"; 402 mController.setVisible(true); 403 404 // WHEN there's a face not recognized message 405 mController.getKeyguardCallback().onBiometricHelp( 406 BIOMETRIC_HELP_FACE_NOT_RECOGNIZED, 407 message, 408 BiometricSourceType.FACE); 409 410 // THEN show sequential messages such as: 'face not recognized' and 411 // 'try fingerprint instead' 412 verifyIndicationMessage( 413 INDICATION_TYPE_BIOMETRIC_MESSAGE, 414 mContext.getString(R.string.keyguard_face_failed)); 415 verifyIndicationMessage( 416 INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP, 417 mContext.getString(R.string.keyguard_suggest_fingerprint)); 418 } 419 420 @Test onBiometricHelp_coEx_faceUnavailable()421 public void onBiometricHelp_coEx_faceUnavailable() { 422 createController(); 423 424 // GIVEN unlocking with fingerprint is possible and allowed 425 fingerprintUnlockIsPossibleAndAllowed(); 426 427 String message = "A message"; 428 mController.setVisible(true); 429 430 // WHEN there's a face unavailable message 431 mController.getKeyguardCallback().onBiometricHelp( 432 BIOMETRIC_HELP_FACE_NOT_AVAILABLE, 433 message, 434 BiometricSourceType.FACE); 435 436 // THEN show sequential messages such as: 'face unlock unavailable' and 437 // 'try fingerprint instead' 438 verifyIndicationMessage( 439 INDICATION_TYPE_BIOMETRIC_MESSAGE, 440 message); 441 verifyIndicationMessage( 442 INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP, 443 mContext.getString(R.string.keyguard_suggest_fingerprint)); 444 } 445 446 447 @Test onBiometricHelp_coEx_faceUnavailable_fpNotAllowed()448 public void onBiometricHelp_coEx_faceUnavailable_fpNotAllowed() { 449 createController(); 450 451 // GIVEN unlocking with fingerprint is possible but not allowed 452 setupFingerprintUnlockPossible(true); 453 when(mKeyguardUpdateMonitor.isUnlockingWithFingerprintAllowed()) 454 .thenReturn(false); 455 456 String message = "A message"; 457 mController.setVisible(true); 458 459 // WHEN there's a face unavailable message 460 mController.getKeyguardCallback().onBiometricHelp( 461 BIOMETRIC_HELP_FACE_NOT_AVAILABLE, 462 message, 463 BiometricSourceType.FACE); 464 465 // THEN show sequential messages such as: 'face unlock unavailable' and 466 // 'try fingerprint instead' 467 verifyIndicationMessage( 468 INDICATION_TYPE_BIOMETRIC_MESSAGE, 469 message); 470 verifyIndicationMessage( 471 INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP, 472 mContext.getString(R.string.keyguard_unlock)); 473 } 474 475 @Test onBiometricHelp_coEx_fpFailure_faceAlreadyUnlocked()476 public void onBiometricHelp_coEx_fpFailure_faceAlreadyUnlocked() { 477 createController(); 478 479 // GIVEN face has already unlocked the device 480 when(mKeyguardUpdateMonitor.getUserUnlockedWithFace(anyInt())).thenReturn(true); 481 482 String message = "A message"; 483 mController.setVisible(true); 484 485 // WHEN there's a fingerprint not recognized message 486 mController.getKeyguardCallback().onBiometricHelp( 487 BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED, 488 message, 489 BiometricSourceType.FINGERPRINT); 490 491 // THEN show sequential messages such as: 'Unlocked by face' and 492 // 'Swipe up to open' 493 verifyIndicationMessage( 494 INDICATION_TYPE_BIOMETRIC_MESSAGE, 495 mContext.getString(R.string.keyguard_face_successful_unlock)); 496 verifyIndicationMessage( 497 INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP, 498 mContext.getString(R.string.keyguard_unlock)); 499 } 500 501 @Test onBiometricHelp_coEx_fpFailure_trustAgentAlreadyUnlocked()502 public void onBiometricHelp_coEx_fpFailure_trustAgentAlreadyUnlocked() { 503 createController(); 504 505 // GIVEN trust agent has already unlocked the device 506 when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(true); 507 508 String message = "A message"; 509 mController.setVisible(true); 510 511 // WHEN there's a fingerprint not recognized message 512 mController.getKeyguardCallback().onBiometricHelp( 513 BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED, 514 message, 515 BiometricSourceType.FINGERPRINT); 516 517 // THEN show sequential messages such as: 'Kept unlocked by TrustAgent' and 518 // 'Swipe up to open' 519 verifyIndicationMessage( 520 INDICATION_TYPE_BIOMETRIC_MESSAGE, 521 mContext.getString(R.string.keyguard_indication_trust_unlocked)); 522 verifyIndicationMessage( 523 INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP, 524 mContext.getString(R.string.keyguard_unlock)); 525 } 526 527 @Test onBiometricHelp_coEx_fpFailure_trustAgentUnlocked_emptyTrustGrantedMessage()528 public void onBiometricHelp_coEx_fpFailure_trustAgentUnlocked_emptyTrustGrantedMessage() { 529 createController(); 530 531 // GIVEN trust agent has already unlocked the device & trust granted message is empty 532 when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(true); 533 mController.showTrustGrantedMessage(false, ""); 534 535 String message = "A message"; 536 mController.setVisible(true); 537 538 // WHEN there's a fingerprint not recognized message 539 mController.getKeyguardCallback().onBiometricHelp( 540 BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED, 541 message, 542 BiometricSourceType.FINGERPRINT); 543 544 // THEN show action to unlock (ie: 'Swipe up to open') 545 verifyNoMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE); 546 verifyIndicationMessage( 547 INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP, 548 mContext.getString(R.string.keyguard_unlock)); 549 } 550 551 @Test transientIndication_visibleWhenDozing_unlessSwipeUp_fromError()552 public void transientIndication_visibleWhenDozing_unlessSwipeUp_fromError() { 553 createController(); 554 String message = mContext.getString(R.string.keyguard_unlock); 555 556 mController.setVisible(true); 557 mController.getKeyguardCallback().onBiometricError(FACE_ERROR_TIMEOUT, 558 "A message", BiometricSourceType.FACE); 559 560 verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, message); 561 mStatusBarStateListener.onDozingChanged(true); 562 563 assertThat(mTextView.getText()).isNotEqualTo(message); 564 } 565 566 @Test transientIndication_visibleWhenDozing_ignoresFingerprintErrorMsg()567 public void transientIndication_visibleWhenDozing_ignoresFingerprintErrorMsg() { 568 createController(); 569 mController.setVisible(true); 570 reset(mRotateTextViewController); 571 572 // WHEN a fingerprint error user cancelled message is received 573 mController.getKeyguardCallback().onBiometricError( 574 BiometricFingerprintConstants.FINGERPRINT_ERROR_USER_CANCELED, "foo", 575 BiometricSourceType.FINGERPRINT); 576 577 // THEN no message is shown 578 verifyNoMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE); 579 verifyNoMessage(INDICATION_TYPE_TRANSIENT); 580 } 581 582 @Test transientIndication_swipeUpToRetry()583 public void transientIndication_swipeUpToRetry() { 584 createController(); 585 String message = mContext.getString(R.string.keyguard_retry); 586 when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(true); 587 when(mKeyguardUpdateMonitor.isFaceEnrolled()).thenReturn(true); 588 when(mKeyguardUpdateMonitor.getIsFaceAuthenticated()).thenReturn(false); 589 590 mController.setVisible(true); 591 mController.getKeyguardCallback().onBiometricError(FACE_ERROR_TIMEOUT, 592 "A message", BiometricSourceType.FACE); 593 594 verify(mStatusBarKeyguardViewManager).setKeyguardMessage(eq(message), any()); 595 } 596 597 @Test transientIndication_swipeUpToRetry_faceAuthenticated()598 public void transientIndication_swipeUpToRetry_faceAuthenticated() { 599 createController(); 600 String message = mContext.getString(R.string.keyguard_retry); 601 when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(true); 602 when(mKeyguardUpdateMonitor.getIsFaceAuthenticated()).thenReturn(true); 603 when(mKeyguardUpdateMonitor.isFaceEnrolled()).thenReturn(true); 604 605 mController.setVisible(true); 606 mController.getKeyguardCallback().onBiometricError(FACE_ERROR_TIMEOUT, 607 "A message", BiometricSourceType.FACE); 608 609 verify(mStatusBarKeyguardViewManager, never()).setKeyguardMessage(eq(message), any()); 610 } 611 612 @Test faceErrorTimeout_whenFingerprintEnrolled_doesNotShowMessage()613 public void faceErrorTimeout_whenFingerprintEnrolled_doesNotShowMessage() { 614 createController(); 615 fingerprintUnlockIsPossibleAndAllowed(); 616 String message = "A message"; 617 618 mController.setVisible(true); 619 mController.getKeyguardCallback().onBiometricError( 620 FACE_ERROR_TIMEOUT, message, BiometricSourceType.FACE); 621 verifyNoMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE); 622 } 623 624 @Test sendFaceHelpMessages_fingerprintEnrolled()625 public void sendFaceHelpMessages_fingerprintEnrolled() { 626 createController(); 627 628 // GIVEN unlocking with fingerprint is possible and allowed 629 fingerprintUnlockIsPossibleAndAllowed(); 630 631 // WHEN help messages received that are allowed to show 632 final String helpString = "helpString"; 633 final int[] msgIds = new int[]{ 634 BiometricFaceConstants.FACE_ACQUIRED_MOUTH_COVERING_DETECTED, 635 BiometricFaceConstants.FACE_ACQUIRED_DARK_GLASSES_DETECTED 636 }; 637 Set<CharSequence> messages = new HashSet<>(); 638 for (int msgId : msgIds) { 639 final String message = helpString + msgId; 640 messages.add(message); 641 mKeyguardUpdateMonitorCallback.onBiometricHelp( 642 msgId, message, BiometricSourceType.FACE); 643 } 644 645 // THEN FACE_ACQUIRED_MOUTH_COVERING_DETECTED and DARK_GLASSES help messages shown 646 verifyIndicationMessages(INDICATION_TYPE_BIOMETRIC_MESSAGE, 647 messages); 648 } 649 650 @Test doNotSendMostFaceHelpMessages_fingerprintEnrolled()651 public void doNotSendMostFaceHelpMessages_fingerprintEnrolled() { 652 createController(); 653 654 // GIVEN unlocking with fingerprint is possible and allowed 655 fingerprintUnlockIsPossibleAndAllowed(); 656 657 // WHEN help messages received that aren't supposed to show 658 final String helpString = "helpString"; 659 final int[] msgIds = new int[]{ 660 BiometricFaceConstants.FACE_ACQUIRED_FACE_OBSCURED, 661 BiometricFaceConstants.FACE_ACQUIRED_TOO_RIGHT, 662 BiometricFaceConstants.FACE_ACQUIRED_TOO_LEFT, 663 BiometricFaceConstants.FACE_ACQUIRED_TOO_HIGH, 664 BiometricFaceConstants.FACE_ACQUIRED_TOO_LOW, 665 BiometricFaceConstants.FACE_ACQUIRED_TOO_BRIGHT 666 }; 667 for (int msgId : msgIds) { 668 mKeyguardUpdateMonitorCallback.onBiometricHelp( 669 msgId, helpString + msgId, BiometricSourceType.FACE); 670 } 671 672 // THEN no messages shown 673 verifyNoMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE); 674 } 675 676 @Test sendAllFaceHelpMessages_fingerprintNotEnrolled()677 public void sendAllFaceHelpMessages_fingerprintNotEnrolled() { 678 createController(); 679 680 // GIVEN fingerprint NOT possible 681 fingerprintUnlockIsNotPossible(); 682 683 // WHEN help messages received 684 final Set<CharSequence> helpStrings = new HashSet<>(); 685 final String helpString = "helpString"; 686 final int[] msgIds = new int[]{ 687 BiometricFaceConstants.FACE_ACQUIRED_FACE_OBSCURED, 688 BiometricFaceConstants.FACE_ACQUIRED_DARK_GLASSES_DETECTED, 689 BiometricFaceConstants.FACE_ACQUIRED_TOO_RIGHT, 690 BiometricFaceConstants.FACE_ACQUIRED_TOO_LEFT, 691 BiometricFaceConstants.FACE_ACQUIRED_TOO_HIGH, 692 BiometricFaceConstants.FACE_ACQUIRED_TOO_LOW, 693 BiometricFaceConstants.FACE_ACQUIRED_TOO_BRIGHT 694 }; 695 for (int msgId : msgIds) { 696 final String numberedHelpString = helpString + msgId; 697 mKeyguardUpdateMonitorCallback.onBiometricHelp( 698 msgId, numberedHelpString, BiometricSourceType.FACE); 699 helpStrings.add(numberedHelpString); 700 } 701 702 // THEN message shown for each call 703 verifyIndicationMessages(INDICATION_TYPE_BIOMETRIC_MESSAGE, helpStrings); 704 } 705 706 @Test sendTooDarkFaceHelpMessages_onTimeout_noFpEnrolled()707 public void sendTooDarkFaceHelpMessages_onTimeout_noFpEnrolled() { 708 createController(); 709 710 // GIVEN fingerprint not possible 711 fingerprintUnlockIsNotPossible(); 712 713 // WHEN help message received and deferred message is valid 714 final String helpString = "helpMsg"; 715 when(mFaceHelpMessageDeferral.getDeferredMessage()).thenReturn(helpString); 716 when(mFaceHelpMessageDeferral.shouldDefer(FACE_ACQUIRED_TOO_DARK)).thenReturn(true); 717 mKeyguardUpdateMonitorCallback.onBiometricHelp( 718 BiometricFaceConstants.FACE_ACQUIRED_TOO_DARK, 719 helpString, 720 BiometricSourceType.FACE 721 ); 722 723 // THEN help message not shown yet 724 verifyNoMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE); 725 726 // WHEN face timeout error received 727 mKeyguardUpdateMonitorCallback.onBiometricError(FACE_ERROR_TIMEOUT, "face timeout", 728 BiometricSourceType.FACE); 729 730 // THEN the low light message shows with suggestion to swipe up to unlock 731 verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, helpString); 732 verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP, 733 mContext.getString(R.string.keyguard_unlock)); 734 } 735 736 @Test sendTooDarkFaceHelpMessages_onTimeout_fingerprintEnrolled()737 public void sendTooDarkFaceHelpMessages_onTimeout_fingerprintEnrolled() { 738 createController(); 739 740 // GIVEN unlocking with fingerprint is possible and allowed 741 fingerprintUnlockIsPossibleAndAllowed(); 742 743 // WHEN help message received and deferredMessage is valid 744 final String helpString = "helpMsg"; 745 when(mFaceHelpMessageDeferral.getDeferredMessage()).thenReturn(helpString); 746 when(mFaceHelpMessageDeferral.shouldDefer(FACE_ACQUIRED_TOO_DARK)).thenReturn(true); 747 mKeyguardUpdateMonitorCallback.onBiometricHelp( 748 BiometricFaceConstants.FACE_ACQUIRED_TOO_DARK, 749 helpString, 750 BiometricSourceType.FACE 751 ); 752 753 // THEN help message not shown yet 754 verifyNoMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE); 755 756 // WHEN face timeout error received 757 mKeyguardUpdateMonitorCallback.onBiometricError(FACE_ERROR_TIMEOUT, "face timeout", 758 BiometricSourceType.FACE); 759 760 // THEN the low light message shows and suggests trying fingerprint 761 verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, helpString); 762 verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP, 763 mContext.getString(R.string.keyguard_suggest_fingerprint)); 764 } 765 766 @Test onRefreshBatteryInfo_computesChargingTime()767 public void onRefreshBatteryInfo_computesChargingTime() throws RemoteException { 768 createController(); 769 BatteryStatus status = new BatteryStatus(BatteryManager.BATTERY_STATUS_CHARGING, 770 80 /* level */, BatteryManager.BATTERY_PLUGGED_WIRELESS, 100 /* health */, 771 0 /* maxChargingWattage */, true /* present */); 772 773 mController.getKeyguardCallback().onRefreshBatteryInfo(status); 774 verify(mIBatteryStats).computeChargeTimeRemaining(); 775 } 776 777 @Test onRefreshBatteryInfo_computesChargingTime_onlyWhenCharging()778 public void onRefreshBatteryInfo_computesChargingTime_onlyWhenCharging() 779 throws RemoteException { 780 createController(); 781 BatteryStatus status = new BatteryStatus(BatteryManager.BATTERY_STATUS_CHARGING, 782 80 /* level */, 0 /* plugged */, 100 /* health */, 783 0 /* maxChargingWattage */, true /* present */); 784 785 mController.getKeyguardCallback().onRefreshBatteryInfo(status); 786 verify(mIBatteryStats, never()).computeChargeTimeRemaining(); 787 } 788 789 /** 790 * Regression test. 791 * We should not make calls to the system_process when updating the doze state. 792 */ 793 @Test setDozing_noIBatteryCalls()794 public void setDozing_noIBatteryCalls() throws RemoteException { 795 createController(); 796 mController.setVisible(true); 797 mStatusBarStateListener.onDozingChanged(true); 798 mStatusBarStateListener.onDozingChanged(false); 799 verify(mIBatteryStats, never()).computeChargeTimeRemaining(); 800 } 801 802 @Test registersKeyguardStateCallback()803 public void registersKeyguardStateCallback() { 804 createController(); 805 verify(mKeyguardStateController).addCallback(any()); 806 } 807 808 @Test unlockMethodCache_listenerUpdatesPluggedIndication()809 public void unlockMethodCache_listenerUpdatesPluggedIndication() { 810 createController(); 811 when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(true); 812 mController.setPowerPluggedIn(true); 813 mController.setVisible(true); 814 815 verifyIndicationMessage( 816 INDICATION_TYPE_TRUST, 817 mContext.getString(R.string.keyguard_indication_trust_unlocked)); 818 } 819 820 @Test onRefreshBatteryInfo_chargingWithLongLife_presentChargingLimited()821 public void onRefreshBatteryInfo_chargingWithLongLife_presentChargingLimited() { 822 createController(); 823 BatteryStatus status = new BatteryStatus(BatteryManager.BATTERY_STATUS_CHARGING, 824 80 /* level */, BatteryManager.BATTERY_PLUGGED_AC, 825 BatteryManager.CHARGING_POLICY_ADAPTIVE_LONGLIFE, 0 /* maxChargingWattage */, 826 true /* present */); 827 828 mController.getKeyguardCallback().onRefreshBatteryInfo(status); 829 mController.setVisible(true); 830 831 verifyIndicationMessage( 832 INDICATION_TYPE_BATTERY, 833 mContext.getString( 834 R.string.keyguard_plugged_in_charging_limited, 835 NumberFormat.getPercentInstance().format(80 / 100f))); 836 } 837 838 @Test onRefreshBatteryInfo_fullChargedWithLongLife_presentChargingLimited()839 public void onRefreshBatteryInfo_fullChargedWithLongLife_presentChargingLimited() { 840 createController(); 841 BatteryStatus status = new BatteryStatus(BatteryManager.BATTERY_STATUS_CHARGING, 842 100 /* level */, BatteryManager.BATTERY_PLUGGED_AC, 843 BatteryManager.CHARGING_POLICY_ADAPTIVE_LONGLIFE, 0 /* maxChargingWattage */, 844 true /* present */); 845 846 mController.getKeyguardCallback().onRefreshBatteryInfo(status); 847 mController.setVisible(true); 848 849 verifyIndicationMessage( 850 INDICATION_TYPE_BATTERY, 851 mContext.getString( 852 R.string.keyguard_plugged_in_charging_limited, 853 NumberFormat.getPercentInstance().format(100 / 100f))); 854 } 855 856 @Test onRefreshBatteryInfo_fullChargedWithoutLongLife_presentCharged()857 public void onRefreshBatteryInfo_fullChargedWithoutLongLife_presentCharged() { 858 createController(); 859 BatteryStatus status = new BatteryStatus(BatteryManager.BATTERY_STATUS_CHARGING, 860 100 /* level */, BatteryManager.BATTERY_PLUGGED_AC, 861 BatteryManager.CHARGING_POLICY_DEFAULT, 0 /* maxChargingWattage */, 862 true /* present */); 863 864 mController.getKeyguardCallback().onRefreshBatteryInfo(status); 865 mController.setVisible(true); 866 867 verifyIndicationMessage( 868 INDICATION_TYPE_BATTERY, 869 mContext.getString(R.string.keyguard_charged)); 870 } 871 872 @Test onRefreshBatteryInfo_dozing_dischargingWithLongLife_presentBatteryPercentage()873 public void onRefreshBatteryInfo_dozing_dischargingWithLongLife_presentBatteryPercentage() { 874 createController(); 875 mController.setVisible(true); 876 BatteryStatus status = new BatteryStatus(BatteryManager.BATTERY_STATUS_DISCHARGING, 877 90 /* level */, 0 /* plugged */, BatteryManager.CHARGING_POLICY_ADAPTIVE_LONGLIFE, 878 0 /* maxChargingWattage */, true /* present */); 879 880 mController.getKeyguardCallback().onRefreshBatteryInfo(status); 881 mStatusBarStateListener.onDozingChanged(true); 882 883 String percentage = NumberFormat.getPercentInstance().format(90 / 100f); 884 assertThat(mTextView.getText()).isEqualTo(percentage); 885 } 886 887 @Test onRequireUnlockForNfc_showsRequireUnlockForNfcIndication()888 public void onRequireUnlockForNfc_showsRequireUnlockForNfcIndication() { 889 createController(); 890 mController.setVisible(true); 891 String message = mContext.getString(R.string.require_unlock_for_nfc); 892 mController.getKeyguardCallback().onRequireUnlockForNfc(); 893 894 verifyTransientMessage(message); 895 } 896 897 @Test testEmptyOwnerInfoHidesIndicationArea()898 public void testEmptyOwnerInfoHidesIndicationArea() { 899 createController(); 900 901 // GIVEN the owner info is set to an empty string & keyguard is showing 902 when(mKeyguardStateController.isShowing()).thenReturn(true); 903 when(mLockPatternUtils.getDeviceOwnerInfo()).thenReturn(""); 904 905 // WHEN asked to update the indication area 906 mController.setVisible(true); 907 mExecutor.runAllReady(); 908 909 // THEN the owner info should be hidden 910 verifyHideIndication(INDICATION_TYPE_OWNER_INFO); 911 } 912 913 @Test testOnKeyguardShowingChanged_notShowing_resetsMessages()914 public void testOnKeyguardShowingChanged_notShowing_resetsMessages() { 915 createController(); 916 917 // GIVEN keyguard isn't showing 918 when(mKeyguardStateController.isShowing()).thenReturn(false); 919 920 // WHEN keyguard showing changed called 921 mKeyguardStateControllerCallback.onKeyguardShowingChanged(); 922 923 // THEN messages are reset 924 verify(mRotateTextViewController).clearMessages(); 925 assertThat(mTextView.getText()).isEqualTo(""); 926 } 927 928 @Test testOnKeyguardShowingChanged_showing_updatesPersistentMessages()929 public void testOnKeyguardShowingChanged_showing_updatesPersistentMessages() { 930 createController(); 931 mController.setVisible(true); 932 mExecutor.runAllReady(); 933 reset(mRotateTextViewController); 934 935 // GIVEN keyguard is showing and not dozing 936 when(mKeyguardStateController.isShowing()).thenReturn(true); 937 mController.setVisible(true); 938 mExecutor.runAllReady(); 939 reset(mRotateTextViewController); 940 941 // WHEN keyguard showing changed called 942 mKeyguardStateControllerCallback.onKeyguardShowingChanged(); 943 mExecutor.runAllReady(); 944 945 // THEN persistent messages are updated (in this case, most messages are hidden since 946 // no info is provided) - verify that this happens 947 verify(mRotateTextViewController).hideIndication(INDICATION_TYPE_DISCLOSURE); 948 verify(mRotateTextViewController).hideIndication(INDICATION_TYPE_OWNER_INFO); 949 verify(mRotateTextViewController).hideIndication(INDICATION_TYPE_BATTERY); 950 verify(mRotateTextViewController).hideIndication(INDICATION_TYPE_TRUST); 951 verify(mRotateTextViewController).hideIndication(INDICATION_TYPE_ALIGNMENT); 952 verify(mRotateTextViewController).hideIndication(INDICATION_TYPE_LOGOUT); 953 } 954 955 @Test onTrustGrantedMessageDoesNotShowUntilTrustGranted()956 public void onTrustGrantedMessageDoesNotShowUntilTrustGranted() { 957 createController(); 958 mController.setVisible(true); 959 reset(mRotateTextViewController); 960 961 // GIVEN a trust granted message but trust isn't granted 962 final String trustGrantedMsg = "testing trust granted message"; 963 mController.getKeyguardCallback().onTrustGrantedForCurrentUser( 964 false, false, new TrustGrantFlags(0), trustGrantedMsg); 965 966 verifyHideIndication(INDICATION_TYPE_TRUST); 967 968 // WHEN trust is granted 969 when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(true); 970 mKeyguardUpdateMonitorCallback.onTrustChanged(getCurrentUser()); 971 972 // THEN verify the trust granted message shows 973 verifyIndicationMessage( 974 INDICATION_TYPE_TRUST, 975 trustGrantedMsg); 976 } 977 978 @Test onTrustGrantedMessageShowsOnTrustGranted()979 public void onTrustGrantedMessageShowsOnTrustGranted() { 980 createController(); 981 mController.setVisible(true); 982 983 // GIVEN trust is granted 984 when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(true); 985 986 // WHEN the showTrustGranted method is called 987 final String trustGrantedMsg = "testing trust granted message"; 988 mController.getKeyguardCallback().onTrustGrantedForCurrentUser( 989 false, false, new TrustGrantFlags(0), trustGrantedMsg); 990 991 // THEN verify the trust granted message shows 992 verifyIndicationMessage( 993 INDICATION_TYPE_TRUST, 994 trustGrantedMsg); 995 } 996 997 @Test onTrustGrantedMessage_nullMessage_showsDefaultMessage()998 public void onTrustGrantedMessage_nullMessage_showsDefaultMessage() { 999 createController(); 1000 mController.setVisible(true); 1001 1002 // GIVEN trust is granted 1003 when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(true); 1004 1005 // WHEN the showTrustGranted method is called with a null message 1006 mController.getKeyguardCallback().onTrustGrantedForCurrentUser( 1007 false, false, new TrustGrantFlags(0), null); 1008 1009 // THEN verify the default trust granted message shows 1010 verifyIndicationMessage( 1011 INDICATION_TYPE_TRUST, 1012 getContext().getString(R.string.keyguard_indication_trust_unlocked)); 1013 } 1014 1015 @Test onTrustGrantedMessage_emptyString_showsNoMessage()1016 public void onTrustGrantedMessage_emptyString_showsNoMessage() { 1017 createController(); 1018 mController.setVisible(true); 1019 1020 // GIVEN trust is granted 1021 when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(true); 1022 1023 // WHEN the showTrustGranted method is called with an EMPTY string 1024 mController.getKeyguardCallback().onTrustGrantedForCurrentUser( 1025 false, false, new TrustGrantFlags(0), ""); 1026 1027 // THEN verify NO trust message is shown 1028 verifyNoMessage(INDICATION_TYPE_TRUST); 1029 } 1030 1031 @Test coEx_faceSuccess_showsPressToOpen()1032 public void coEx_faceSuccess_showsPressToOpen() { 1033 // GIVEN bouncer isn't showing, can skip bouncer, udfps is supported, no a11y enabled 1034 when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false); 1035 when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(getCurrentUser())) 1036 .thenReturn(true); 1037 when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true); 1038 when(mAccessibilityManager.isEnabled()).thenReturn(false); 1039 when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(false); 1040 createController(); 1041 mController.setVisible(true); 1042 1043 // WHEN face auth succeeds 1044 when(mKeyguardUpdateMonitor.getIsFaceAuthenticated()).thenReturn(true); 1045 mController.getKeyguardCallback().onBiometricAuthenticated(0, 1046 BiometricSourceType.FACE, false); 1047 1048 // THEN 'face unlocked' then 'press unlock icon to open' message show 1049 String unlockedByFace = mContext.getString(R.string.keyguard_face_successful_unlock); 1050 verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, unlockedByFace); 1051 String pressToOpen = mContext.getString(R.string.keyguard_unlock_press); 1052 verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP, pressToOpen); 1053 } 1054 1055 @Test coEx_faceSuccess_touchExplorationEnabled_showsFaceUnlockedSwipeToOpen()1056 public void coEx_faceSuccess_touchExplorationEnabled_showsFaceUnlockedSwipeToOpen() { 1057 // GIVEN bouncer isn't showing, can skip bouncer, udfps is supported, a11y enabled 1058 when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false); 1059 when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(getCurrentUser())) 1060 .thenReturn(true); 1061 when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true); 1062 when(mAccessibilityManager.isEnabled()).thenReturn(true); 1063 when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true); 1064 createController(); 1065 mController.setVisible(true); 1066 1067 // WHEN face authenticated 1068 when(mKeyguardUpdateMonitor.getIsFaceAuthenticated()).thenReturn(true); 1069 mController.getKeyguardCallback().onBiometricAuthenticated(0, 1070 BiometricSourceType.FACE, false); 1071 1072 // THEN show 'face unlocked' and 'swipe up to open' messages 1073 String unlockedByFace = mContext.getString(R.string.keyguard_face_successful_unlock); 1074 verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, unlockedByFace); 1075 String swipeUpToOpen = mContext.getString(R.string.keyguard_unlock); 1076 verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP, swipeUpToOpen); 1077 } 1078 1079 @Test coEx_faceSuccess_a11yEnabled_showsFaceUnlockedSwipeToOpen()1080 public void coEx_faceSuccess_a11yEnabled_showsFaceUnlockedSwipeToOpen() { 1081 // GIVEN bouncer isn't showing, can skip bouncer, udfps is supported, a11y is enabled 1082 when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false); 1083 when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(getCurrentUser())) 1084 .thenReturn(true); 1085 when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true); 1086 when(mAccessibilityManager.isEnabled()).thenReturn(true); 1087 createController(); 1088 mController.setVisible(true); 1089 1090 // WHEN face auth is successful 1091 when(mKeyguardUpdateMonitor.getIsFaceAuthenticated()).thenReturn(true); 1092 mController.getKeyguardCallback().onBiometricAuthenticated(0, 1093 BiometricSourceType.FACE, false); 1094 1095 // THEN show 'face unlocked' and 'swipe up to open' messages 1096 String unlockedByFace = mContext.getString(R.string.keyguard_face_successful_unlock); 1097 verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, unlockedByFace); 1098 String swipeUpToOpen = mContext.getString(R.string.keyguard_unlock); 1099 verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP, swipeUpToOpen); 1100 } 1101 1102 @Test faceOnly_faceSuccess_showsFaceUnlockedSwipeToOpen()1103 public void faceOnly_faceSuccess_showsFaceUnlockedSwipeToOpen() { 1104 // GIVEN bouncer isn't showing, can skip bouncer, no udfps supported 1105 when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false); 1106 when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(getCurrentUser())) 1107 .thenReturn(true); 1108 when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(false); 1109 createController(); 1110 mController.setVisible(true); 1111 1112 // WHEN face auth is successful 1113 when(mKeyguardUpdateMonitor.getIsFaceAuthenticated()).thenReturn(true); 1114 mController.getKeyguardCallback().onBiometricAuthenticated(0, 1115 BiometricSourceType.FACE, false); 1116 1117 // THEN show 'face unlocked' and 'swipe up to open' messages 1118 String unlockedByFace = mContext.getString(R.string.keyguard_face_successful_unlock); 1119 verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, unlockedByFace); 1120 String swipeUpToOpen = mContext.getString(R.string.keyguard_unlock); 1121 verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP, swipeUpToOpen); 1122 } 1123 1124 @Test udfpsOnly_a11yEnabled_showsSwipeToOpen()1125 public void udfpsOnly_a11yEnabled_showsSwipeToOpen() { 1126 // GIVEN bouncer isn't showing, can skip bouncer, udfps is supported, a11y is enabled 1127 when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false); 1128 when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(getCurrentUser())) 1129 .thenReturn(true); 1130 when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true); 1131 when(mAccessibilityManager.isEnabled()).thenReturn(true); 1132 when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true); 1133 createController(); 1134 mController.setVisible(true); 1135 1136 // WHEN showActionToUnlock 1137 mController.showActionToUnlock(); 1138 1139 // THEN show 'swipe up to open' message 1140 String swipeToOpen = mContext.getString(R.string.keyguard_unlock); 1141 verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, swipeToOpen); 1142 } 1143 1144 @Test udfpsOnly_showsPressToOpen()1145 public void udfpsOnly_showsPressToOpen() { 1146 // GIVEN bouncer isn't showing, udfps is supported, a11y is NOT enabled, can skip bouncer 1147 when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false); 1148 when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(getCurrentUser())) 1149 .thenReturn(true); 1150 when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true); 1151 when(mAccessibilityManager.isEnabled()).thenReturn(false); 1152 when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(false); 1153 createController(); 1154 mController.setVisible(true); 1155 1156 // WHEN showActionToUnlock 1157 mController.showActionToUnlock(); 1158 1159 // THEN show 'press unlock icon to open' message 1160 String pressToOpen = mContext.getString(R.string.keyguard_unlock_press); 1161 verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, pressToOpen); 1162 } 1163 1164 @Test canSkipBouncer_noSecurity_showSwipeToUnlockHint()1165 public void canSkipBouncer_noSecurity_showSwipeToUnlockHint() { 1166 // GIVEN bouncer isn't showing, can skip bouncer, no security (udfps isn't supported, 1167 // face wasn't authenticated) 1168 when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false); 1169 when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(getCurrentUser())) 1170 .thenReturn(true); 1171 when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(false); 1172 createController(); 1173 mController.setVisible(true); 1174 1175 // WHEN showActionToUnlock 1176 mController.showActionToUnlock(); 1177 1178 // THEN show 'swipe up to open' message 1179 String swipeToOpen = mContext.getString(R.string.keyguard_unlock); 1180 verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, swipeToOpen); 1181 } 1182 1183 @Test cannotSkipBouncer_showSwipeToUnlockHint()1184 public void cannotSkipBouncer_showSwipeToUnlockHint() { 1185 // GIVEN bouncer isn't showing and cannot skip bouncer 1186 when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false); 1187 when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(getCurrentUser())) 1188 .thenReturn(false); 1189 createController(); 1190 mController.setVisible(true); 1191 1192 // WHEN showActionToUnlock 1193 mController.showActionToUnlock(); 1194 1195 // THEN show 'swipe up to open' message 1196 String swipeToOpen = mContext.getString(R.string.keyguard_unlock); 1197 verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, swipeToOpen); 1198 } 1199 1200 @Test faceOnAcquired_processFrame()1201 public void faceOnAcquired_processFrame() { 1202 createController(); 1203 1204 // WHEN face sends an acquired message 1205 final int acquireInfo = 1; 1206 mKeyguardUpdateMonitorCallback.onBiometricAcquired(BiometricSourceType.FACE, acquireInfo); 1207 1208 // THEN face help message deferral should process the acquired frame 1209 verify(mFaceHelpMessageDeferral).processFrame(acquireInfo); 1210 } 1211 1212 @Test fingerprintOnAcquired_noProcessFrame()1213 public void fingerprintOnAcquired_noProcessFrame() { 1214 createController(); 1215 1216 // WHEN fingerprint sends an acquired message 1217 mKeyguardUpdateMonitorCallback.onBiometricAcquired(BiometricSourceType.FINGERPRINT, 1); 1218 1219 // THEN face help message deferral should NOT process any acquired frames 1220 verify(mFaceHelpMessageDeferral, never()).processFrame(anyInt()); 1221 } 1222 1223 @Test onBiometricHelp_fingerprint_faceHelpMessageDeferralDoesNothing()1224 public void onBiometricHelp_fingerprint_faceHelpMessageDeferralDoesNothing() { 1225 createController(); 1226 1227 // WHEN fingerprint sends an onBiometricHelp 1228 mKeyguardUpdateMonitorCallback.onBiometricHelp( 1229 1, 1230 "placeholder", 1231 BiometricSourceType.FINGERPRINT); 1232 1233 // THEN face help message deferral is NOT: reset, updated, or checked for shouldDefer 1234 verify(mFaceHelpMessageDeferral, never()).reset(); 1235 verify(mFaceHelpMessageDeferral, never()).updateMessage(anyInt(), anyString()); 1236 verify(mFaceHelpMessageDeferral, never()).shouldDefer(anyInt()); 1237 } 1238 1239 @Test onBiometricFailed_resetFaceHelpMessageDeferral()1240 public void onBiometricFailed_resetFaceHelpMessageDeferral() { 1241 createController(); 1242 1243 // WHEN face sends an onBiometricHelp BIOMETRIC_HELP_FACE_NOT_RECOGNIZED 1244 mKeyguardUpdateMonitorCallback.onBiometricAuthFailed(BiometricSourceType.FACE); 1245 1246 // THEN face help message deferral is reset 1247 verify(mFaceHelpMessageDeferral).reset(); 1248 } 1249 1250 @Test onBiometricError_resetFaceHelpMessageDeferral()1251 public void onBiometricError_resetFaceHelpMessageDeferral() { 1252 createController(); 1253 1254 // WHEN face has an error 1255 mKeyguardUpdateMonitorCallback.onBiometricError(4, "string", 1256 BiometricSourceType.FACE); 1257 1258 // THEN face help message deferral is reset 1259 verify(mFaceHelpMessageDeferral).reset(); 1260 } 1261 1262 @Test onBiometricHelp_faceAcquiredInfo_faceHelpMessageDeferral()1263 public void onBiometricHelp_faceAcquiredInfo_faceHelpMessageDeferral() { 1264 createController(); 1265 1266 // WHEN face sends an onBiometricHelp BIOMETRIC_HELP_FACE_NOT_RECOGNIZED 1267 final int msgId = 1; 1268 final String helpString = "test"; 1269 mKeyguardUpdateMonitorCallback.onBiometricHelp( 1270 msgId, 1271 "test", 1272 BiometricSourceType.FACE); 1273 1274 // THEN face help message deferral is NOT reset and message IS updated 1275 verify(mFaceHelpMessageDeferral, never()).reset(); 1276 verify(mFaceHelpMessageDeferral).updateMessage(msgId, helpString); 1277 } 1278 1279 1280 @Test onBiometricError_faceLockedOutFirstTime_showsThePassedInMessage()1281 public void onBiometricError_faceLockedOutFirstTime_showsThePassedInMessage() { 1282 createController(); 1283 onFaceLockoutError("first lockout"); 1284 1285 verifyIndicationShown(INDICATION_TYPE_BIOMETRIC_MESSAGE, "first lockout"); 1286 } 1287 1288 @Test onBiometricError_faceLockedOutFirstTimeAndFpAllowed_showsTheFpFollowupMessage()1289 public void onBiometricError_faceLockedOutFirstTimeAndFpAllowed_showsTheFpFollowupMessage() { 1290 createController(); 1291 fingerprintUnlockIsPossibleAndAllowed(); 1292 onFaceLockoutError("first lockout"); 1293 1294 verifyIndicationShown(INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP, 1295 mContext.getString(R.string.keyguard_suggest_fingerprint)); 1296 } 1297 1298 @Test onBiometricError_faceLockedOutFirstTimeAndFpNotAllowed_showsDefaultFollowup()1299 public void onBiometricError_faceLockedOutFirstTimeAndFpNotAllowed_showsDefaultFollowup() { 1300 createController(); 1301 fingerprintUnlockIsNotPossible(); 1302 onFaceLockoutError("first lockout"); 1303 1304 verifyIndicationShown(INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP, 1305 mContext.getString(R.string.keyguard_unlock)); 1306 } 1307 1308 @Test onBiometricError_faceLockedOutSecondTimeInSession_showsUnavailableMessage()1309 public void onBiometricError_faceLockedOutSecondTimeInSession_showsUnavailableMessage() { 1310 createController(); 1311 onFaceLockoutError("first lockout"); 1312 clearInvocations(mRotateTextViewController); 1313 1314 onFaceLockoutError("second lockout"); 1315 1316 verifyIndicationShown(INDICATION_TYPE_BIOMETRIC_MESSAGE, 1317 mContext.getString(R.string.keyguard_face_unlock_unavailable)); 1318 } 1319 1320 @Test onBiometricError_faceLockedOutSecondTimeOnBouncer_showsUnavailableMessage()1321 public void onBiometricError_faceLockedOutSecondTimeOnBouncer_showsUnavailableMessage() { 1322 createController(); 1323 onFaceLockoutError("first lockout"); 1324 clearInvocations(mRotateTextViewController); 1325 when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(true); 1326 1327 onFaceLockoutError("second lockout"); 1328 1329 verify(mStatusBarKeyguardViewManager) 1330 .setKeyguardMessage( 1331 eq(mContext.getString(R.string.keyguard_face_unlock_unavailable)), 1332 any()); 1333 } 1334 1335 @Test onBiometricError_faceLockedOutSecondTimeButUdfpsActive_showsNoMessage()1336 public void onBiometricError_faceLockedOutSecondTimeButUdfpsActive_showsNoMessage() { 1337 createController(); 1338 onFaceLockoutError("first lockout"); 1339 clearInvocations(mRotateTextViewController); 1340 1341 when(mAuthController.isUdfpsFingerDown()).thenReturn(true); 1342 onFaceLockoutError("second lockout"); 1343 1344 verifyNoMoreInteractions(mRotateTextViewController); 1345 } 1346 1347 @Test onBiometricError_faceLockedOutAgainAndFpAllowed_showsTheFpFollowupMessage()1348 public void onBiometricError_faceLockedOutAgainAndFpAllowed_showsTheFpFollowupMessage() { 1349 createController(); 1350 fingerprintUnlockIsPossibleAndAllowed(); 1351 onFaceLockoutError("first lockout"); 1352 clearInvocations(mRotateTextViewController); 1353 1354 onFaceLockoutError("second lockout"); 1355 1356 verifyIndicationShown(INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP, 1357 mContext.getString(R.string.keyguard_suggest_fingerprint)); 1358 } 1359 1360 @Test onBiometricError_faceLockedOutAgainAndFpNotAllowed_showsDefaultFollowup()1361 public void onBiometricError_faceLockedOutAgainAndFpNotAllowed_showsDefaultFollowup() { 1362 createController(); 1363 fingerprintUnlockIsNotPossible(); 1364 onFaceLockoutError("first lockout"); 1365 clearInvocations(mRotateTextViewController); 1366 1367 onFaceLockoutError("second lockout"); 1368 1369 verifyIndicationShown(INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP, 1370 mContext.getString(R.string.keyguard_unlock)); 1371 } 1372 1373 @Test onBiometricError_whenFaceLockoutReset_onLockOutError_showsPassedInMessage()1374 public void onBiometricError_whenFaceLockoutReset_onLockOutError_showsPassedInMessage() { 1375 createController(); 1376 onFaceLockoutError("first lockout"); 1377 clearInvocations(mRotateTextViewController); 1378 when(mKeyguardUpdateMonitor.isFaceLockedOut()).thenReturn(false); 1379 mKeyguardUpdateMonitorCallback.onLockedOutStateChanged(BiometricSourceType.FACE); 1380 1381 onFaceLockoutError("second lockout"); 1382 1383 verifyIndicationShown(INDICATION_TYPE_BIOMETRIC_MESSAGE, "second lockout"); 1384 } 1385 1386 @Test onFpLockoutStateChanged_whenFpIsLockedOut_showsPersistentMessage()1387 public void onFpLockoutStateChanged_whenFpIsLockedOut_showsPersistentMessage() { 1388 createController(); 1389 mController.setVisible(true); 1390 when(mKeyguardUpdateMonitor.isFingerprintLockedOut()).thenReturn(true); 1391 1392 mKeyguardUpdateMonitorCallback.onLockedOutStateChanged(BiometricSourceType.FINGERPRINT); 1393 1394 verifyIndicationShown(INDICATION_TYPE_PERSISTENT_UNLOCK_MESSAGE, 1395 mContext.getString(R.string.keyguard_unlock)); 1396 } 1397 1398 @Test onFpLockoutStateChanged_whenFpIsNotLockedOut_showsPersistentMessage()1399 public void onFpLockoutStateChanged_whenFpIsNotLockedOut_showsPersistentMessage() { 1400 createController(); 1401 mController.setVisible(true); 1402 clearInvocations(mRotateTextViewController); 1403 when(mKeyguardUpdateMonitor.isFingerprintLockedOut()).thenReturn(false); 1404 1405 mKeyguardUpdateMonitorCallback.onLockedOutStateChanged(BiometricSourceType.FINGERPRINT); 1406 1407 verifyHideIndication(INDICATION_TYPE_PERSISTENT_UNLOCK_MESSAGE); 1408 } 1409 1410 @Test onVisibilityChange_showsPersistentMessage_ifFpIsLockedOut()1411 public void onVisibilityChange_showsPersistentMessage_ifFpIsLockedOut() { 1412 createController(); 1413 mController.setVisible(false); 1414 when(mKeyguardUpdateMonitor.isFingerprintLockedOut()).thenReturn(true); 1415 mKeyguardUpdateMonitorCallback.onLockedOutStateChanged(BiometricSourceType.FINGERPRINT); 1416 clearInvocations(mRotateTextViewController); 1417 1418 mController.setVisible(true); 1419 1420 verifyIndicationShown(INDICATION_TYPE_PERSISTENT_UNLOCK_MESSAGE, 1421 mContext.getString(R.string.keyguard_unlock)); 1422 } 1423 1424 @Test onBiometricError_whenFaceIsLocked_onMultipleLockOutErrors_showUnavailableMessage()1425 public void onBiometricError_whenFaceIsLocked_onMultipleLockOutErrors_showUnavailableMessage() { 1426 createController(); 1427 onFaceLockoutError("first lockout"); 1428 clearInvocations(mRotateTextViewController); 1429 when(mKeyguardUpdateMonitor.isFaceLockedOut()).thenReturn(true); 1430 mKeyguardUpdateMonitorCallback.onLockedOutStateChanged(BiometricSourceType.FACE); 1431 1432 onFaceLockoutError("second lockout"); 1433 1434 verifyIndicationShown(INDICATION_TYPE_BIOMETRIC_MESSAGE, 1435 mContext.getString(R.string.keyguard_face_unlock_unavailable)); 1436 } 1437 1438 @Test onBiometricError_screenIsTurningOn_faceLockedOutFpIsNotAvailable_showsMessage()1439 public void onBiometricError_screenIsTurningOn_faceLockedOutFpIsNotAvailable_showsMessage() { 1440 createController(); 1441 screenIsTurningOn(); 1442 fingerprintUnlockIsNotPossible(); 1443 1444 onFaceLockoutError("lockout error"); 1445 verifyNoMoreInteractions(mRotateTextViewController); 1446 1447 mScreenObserver.onScreenTurnedOn(); 1448 1449 verifyIndicationShown(INDICATION_TYPE_BIOMETRIC_MESSAGE, 1450 "lockout error"); 1451 verifyIndicationShown(INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP, 1452 mContext.getString(R.string.keyguard_unlock)); 1453 } 1454 1455 @Test onBiometricError_screenIsTurningOn_faceLockedOutFpIsAvailable_showsMessage()1456 public void onBiometricError_screenIsTurningOn_faceLockedOutFpIsAvailable_showsMessage() { 1457 createController(); 1458 screenIsTurningOn(); 1459 fingerprintUnlockIsPossibleAndAllowed(); 1460 1461 onFaceLockoutError("lockout error"); 1462 verifyNoMoreInteractions(mRotateTextViewController); 1463 1464 mScreenObserver.onScreenTurnedOn(); 1465 1466 verifyIndicationShown(INDICATION_TYPE_BIOMETRIC_MESSAGE, 1467 "lockout error"); 1468 verifyIndicationShown(INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP, 1469 mContext.getString(R.string.keyguard_suggest_fingerprint)); 1470 } 1471 screenIsTurningOn()1472 private void screenIsTurningOn() { 1473 when(mScreenLifecycle.getScreenState()).thenReturn(SCREEN_TURNING_ON); 1474 } 1475 sendUpdateDisclosureBroadcast()1476 private void sendUpdateDisclosureBroadcast() { 1477 mBroadcastReceiver.onReceive(mContext, new Intent()); 1478 } 1479 verifyIndicationMessages(int type, Set<CharSequence> messages)1480 private void verifyIndicationMessages(int type, Set<CharSequence> messages) { 1481 verify(mRotateTextViewController, times(messages.size())).updateIndication(eq(type), 1482 mKeyguardIndicationCaptor.capture(), anyBoolean()); 1483 List<KeyguardIndication> kis = mKeyguardIndicationCaptor.getAllValues(); 1484 1485 for (KeyguardIndication ki : kis) { 1486 final CharSequence msg = ki.getMessage(); 1487 assertTrue(messages.contains(msg)); // check message is shown 1488 messages.remove(msg); 1489 } 1490 assertThat(messages.size()).isEqualTo(0); // check that all messages accounted for (removed) 1491 } 1492 verifyIndicationMessage(int type, String message)1493 private void verifyIndicationMessage(int type, String message) { 1494 verify(mRotateTextViewController).updateIndication(eq(type), 1495 mKeyguardIndicationCaptor.capture(), anyBoolean()); 1496 assertThat(mKeyguardIndicationCaptor.getValue().getMessage()) 1497 .isEqualTo(message); 1498 } 1499 verifyHideIndication(int type)1500 private void verifyHideIndication(int type) { 1501 if (type == INDICATION_TYPE_TRANSIENT) { 1502 verify(mRotateTextViewController).hideTransient(); 1503 verify(mRotateTextViewController, never()).showTransient(anyString()); 1504 } else { 1505 verify(mRotateTextViewController).hideIndication(type); 1506 verify(mRotateTextViewController, never()).updateIndication(eq(type), 1507 anyObject(), anyBoolean()); 1508 } 1509 } 1510 verifyTransientMessage(String message)1511 private void verifyTransientMessage(String message) { 1512 verify(mRotateTextViewController).showTransient(eq(message)); 1513 } 1514 verifyNoMessage(int type)1515 private void verifyNoMessage(int type) { 1516 if (type == INDICATION_TYPE_TRANSIENT) { 1517 verify(mRotateTextViewController, never()).showTransient(anyString()); 1518 } else { 1519 verify(mRotateTextViewController, never()).updateIndication(eq(type), 1520 anyObject(), anyBoolean()); 1521 } 1522 } 1523 verifyIndicationShown(int indicationType, String message)1524 private void verifyIndicationShown(int indicationType, String message) { 1525 verify(mRotateTextViewController) 1526 .updateIndication(eq(indicationType), 1527 mKeyguardIndicationCaptor.capture(), 1528 eq(true)); 1529 assertThat(mKeyguardIndicationCaptor.getValue().getMessage().toString()) 1530 .isEqualTo(message); 1531 } 1532 fingerprintUnlockIsNotPossible()1533 private void fingerprintUnlockIsNotPossible() { 1534 setupFingerprintUnlockPossible(false); 1535 } 1536 fingerprintUnlockIsPossibleAndAllowed()1537 private void fingerprintUnlockIsPossibleAndAllowed() { 1538 setupFingerprintUnlockPossible(true); 1539 when(mKeyguardUpdateMonitor.isUnlockingWithFingerprintAllowed()).thenReturn(true); 1540 } 1541 setupFingerprintUnlockPossible(boolean possible)1542 private void setupFingerprintUnlockPossible(boolean possible) { 1543 when(mKeyguardUpdateMonitor 1544 .getCachedIsUnlockWithFingerprintPossible(getCurrentUser())) 1545 .thenReturn(possible); 1546 } 1547 getCurrentUser()1548 private int getCurrentUser() { 1549 return mCurrentUserId; 1550 } 1551 onFaceLockoutError(String errMsg)1552 private void onFaceLockoutError(String errMsg) { 1553 mKeyguardUpdateMonitorCallback.onBiometricError(FACE_ERROR_LOCKOUT_PERMANENT, 1554 errMsg, 1555 BiometricSourceType.FACE); 1556 } 1557 } 1558