Merge "Update FP failure logic when device is unlocked" into tm-qpr-dev
This commit is contained in:
@@ -1311,7 +1311,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean getUserHasTrust(int userId) {
|
public boolean getUserHasTrust(int userId) {
|
||||||
return !isTrustDisabled() && mUserHasTrust.get(userId);
|
return !isTrustDisabled() && mUserHasTrust.get(userId)
|
||||||
|
&& isUnlockingWithTrustAgentAllowed();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1319,12 +1320,19 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
*/
|
*/
|
||||||
public boolean getUserUnlockedWithBiometric(int userId) {
|
public boolean getUserUnlockedWithBiometric(int userId) {
|
||||||
BiometricAuthenticated fingerprint = mUserFingerprintAuthenticated.get(userId);
|
BiometricAuthenticated fingerprint = mUserFingerprintAuthenticated.get(userId);
|
||||||
BiometricAuthenticated face = mUserFaceAuthenticated.get(userId);
|
|
||||||
boolean fingerprintAllowed = fingerprint != null && fingerprint.mAuthenticated
|
boolean fingerprintAllowed = fingerprint != null && fingerprint.mAuthenticated
|
||||||
&& isUnlockingWithBiometricAllowed(fingerprint.mIsStrongBiometric);
|
&& isUnlockingWithBiometricAllowed(fingerprint.mIsStrongBiometric);
|
||||||
boolean faceAllowed = face != null && face.mAuthenticated
|
return fingerprintAllowed || getUserUnlockedWithFace(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the user is unlocked with face.
|
||||||
|
*/
|
||||||
|
public boolean getUserUnlockedWithFace(int userId) {
|
||||||
|
BiometricAuthenticated face = mUserFaceAuthenticated.get(userId);
|
||||||
|
return face != null && face.mAuthenticated
|
||||||
&& isUnlockingWithBiometricAllowed(face.mIsStrongBiometric);
|
&& isUnlockingWithBiometricAllowed(face.mIsStrongBiometric);
|
||||||
return fingerprintAllowed || faceAllowed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1399,6 +1407,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
|||||||
return mUserTrustIsUsuallyManaged.get(userId);
|
return mUserTrustIsUsuallyManaged.get(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isUnlockingWithTrustAgentAllowed() {
|
||||||
|
return isUnlockingWithBiometricAllowed(true);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isUnlockingWithBiometricAllowed(boolean isStrongBiometric) {
|
public boolean isUnlockingWithBiometricAllowed(boolean isStrongBiometric) {
|
||||||
// StrongAuthTracker#isUnlockingWithBiometricAllowed includes
|
// StrongAuthTracker#isUnlockingWithBiometricAllowed includes
|
||||||
// STRONG_AUTH_REQUIRED_AFTER_LOCKOUT which is the same as mFingerprintLockedOutPermanent;
|
// STRONG_AUTH_REQUIRED_AFTER_LOCKOUT which is the same as mFingerprintLockedOutPermanent;
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import static android.view.View.GONE;
|
|||||||
import static android.view.View.VISIBLE;
|
import static android.view.View.VISIBLE;
|
||||||
|
|
||||||
import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED;
|
import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED;
|
||||||
|
import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED;
|
||||||
import static com.android.keyguard.KeyguardUpdateMonitor.getCurrentUser;
|
import static com.android.keyguard.KeyguardUpdateMonitor.getCurrentUser;
|
||||||
import static com.android.systemui.DejankUtils.whitelistIpcs;
|
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.IMPORTANT_MSG_MIN_DURATION;
|
||||||
@@ -539,23 +540,23 @@ public class KeyguardIndicationController {
|
|||||||
.build(),
|
.build(),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
if (!TextUtils.isEmpty(mBiometricMessageFollowUp)) {
|
|
||||||
mRotateTextViewController.updateIndication(
|
|
||||||
INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP,
|
|
||||||
new KeyguardIndication.Builder()
|
|
||||||
.setMessage(mBiometricMessageFollowUp)
|
|
||||||
.setMinVisibilityMillis(IMPORTANT_MSG_MIN_DURATION)
|
|
||||||
.setTextColor(mInitialTextColorState)
|
|
||||||
.build(),
|
|
||||||
true
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
mRotateTextViewController.hideIndication(
|
|
||||||
INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
mRotateTextViewController.hideIndication(INDICATION_TYPE_BIOMETRIC_MESSAGE);
|
mRotateTextViewController.hideIndication(
|
||||||
mRotateTextViewController.hideIndication(INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP);
|
INDICATION_TYPE_BIOMETRIC_MESSAGE);
|
||||||
|
}
|
||||||
|
if (!TextUtils.isEmpty(mBiometricMessageFollowUp)) {
|
||||||
|
mRotateTextViewController.updateIndication(
|
||||||
|
INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP,
|
||||||
|
new KeyguardIndication.Builder()
|
||||||
|
.setMessage(mBiometricMessageFollowUp)
|
||||||
|
.setMinVisibilityMillis(IMPORTANT_MSG_MIN_DURATION)
|
||||||
|
.setTextColor(mInitialTextColorState)
|
||||||
|
.build(),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
mRotateTextViewController.hideIndication(
|
||||||
|
INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -784,7 +785,8 @@ public class KeyguardIndicationController {
|
|||||||
*/
|
*/
|
||||||
private void showBiometricMessage(CharSequence biometricMessage,
|
private void showBiometricMessage(CharSequence biometricMessage,
|
||||||
@Nullable CharSequence biometricMessageFollowUp) {
|
@Nullable CharSequence biometricMessageFollowUp) {
|
||||||
if (TextUtils.equals(biometricMessage, mBiometricMessage)) {
|
if (TextUtils.equals(biometricMessage, mBiometricMessage)
|
||||||
|
&& TextUtils.equals(biometricMessageFollowUp, mBiometricMessageFollowUp)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -793,7 +795,8 @@ public class KeyguardIndicationController {
|
|||||||
|
|
||||||
mHandler.removeMessages(MSG_SHOW_ACTION_TO_UNLOCK);
|
mHandler.removeMessages(MSG_SHOW_ACTION_TO_UNLOCK);
|
||||||
hideBiometricMessageDelayed(
|
hideBiometricMessageDelayed(
|
||||||
mBiometricMessageFollowUp != null
|
!TextUtils.isEmpty(mBiometricMessage)
|
||||||
|
&& !TextUtils.isEmpty(mBiometricMessageFollowUp)
|
||||||
? IMPORTANT_MSG_MIN_DURATION * 2
|
? IMPORTANT_MSG_MIN_DURATION * 2
|
||||||
: DEFAULT_HIDE_DELAY_MS
|
: DEFAULT_HIDE_DELAY_MS
|
||||||
);
|
);
|
||||||
@@ -1091,6 +1094,8 @@ public class KeyguardIndicationController {
|
|||||||
&& msgId != BIOMETRIC_HELP_FACE_NOT_RECOGNIZED;
|
&& msgId != BIOMETRIC_HELP_FACE_NOT_RECOGNIZED;
|
||||||
final boolean faceAuthFailed = biometricSourceType == FACE
|
final boolean faceAuthFailed = biometricSourceType == FACE
|
||||||
&& msgId == BIOMETRIC_HELP_FACE_NOT_RECOGNIZED; // ran through matcher & failed
|
&& msgId == BIOMETRIC_HELP_FACE_NOT_RECOGNIZED; // ran through matcher & failed
|
||||||
|
final boolean fpAuthFailed = biometricSourceType == FINGERPRINT
|
||||||
|
&& msgId == BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED; // ran matcher & failed
|
||||||
final boolean isUnlockWithFingerprintPossible = canUnlockWithFingerprint();
|
final boolean isUnlockWithFingerprintPossible = canUnlockWithFingerprint();
|
||||||
final boolean isCoExFaceAcquisitionMessage =
|
final boolean isCoExFaceAcquisitionMessage =
|
||||||
faceAuthSoftError && isUnlockWithFingerprintPossible;
|
faceAuthSoftError && isUnlockWithFingerprintPossible;
|
||||||
@@ -1113,6 +1118,22 @@ public class KeyguardIndicationController {
|
|||||||
mContext.getString(R.string.keyguard_face_failed),
|
mContext.getString(R.string.keyguard_face_failed),
|
||||||
mContext.getString(R.string.keyguard_suggest_fingerprint)
|
mContext.getString(R.string.keyguard_suggest_fingerprint)
|
||||||
);
|
);
|
||||||
|
} else if (fpAuthFailed
|
||||||
|
&& mKeyguardUpdateMonitor.getUserUnlockedWithFace(getCurrentUser())) {
|
||||||
|
// 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(
|
||||||
|
mContext.getString(R.string.keyguard_face_successful_unlock),
|
||||||
|
mContext.getString(R.string.keyguard_unlock)
|
||||||
|
);
|
||||||
|
} else if (fpAuthFailed
|
||||||
|
&& mKeyguardUpdateMonitor.getUserHasTrust(
|
||||||
|
KeyguardUpdateMonitor.getCurrentUser())) {
|
||||||
|
showBiometricMessage(
|
||||||
|
getTrustGrantedIndication(),
|
||||||
|
mContext.getString(R.string.keyguard_unlock)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
showBiometricMessage(helpString);
|
showBiometricMessage(helpString);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -437,6 +437,11 @@ public class KeyguardStateControllerImpl implements KeyguardStateController, Dum
|
|||||||
update(false /* updateAlways */);
|
update(false /* updateAlways */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLockedOutStateChanged(BiometricSourceType biometricSourceType) {
|
||||||
|
update(false /* updateAlways */);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onKeyguardVisibilityChanged(boolean visible) {
|
public void onKeyguardVisibilityChanged(boolean visible) {
|
||||||
update(false /* updateAlways */);
|
update(false /* updateAlways */);
|
||||||
|
|||||||
@@ -685,11 +685,35 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
|||||||
// WHEN fingerprint is locked out
|
// WHEN fingerprint is locked out
|
||||||
fingerprintErrorLockedOut();
|
fingerprintErrorLockedOut();
|
||||||
|
|
||||||
// THEN unlocking with fingeprint is not allowed
|
// THEN unlocking with fingerprint is not allowed
|
||||||
Assert.assertFalse(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(
|
Assert.assertFalse(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(
|
||||||
BiometricSourceType.FINGERPRINT));
|
BiometricSourceType.FINGERPRINT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void trustAgentHasTrust() {
|
||||||
|
// WHEN user has trust
|
||||||
|
mKeyguardUpdateMonitor.onTrustChanged(true, true, getCurrentUser(), 0, null);
|
||||||
|
|
||||||
|
// THEN user is considered as "having trust" and bouncer can be skipped
|
||||||
|
Assert.assertTrue(mKeyguardUpdateMonitor.getUserHasTrust(getCurrentUser()));
|
||||||
|
Assert.assertTrue(mKeyguardUpdateMonitor.getUserCanSkipBouncer(getCurrentUser()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void trustAgentHasTrust_fingerprintLockout() {
|
||||||
|
// GIVEN user has trust
|
||||||
|
mKeyguardUpdateMonitor.onTrustChanged(true, true, getCurrentUser(), 0, null);
|
||||||
|
Assert.assertTrue(mKeyguardUpdateMonitor.getUserHasTrust(getCurrentUser()));
|
||||||
|
|
||||||
|
// WHEN fingerprint is locked out
|
||||||
|
fingerprintErrorLockedOut();
|
||||||
|
|
||||||
|
// THEN user is NOT considered as "having trust" and bouncer cannot be skipped
|
||||||
|
Assert.assertFalse(mKeyguardUpdateMonitor.getUserHasTrust(getCurrentUser()));
|
||||||
|
Assert.assertFalse(mKeyguardUpdateMonitor.getUserCanSkipBouncer(getCurrentUser()));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTriesToAuthenticate_whenBouncer() {
|
public void testTriesToAuthenticate_whenBouncer() {
|
||||||
setKeyguardBouncerVisibility(true);
|
setKeyguardBouncerVisibility(true);
|
||||||
|
|||||||
@@ -619,6 +619,82 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
|
|||||||
mContext.getString(R.string.keyguard_suggest_fingerprint));
|
mContext.getString(R.string.keyguard_suggest_fingerprint));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onBiometricHelp_coEx_fpFailure_faceAlreadyUnlocked() {
|
||||||
|
createController();
|
||||||
|
|
||||||
|
// GIVEN face has already unlocked the device
|
||||||
|
when(mKeyguardUpdateMonitor.getUserUnlockedWithFace(anyInt())).thenReturn(true);
|
||||||
|
|
||||||
|
String message = "A message";
|
||||||
|
mController.setVisible(true);
|
||||||
|
|
||||||
|
// WHEN there's a fingerprint not recognized message
|
||||||
|
mController.getKeyguardCallback().onBiometricHelp(
|
||||||
|
BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED,
|
||||||
|
message,
|
||||||
|
BiometricSourceType.FINGERPRINT);
|
||||||
|
|
||||||
|
// THEN show sequential messages such as: 'Unlocked by face' and
|
||||||
|
// 'Swipe up to open'
|
||||||
|
verifyIndicationMessage(
|
||||||
|
INDICATION_TYPE_BIOMETRIC_MESSAGE,
|
||||||
|
mContext.getString(R.string.keyguard_face_successful_unlock));
|
||||||
|
verifyIndicationMessage(
|
||||||
|
INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP,
|
||||||
|
mContext.getString(R.string.keyguard_unlock));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onBiometricHelp_coEx_fpFailure_trustAgentAlreadyUnlocked() {
|
||||||
|
createController();
|
||||||
|
|
||||||
|
// GIVEN trust agent has already unlocked the device
|
||||||
|
when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(true);
|
||||||
|
|
||||||
|
String message = "A message";
|
||||||
|
mController.setVisible(true);
|
||||||
|
|
||||||
|
// WHEN there's a fingerprint not recognized message
|
||||||
|
mController.getKeyguardCallback().onBiometricHelp(
|
||||||
|
BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED,
|
||||||
|
message,
|
||||||
|
BiometricSourceType.FINGERPRINT);
|
||||||
|
|
||||||
|
// THEN show sequential messages such as: 'Kept unlocked by TrustAgent' and
|
||||||
|
// 'Swipe up to open'
|
||||||
|
verifyIndicationMessage(
|
||||||
|
INDICATION_TYPE_BIOMETRIC_MESSAGE,
|
||||||
|
mContext.getString(R.string.keyguard_indication_trust_unlocked));
|
||||||
|
verifyIndicationMessage(
|
||||||
|
INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP,
|
||||||
|
mContext.getString(R.string.keyguard_unlock));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onBiometricHelp_coEx_fpFailure_trustAgentUnlocked_emptyTrustGrantedMessage() {
|
||||||
|
createController();
|
||||||
|
|
||||||
|
// GIVEN trust agent has already unlocked the device & trust granted message is empty
|
||||||
|
when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(true);
|
||||||
|
mController.showTrustGrantedMessage(false, "");
|
||||||
|
|
||||||
|
String message = "A message";
|
||||||
|
mController.setVisible(true);
|
||||||
|
|
||||||
|
// WHEN there's a fingerprint not recognized message
|
||||||
|
mController.getKeyguardCallback().onBiometricHelp(
|
||||||
|
BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED,
|
||||||
|
message,
|
||||||
|
BiometricSourceType.FINGERPRINT);
|
||||||
|
|
||||||
|
// THEN show action to unlock (ie: 'Swipe up to open')
|
||||||
|
verifyNoMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE);
|
||||||
|
verifyIndicationMessage(
|
||||||
|
INDICATION_TYPE_BIOMETRIC_MESSAGE_FOLLOW_UP,
|
||||||
|
mContext.getString(R.string.keyguard_unlock));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void transientIndication_visibleWhenDozing_unlessSwipeUp_fromError() {
|
public void transientIndication_visibleWhenDozing_unlessSwipeUp_fromError() {
|
||||||
createController();
|
createController();
|
||||||
|
|||||||
Reference in New Issue
Block a user