Fix screen lock presentation logic.

This commit is contained in:
Matthew Chen 2018-03-22 18:38:31 -04:00
parent 4fe5432ac6
commit 0e00428da5
2 changed files with 54 additions and 15 deletions

View file

@ -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)

View file

@ -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