Prechádzať zdrojové kódy

VLCKeychainCoordinator: fix multiple queries for touchid

Removed state and the passcodevalidation notification in favor of a completion block.
Removed > iOS8 check
Carola Nitz 7 rokov pred
rodič
commit
79fb6edf82

+ 0 - 2
Sources/VLCAppDelegate.h

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

+ 33 - 38
Sources/VLCAppDelegate.m

@@ -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();
     }
 }
 

+ 1 - 3
Sources/VLCKeychainCoordinator.h

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

+ 38 - 58
Sources/VLCKeychainCoordinator.m

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

+ 0 - 5
Sources/VLCLibraryViewController.m

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

+ 0 - 6
Sources/VLCMiniPlaybackView.m

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