From 9ded0e1d48c016883858dd2dc574787524c6df84 Mon Sep 17 00:00:00 2001 From: Brian Colonna Date: Mon, 8 Oct 2012 13:02:41 -0400 Subject: [PATCH] FUL fallback is no longer account login - fix b/7280196 When Face Unlock failed the maximum number of times (3), it was asking for account login when it should have been asking for the backup lock that the user chose when setting up Face Unlock. This change splits the isBiometricUnlockEnabled() function into two. One of them strictly checks whether it exists and is selected. The other one checks whether too many attempts have occurred. When deciding which backup to choose, the decision is now based only on whether Face Unlock is enabled. Checking whether too many attempts had occurred caused the bug because the check indicated it had already 'fallen back' to pattern, and the backup for pattern was being selected instead of the backup for biometric unlock. Change-Id: I6b9cf2c5155e8c14933cbfc8f5d58ebc007e53cb --- .../impl/keyguard/KeyguardHostView.java | 3 +- .../impl/keyguard/KeyguardSecurityModel.java | 40 ++++++++++++------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java index 8e9362e4c5546..6ea35138446e0 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java @@ -403,8 +403,7 @@ public class KeyguardHostView extends KeyguardViewBase { * account unlock screen and biometric unlock to show the user's normal unlock. */ private void showBackupSecurity() { - SecurityMode currentMode = mSecurityModel.getAlternateFor(mSecurityModel.getSecurityMode()); - showSecurityScreen(mSecurityModel.getBackupFor(currentMode)); + showSecurityScreen(mSecurityModel.getBackupSecurityMode()); } public boolean showNextSecurityScreenIfPresent() { diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityModel.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityModel.java index ac0b3465e2225..30cd67b0ea4b6 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityModel.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityModel.java @@ -49,18 +49,23 @@ public class KeyguardSecurityModel { } /** - * This returns false if there is any condition that indicates that the biometric unlock should - * not be used before the next time the unlock screen is recreated. In other words, if this - * returns false there is no need to even construct the biometric unlock. + * Returns true if biometric unlock is installed and selected. If this returns false there is + * no need to even construct the biometric unlock. */ private boolean isBiometricUnlockEnabled() { - KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext); - final boolean backupIsTimedOut = - monitor.getFailedUnlockAttempts() >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT; return mLockPatternUtils.usingBiometricWeak() - && mLockPatternUtils.isBiometricWeakInstalled() - && !monitor.getMaxBiometricUnlockAttemptsReached() - && !backupIsTimedOut; + && mLockPatternUtils.isBiometricWeakInstalled(); + } + + /** + * Returns true if a condition is currently suppressing the biometric unlock. If this returns + * true there is no need to even construct the biometric unlock. + */ + private boolean isBiometricUnlockSuppressed() { + KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext); + final boolean backupIsTimedOut = monitor.getFailedUnlockAttempts() >= + LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT; + return monitor.getMaxBiometricUnlockAttemptsReached() || backupIsTimedOut; } SecurityMode getSecurityMode() { @@ -107,7 +112,7 @@ public class KeyguardSecurityModel { * @return alternate or the given mode */ SecurityMode getAlternateFor(SecurityMode mode) { - if (isBiometricUnlockEnabled() + if (isBiometricUnlockEnabled() && !isBiometricUnlockSuppressed() && (mode == SecurityMode.Password || mode == SecurityMode.Pattern)) { return SecurityMode.Biometric; } @@ -118,16 +123,23 @@ public class KeyguardSecurityModel { * Some unlock methods can have a backup which gives the user another way to get into * the device. This is currently only supported for Biometric and Pattern unlock. * - * @param mode the mode we want the backup for - * @return backup method or given mode + * @return backup method or current security mode */ - SecurityMode getBackupFor(SecurityMode mode) { + SecurityMode getBackupSecurityMode() { + SecurityMode mode = getSecurityMode(); + + // Note that getAlternateFor() cannot be called here because we want to get the backup for + // biometric unlock even if it's suppressed; it just has to be enabled. + if (isBiometricUnlockEnabled() + && (mode == SecurityMode.Password || mode == SecurityMode.Pattern)) { + mode = SecurityMode.Biometric; + } switch(mode) { case Biometric: return getSecurityMode(); case Pattern: return SecurityMode.Account; } - return mode; // no backup, return what was given + return mode; // no backup, return current security mode } }