From eb9c65e975347f80dee05c3e34deedb7f6537bb3 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 28 Mar 2018 12:32:57 -0400 Subject: [PATCH] Improve handling of local authentication errors. --- Signal/src/util/OWSScreenLock.swift | 16 ++++++++++++---- Signal/src/util/OWSScreenLockUI.m | 10 ++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/Signal/src/util/OWSScreenLock.swift b/Signal/src/util/OWSScreenLock.swift index d8ae13f3b..4b19231ba 100644 --- a/Signal/src/util/OWSScreenLock.swift +++ b/Signal/src/util/OWSScreenLock.swift @@ -11,6 +11,7 @@ import LocalAuthentication case success case cancel case failure(error:String) + case unexpectedFailure(error:String) } @objc public let screenLockTimeoutDefault = 15 * kMinuteInterval @@ -122,6 +123,8 @@ import LocalAuthentication switch outcome { case .failure(let error): completion(self.authenticationError(errorDescription: error)) + case .unexpectedFailure(let error): + completion(self.authenticationError(errorDescription: error)) case .success: self.setIsScreenLockEnabled(value: true) completion(nil) @@ -144,6 +147,8 @@ import LocalAuthentication switch outcome { case .failure(let error): completion(self.authenticationError(errorDescription: error)) + case .unexpectedFailure(let error): + completion(self.authenticationError(errorDescription: error)) case .success: self.setIsScreenLockEnabled(value: false) completion(nil) @@ -155,6 +160,7 @@ import LocalAuthentication @objc public func tryToUnlockScreenLock(success: @escaping (() -> Void), failure: @escaping ((Error) -> Void), + unexpectedFailure: @escaping ((Error) -> Void), cancel: @escaping (() -> Void)) { guard !ignoreUnlockUntilActive else { DispatchQueue.main.async { @@ -171,6 +177,8 @@ import LocalAuthentication switch outcome { case .failure(let error): failure(self.authenticationError(errorDescription: error)) + case .unexpectedFailure(let error): + unexpectedFailure(self.authenticationError(errorDescription: error)) case .success: success() case .cancel: @@ -215,7 +223,7 @@ import LocalAuthentication case .success: owsFail("\(self.logTag) local authentication unexpected success") completion(.failure(error:defaultErrorDescription)) - case .cancel, .failure: + case .cancel, .failure, .unexpectedFailure: completion(outcome) } return @@ -235,7 +243,7 @@ import LocalAuthentication case .success: owsFail("\(self.logTag) local authentication unexpected success") completion(.failure(error:defaultErrorDescription)) - case .cancel, .failure: + case .cancel, .failure, .unexpectedFailure: completion(outcome) } } @@ -296,10 +304,10 @@ import LocalAuthentication comment: "Indicates that Touch ID/Face ID/Phone Passcode is 'locked out' on this device due to authentication failures.")) case .invalidContext: owsFail("\(self.logTag) context not valid.") - return .failure(error:defaultErrorDescription) + return .unexpectedFailure(error:defaultErrorDescription) case .notInteractive: owsFail("\(self.logTag) context not interactive.") - return .failure(error:defaultErrorDescription) + return .unexpectedFailure(error:defaultErrorDescription) } } return .failure(error:defaultErrorDescription) diff --git a/Signal/src/util/OWSScreenLockUI.m b/Signal/src/util/OWSScreenLockUI.m index 41e24c563..9cdfde474 100644 --- a/Signal/src/util/OWSScreenLockUI.m +++ b/Signal/src/util/OWSScreenLockUI.m @@ -202,6 +202,16 @@ NS_ASSUME_NONNULL_BEGIN [self showScreenLockFailureAlertWithMessage:error.localizedDescription]; } + unexpectedFailure:^(NSError *error) { + DDLogInfo(@"%@ unlock screen lock unexpectedly failed.", self.logTag); + + // Local Authentication isn't working properly. + // This isn't covered by the docs or the forums but in practice + // it appears to be effective to retry again after waiting a bit. + dispatch_async(dispatch_get_main_queue(), ^{ + [self clearAuthUIWhenActive]; + }); + } cancel:^{ DDLogInfo(@"%@ unlock screen lock cancelled.", self.logTag);