diff --git a/Signal/src/util/OWSScreenLock.swift b/Signal/src/util/OWSScreenLock.swift index ad054ed57..a518be383 100644 --- a/Signal/src/util/OWSScreenLock.swift +++ b/Signal/src/util/OWSScreenLock.swift @@ -34,7 +34,7 @@ import LocalAuthentication // We don't want the verification process itself to trigger unlock verification. // Passcode-code only authentication process deactivates the app. - private var ignoreUnlock = false + private var ignoreUnlockUntilActive = false // MARK - Singleton class @@ -48,6 +48,21 @@ import LocalAuthentication super.init() SwiftSingletons.register(self) + + NotificationCenter.default.addObserver(self, + selector: #selector(didBecomeActive), + name: NSNotification.Name.OWSApplicationDidBecomeActive, + object: nil) + } + + deinit { + NotificationCenter.default.removeObserver(self) + } + + func didBecomeActive() { + AssertIsOnMainThread() + + ignoreUnlockUntilActive = false } // MARK: - Properties @@ -141,7 +156,7 @@ import LocalAuthentication @objc public func tryToUnlockScreenLock(success: @escaping (() -> Void), failure: @escaping ((Error) -> Void), cancel: @escaping (() -> Void)) { - guard !ignoreUnlock else { + guard !ignoreUnlockUntilActive else { DispatchQueue.main.async { success() } @@ -206,14 +221,10 @@ import LocalAuthentication return } - // Use ignoreUnlock to suppress unlock verifications. - ignoreUnlock = true + // Use ignoreUnlockUntilActive to suppress unlock verifications. + ignoreUnlockUntilActive = 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 c86c1ddbe..6cdb14b81 100644 --- a/Signal/src/util/OWSScreenLockUI.m +++ b/Signal/src/util/OWSScreenLockUI.m @@ -13,6 +13,7 @@ NS_ASSUME_NONNULL_BEGIN // updated conservatively, e.g. the flag is cleared during // "will enter background." @property (nonatomic) BOOL appIsInactive; +@property (nonatomic) BOOL appIsInBackground; @property (nonatomic, nullable) NSDate *appBecameInactiveDate; @property (nonatomic) UIWindow *screenBlockingWindow; @property (nonatomic) BOOL hasUnlockedScreenLock; @@ -64,6 +65,14 @@ NS_ASSUME_NONNULL_BEGIN selector:@selector(applicationWillResignActive:) name:OWSApplicationWillResignActiveNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(applicationWillEnterForeground:) + name:OWSApplicationWillEnterForegroundNotification + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(applicationDidEnterBackground:) + name:OWSApplicationDidEnterBackgroundNotification + object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(registrationStateDidChange) name:RegistrationStateDidChangeNotification @@ -105,6 +114,13 @@ NS_ASSUME_NONNULL_BEGIN [self ensureScreenProtection]; } +- (void)setAppIsInBackground:(BOOL)appIsInBackground +{ + _appIsInBackground = appIsInBackground; + + [self ensureScreenProtection]; +} + - (void)ensureScreenProtection { OWSAssertIsOnMainThread(); @@ -123,12 +139,14 @@ NS_ASSUME_NONNULL_BEGIN // Don't show 'Screen Lock' if 'Screen Lock' isn't enabled. } else if (self.hasUnlockedScreenLock) { // Don't show 'Screen Lock' if 'Screen Lock' has been unlocked. - } 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) { + } else if (self.appIsInBackground) { + // Don't show 'Screen Lock' if app is in background. + } else if (self.appIsInactive) { // Don't show 'Screen Lock' if app is inactive. + } else if (!self.appBecameInactiveDate) { + // Show 'Screen Lock' if app has just launched. + shouldHaveScreenLock = YES; + DDLogVerbose(@"%@, shouldHaveScreenLock 2: %d", self.logTag, self.appIsInBackground); } else { OWSAssert(self.appBecameInactiveDate); @@ -136,13 +154,13 @@ NS_ASSUME_NONNULL_BEGIN NSTimeInterval screenLockTimeout = OWSScreenLock.sharedManager.screenLockTimeout; OWSAssert(screenLockInterval >= 0); OWSAssert(screenLockTimeout >= 0); - if (self.appBecameInactiveDate && screenLockInterval < screenLockTimeout) { + if (screenLockInterval < screenLockTimeout) { // Don't show 'Screen Lock' if 'Screen Lock' timeout hasn't elapsed. shouldHaveScreenLock = NO; } else { // Otherwise, show 'Screen Lock'. shouldHaveScreenLock = YES; - DDLogVerbose(@"%@, shouldHaveScreenLock 1: %d", self.logTag, self.appIsInactive); + DDLogVerbose(@"%@, shouldHaveScreenLock 1: %d", self.logTag, self.appIsInBackground); } } @@ -248,6 +266,16 @@ NS_ASSUME_NONNULL_BEGIN self.appIsInactive = YES; } +- (void)applicationWillEnterForeground:(NSNotification *)notification +{ + self.appIsInBackground = NO; +} + +- (void)applicationDidEnterBackground:(NSNotification *)notification +{ + self.appIsInBackground = YES; +} + @end NS_ASSUME_NONNULL_END