@@ -129,6 +129,10 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
129129 // So the user has a consistent amount of time when brought to the backup method from FaceLock
130130 private final int BACKUP_LOCK_TIMEOUT = 5000 ;
131131
132+ // Needed to keep track of failed FaceUnlock attempts
133+ private int mFailedFaceUnlockAttempts = 0 ;
134+ private static final int FAILED_FACE_UNLOCK_ATTEMPTS_BEFORE_BACKUP = 15 ;
135+
132136 /**
133137 * The current {@link KeyguardScreen} will use this to communicate back to us.
134138 */
@@ -424,6 +428,7 @@ public boolean doesFallbackUnlockScreenExist() {
424428 }
425429
426430 public void reportSuccessfulUnlockAttempt () {
431+ mFailedFaceUnlockAttempts = 0 ;
427432 mLockPatternUtils .reportSuccessfulPasswordAttempt ();
428433 }
429434 };
@@ -536,7 +541,16 @@ public void onScreenTurnedOff() {
536541 * FaceLock, but only if we're not dealing with a call
537542 */
538543 private void activateFaceLockIfAble () {
539- if (mUpdateMonitor .getPhoneState () == TelephonyManager .CALL_STATE_IDLE && !mHasOverlay ) {
544+ final boolean tooManyFaceUnlockTries =
545+ (mFailedFaceUnlockAttempts >= FAILED_FACE_UNLOCK_ATTEMPTS_BEFORE_BACKUP );
546+ final int failedBackupAttempts = mUpdateMonitor .getFailedAttempts ();
547+ final boolean backupIsTimedOut =
548+ (failedBackupAttempts >= LockPatternUtils .FAILED_ATTEMPTS_BEFORE_TIMEOUT );
549+ if (tooManyFaceUnlockTries ) Log .i (TAG , "tooManyFaceUnlockTries: " + tooManyFaceUnlockTries );
550+ if (mUpdateMonitor .getPhoneState () == TelephonyManager .CALL_STATE_IDLE
551+ && !mHasOverlay
552+ && !tooManyFaceUnlockTries
553+ && !backupIsTimedOut ) {
540554 bindToFaceLock ();
541555 // Show FaceLock area, but only for a little bit so lockpattern will become visible if
542556 // FaceLock fails to start or crashes
@@ -1257,7 +1271,7 @@ public void unlock() {
12571271 }
12581272
12591273 // Stops the FaceLock UI and exposes the backup method without unlocking
1260- // This means either the user has cancelled out or FaceLock failed to recognize them
1274+ // This means the user has cancelled out
12611275 @ Override
12621276 public void cancel () {
12631277 if (DEBUG ) Log .d (TAG , "FaceLock cancel()" );
@@ -1266,6 +1280,17 @@ public void cancel() {
12661280 mKeyguardScreenCallback .pokeWakelock (BACKUP_LOCK_TIMEOUT );
12671281 }
12681282
1283+ // Stops the FaceLock UI and exposes the backup method without unlocking
1284+ // This means FaceLock failed to recognize them
1285+ @ Override
1286+ public void reportFailedAttempt () {
1287+ if (DEBUG ) Log .d (TAG , "FaceLock reportFailedAttempt()" );
1288+ mFailedFaceUnlockAttempts ++;
1289+ hideFaceLockArea (); // Expose fallback
1290+ stopFaceLock ();
1291+ mKeyguardScreenCallback .pokeWakelock (BACKUP_LOCK_TIMEOUT );
1292+ }
1293+
12691294 // Allows the Face Unlock service to poke the wake lock to keep the lockscreen alive
12701295 @ Override
12711296 public void pokeWakelock () {
0 commit comments