Respond to CR.

pull/1/head
Matthew Chen 7 years ago
parent 930d89242d
commit 72b602c3d8

@ -316,7 +316,8 @@ import LocalAuthentication
let context = LAContext() let context = LAContext()
// If user has set any non-zero timeout, recycle biometric auth // If user has set any non-zero timeout, recycle biometric auth
// in the same period as our normal screen lock timeout. // in the same period as our normal screen lock timeout, up to
// max of 10 seconds.
context.touchIDAuthenticationAllowableReuseDuration = TimeInterval(min(10.0, screenLockTimeout())) context.touchIDAuthenticationAllowableReuseDuration = TimeInterval(min(10.0, screenLockTimeout()))
if #available(iOS 11.0, *) { if #available(iOS 11.0, *) {

@ -13,6 +13,10 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic) UIWindow *screenBlockingWindow; @property (nonatomic) UIWindow *screenBlockingWindow;
@property (nonatomic) UIViewController *screenBlockingViewController; @property (nonatomic) UIViewController *screenBlockingViewController;
@property (nonatomic) UIView *screenBlockingImageView;
@property (nonatomic) UIView *screenBlockingButton;
@property (nonatomic) NSArray<NSLayoutConstraint *> *screenBlockingConstraints;
@property (nonatomic) NSString *screenBlockingSignature;
// Unlike UIApplication.applicationState, this state is // Unlike UIApplication.applicationState, this state is
// updated conservatively, e.g. the flag is cleared during // updated conservatively, e.g. the flag is cleared during
@ -156,7 +160,7 @@ NS_ASSUME_NONNULL_BEGIN
if (self.screenBlockingWindow.hidden != !shouldShowBlockWindow) { if (self.screenBlockingWindow.hidden != !shouldShowBlockWindow) {
DDLogInfo(@"%@, %@.", self.logTag, shouldShowBlockWindow ? @"showing block window" : @"hiding block window"); DDLogInfo(@"%@, %@.", self.logTag, shouldShowBlockWindow ? @"showing block window" : @"hiding block window");
} }
[self updateScreenBlockingWindow:shouldShowBlockWindow shouldHaveScreenLock:shouldHaveScreenLock]; [self updateScreenBlockingWindow:shouldShowBlockWindow shouldHaveScreenLock:shouldHaveScreenLock animated:YES];
if (shouldHaveScreenLock && !self.didLastUnlockAttemptFail) { if (shouldHaveScreenLock && !self.didLastUnlockAttemptFail) {
[self tryToPresentScreenLockUI]; [self tryToPresentScreenLockUI];
@ -208,6 +212,8 @@ NS_ASSUME_NONNULL_BEGIN
// Re-show the unlock UI. // Re-show the unlock UI.
[self ensureScreenProtection]; [self ensureScreenProtection];
}]; }];
[self ensureScreenProtection];
} }
- (BOOL)shouldHaveScreenProtection - (BOOL)shouldHaveScreenProtection
@ -318,12 +324,52 @@ NS_ASSUME_NONNULL_BEGIN
UIViewController *viewController = [UIViewController new]; UIViewController *viewController = [UIViewController new];
viewController.view.backgroundColor = UIColor.ows_materialBlueColor; viewController.view.backgroundColor = UIColor.ows_materialBlueColor;
UIView *rootView = viewController.view;
UIView *edgesView = [UIView containerView];
[rootView addSubview:edgesView];
[edgesView autoPinEdgeToSuperviewEdge:ALEdgeTop];
[edgesView autoPinEdgeToSuperviewEdge:ALEdgeBottom];
[edgesView autoPinWidthToSuperview];
UIImage *image = [UIImage imageNamed:@"logoSignal"];
UIImageView *imageView = [UIImageView new];
imageView.image = image;
[edgesView addSubview:imageView];
[imageView autoHCenterInSuperview];
const CGSize screenSize = UIScreen.mainScreen.bounds.size;
const CGFloat shortScreenDimension = MIN(screenSize.width, screenSize.height);
const CGFloat imageSize = round(shortScreenDimension / 3.f);
[imageView autoSetDimension:ALDimensionWidth toSize:imageSize];
[imageView autoSetDimension:ALDimensionHeight toSize:imageSize];
const CGFloat kButtonHeight = 40.f;
OWSFlatButton *button =
[OWSFlatButton buttonWithTitle:NSLocalizedString(@"SCREEN_LOCK_UNLOCK_SIGNAL",
@"Label for button on lock screen that lets users unlock Signal.")
font:[OWSFlatButton fontForHeight:kButtonHeight]
titleColor:[UIColor ows_materialBlueColor]
backgroundColor:[UIColor whiteColor]
target:self
selector:@selector(showUnlockUI)];
[edgesView addSubview:button];
[button autoSetDimension:ALDimensionHeight toSize:kButtonHeight];
[button autoPinLeadingToSuperviewWithMargin:50.f];
[button autoPinTrailingToSuperviewWithMargin:50.f];
const CGFloat kVMargin = 65.f;
[button autoPinBottomToSuperviewWithMargin:kVMargin];
window.rootViewController = viewController; window.rootViewController = viewController;
self.screenBlockingWindow = window; self.screenBlockingWindow = window;
self.screenBlockingViewController = viewController; self.screenBlockingViewController = viewController;
self.screenBlockingImageView = imageView;
self.screenBlockingButton = button;
[self updateScreenBlockingWindow:YES shouldHaveScreenLock:NO]; [self updateScreenBlockingWindow:YES shouldHaveScreenLock:NO animated:NO];
} }
// The "screen blocking" window has three possible states: // The "screen blocking" window has three possible states:
@ -333,26 +379,19 @@ NS_ASSUME_NONNULL_BEGIN
// * "Screen Lock, local auth UI presented". Move the Signal logo so that it is visible. // * "Screen Lock, local auth UI presented". Move the Signal logo so that it is visible.
// * "Screen Lock, local auth UI not presented". Move the Signal logo so that it is visible, // * "Screen Lock, local auth UI not presented". Move the Signal logo so that it is visible,
// show "unlock" button. // show "unlock" button.
- (void)updateScreenBlockingWindow:(BOOL)shouldShowBlockWindow shouldHaveScreenLock:(BOOL)shouldHaveScreenLock - (void)updateScreenBlockingWindow:(BOOL)shouldShowBlockWindow
shouldHaveScreenLock:(BOOL)shouldHaveScreenLock
animated:(BOOL)animated
{ {
OWSAssertIsOnMainThread(); OWSAssertIsOnMainThread();
self.screenBlockingWindow.hidden = !shouldShowBlockWindow; self.screenBlockingWindow.hidden = !shouldShowBlockWindow;
UIView *rootView = self.screenBlockingViewController.view; UIView *rootView = self.screenBlockingViewController.view;
for (UIView *subview in rootView.subviews) {
[subview removeFromSuperview];
}
UIImage *image = [UIImage imageNamed:@"logoSignal"]; [NSLayoutConstraint deactivateConstraints:self.screenBlockingConstraints];
UIImageView *imageView = [UIImageView new];
imageView.image = image;
const CGSize screenSize = UIScreen.mainScreen.bounds.size; NSMutableArray<NSLayoutConstraint *> *screenBlockingConstraints = [NSMutableArray new];
const CGFloat shortScreenDimension = MIN(screenSize.width, screenSize.height);
const CGFloat imageSize = round(shortScreenDimension / 3.f);
[imageView autoSetDimension:ALDimensionWidth toSize:imageSize];
[imageView autoSetDimension:ALDimensionHeight toSize:imageSize];
BOOL shouldShowUnlockButton = (!self.appIsInactive && !self.appIsInBackground && self.didLastUnlockAttemptFail); BOOL shouldShowUnlockButton = (!self.appIsInactive && !self.appIsInBackground && self.didLastUnlockAttemptFail);
@ -363,41 +402,36 @@ NS_ASSUME_NONNULL_BEGIN
shouldHaveScreenLock, shouldHaveScreenLock,
shouldShowUnlockButton); shouldShowUnlockButton);
if (shouldHaveScreenLock) { NSString *signature = [NSString stringWithFormat:@"%d %d", shouldHaveScreenLock, self.isShowingScreenLockUI];
const CGFloat kVMargin = 50.f; if ([NSObject isNullableObject:self.screenBlockingSignature equalTo:signature]) {
[rootView addSubview:imageView]; // Skip redundant work to avoid interfering with ongoing animations.
[imageView autoHCenterInSuperview]; return;
[imageView autoPinTopToSuperviewWithMargin:kVMargin]; }
const CGFloat kButtonHeight = 40.f; self.screenBlockingButton.hidden = !shouldHaveScreenLock;
OWSFlatButton *button =
[OWSFlatButton buttonWithTitle:NSLocalizedString(@"SCREEN_LOCK_UNLOCK_SIGNAL",
@"Label for button on lock screen that lets users unlock Signal.")
font:[OWSFlatButton fontForHeight:kButtonHeight]
titleColor:[UIColor ows_materialBlueColor]
backgroundColor:[UIColor whiteColor]
target:self
selector:@selector(showUnlockUI)];
[rootView addSubview:button];
[button autoVCenterInSuperview];
[button autoSetDimension:ALDimensionHeight toSize:kButtonHeight];
[button autoPinLeadingToSuperviewWithMargin:50.f];
[button autoPinTrailingToSuperviewWithMargin:50.f];
button.hidden = !shouldShowUnlockButton; if (self.isShowingScreenLockUI) {
const CGFloat kVMargin = 60.f;
[screenBlockingConstraints addObject:[self.screenBlockingImageView autoPinEdge:ALEdgeTop
toEdge:ALEdgeTop
ofView:rootView
withOffset:kVMargin]];
} else { } else {
UIView *edgesView = [UIView containerView]; [screenBlockingConstraints addObject:[self.screenBlockingImageView autoVCenterInSuperview]];
[rootView addSubview:edgesView];
[edgesView autoPinEdgeToSuperviewEdge:ALEdgeTop];
[edgesView autoPinEdgeToSuperviewEdge:ALEdgeBottom];
[edgesView autoPinWidthToSuperview];
[edgesView addSubview:imageView];
[imageView autoCenterInSuperview];
} }
self.screenBlockingConstraints = screenBlockingConstraints;
self.screenBlockingSignature = signature;
if (animated) {
[UIView animateWithDuration:0.35f
animations:^{
[rootView layoutIfNeeded];
}];
} else {
[rootView layoutIfNeeded]; [rootView layoutIfNeeded];
} }
}
- (void)showUnlockUI - (void)showUnlockUI
{ {
@ -434,17 +468,18 @@ NS_ASSUME_NONNULL_BEGIN
self.shouldClearAuthUIWhenActive = YES; self.shouldClearAuthUIWhenActive = YES;
} else { } else {
self.isShowingScreenLockUI = NO; self.isShowingScreenLockUI = NO;
[self ensureScreenProtection];
} }
} }
- (void)applicationDidBecomeActive:(NSNotification *)notification - (void)applicationDidBecomeActive:(NSNotification *)notification
{ {
self.appIsInactive = NO;
if (self.shouldClearAuthUIWhenActive) { if (self.shouldClearAuthUIWhenActive) {
self.shouldClearAuthUIWhenActive = NO; self.shouldClearAuthUIWhenActive = NO;
self.isShowingScreenLockUI = NO; self.isShowingScreenLockUI = NO;
} }
self.appIsInactive = NO;
} }
- (void)applicationWillResignActive:(NSNotification *)notification - (void)applicationWillResignActive:(NSNotification *)notification

Loading…
Cancel
Save