Commit 79fb6edf authored by Carola Nitz's avatar Carola Nitz

VLCKeychainCoordinator: fix multiple queries for touchid

Removed state and the passcodevalidation notification in favor of a completion block.
Removed > iOS8 check
parent edc273ed
......@@ -31,8 +31,6 @@ extern NSString *const VLCDropboxSessionWasAuthorized;
@property (nonatomic, strong) UIWindow *window;
@property (nonatomic, readonly) BOOL passcodeValidated;
@property (atomic, strong) id<OIDAuthorizationFlowSession> currentGoogleAuthorizationFlow;
@end
......@@ -36,6 +36,7 @@
#import "VLCDropboxConstants.h"
#import <ObjectiveDropboxOfficial/ObjectiveDropboxOfficial.h>
#import "VLCPlaybackNavigationController.h"
#import "PAPasscodeViewController.h"
NSString *const VLCDropboxSessionWasAuthorized = @"VLCDropboxSessionWasAuthorized";
......@@ -43,7 +44,6 @@ NSString *const VLCDropboxSessionWasAuthorized = @"VLCDropboxSessionWasAuthorize
@interface VLCAppDelegate () <VLCMediaFileDiscovererDelegate>
{
BOOL _passcodeValidated;
BOOL _isRunningMigration;
BOOL _isComingFromHandoff;
VLCWatchCommunication *_watchCommunication;
......@@ -99,12 +99,6 @@ NSString *const VLCDropboxSessionWasAuthorized = @"VLCDropboxSessionWasAuthorize
// Configure Dropbox
[DBClientsManager setupWithAppKey:kVLCDropboxAppKey];
/* listen to validation notification */
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(passcodeWasValidated:)
name:VLCPasscodeValidated
object:nil];
[self setupAppearence];
// Init the HTTP Server and clean its cache
......@@ -113,18 +107,23 @@ NSString *const VLCDropboxSessionWasAuthorized = @"VLCDropboxSessionWasAuthorize
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// enable crash preventer
void (^setupBlock)() = ^{
_libraryViewController = [[VLCLibraryViewController alloc] init];
VLCSidebarController *sidebarVC = [VLCSidebarController sharedInstance];
UINavigationController *navCon = [[UINavigationController alloc] initWithRootViewController:_libraryViewController];
sidebarVC.contentViewController = navCon;
__weak typeof(self) weakSelf = self;
void (^setupLibraryBlock)() = ^{
_libraryViewController = [[VLCLibraryViewController alloc] init];
UINavigationController *navCon = [[UINavigationController alloc] initWithRootViewController:_libraryViewController];
VLCPlayerDisplayController *playerDisplayController = [VLCPlayerDisplayController sharedInstance];
playerDisplayController.childViewController = sidebarVC.fullViewController;
VLCSidebarController *sidebarVC = [VLCSidebarController sharedInstance];
sidebarVC.contentViewController = navCon;
self.window.rootViewController = playerDisplayController;
[self.window makeKeyAndVisible];
VLCPlayerDisplayController *playerDisplayController = [VLCPlayerDisplayController sharedInstance];
playerDisplayController.childViewController = sidebarVC.fullViewController;
[self validatePasscode];
weakSelf.window.rootViewController = playerDisplayController;
};
UINavigationController *navCon = [[UINavigationController alloc] initWithRootViewController:[[UIViewController alloc] init]];
self.window.rootViewController = navCon;
[self.window makeKeyAndVisible];
[self validatePasscodeIfNeededWithCompletion:setupLibraryBlock];
BOOL spotlightEnabled = ![[VLCKeychainCoordinator defaultCoordinator] passcodeLockEnabled];
[[MLMediaLibrary sharedMediaLibrary] setSpotlightIndexingEnabled:spotlightEnabled];
......@@ -407,8 +406,20 @@ didFailToContinueUserActivityWithType:(NSString *)userActivityType
- (void)applicationWillResignActive:(UIApplication *)application
{
_passcodeValidated = NO;
[self validatePasscode];
//Touch ID is shown
if ([_window.rootViewController.presentedViewController isKindOfClass:[UINavigationController class]]){
UINavigationController *navCon = (UINavigationController *)_window.rootViewController.presentedViewController;
if ([navCon.topViewController isKindOfClass:[PAPasscodeViewController class]]){
return;
}
}
__weak typeof(self) weakself = self;
[self validatePasscodeIfNeededWithCompletion:^{
[weakself.libraryViewController updateViewContents];
if ([VLCPlaybackController sharedInstance].isPlaying){
[[VLCPlayerDisplayController sharedInstance] pushPlaybackView];
}
}];
[[MLMediaLibrary sharedMediaLibrary] applicationWillExit];
}
......@@ -424,7 +435,6 @@ didFailToContinueUserActivityWithType:(NSString *)userActivityType
- (void)applicationWillTerminate:(UIApplication *)application
{
_passcodeValidated = NO;
[[NSUserDefaults standardUserDefaults] synchronize];
}
......@@ -465,30 +475,15 @@ didFailToContinueUserActivityWithType:(NSString *)userActivityType
#pragma mark - pass code validation
- (void)passcodeWasValidated:(NSNotification *)aNotifcation
{
_passcodeValidated = YES;
[self.libraryViewController updateViewContents];
if ([VLCPlaybackController sharedInstance].isPlaying)
[[VLCPlayerDisplayController sharedInstance] pushPlaybackView];
}
- (BOOL)passcodeValidated
{
return _passcodeValidated;
}
- (void)validatePasscode
- (void)validatePasscodeIfNeededWithCompletion:(void(^)(void))completion
{
VLCKeychainCoordinator *keychainCoordinator = [VLCKeychainCoordinator defaultCoordinator];
if (!_passcodeValidated && [keychainCoordinator passcodeLockEnabled]) {
if ([keychainCoordinator passcodeLockEnabled]) {
[[VLCPlayerDisplayController sharedInstance] dismissPlaybackView];
[keychainCoordinator validatePasscode];
[keychainCoordinator validatePasscodeWithCompletion:completion];
} else {
_passcodeValidated = YES;
[self passcodeValidated];
completion();
}
}
......
......@@ -10,15 +10,13 @@
* Refer to the COPYING file of the official project for license.
*****************************************************************************/
extern NSString *const VLCPasscodeValidated;
@interface VLCKeychainCoordinator : NSObject
+ (instancetype)defaultCoordinator;
@property (readonly) BOOL passcodeLockEnabled;
- (void)validatePasscode;
- (void)validatePasscodeWithCompletion:(void(^)(void))completion;
- (void)setPasscode:(NSString *)passcode;
@end
......@@ -12,20 +12,16 @@
#import "VLCKeychainCoordinator.h"
#import "PAPasscodeViewController.h"
#import "VLCAppDelegate.h"
#import <XKKeychain/XKKeychainGenericPasswordItem.h>
#import <LocalAuthentication/LocalAuthentication.h>
NSString *const VLCPasscodeValidated = @"VLCPasscodeValidated";
NSString *const VLCPasscode = @"org.videolan.vlc-ios.passcode";
@interface VLCKeychainCoordinator () <PAPasscodeViewControllerDelegate>
{
PAPasscodeViewController *_passcodeLockController;
NSDictionary *_passcodeQuery;
BOOL _inValidation;
BOOL _inTouchID;
__weak void (^_completion)(void);
BOOL _avoidPromptingTouchID;
}
@end
......@@ -57,19 +53,14 @@ NSString *const VLCPasscode = @"org.videolan.vlc-ios.passcode";
return self;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)appInForeground:(NSNotification *)notification
{
/* our touch ID session is killed by the OS if the app moves to background, so re-init */
if (_inValidation) {
if (SYSTEM_RUNS_IOS8_OR_LATER) {
if ([[NSUserDefaults standardUserDefaults] boolForKey:kVLCSettingPasscodeAllowTouchID]) {
[self _touchIDQuery];
}
UIViewController *rootViewController = [UIApplication sharedApplication].delegate.window.rootViewController;
if ([rootViewController.presentedViewController isKindOfClass:[UINavigationController class]]){
UINavigationController *navCon = (UINavigationController *)rootViewController.presentedViewController;
if ([navCon.topViewController isKindOfClass:[PAPasscodeViewController class]] && [self touchIDEnabled]){
[self _touchIDQuery];
}
}
}
......@@ -86,89 +77,78 @@ NSString *const VLCPasscode = @"org.videolan.vlc-ios.passcode";
[XKKeychainGenericPasswordItem removeItemsForService:VLCPasscode error:nil];
[defaults setBool:YES forKey:kVLCSettingPasscodeResetOnUpgrade];
[defaults synchronize];
return nil;
}
- (BOOL)passcodeLockEnabled
- (BOOL)touchIDEnabled
{
NSString *passcode = [self _obtainPasscode];
if (!passcode)
return NO;
if (passcode.length == 0)
return NO;
return YES;
return [[NSUserDefaults standardUserDefaults] boolForKey:kVLCSettingPasscodeAllowTouchID];
}
- (void)validatePasscode
- (BOOL)passcodeLockEnabled
{
/* we may be called repeatedly as Touch ID uses an out-of-process dialog */
if (_inValidation)
return;
_inValidation = YES;
return [[NSUserDefaults standardUserDefaults] boolForKey:kVLCSettingPasscodeOnKey];
}
- (void)validatePasscodeWithCompletion:(void(^)(void))completion
{
NSString *passcode = [self _obtainPasscode];
if (passcode == nil || [passcode isEqualToString:@""]) {
[[NSNotificationCenter defaultCenter] postNotificationName:VLCPasscodeValidated object:self];
completion();
return;
}
_passcodeLockController = [[PAPasscodeViewController alloc] initForAction:PasscodeActionEnter];
_passcodeLockController.delegate = self;
_passcodeLockController.passcode = passcode;
_completion = completion;
VLCAppDelegate *appDelegate = (VLCAppDelegate *)[UIApplication sharedApplication].delegate;
UIViewController *rootViewController = [UIApplication sharedApplication].delegate.window.rootViewController;
if (appDelegate.window.rootViewController.presentedViewController)
[appDelegate.window.rootViewController dismissViewControllerAnimated:NO completion:nil];
if (rootViewController.presentedViewController)
[rootViewController dismissViewControllerAnimated:NO completion:nil];
UINavigationController *navCon = [[UINavigationController alloc] initWithRootViewController:_passcodeLockController];
navCon.modalPresentationStyle = UIModalPresentationFullScreen;
[appDelegate.window.rootViewController presentViewController:navCon animated:NO completion:nil];
if (SYSTEM_RUNS_IOS8_OR_LATER) {
[rootViewController presentViewController:navCon animated:YES completion:^{
if ([[NSUserDefaults standardUserDefaults] boolForKey:kVLCSettingPasscodeAllowTouchID]) {
[self _touchIDQuery];
}
}
}];
}
- (void)_touchIDQuery
{
/* don't launch multiple times */
if (_inTouchID)
//if we just entered background don't show TouchID
if (_avoidPromptingTouchID || [UIApplication sharedApplication].applicationState == UIApplicationStateInactive)
return;
_inTouchID = YES;
LAContext *myContext = [[LAContext alloc] init];
if ([myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:nil]) {
_avoidPromptingTouchID = YES;
[myContext evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
localizedReason:NSLocalizedString(@"TOUCHID_UNLOCK", nil)
reply:^(BOOL success, NSError *error) {
if (success) {
[self PAPasscodeViewControllerDidEnterPasscode:nil];
} else if (error.code == LAErrorSystemCancel)
_inTouchID = NO;
//if we cancel we don't want to show TouchID again
dispatch_async(dispatch_get_main_queue(), ^{
_avoidPromptingTouchID = !success;
if (success) {
[[UIApplication sharedApplication].delegate.window.rootViewController dismissViewControllerAnimated:YES completion:^{
_completion();
}];
}
});
}];
}
}
- (void)PAPasscodeViewControllerDidEnterPasscode:(PAPasscodeViewController *)controller
{
if (![NSThread isMainThread]) {
[self performSelectorOnMainThread:@selector(PAPasscodeViewControllerDidEnterPasscode:) withObject:controller waitUntilDone:NO];
return;
}
[[NSNotificationCenter defaultCenter] postNotificationName:VLCPasscodeValidated object:self];
VLCAppDelegate *appDelegate = (VLCAppDelegate *)[UIApplication sharedApplication].delegate;
[appDelegate.window.rootViewController dismissViewControllerAnimated:YES completion:nil];
_inValidation = NO;
_inTouchID = NO;
_avoidPromptingTouchID = NO;
[[UIApplication sharedApplication].delegate.window.rootViewController dismissViewControllerAnimated:YES completion:^{
_completion();
}];
}
- (void)PAPasscodeViewController:(PAPasscodeViewController *)controller didFailToEnterPasscode:(NSInteger)attempts
......
......@@ -450,11 +450,6 @@ static NSString *kUsingTableViewToShowData = @"UsingTableViewToShowData";
- (void)updateViewContents
{
if (![(VLCAppDelegate *)[UIApplication sharedApplication].delegate passcodeValidated]) {
APLog(@"library is locked, won't show contents");
return;
}
self.navigationItem.leftBarButtonItem = _menuButton;
[_mediaDataSource updateContentsForSelection:nil];
_removeFromFolderBarButtonItem.enabled = NO;
......
......@@ -47,12 +47,6 @@
selector:@selector(appBecameActive:)
name:UIApplicationDidBecomeActiveNotification
object:nil];
#if TARGET_OS_IOS
[center addObserver:self
selector:@selector(appBecameActive:)
name:VLCPasscodeValidated
object:nil];
#endif
}
return self;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment