From b012efc12d005d2ecde82398d7a230deab6842cc Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Thu, 22 Mar 2018 17:28:05 -0400 Subject: [PATCH] Fix screen lock presentation logic. --- Signal/src/util/OWSScreenLock.swift | 19 +++++++++++++++++++ Signal/src/util/OWSScreenLockUI.m | 8 +++++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/Signal/src/util/OWSScreenLock.swift b/Signal/src/util/OWSScreenLock.swift index fffe6de24b..ad054ed57b 100644 --- a/Signal/src/util/OWSScreenLock.swift +++ b/Signal/src/util/OWSScreenLock.swift @@ -32,6 +32,10 @@ import LocalAuthentication private let OWSScreenLock_Key_IsScreenLockEnabled = "OWSScreenLock_Key_IsScreenLockEnabled" private let OWSScreenLock_Key_ScreenLockTimeoutSeconds = "OWSScreenLock_Key_ScreenLockTimeoutSeconds" + // We don't want the verification process itself to trigger unlock verification. + // Passcode-code only authentication process deactivates the app. + private var ignoreUnlock = false + // MARK - Singleton class @objc(sharedManager) @@ -137,6 +141,13 @@ import LocalAuthentication @objc public func tryToUnlockScreenLock(success: @escaping (() -> Void), failure: @escaping ((Error) -> Void), cancel: @escaping (() -> Void)) { + guard !ignoreUnlock else { + DispatchQueue.main.async { + success() + } + return + } + tryToVerifyLocalAuthentication(localizedReason: NSLocalizedString("SCREEN_LOCK_REASON_UNLOCK_SCREEN_LOCK", comment: "Description of how and why Signal iOS uses Touch ID/Face ID/Phone Passcode to unlock 'screen lock'."), completion: { (outcome: OWSScreenLockOutcome) in @@ -159,6 +170,7 @@ import LocalAuthentication // isScreenLockEnabled. private func tryToVerifyLocalAuthentication(localizedReason: String, completion completionParam: @escaping ((OWSScreenLockOutcome) -> Void)) { + AssertIsOnMainThread() // Ensure completion is always called on the main thread. let completion = { (outcome: OWSScreenLockOutcome) in @@ -194,7 +206,14 @@ import LocalAuthentication return } + // Use ignoreUnlock to suppress unlock verifications. + ignoreUnlock = true context.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: localizedReason) { success, evaluateError in + + DispatchQueue.main.async { + self.ignoreUnlock = false + } + if success { Logger.info("\(self.logTag) local authentication succeeded.") completion(.success) diff --git a/Signal/src/util/OWSScreenLockUI.m b/Signal/src/util/OWSScreenLockUI.m index d0e26d6119..c86c1ddbed 100644 --- a/Signal/src/util/OWSScreenLockUI.m +++ b/Signal/src/util/OWSScreenLockUI.m @@ -117,9 +117,7 @@ NS_ASSUME_NONNULL_BEGIN } BOOL shouldHaveScreenLock = NO; - if (self.appIsInactive) { - // Don't show 'Screen Lock' if app is inactive. - } else if (![TSAccountManager isRegistered]) { + if (![TSAccountManager isRegistered]) { // Don't show 'Screen Lock' if user is not registered. } else if (!OWSScreenLock.sharedManager.isScreenLockEnabled) { // Don't show 'Screen Lock' if 'Screen Lock' isn't enabled. @@ -128,6 +126,9 @@ NS_ASSUME_NONNULL_BEGIN } else if (!self.appBecameInactiveDate) { // Show 'Screen Lock' if app hasn't become inactive yet (just launched). shouldHaveScreenLock = YES; + DDLogVerbose(@"%@, shouldHaveScreenLock 2: %d", self.logTag, self.appIsInactive); + } else if (!self.appIsInactive) { + // Don't show 'Screen Lock' if app is inactive. } else { OWSAssert(self.appBecameInactiveDate); @@ -141,6 +142,7 @@ NS_ASSUME_NONNULL_BEGIN } else { // Otherwise, show 'Screen Lock'. shouldHaveScreenLock = YES; + DDLogVerbose(@"%@, shouldHaveScreenLock 1: %d", self.logTag, self.appIsInactive); } }