Loading packages/SystemUI/res-keyguard/values/strings.xml +1 −1 Original line number Diff line number Diff line Loading @@ -217,7 +217,7 @@ the force lock button. [CHAR LIMIT=80] --> <string name="kg_prompt_reason_user_request">Device was locked manually</string> <!-- Face hint message when finger was not recognized. [CHAR LIMIT=20] --> <!-- Face hint message when face was not recognized. [CHAR LIMIT=20] --> <string name="kg_face_not_recognized">Not recognized</string> <!-- Error message indicating that the camera privacy sensor has been turned on [CHAR LIMIT=53] --> Loading packages/SystemUI/res/values/strings.xml +4 −0 Original line number Diff line number Diff line Loading @@ -389,6 +389,10 @@ <string name="fingerprint_dialog_use_fingerprint_instead">Can\u2019t recognize face. Use fingerprint instead.</string> <!-- Message shown to inform the user a face cannot be recognized and fingerprint should instead be used.[CHAR LIMIT=50] --> <string name="keyguard_face_failed_use_fp">@string/fingerprint_dialog_use_fingerprint_instead</string> <!-- Message shown to inform the user a face cannot be recognized. [CHAR LIMIT=25] --> <string name="keyguard_face_failed">Can\u2019t recognize face</string> <!-- Message shown to suggest using fingerprint sensor to authenticate after another biometric failed. [CHAR LIMIT=25] --> <string name="keyguard_suggest_fingerprint">Use fingerprint instead</string> <!-- Content description of the bluetooth icon when connected for accessibility (not shown on the screen). [CHAR LIMIT=NONE] --> <string name="accessibility_bluetooth_connected">Bluetooth connected.</string> Loading packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java +38 −23 Original line number Diff line number Diff line Loading @@ -19,9 +19,12 @@ package com.android.systemui.statusbar; import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED; import static android.app.admin.DevicePolicyResources.Strings.SystemUi.KEYGUARD_MANAGEMENT_DISCLOSURE; import static android.app.admin.DevicePolicyResources.Strings.SystemUi.KEYGUARD_NAMED_MANAGEMENT_DISCLOSURE; import static android.hardware.biometrics.BiometricSourceType.FACE; import static android.view.View.GONE; import static android.view.View.VISIBLE; import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED; import static com.android.keyguard.KeyguardUpdateMonitor.getCurrentUser; import static com.android.systemui.DejankUtils.whitelistIpcs; import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.IMPORTANT_MSG_MIN_DURATION; import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_ALIGNMENT; Loading Loading @@ -428,9 +431,9 @@ public class KeyguardIndicationController { if (info == null) { // Use the current user owner information if enabled. final boolean ownerInfoEnabled = mLockPatternUtils.isOwnerInfoEnabled( KeyguardUpdateMonitor.getCurrentUser()); getCurrentUser()); if (ownerInfoEnabled) { info = mLockPatternUtils.getOwnerInfo(KeyguardUpdateMonitor.getCurrentUser()); info = mLockPatternUtils.getOwnerInfo(getCurrentUser()); } } Loading Loading @@ -595,7 +598,7 @@ public class KeyguardIndicationController { private void updateLockScreenLogoutView() { final boolean shouldShowLogout = mKeyguardUpdateMonitor.isLogoutEnabled() && KeyguardUpdateMonitor.getCurrentUser() != UserHandle.USER_SYSTEM; && getCurrentUser() != UserHandle.USER_SYSTEM; if (shouldShowLogout) { mRotateTextViewController.updateIndication( INDICATION_TYPE_LOGOUT, Loading @@ -610,7 +613,7 @@ public class KeyguardIndicationController { if (mFalsingManager.isFalseTap(LOW_PENALTY)) { return; } int currentUserId = KeyguardUpdateMonitor.getCurrentUser(); int currentUserId = getCurrentUser(); mDevicePolicyManager.logoutUser(); }) .build(), Loading Loading @@ -767,7 +770,7 @@ public class KeyguardIndicationController { mHandler.removeMessages(MSG_HIDE_BIOMETRIC_MESSAGE); hideBiometricMessageDelayed( mBiometricMessageFollowUp != null ? DEFAULT_HIDE_DELAY_MS * 2 ? IMPORTANT_MSG_MIN_DURATION * 2 : DEFAULT_HIDE_DELAY_MS ); Loading Loading @@ -847,7 +850,7 @@ public class KeyguardIndicationController { mTopIndicationView.setVisibility(GONE); mTopIndicationView.setText(null); mLockScreenIndicationView.setVisibility(View.VISIBLE); updateLockScreenIndications(animate, KeyguardUpdateMonitor.getCurrentUser()); updateLockScreenIndications(animate, getCurrentUser()); } protected String computePowerIndication() { Loading Loading @@ -915,7 +918,7 @@ public class KeyguardIndicationController { public void showActionToUnlock() { if (mDozing && !mKeyguardUpdateMonitor.getUserCanSkipBouncer( KeyguardUpdateMonitor.getCurrentUser())) { getCurrentUser())) { return; } Loading @@ -928,7 +931,7 @@ public class KeyguardIndicationController { } } else { final boolean canSkipBouncer = mKeyguardUpdateMonitor.getUserCanSkipBouncer( KeyguardUpdateMonitor.getCurrentUser()); getCurrentUser()); if (canSkipBouncer) { final boolean faceAuthenticated = mKeyguardUpdateMonitor.getIsFaceAuthenticated(); final boolean udfpsSupported = mKeyguardUpdateMonitor.isUdfpsSupported(); Loading Loading @@ -1045,12 +1048,15 @@ public class KeyguardIndicationController { return; } boolean showActionToUnlock = msgId == KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED; if (biometricSourceType == BiometricSourceType.FACE && !showActionToUnlock && mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible( KeyguardUpdateMonitor.getCurrentUser()) final boolean faceAuthSoftError = biometricSourceType == FACE && msgId != BIOMETRIC_HELP_FACE_NOT_RECOGNIZED; final boolean faceAuthFailed = biometricSourceType == FACE && msgId == BIOMETRIC_HELP_FACE_NOT_RECOGNIZED; // ran through matcher & failed final boolean isUnlockWithFingerprintPossible = mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible( getCurrentUser()); if (faceAuthSoftError && isUnlockWithFingerprintPossible && !mCoExFaceHelpMsgIdsToShow.contains(msgId)) { if (DEBUG) { Log.d(TAG, "skip showing msgId=" + msgId + " helpString=" + helpString Loading @@ -1061,8 +1067,16 @@ public class KeyguardIndicationController { mStatusBarKeyguardViewManager.showBouncerMessage(helpString, mInitialTextColorState); } else if (mScreenLifecycle.getScreenState() == SCREEN_ON) { if (faceAuthFailed && isUnlockWithFingerprintPossible) { showBiometricMessage( mContext.getString(R.string.keyguard_face_failed), mContext.getString(R.string.keyguard_suggest_fingerprint) ); } else { showBiometricMessage(helpString); } else if (showActionToUnlock) { } } else if (faceAuthFailed) { // show action to unlock mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SHOW_ACTION_TO_UNLOCK), TRANSIENT_BIOMETRIC_ERROR_TIMEOUT); } else { Loading @@ -1080,17 +1094,17 @@ public class KeyguardIndicationController { return; } if (biometricSourceType == BiometricSourceType.FACE if (biometricSourceType == FACE && msgId == FaceManager.FACE_ERROR_UNABLE_TO_PROCESS) { // suppress all face UNABLE_TO_PROCESS errors if (DEBUG) { Log.d(TAG, "skip showing FACE_ERROR_UNABLE_TO_PROCESS errString=" + errString); } } else if (biometricSourceType == BiometricSourceType.FACE } else if (biometricSourceType == FACE && msgId == FaceManager.FACE_ERROR_TIMEOUT) { if (mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible( KeyguardUpdateMonitor.getCurrentUser())) { getCurrentUser())) { // no message if fingerprint is also enrolled if (DEBUG) { Log.d(TAG, "skip showing FACE_ERROR_TIMEOUT due to co-ex logic"); Loading Loading @@ -1122,8 +1136,9 @@ public class KeyguardIndicationController { BiometricSourceType biometricSourceType, KeyguardUpdateMonitor updateMonitor) { if (biometricSourceType == BiometricSourceType.FINGERPRINT) return shouldSuppressFingerprintError(msgId, updateMonitor); if (biometricSourceType == BiometricSourceType.FACE) if (biometricSourceType == FACE) { return shouldSuppressFaceError(msgId, updateMonitor); } return false; } Loading Loading @@ -1152,7 +1167,7 @@ public class KeyguardIndicationController { @Override public void onTrustChanged(int userId) { if (KeyguardUpdateMonitor.getCurrentUser() != userId) { if (getCurrentUser() != userId) { return; } updateDeviceEntryIndication(false); Loading @@ -1172,7 +1187,7 @@ public class KeyguardIndicationController { @Override public void onBiometricRunningStateChanged(boolean running, BiometricSourceType biometricSourceType) { if (running && biometricSourceType == BiometricSourceType.FACE) { if (running && biometricSourceType == FACE) { // Let's hide any previous messages when authentication starts, otherwise // multiple auth attempts would overlap. hideBiometricMessage(); Loading @@ -1186,7 +1201,7 @@ public class KeyguardIndicationController { super.onBiometricAuthenticated(userId, biometricSourceType, isStrongBiometric); hideBiometricMessage(); if (biometricSourceType == BiometricSourceType.FACE if (biometricSourceType == FACE && !mKeyguardBypassController.canBypass()) { showActionToUnlock(); } Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java +27 −0 Original line number Diff line number Diff line Loading @@ -569,6 +569,33 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase { verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, message); } @Test public void onBiometricHelp_coEx_faceFailure() { createController(); // GIVEN unlocking with fingerprint is possible when(mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(anyInt())) .thenReturn(true); String message = "A message"; mController.setVisible(true); // WHEN there's a face not recognized message mController.getKeyguardCallback().onBiometricHelp( KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED, message, BiometricSourceType.FACE); // THEN show sequential messages such as: 'face not recognized' and // 'try fingerprint instead' verifyIndicationMessage( INDICATION_TYPE_BIOMETRIC_MESSAGE, mContext.getString(R.string.keyguard_face_failed)); verifyIndicationMessage( INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP, mContext.getString(R.string.keyguard_suggest_fingerprint)); } @Test public void transientIndication_visibleWhenDozing_unlessSwipeUp_fromError() { createController(); Loading Loading
packages/SystemUI/res-keyguard/values/strings.xml +1 −1 Original line number Diff line number Diff line Loading @@ -217,7 +217,7 @@ the force lock button. [CHAR LIMIT=80] --> <string name="kg_prompt_reason_user_request">Device was locked manually</string> <!-- Face hint message when finger was not recognized. [CHAR LIMIT=20] --> <!-- Face hint message when face was not recognized. [CHAR LIMIT=20] --> <string name="kg_face_not_recognized">Not recognized</string> <!-- Error message indicating that the camera privacy sensor has been turned on [CHAR LIMIT=53] --> Loading
packages/SystemUI/res/values/strings.xml +4 −0 Original line number Diff line number Diff line Loading @@ -389,6 +389,10 @@ <string name="fingerprint_dialog_use_fingerprint_instead">Can\u2019t recognize face. Use fingerprint instead.</string> <!-- Message shown to inform the user a face cannot be recognized and fingerprint should instead be used.[CHAR LIMIT=50] --> <string name="keyguard_face_failed_use_fp">@string/fingerprint_dialog_use_fingerprint_instead</string> <!-- Message shown to inform the user a face cannot be recognized. [CHAR LIMIT=25] --> <string name="keyguard_face_failed">Can\u2019t recognize face</string> <!-- Message shown to suggest using fingerprint sensor to authenticate after another biometric failed. [CHAR LIMIT=25] --> <string name="keyguard_suggest_fingerprint">Use fingerprint instead</string> <!-- Content description of the bluetooth icon when connected for accessibility (not shown on the screen). [CHAR LIMIT=NONE] --> <string name="accessibility_bluetooth_connected">Bluetooth connected.</string> Loading
packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java +38 −23 Original line number Diff line number Diff line Loading @@ -19,9 +19,12 @@ package com.android.systemui.statusbar; import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED; import static android.app.admin.DevicePolicyResources.Strings.SystemUi.KEYGUARD_MANAGEMENT_DISCLOSURE; import static android.app.admin.DevicePolicyResources.Strings.SystemUi.KEYGUARD_NAMED_MANAGEMENT_DISCLOSURE; import static android.hardware.biometrics.BiometricSourceType.FACE; import static android.view.View.GONE; import static android.view.View.VISIBLE; import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED; import static com.android.keyguard.KeyguardUpdateMonitor.getCurrentUser; import static com.android.systemui.DejankUtils.whitelistIpcs; import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.IMPORTANT_MSG_MIN_DURATION; import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_ALIGNMENT; Loading Loading @@ -428,9 +431,9 @@ public class KeyguardIndicationController { if (info == null) { // Use the current user owner information if enabled. final boolean ownerInfoEnabled = mLockPatternUtils.isOwnerInfoEnabled( KeyguardUpdateMonitor.getCurrentUser()); getCurrentUser()); if (ownerInfoEnabled) { info = mLockPatternUtils.getOwnerInfo(KeyguardUpdateMonitor.getCurrentUser()); info = mLockPatternUtils.getOwnerInfo(getCurrentUser()); } } Loading Loading @@ -595,7 +598,7 @@ public class KeyguardIndicationController { private void updateLockScreenLogoutView() { final boolean shouldShowLogout = mKeyguardUpdateMonitor.isLogoutEnabled() && KeyguardUpdateMonitor.getCurrentUser() != UserHandle.USER_SYSTEM; && getCurrentUser() != UserHandle.USER_SYSTEM; if (shouldShowLogout) { mRotateTextViewController.updateIndication( INDICATION_TYPE_LOGOUT, Loading @@ -610,7 +613,7 @@ public class KeyguardIndicationController { if (mFalsingManager.isFalseTap(LOW_PENALTY)) { return; } int currentUserId = KeyguardUpdateMonitor.getCurrentUser(); int currentUserId = getCurrentUser(); mDevicePolicyManager.logoutUser(); }) .build(), Loading Loading @@ -767,7 +770,7 @@ public class KeyguardIndicationController { mHandler.removeMessages(MSG_HIDE_BIOMETRIC_MESSAGE); hideBiometricMessageDelayed( mBiometricMessageFollowUp != null ? DEFAULT_HIDE_DELAY_MS * 2 ? IMPORTANT_MSG_MIN_DURATION * 2 : DEFAULT_HIDE_DELAY_MS ); Loading Loading @@ -847,7 +850,7 @@ public class KeyguardIndicationController { mTopIndicationView.setVisibility(GONE); mTopIndicationView.setText(null); mLockScreenIndicationView.setVisibility(View.VISIBLE); updateLockScreenIndications(animate, KeyguardUpdateMonitor.getCurrentUser()); updateLockScreenIndications(animate, getCurrentUser()); } protected String computePowerIndication() { Loading Loading @@ -915,7 +918,7 @@ public class KeyguardIndicationController { public void showActionToUnlock() { if (mDozing && !mKeyguardUpdateMonitor.getUserCanSkipBouncer( KeyguardUpdateMonitor.getCurrentUser())) { getCurrentUser())) { return; } Loading @@ -928,7 +931,7 @@ public class KeyguardIndicationController { } } else { final boolean canSkipBouncer = mKeyguardUpdateMonitor.getUserCanSkipBouncer( KeyguardUpdateMonitor.getCurrentUser()); getCurrentUser()); if (canSkipBouncer) { final boolean faceAuthenticated = mKeyguardUpdateMonitor.getIsFaceAuthenticated(); final boolean udfpsSupported = mKeyguardUpdateMonitor.isUdfpsSupported(); Loading Loading @@ -1045,12 +1048,15 @@ public class KeyguardIndicationController { return; } boolean showActionToUnlock = msgId == KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED; if (biometricSourceType == BiometricSourceType.FACE && !showActionToUnlock && mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible( KeyguardUpdateMonitor.getCurrentUser()) final boolean faceAuthSoftError = biometricSourceType == FACE && msgId != BIOMETRIC_HELP_FACE_NOT_RECOGNIZED; final boolean faceAuthFailed = biometricSourceType == FACE && msgId == BIOMETRIC_HELP_FACE_NOT_RECOGNIZED; // ran through matcher & failed final boolean isUnlockWithFingerprintPossible = mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible( getCurrentUser()); if (faceAuthSoftError && isUnlockWithFingerprintPossible && !mCoExFaceHelpMsgIdsToShow.contains(msgId)) { if (DEBUG) { Log.d(TAG, "skip showing msgId=" + msgId + " helpString=" + helpString Loading @@ -1061,8 +1067,16 @@ public class KeyguardIndicationController { mStatusBarKeyguardViewManager.showBouncerMessage(helpString, mInitialTextColorState); } else if (mScreenLifecycle.getScreenState() == SCREEN_ON) { if (faceAuthFailed && isUnlockWithFingerprintPossible) { showBiometricMessage( mContext.getString(R.string.keyguard_face_failed), mContext.getString(R.string.keyguard_suggest_fingerprint) ); } else { showBiometricMessage(helpString); } else if (showActionToUnlock) { } } else if (faceAuthFailed) { // show action to unlock mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SHOW_ACTION_TO_UNLOCK), TRANSIENT_BIOMETRIC_ERROR_TIMEOUT); } else { Loading @@ -1080,17 +1094,17 @@ public class KeyguardIndicationController { return; } if (biometricSourceType == BiometricSourceType.FACE if (biometricSourceType == FACE && msgId == FaceManager.FACE_ERROR_UNABLE_TO_PROCESS) { // suppress all face UNABLE_TO_PROCESS errors if (DEBUG) { Log.d(TAG, "skip showing FACE_ERROR_UNABLE_TO_PROCESS errString=" + errString); } } else if (biometricSourceType == BiometricSourceType.FACE } else if (biometricSourceType == FACE && msgId == FaceManager.FACE_ERROR_TIMEOUT) { if (mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible( KeyguardUpdateMonitor.getCurrentUser())) { getCurrentUser())) { // no message if fingerprint is also enrolled if (DEBUG) { Log.d(TAG, "skip showing FACE_ERROR_TIMEOUT due to co-ex logic"); Loading Loading @@ -1122,8 +1136,9 @@ public class KeyguardIndicationController { BiometricSourceType biometricSourceType, KeyguardUpdateMonitor updateMonitor) { if (biometricSourceType == BiometricSourceType.FINGERPRINT) return shouldSuppressFingerprintError(msgId, updateMonitor); if (biometricSourceType == BiometricSourceType.FACE) if (biometricSourceType == FACE) { return shouldSuppressFaceError(msgId, updateMonitor); } return false; } Loading Loading @@ -1152,7 +1167,7 @@ public class KeyguardIndicationController { @Override public void onTrustChanged(int userId) { if (KeyguardUpdateMonitor.getCurrentUser() != userId) { if (getCurrentUser() != userId) { return; } updateDeviceEntryIndication(false); Loading @@ -1172,7 +1187,7 @@ public class KeyguardIndicationController { @Override public void onBiometricRunningStateChanged(boolean running, BiometricSourceType biometricSourceType) { if (running && biometricSourceType == BiometricSourceType.FACE) { if (running && biometricSourceType == FACE) { // Let's hide any previous messages when authentication starts, otherwise // multiple auth attempts would overlap. hideBiometricMessage(); Loading @@ -1186,7 +1201,7 @@ public class KeyguardIndicationController { super.onBiometricAuthenticated(userId, biometricSourceType, isStrongBiometric); hideBiometricMessage(); if (biometricSourceType == BiometricSourceType.FACE if (biometricSourceType == FACE && !mKeyguardBypassController.canBypass()) { showActionToUnlock(); } Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java +27 −0 Original line number Diff line number Diff line Loading @@ -569,6 +569,33 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase { verifyIndicationMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE, message); } @Test public void onBiometricHelp_coEx_faceFailure() { createController(); // GIVEN unlocking with fingerprint is possible when(mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(anyInt())) .thenReturn(true); String message = "A message"; mController.setVisible(true); // WHEN there's a face not recognized message mController.getKeyguardCallback().onBiometricHelp( KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED, message, BiometricSourceType.FACE); // THEN show sequential messages such as: 'face not recognized' and // 'try fingerprint instead' verifyIndicationMessage( INDICATION_TYPE_BIOMETRIC_MESSAGE, mContext.getString(R.string.keyguard_face_failed)); verifyIndicationMessage( INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP, mContext.getString(R.string.keyguard_suggest_fingerprint)); } @Test public void transientIndication_visibleWhenDozing_unlessSwipeUp_fromError() { createController(); Loading