@@ -130,6 +130,10 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
130130 // So the user has a consistent amount of time when brought to the backup method from FaceLock
131131 private final int BACKUP_LOCK_TIMEOUT = 5000 ;
132132
133+ // Needed to keep track of failed FaceUnlock attempts
134+ private int mFailedFaceUnlockAttempts = 0 ;
135+ private static final int FAILED_FACE_UNLOCK_ATTEMPTS_BEFORE_BACKUP = 15 ;
136+
133137 /**
134138 * The current {@link KeyguardScreen} will use this to communicate back to us.
135139 */
@@ -439,6 +443,7 @@ public boolean doesFallbackUnlockScreenExist() {
439443 }
440444
441445 public void reportSuccessfulUnlockAttempt () {
446+ mFailedFaceUnlockAttempts = 0 ;
442447 mLockPatternUtils .reportSuccessfulPasswordAttempt ();
443448 }
444449 };
@@ -553,7 +558,16 @@ public void onScreenTurnedOff() {
553558 * FaceLock, but only if we're not dealing with a call
554559 */
555560 private void activateFaceLockIfAble () {
556- if (mUpdateMonitor .getPhoneState () == TelephonyManager .CALL_STATE_IDLE && !mHasOverlay ) {
561+ final boolean tooManyFaceUnlockTries =
562+ (mFailedFaceUnlockAttempts >= FAILED_FACE_UNLOCK_ATTEMPTS_BEFORE_BACKUP );
563+ final int failedBackupAttempts = mUpdateMonitor .getFailedAttempts ();
564+ final boolean backupIsTimedOut =
565+ (failedBackupAttempts >= LockPatternUtils .FAILED_ATTEMPTS_BEFORE_TIMEOUT );
566+ if (tooManyFaceUnlockTries ) Log .i (TAG , "tooManyFaceUnlockTries: " + tooManyFaceUnlockTries );
567+ if (mUpdateMonitor .getPhoneState () == TelephonyManager .CALL_STATE_IDLE
568+ && !mHasOverlay
569+ && !tooManyFaceUnlockTries
570+ && !backupIsTimedOut ) {
557571 bindToFaceLock ();
558572 // Show FaceLock area, but only for a little bit so lockpattern will become visible if
559573 // FaceLock fails to start or crashes
@@ -1296,7 +1310,7 @@ public void unlock() {
12961310 }
12971311
12981312 // Stops the FaceLock UI and exposes the backup method without unlocking
1299- // This means either the user has cancelled out or FaceLock failed to recognize them
1313+ // This means the user has cancelled out
13001314 @ Override
13011315 public void cancel () {
13021316 if (DEBUG ) Log .d (TAG , "FaceLock cancel()" );
@@ -1305,6 +1319,17 @@ public void cancel() {
13051319 mKeyguardScreenCallback .pokeWakelock (BACKUP_LOCK_TIMEOUT );
13061320 }
13071321
1322+ // Stops the FaceLock UI and exposes the backup method without unlocking
1323+ // This means FaceLock failed to recognize them
1324+ @ Override
1325+ public void reportFailedAttempt () {
1326+ if (DEBUG ) Log .d (TAG , "FaceLock reportFailedAttempt()" );
1327+ mFailedFaceUnlockAttempts ++;
1328+ hideFaceLockArea (); // Expose fallback
1329+ stopFaceLock ();
1330+ mKeyguardScreenCallback .pokeWakelock (BACKUP_LOCK_TIMEOUT );
1331+ }
1332+
13081333 // Allows the Face Unlock service to poke the wake lock to keep the lockscreen alive
13091334 @ Override
13101335 public void pokeWakelock () {
0 commit comments