From feb5d68f83c60a96e83557fa70553be33628c088 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Tue, 27 Mar 2018 12:58:21 -0400 Subject: [PATCH] Improve handling of unexpected failures in local authentication. --- Signal/src/util/OWSScreenLock.swift | 19 +++++++++++++++---- Signal/src/util/OWSScreenLockUI.m | 13 ++++++++++++- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/Signal/src/util/OWSScreenLock.swift b/Signal/src/util/OWSScreenLock.swift index a518be383..9db55613b 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.") - break + return .unexpectedFailure(error:defaultErrorDescription) case .notInteractive: owsFail("\(self.logTag) context not interactive.") - break + return .unexpectedFailure(error:defaultErrorDescription) } } return .failure(error:defaultErrorDescription) @@ -316,6 +324,9 @@ import LocalAuthentication let context = LAContext() context.touchIDAuthenticationAllowableReuseDuration = TimeInterval(screenLockTimeout()) + if #available(iOS 11.0, *) { + assert(!context.interactionNotAllowed) + } return context } diff --git a/Signal/src/util/OWSScreenLockUI.m b/Signal/src/util/OWSScreenLockUI.m index a6ace8ec6..3e1977e55 100644 --- a/Signal/src/util/OWSScreenLockUI.m +++ b/Signal/src/util/OWSScreenLockUI.m @@ -145,6 +145,9 @@ NS_ASSUME_NONNULL_BEGIN shouldHaveScreenProtection, shouldHaveScreenLock, shouldShowBlockWindow); + if (self.screenBlockingWindow.hidden != shouldShowBlockWindow) { + DDLogInfo(@"%@, %@.", self.logTag, shouldShowBlockWindow ? @"showing block window" : @"hiding block window"); + } self.screenBlockingWindow.hidden = !shouldShowBlockWindow; [self.screenLockUITimer invalidate]; @@ -199,7 +202,7 @@ NS_ASSUME_NONNULL_BEGIN return; } - DDLogVerbose(@"%@, try to unlock screen lock", self.logTag); + DDLogInfo(@"%@, try to unlock screen lock", self.logTag); self.isShowingScreenLockUI = YES; self.lastUnlockAttemptDate = [NSDate new]; @@ -217,6 +220,14 @@ NS_ASSUME_NONNULL_BEGIN [self showScreenLockFailureAlertWithMessage:error.localizedDescription]; } + unexpectedFailure:^(NSError *error) { + DDLogInfo(@"%@ unlock screen lock unexpectedly failed.", self.logTag); + self.isShowingScreenLockUI = NO; + + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [self ensureScreenProtection]; + }); + } cancel:^{ DDLogInfo(@"%@ unlock screen lock cancelled.", self.logTag); self.isShowingScreenLockUI = NO;