diff options
6 files changed, 301 insertions, 47 deletions
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardMessageAreaController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardMessageAreaController.java index 363dd014beb6..f528ec8af134 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardMessageAreaController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardMessageAreaController.java @@ -18,11 +18,16 @@ package com.android.keyguard; import android.content.res.ColorStateList; import android.content.res.Configuration; +import android.hardware.biometrics.BiometricSourceType; +import android.os.SystemClock; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; +import android.util.Log; +import android.util.Pair; import android.view.View; +import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import com.android.systemui.statusbar.policy.ConfigurationController; @@ -40,6 +45,16 @@ import javax.inject.Inject; public class KeyguardMessageAreaController<T extends KeyguardMessageArea> extends ViewController<T> { /** + * Pair representing: + * first - BiometricSource the currently displayed message is associated with. + * second - Timestamp the biometric message came in uptimeMillis. + * This Pair can be null if the message is not associated with a biometric. + */ + @Nullable + private Pair<BiometricSourceType, Long> mMessageBiometricSource = null; + private static final Long SKIP_SHOWING_FACE_MESSAGE_AFTER_FP_MESSAGE_MS = 3500L; + + /** * Delay before speaking an accessibility announcement. Used to prevent * lift-to-type from interrupting itself. */ @@ -149,12 +164,42 @@ public class KeyguardMessageAreaController<T extends KeyguardMessageArea> * Sets a message to the underlying text view. */ public void setMessage(CharSequence s, boolean animate) { + setMessage(s, animate, null); + } + + /** + * Sets a message to the underlying text view. + */ + public void setMessage(CharSequence s, BiometricSourceType biometricSourceType) { + setMessage(s, true, biometricSourceType); + } + + private void setMessage( + CharSequence s, + boolean animate, + BiometricSourceType biometricSourceType) { + final long uptimeMillis = SystemClock.uptimeMillis(); + if (skipShowingFaceMessage(biometricSourceType, uptimeMillis)) { + Log.d("KeyguardMessageAreaController", "Skip showing face message \"" + s + "\""); + return; + } + mMessageBiometricSource = new Pair<>(biometricSourceType, uptimeMillis); if (mView.isDisabled()) { return; } mView.setMessage(s, animate); } + private boolean skipShowingFaceMessage( + BiometricSourceType biometricSourceType, Long currentUptimeMillis + ) { + return mMessageBiometricSource != null + && biometricSourceType == BiometricSourceType.FACE + && mMessageBiometricSource.first == BiometricSourceType.FINGERPRINT + && (currentUptimeMillis - mMessageBiometricSource.second) + < SKIP_SHOWING_FACE_MESSAGE_AFTER_FP_MESSAGE_MS; + } + public void setMessage(int resId) { String message = resId != 0 ? mView.getResources().getString(resId) : null; setMessage(message); diff --git a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt index d2ad096c1207..ce4032aaea05 100644 --- a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt +++ b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardLogger.kt @@ -16,6 +16,7 @@ package com.android.keyguard.logging +import android.hardware.biometrics.BiometricSourceType import com.android.systemui.biometrics.AuthRippleController import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController import com.android.systemui.log.LogBuffer @@ -117,6 +118,26 @@ constructor( ) } + fun logDropNonFingerprintMessage( + message: CharSequence, + followUpMessage: CharSequence?, + biometricSourceType: BiometricSourceType?, + ) { + buffer.log( + KeyguardIndicationController.TAG, + LogLevel.DEBUG, + { + str1 = message.toString() + str2 = followUpMessage?.toString() + str3 = biometricSourceType?.name + }, + { + "droppingNonFingerprintMessage message=$str1 " + + "followUpMessage:$str2 biometricSourceType:$str3" + } + ) + } + fun logUpdateBatteryIndication( powerIndication: String, pluggedIn: Boolean, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java index 19fe60a60bf5..7ee3a70bc6be 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java @@ -71,6 +71,7 @@ import android.os.UserManager; import android.provider.DeviceConfig; import android.text.TextUtils; import android.text.format.Formatter; +import android.util.Pair; import android.view.View; import android.view.ViewGroup; import android.view.accessibility.AccessibilityManager; @@ -187,6 +188,7 @@ public class KeyguardIndicationController { private CharSequence mTransientIndication; private CharSequence mBiometricMessage; private CharSequence mBiometricMessageFollowUp; + private BiometricSourceType mBiometricMessageSource; protected ColorStateList mInitialTextColorState; private boolean mVisible; private boolean mOrganizationOwnedDevice; @@ -206,7 +208,7 @@ public class KeyguardIndicationController { private int mBatteryLevel; private boolean mBatteryPresent = true; private long mChargingTimeRemaining; - private String mBiometricErrorMessageToShowOnScreenOn; + private Pair<String, BiometricSourceType> mBiometricErrorMessageToShowOnScreenOn; private final Set<Integer> mCoExFaceAcquisitionMsgIdsToShow; private final FaceHelpMessageDeferral mFaceAcquiredMessageDeferral; private boolean mInited; @@ -225,15 +227,18 @@ public class KeyguardIndicationController { mIsActiveDreamLockscreenHosted = isLockscreenHosted; updateDeviceEntryIndication(false); }; - private final ScreenLifecycle.Observer mScreenObserver = - new ScreenLifecycle.Observer() { + private final ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() { @Override public void onScreenTurnedOn() { mHandler.removeMessages(MSG_RESET_ERROR_MESSAGE_ON_SCREEN_ON); if (mBiometricErrorMessageToShowOnScreenOn != null) { String followUpMessage = mFaceLockedOutThisAuthSession ? faceLockedOutFollowupMessage() : null; - showBiometricMessage(mBiometricErrorMessageToShowOnScreenOn, followUpMessage); + showBiometricMessage( + mBiometricErrorMessageToShowOnScreenOn.first, + followUpMessage, + mBiometricErrorMessageToShowOnScreenOn.second + ); // We want to keep this message around in case the screen was off hideBiometricMessageDelayed(DEFAULT_HIDE_DELAY_MS); mBiometricErrorMessageToShowOnScreenOn = null; @@ -879,8 +884,35 @@ public class KeyguardIndicationController { updateTransient(); } - private void showBiometricMessage(CharSequence biometricMessage) { - showBiometricMessage(biometricMessage, null); + private void showSuccessBiometricMessage( + CharSequence biometricMessage, + @Nullable CharSequence biometricMessageFollowUp, + BiometricSourceType biometricSourceType + ) { + showBiometricMessage(biometricMessage, biometricMessageFollowUp, biometricSourceType, true); + } + + private void showSuccessBiometricMessage(CharSequence biometricMessage, + BiometricSourceType biometricSourceType) { + showSuccessBiometricMessage(biometricMessage, null, biometricSourceType); + } + + private void showBiometricMessage(CharSequence biometricMessage, + BiometricSourceType biometricSourceType) { + showBiometricMessage(biometricMessage, null, biometricSourceType, false); + } + + private void showBiometricMessage( + CharSequence biometricMessage, + @Nullable CharSequence biometricMessageFollowUp, + BiometricSourceType biometricSourceType + ) { + showBiometricMessage( + biometricMessage, + biometricMessageFollowUp, + biometricSourceType, + false + ); } /** @@ -889,15 +921,33 @@ public class KeyguardIndicationController { * by {@link KeyguardIndicationRotateTextViewController}, see class for rotating message * logic. */ - private void showBiometricMessage(CharSequence biometricMessage, - @Nullable CharSequence biometricMessageFollowUp) { + private void showBiometricMessage( + CharSequence biometricMessage, + @Nullable CharSequence biometricMessageFollowUp, + BiometricSourceType biometricSourceType, + boolean isSuccessMessage + ) { if (TextUtils.equals(biometricMessage, mBiometricMessage) + && biometricSourceType == mBiometricMessageSource && TextUtils.equals(biometricMessageFollowUp, mBiometricMessageFollowUp)) { return; } + if (!isSuccessMessage + && mBiometricMessageSource == FINGERPRINT + && biometricSourceType != FINGERPRINT) { + // drop all non-fingerprint biometric messages if there's a fingerprint message showing + mKeyguardLogger.logDropNonFingerprintMessage( + biometricMessage, + biometricMessageFollowUp, + biometricSourceType + ); + return; + } + mBiometricMessage = biometricMessage; mBiometricMessageFollowUp = biometricMessageFollowUp; + mBiometricMessageSource = biometricSourceType; mHandler.removeMessages(MSG_SHOW_ACTION_TO_UNLOCK); hideBiometricMessageDelayed( @@ -914,6 +964,7 @@ public class KeyguardIndicationController { if (mBiometricMessage != null || mBiometricMessageFollowUp != null) { mBiometricMessage = null; mBiometricMessageFollowUp = null; + mBiometricMessageSource = null; mHideBiometricMessageHandler.cancel(); updateBiometricMessage(); } @@ -1085,7 +1136,8 @@ public class KeyguardIndicationController { } else { message = mContext.getString(R.string.keyguard_retry); } - mStatusBarKeyguardViewManager.setKeyguardMessage(message, mInitialTextColorState); + mStatusBarKeyguardViewManager.setKeyguardMessage(message, mInitialTextColorState, + null); } } else { final boolean canSkipBouncer = mKeyguardUpdateMonitor.getUserCanSkipBouncer( @@ -1097,34 +1149,40 @@ public class KeyguardIndicationController { || mAccessibilityManager.isTouchExplorationEnabled(); if (udfpsSupported && faceAuthenticated) { // co-ex if (a11yEnabled) { - showBiometricMessage( + showSuccessBiometricMessage( mContext.getString(R.string.keyguard_face_successful_unlock), - mContext.getString(R.string.keyguard_unlock) + mContext.getString(R.string.keyguard_unlock), + FACE ); } else { - showBiometricMessage( + showSuccessBiometricMessage( mContext.getString(R.string.keyguard_face_successful_unlock), - mContext.getString(R.string.keyguard_unlock_press) + mContext.getString(R.string.keyguard_unlock_press), + FACE ); } } else if (faceAuthenticated) { // face-only - showBiometricMessage( + showSuccessBiometricMessage( mContext.getString(R.string.keyguard_face_successful_unlock), - mContext.getString(R.string.keyguard_unlock) + mContext.getString(R.string.keyguard_unlock), + FACE ); } else if (udfpsSupported) { // udfps-only if (a11yEnabled) { - showBiometricMessage(mContext.getString(R.string.keyguard_unlock)); + showSuccessBiometricMessage( + mContext.getString(R.string.keyguard_unlock), + null + ); } else { - showBiometricMessage(mContext.getString( - R.string.keyguard_unlock_press)); + showSuccessBiometricMessage(mContext.getString( + R.string.keyguard_unlock_press), null); } } else { // no security or unlocked by a trust agent - showBiometricMessage(mContext.getString(R.string.keyguard_unlock)); + showSuccessBiometricMessage(mContext.getString(R.string.keyguard_unlock), null); } } else { // suggest swiping up for the primary authentication bouncer - showBiometricMessage(mContext.getString(R.string.keyguard_unlock)); + showBiometricMessage(mContext.getString(R.string.keyguard_unlock), null); } } } @@ -1245,49 +1303,55 @@ public class KeyguardIndicationController { mBouncerMessageInteractor.setFaceAcquisitionMessage(helpString); } mStatusBarKeyguardViewManager.setKeyguardMessage(helpString, - mInitialTextColorState); + mInitialTextColorState, biometricSourceType); } else if (mScreenLifecycle.getScreenState() == SCREEN_ON) { if (isCoExFaceAcquisitionMessage && msgId == FACE_ACQUIRED_TOO_DARK) { showBiometricMessage( helpString, - mContext.getString(R.string.keyguard_suggest_fingerprint) + mContext.getString(R.string.keyguard_suggest_fingerprint), + biometricSourceType ); } else if (faceAuthFailed && isUnlockWithFingerprintPossible) { showBiometricMessage( mContext.getString(R.string.keyguard_face_failed), - mContext.getString(R.string.keyguard_suggest_fingerprint) + mContext.getString(R.string.keyguard_suggest_fingerprint), + biometricSourceType ); } else if (fpAuthFailed && mKeyguardUpdateMonitor.isCurrentUserUnlockedWithFace()) { // face had already previously unlocked the device, so instead of showing a // fingerprint error, tell them they have already unlocked with face auth // and how to enter their device - showBiometricMessage( + showSuccessBiometricMessage( mContext.getString(R.string.keyguard_face_successful_unlock), - mContext.getString(R.string.keyguard_unlock) + mContext.getString(R.string.keyguard_unlock), + null ); } else if (fpAuthFailed && mKeyguardUpdateMonitor.getUserHasTrust(getCurrentUser())) { - showBiometricMessage( + showSuccessBiometricMessage( getTrustGrantedIndication(), - mContext.getString(R.string.keyguard_unlock) + mContext.getString(R.string.keyguard_unlock), + null ); } else if (faceAuthUnavailable) { showBiometricMessage( helpString, isUnlockWithFingerprintPossible ? mContext.getString(R.string.keyguard_suggest_fingerprint) - : mContext.getString(R.string.keyguard_unlock) + : mContext.getString(R.string.keyguard_unlock), + biometricSourceType ); } else { - showBiometricMessage(helpString); + showBiometricMessage(helpString, biometricSourceType); } } else if (faceAuthFailed) { // show action to unlock mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SHOW_ACTION_TO_UNLOCK), TRANSIENT_BIOMETRIC_ERROR_TIMEOUT); } else { - mBiometricErrorMessageToShowOnScreenOn = helpString; + mBiometricErrorMessageToShowOnScreenOn = + new Pair<>(helpString, biometricSourceType); mHandler.sendMessageDelayed( mHandler.obtainMessage(MSG_RESET_ERROR_MESSAGE_ON_SCREEN_ON), 1000); @@ -1333,7 +1397,7 @@ public class KeyguardIndicationController { } else if (mIndicationHelper.isFaceLockoutErrorMsg(msgId)) { handleFaceLockoutError(errString); } else { - showErrorMessageNowOrLater(errString, null); + showErrorMessageNowOrLater(errString, null, FACE); } } @@ -1343,7 +1407,7 @@ public class KeyguardIndicationController { msgId, errString); } else { - showErrorMessageNowOrLater(errString, null); + showErrorMessageNowOrLater(errString, null, FINGERPRINT); } } @@ -1371,7 +1435,7 @@ public class KeyguardIndicationController { @Override public void onTrustAgentErrorMessage(CharSequence message) { - showBiometricMessage(message); + showBiometricMessage(message, null); } @Override @@ -1459,12 +1523,13 @@ public class KeyguardIndicationController { // had too many unsuccessful attempts. if (!mFaceLockedOutThisAuthSession) { mFaceLockedOutThisAuthSession = true; - showErrorMessageNowOrLater(errString, followupMessage); + showErrorMessageNowOrLater(errString, followupMessage, FACE); } else if (!mAuthController.isUdfpsFingerDown()) { // On subsequent lockouts, we show a more generic locked out message. showErrorMessageNowOrLater( mContext.getString(R.string.keyguard_face_unlock_unavailable), - followupMessage); + followupMessage, + FACE); } } @@ -1484,7 +1549,8 @@ public class KeyguardIndicationController { && !mStatusBarKeyguardViewManager.isBouncerShowing()) { showBiometricMessage( deferredFaceMessage, - mContext.getString(R.string.keyguard_suggest_fingerprint) + mContext.getString(R.string.keyguard_suggest_fingerprint), + FACE ); } else { // otherwise, don't show any message @@ -1496,7 +1562,8 @@ public class KeyguardIndicationController { // user to manually retry. showBiometricMessage( deferredFaceMessage, - mContext.getString(R.string.keyguard_unlock) + mContext.getString(R.string.keyguard_unlock), + FACE ); } else { // Face-only @@ -1510,13 +1577,15 @@ public class KeyguardIndicationController { getCurrentUser()) && mKeyguardUpdateMonitor.isUnlockingWithFingerprintAllowed(); } - private void showErrorMessageNowOrLater(String errString, @Nullable String followUpMsg) { + private void showErrorMessageNowOrLater(String errString, @Nullable String followUpMsg, + BiometricSourceType biometricSourceType) { if (mStatusBarKeyguardViewManager.isBouncerShowing()) { - mStatusBarKeyguardViewManager.setKeyguardMessage(errString, mInitialTextColorState); + mStatusBarKeyguardViewManager.setKeyguardMessage(errString, mInitialTextColorState, + biometricSourceType); } else if (mScreenLifecycle.getScreenState() == SCREEN_ON) { - showBiometricMessage(errString, followUpMsg); + showBiometricMessage(errString, followUpMsg, biometricSourceType); } else { - mBiometricErrorMessageToShowOnScreenOn = errString; + mBiometricErrorMessageToShowOnScreenOn = new Pair<>(errString, biometricSourceType); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index 29fd2258b40c..66b16e357d91 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -781,7 +781,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb } updateAlternateBouncerShowing(mAlternateBouncerInteractor.show()); - setKeyguardMessage(message, null); + setKeyguardMessage(message, null, null); return; } @@ -1444,11 +1444,12 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb } /** Display security message to relevant KeyguardMessageArea. */ - public void setKeyguardMessage(String message, ColorStateList colorState) { + public void setKeyguardMessage(String message, ColorStateList colorState, + BiometricSourceType biometricSourceType) { if (mAlternateBouncerInteractor.isVisibleState()) { if (mKeyguardMessageAreaController != null) { DeviceEntryUdfpsRefactor.assertInLegacyMode(); - mKeyguardMessageAreaController.setMessage(message); + mKeyguardMessageAreaController.setMessage(message, biometricSourceType); } } else { mPrimaryBouncerInteractor.showMessage(message, colorState); diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardMessageAreaControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardMessageAreaControllerTest.java index d4522d003d52..93e7602715b1 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardMessageAreaControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardMessageAreaControllerTest.java @@ -19,11 +19,14 @@ package com.android.keyguard; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.hardware.biometrics.BiometricSourceType; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; @@ -119,4 +122,51 @@ public class KeyguardMessageAreaControllerTest extends SysuiTestCase { when(mKeyguardMessageArea.getText()).thenReturn(msg); assertThat(mMessageAreaController.getMessage()).isEqualTo(msg); } + + @Test + public void testFingerprintMessageUpdate() { + String msg = "fpMessage"; + mMessageAreaController.setMessage( + msg, BiometricSourceType.FINGERPRINT + ); + verify(mKeyguardMessageArea).setMessage(msg, /* animate= */ true); + + String msg2 = "fpMessage2"; + mMessageAreaController.setMessage( + msg2, BiometricSourceType.FINGERPRINT + ); + verify(mKeyguardMessageArea).setMessage(msg2, /* animate= */ true); + } + + @Test + public void testFaceMessageDroppedWhileFingerprintMessageShowing() { + String fpMsg = "fpMessage"; + mMessageAreaController.setMessage( + fpMsg, BiometricSourceType.FINGERPRINT + ); + verify(mKeyguardMessageArea).setMessage(eq(fpMsg), /* animate= */ anyBoolean()); + + String faceMessage = "faceMessage"; + mMessageAreaController.setMessage( + faceMessage, BiometricSourceType.FACE + ); + verify(mKeyguardMessageArea, never()) + .setMessage(eq(faceMessage), /* animate= */ anyBoolean()); + } + + @Test + public void testGenericMessageShowsAfterFingerprintMessageShowing() { + String fpMsg = "fpMessage"; + mMessageAreaController.setMessage( + fpMsg, BiometricSourceType.FINGERPRINT + ); + verify(mKeyguardMessageArea).setMessage(eq(fpMsg), /* animate= */ anyBoolean()); + + String genericMessage = "genericMessage"; + mMessageAreaController.setMessage( + genericMessage, null + ); + verify(mKeyguardMessageArea) + .setMessage(eq(genericMessage), /* animate= */ anyBoolean()); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java index aa53558e858d..a8002e10d3a7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java @@ -593,7 +593,7 @@ public class KeyguardIndicationControllerTest extends KeyguardIndicationControll mController.getKeyguardCallback().onBiometricError(FACE_ERROR_TIMEOUT, "A message", BiometricSourceType.FACE); - verify(mStatusBarKeyguardViewManager).setKeyguardMessage(eq(message), any()); + verify(mStatusBarKeyguardViewManager).setKeyguardMessage(eq(message), any(), any()); } @Test @@ -608,7 +608,8 @@ public class KeyguardIndicationControllerTest extends KeyguardIndicationControll mController.getKeyguardCallback().onBiometricError(FACE_ERROR_TIMEOUT, "A message", BiometricSourceType.FACE); - verify(mStatusBarKeyguardViewManager, never()).setKeyguardMessage(eq(message), any()); + verify(mStatusBarKeyguardViewManager, never()).setKeyguardMessage( + eq(message), any(), any()); } @Test @@ -1331,7 +1332,9 @@ public class KeyguardIndicationControllerTest extends KeyguardIndicationControll verify(mStatusBarKeyguardViewManager) .setKeyguardMessage( eq(mContext.getString(R.string.keyguard_face_unlock_unavailable)), - any()); + any(), + any() + ); } @Test @@ -1471,6 +1474,71 @@ public class KeyguardIndicationControllerTest extends KeyguardIndicationControll mContext.getString(R.string.keyguard_suggest_fingerprint)); } + @Test + public void faceErrorMessageDroppedBecauseFingerprintMessageShowing() { + createController(); + mController.setVisible(true); + mController.getKeyguardCallback().onBiometricHelp(BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED, + "fp not recognized", BiometricSourceType.FINGERPRINT); + clearInvocations(mRotateTextViewController); + + onFaceLockoutError("lockout"); + verifyNoMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE); + } + + @Test + public void faceUnlockedMessageShowsEvenWhenFingerprintMessageShowing() { + createController(); + mController.setVisible(true); + mController.getKeyguardCallback().onBiometricHelp(BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED, + "fp not recognized", BiometricSourceType.FINGERPRINT); + clearInvocations(mRotateTextViewController); + + when(mKeyguardUpdateMonitor.getIsFaceAuthenticated()).thenReturn(true); + when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(getCurrentUser())) + .thenReturn(true); + mController.getKeyguardCallback().onBiometricAuthenticated(0, + BiometricSourceType.FACE, false); + verifyIndicationMessage( + INDICATION_TYPE_BIOMETRIC_MESSAGE, + mContext.getString(R.string.keyguard_face_successful_unlock)); + } + + @Test + public void onTrustAgentErrorMessageDroppedBecauseFingerprintMessageShowing() { + createController(); + mController.setVisible(true); + mController.getKeyguardCallback().onBiometricHelp(BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED, + "fp not recognized", BiometricSourceType.FINGERPRINT); + clearInvocations(mRotateTextViewController); + + mKeyguardUpdateMonitorCallback.onTrustAgentErrorMessage("testMessage"); + verifyNoMessage(INDICATION_TYPE_TRUST); + verifyNoMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE); + } + + @Test + public void trustGrantedMessageShowsEvenWhenFingerprintMessageShowing() { + createController(); + mController.setVisible(true); + mController.getKeyguardCallback().onBiometricHelp(BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED, + "fp not recognized", BiometricSourceType.FINGERPRINT); + clearInvocations(mRotateTextViewController); + + // GIVEN trust is granted + when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(true); + + // WHEN the showTrustGranted method is called + final String trustGrantedMsg = "testing trust granted message after fp message"; + mController.getKeyguardCallback().onTrustGrantedForCurrentUser( + false, false, new TrustGrantFlags(0), trustGrantedMsg); + + // THEN verify the trust granted message shows + verifyIndicationMessage( + INDICATION_TYPE_TRUST, + trustGrantedMsg); + } + private void screenIsTurningOn() { when(mScreenLifecycle.getScreenState()).thenReturn(SCREEN_TURNING_ON); } |