Merge branch 'charlesmchen/screenLock3'

This commit is contained in:
Matthew Chen 2018-03-22 18:08:30 -04:00
commit 4fe5432ac6
4 changed files with 40 additions and 27 deletions

View file

@ -95,7 +95,7 @@ NS_ASSUME_NONNULL_BEGIN
if (OWSScreenLock.sharedManager.isScreenLockEnabled) {
OWSTableSection *screenLockTimeoutSection = [OWSTableSection new];
uint32_t screenLockTimeout = (uint32_t)round(OWSScreenLock.sharedManager.screenLockTimeout);
NSString *screenLockTimeoutString = [self formatScreenLockTimeout:screenLockTimeout];
NSString *screenLockTimeoutString = [self formatScreenLockTimeout:screenLockTimeout useShortFormat:YES];
[screenLockTimeoutSection
addItem:[OWSTableItem
disclosureItemWithText:
@ -111,14 +111,10 @@ NS_ASSUME_NONNULL_BEGIN
OWSTableSection *screenSecuritySection = [OWSTableSection new];
screenSecuritySection.headerTitle = NSLocalizedString(@"SETTINGS_SECURITY_TITLE", @"Section header");
screenSecuritySection.footerTitle = NSLocalizedString(@"SETTINGS_SCREEN_SECURITY_DETAIL", nil);
[screenSecuritySection
addItem:[OWSTableItem switchItemWithText:NSLocalizedString(@"SETTINGS_SCREEN_SECURITY", @"")
// If 'Screen Lock' is enabled, 'Screen Protection' is auto-enabled.
isOn:([Environment.preferences screenSecurityIsEnabled]
|| OWSScreenLock.sharedManager.isScreenLockEnabled)
isEnabled:!OWSScreenLock.sharedManager.isScreenLockEnabled
target:weakSelf
selector:@selector(didToggleScreenSecuritySwitch:)]];
[screenSecuritySection addItem:[OWSTableItem switchItemWithText:NSLocalizedString(@"SETTINGS_SCREEN_SECURITY", @"")
isOn:[Environment.preferences screenSecurityIsEnabled]
target:weakSelf
selector:@selector(didToggleScreenSecuritySwitch:)]];
[contents addSection:screenSecuritySection];
OWSTableSection *removeMetadataSection = [OWSTableSection new];
@ -361,7 +357,7 @@ NS_ASSUME_NONNULL_BEGIN
preferredStyle:UIAlertControllerStyleActionSheet];
for (NSNumber *timeoutValue in OWSScreenLock.sharedManager.screenLockTimeouts) {
uint32_t screenLockTimeout = (uint32_t)round(timeoutValue.doubleValue);
NSString *screenLockTimeoutString = [self formatScreenLockTimeout:screenLockTimeout];
NSString *screenLockTimeoutString = [self formatScreenLockTimeout:screenLockTimeout useShortFormat:NO];
[controller addAction:[UIAlertAction actionWithTitle:screenLockTimeoutString
style:UIAlertActionStyleDefault
@ -375,13 +371,13 @@ NS_ASSUME_NONNULL_BEGIN
[fromViewController presentViewController:controller animated:YES completion:nil];
}
- (NSString *)formatScreenLockTimeout:(NSInteger)value
- (NSString *)formatScreenLockTimeout:(NSInteger)value useShortFormat:(BOOL)useShortFormat
{
if (value <= 1) {
return NSLocalizedString(@"SCREEN_LOCK_ACTIVITY_TIMEOUT_NONE",
@"Indicates a delay of zero seconds, and that 'screen lock activity' will timeout immediately.");
}
return [NSString formatDurationSeconds:(uint32_t)value useShortFormat:YES];
return [NSString formatDurationSeconds:(uint32_t)value useShortFormat:useShortFormat];
}
@end

View file

@ -10,18 +10,16 @@ import LocalAuthentication
public enum OWSScreenLockOutcome {
case success
case cancel
// case userCancel
// case otherCancel
case failure(error:String)
// case permanentFailure(error:String)
}
@objc public let screenLockTimeoutDefault = 15 * kMinuteInterval
@objc public let screenLockTimeouts = [
5 * kSecondInterval,
15 * kSecondInterval,
30 * kSecondInterval,
1 * kMinuteInterval,
5 * kMinuteInterval,
15 * kMinuteInterval,
30 * kMinuteInterval,
1 * kHourInterval,
0
]
@ -34,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)
@ -78,8 +80,7 @@ import LocalAuthentication
return 0
}
let defaultTimeout = screenLockTimeouts[0]
return self.dbConnection.double(forKey: OWSScreenLock_Key_ScreenLockTimeoutSeconds, inCollection: OWSScreenLock_Collection, defaultValue: defaultTimeout)
return self.dbConnection.double(forKey: OWSScreenLock_Key_ScreenLockTimeoutSeconds, inCollection: OWSScreenLock_Collection, defaultValue: screenLockTimeoutDefault)
}
@objc public func setScreenLockTimeout(_ value: TimeInterval) {
@ -140,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
@ -162,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
@ -197,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)

View file

@ -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,15 +142,15 @@ NS_ASSUME_NONNULL_BEGIN
} else {
// Otherwise, show 'Screen Lock'.
shouldHaveScreenLock = YES;
DDLogVerbose(@"%@, shouldHaveScreenLock 1: %d", self.logTag, self.appIsInactive);
}
}
// Show 'Screen Protection' if:
//
// * App is inactive and...
// * Either 'Screen Protection' or 'Screen Lock' is enabled.
BOOL shouldHaveScreenProtection = (self.appIsInactive
&& (Environment.preferences.screenSecurityIsEnabled || OWSScreenLock.sharedManager.isScreenLockEnabled));
// * 'Screen Protection' is enabled.
BOOL shouldHaveScreenProtection = (self.appIsInactive && Environment.preferences.screenSecurityIsEnabled);
BOOL shouldShowBlockWindow = shouldHaveScreenProtection || shouldHaveScreenLock;
DDLogVerbose(@"%@, shouldHaveScreenProtection: %d, shouldHaveScreenLock: %d, shouldShowBlockWindow: %d",

View file

@ -1538,7 +1538,7 @@
"SCAN_QR_CODE_VIEW_TITLE" = "Scan QR Code";
/* Indicates a delay of zero seconds, and that 'screen lock activity' will timeout immediately. */
"SCREEN_LOCK_ACTIVITY_TIMEOUT_NONE" = "None";
"SCREEN_LOCK_ACTIVITY_TIMEOUT_NONE" = "Instant";
/* Title for alert indicating that screen lock could not be disabled. */
"SCREEN_LOCK_DISABLE_FAILED" = "Screen Lock Could Not Be Disabled";