diff --git a/platform-darwin/External/Pearl b/platform-darwin/External/Pearl index c74e9635..0dbcd1ce 160000 --- a/platform-darwin/External/Pearl +++ b/platform-darwin/External/Pearl @@ -1 +1 @@ -Subproject commit c74e9635377568b4c8a4bd63f7b081288c8e4f49 +Subproject commit 0dbcd1cebc640a2498b63ff8d25dffb6bfc89577 diff --git a/platform-darwin/MasterPassword-iOS.xcodeproj/project.pbxproj b/platform-darwin/MasterPassword-iOS.xcodeproj/project.pbxproj index cbf2673a..ed0a8821 100644 --- a/platform-darwin/MasterPassword-iOS.xcodeproj/project.pbxproj +++ b/platform-darwin/MasterPassword-iOS.xcodeproj/project.pbxproj @@ -17,6 +17,7 @@ 93D392EC39DA43C46C692C12 /* NSDictionary+Indexing.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D393B97158D7BE9332EA53 /* NSDictionary+Indexing.h */; }; 93D392FD5E2052F7D7DB3774 /* NSString+MPMarkDown.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39C41A27AA42D044D68AE /* NSString+MPMarkDown.m */; }; 93D3932889B6B4206E66A6D6 /* PearlEMail.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D39F7C9F47BF6387FBC5C3 /* PearlEMail.h */; }; + 93D39359B0DF9823F6C56A05 /* PearlHangDetector.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D39D8508BF868907E9732E /* PearlHangDetector.h */; }; 93D39392DEDA376F93C6C718 /* MPCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39BAA71DE51B4D8A1286C /* MPCell.m */; }; 93D3939661CE37180AF7CD6A /* MPStoreViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D3957D76F71A652716EECC /* MPStoreViewController.m */; }; 93D393AA69A1193401160418 /* UIView+AlphaScale.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39488AB33616661725929 /* UIView+AlphaScale.m */; }; @@ -26,6 +27,7 @@ 93D394B5036C882B33C71872 /* MPSitesSegue.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39E7A12CC352B2825AA66 /* MPSitesSegue.m */; }; 93D39508A6814612A5B3C226 /* MPMessageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D399B36CDB2004D7C51391 /* MPMessageViewController.m */; }; 93D39536EB550E811CCD04BC /* UIResponder+PearlFirstResponder.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D394482BB07F90E8FD1314 /* UIResponder+PearlFirstResponder.h */; }; + 93D395373A425B05C86B2268 /* PearlHangDetector.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39BDA5DB85FCDE4E6450A /* PearlHangDetector.m */; }; 93D3954E96236384AFA00453 /* UIScrollView+PearlAdjustInsets.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D390FB3110DCCE68E600DC /* UIScrollView+PearlAdjustInsets.m */; }; 93D3954FCE045A3CC7E804B7 /* MPUsersViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D399E571F61E50A9BF8FAF /* MPUsersViewController.m */; }; 93D3957237D303DE2D38C267 /* MPAvatarCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39B381350802A194BF332 /* MPAvatarCell.m */; }; @@ -542,6 +544,7 @@ 93D39B455A71EC98C749E623 /* MPOverlayViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOverlayViewController.h; sourceTree = ""; }; 93D39B7B765546B1F1900CB7 /* UIView+Visible.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+Visible.h"; sourceTree = ""; }; 93D39BAA71DE51B4D8A1286C /* MPCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPCell.m; sourceTree = ""; }; + 93D39BDA5DB85FCDE4E6450A /* PearlHangDetector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlHangDetector.m; sourceTree = ""; }; 93D39C41A27AA42D044D68AE /* NSString+MPMarkDown.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSString+MPMarkDown.m"; path = "iOS/NSString+MPMarkDown.m"; sourceTree = ""; }; 93D39C426E03358384018E85 /* MPAnswersViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAnswersViewController.m; sourceTree = ""; }; 93D39C44361BE57AF0B3071F /* MPSitesSegue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSitesSegue.h; sourceTree = ""; }; @@ -554,6 +557,7 @@ 93D39D4E713564B7654341B0 /* mpw-algorithm_v3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "mpw-algorithm_v3.c"; sourceTree = ""; }; 93D39D6604447D7708039155 /* MPAnswersViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAnswersViewController.h; sourceTree = ""; }; 93D39D72239990DDAC2D75B0 /* MPTypes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPTypes.m; sourceTree = ""; }; + 93D39D8508BF868907E9732E /* PearlHangDetector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlHangDetector.h; sourceTree = ""; }; 93D39D8A953779B35403AF6E /* PearlUICollectionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlUICollectionView.m; sourceTree = ""; }; 93D39DA27D768B53C8B1330C /* MPAvatarCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAvatarCell.h; sourceTree = ""; }; 93D39DE2CB351D4E3789462B /* UIScrollView+PearlAdjustInsets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIScrollView+PearlAdjustInsets.h"; sourceTree = ""; }; @@ -3061,6 +3065,8 @@ DAFE45F915039823003ABA7C /* Resources */, 93D39FBF8FCEB4C106272334 /* NSOrderedSetOrArray.h */, 93D39789AAF49338F8AC8B02 /* NSOrderedSetOrArray.m */, + 93D39BDA5DB85FCDE4E6450A /* PearlHangDetector.m */, + 93D39D8508BF868907E9732E /* PearlHangDetector.h */, ); path = Pearl; sourceTree = ""; @@ -3287,6 +3293,7 @@ 93D3959696396A91961C6148 /* UIView+AlphaScale.h in Headers */, 93D39BFB5F5F9337F6565DE3 /* UIView+Visible.h in Headers */, 93D39861AEE621B287EA93E9 /* PearlLinks.h in Headers */, + 93D39359B0DF9823F6C56A05 /* PearlHangDetector.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4003,6 +4010,7 @@ 93D393AA69A1193401160418 /* UIView+AlphaScale.m in Sources */, 93D3942C1B117EE4851AA7B6 /* UIView+Visible.m in Sources */, 93D397FCAAC6FA885247A4F9 /* PearlLinks.m in Sources */, + 93D395373A425B05C86B2268 /* PearlHangDetector.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/platform-darwin/Source/iOS/MPiOSAppDelegate.m b/platform-darwin/Source/iOS/MPiOSAppDelegate.m index c8b85f4a..f24b639d 100644 --- a/platform-darwin/Source/iOS/MPiOSAppDelegate.m +++ b/platform-darwin/Source/iOS/MPiOSAppDelegate.m @@ -21,11 +21,10 @@ #import "MPAppDelegate_Store.h" #import "MPStoreViewController.h" -#define MP_HANG_TIME_MAIN 3 // s - @interface MPiOSAppDelegate() @property(nonatomic, strong) UIDocumentInteractionController *interactionController; +@property(nonatomic, strong) PearlHangDetector *hangDetector; @end @@ -37,7 +36,7 @@ dispatch_once( &once, ^{ [PearlLogger get].historyLevel = [[MPiOSConfig get].traceMode boolValue]? PearlLogLevelTrace: PearlLogLevelInfo; #ifdef DEBUG - [PearlLogger get].printLevel = PearlLogLevelDebug; //Trace; + [PearlLogger get].printLevel = PearlLogLevelTrace; #else [PearlLogger get].printLevel = [[MPiOSConfig get].traceMode boolValue]? PearlLogLevelDebug: PearlLogLevelInfo; #endif @@ -76,7 +75,11 @@ } #endif - [self installHangDetector]; + [self.hangDetector = [[PearlHangDetector alloc] initWithHangAction:^(NSTimeInterval hangTime) { + MPError( [NSError errorWithDomain:MPErrorDomain code:MPErrorHangCode userInfo:@{ + @"time": @(hangTime) + }], @"Timeout waiting for main thread after %fs.", hangTime ); + }] start]; } @catch (id exception) { err( @"During Analytics Setup: %@", exception ); @@ -143,31 +146,6 @@ return YES; } -- (void)installHangDetector { - - __block NSDate *latestPing = [NSDate date]; - __block __weak VoidBlock wPingOp, wPongOp; - - VoidBlock pingOp = ^{ - latestPing = [NSDate date]; - dispatch_after( dispatch_time( DISPATCH_TIME_NOW, 100 * NSEC_PER_MSEC ), dispatch_get_main_queue(), wPingOp ); - }, pongOp = ^{ - NSTimeInterval hangTime = -[latestPing timeIntervalSinceNow]; - if (hangTime > MP_HANG_TIME_MAIN) { - MPError( [NSError errorWithDomain:MPErrorDomain code:MPErrorHangCode userInfo:@{ - @"time": @(hangTime) - }], @"Timeout waiting for main thread after %fs.", hangTime ); - } - else - dbg( @"hangTime=%f", hangTime ); - - dispatch_after( dispatch_time( DISPATCH_TIME_NOW, NSEC_PER_SEC ), dispatch_get_global_queue( QOS_CLASS_BACKGROUND, 0 ), wPongOp ); - }; - - (wPingOp = pingOp)(); - (wPongOp = pongOp)(); -} - - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { @@ -257,6 +235,40 @@ [activityOverlay cancelOverlayAnimated:YES]; } +- (void)applicationWillEnterForeground:(UIApplication *)application { + + inf( @"Will foreground" ); + + [super applicationWillEnterForeground:application]; + + [self.hangDetector start]; +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + + inf( @"Re-activated" ); + [[NSNotificationCenter defaultCenter] postNotificationName:MPCheckConfigNotification object:nil]; + + PearlNotMainQueue( ^{ + NSString *importHeader = @"# Master Password site export"; + NSString *importedSitesString = [UIPasteboard generalPasteboard].string; + if ([importedSitesString length] > [importHeader length] && + [[importedSitesString substringToIndex:[importHeader length]] isEqualToString:importHeader]) + [PearlAlert showAlertWithTitle:@"Import Sites?" message: + @"We've detected Master Password import sites on your pasteboard, would you like to import them?" + viewStyle:UIAlertViewStyleDefault initAlert:nil + tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex) { + if (buttonIndex == [alert cancelButtonIndex]) + return; + + [self importSites:importedSitesString]; + [UIPasteboard generalPasteboard].string = @""; + } cancelTitle:@"No" otherTitles:@"Import Sites", nil]; + } ); + + [super applicationDidBecomeActive:application]; +} + - (void)applicationDidReceiveMemoryWarning:(UIApplication *)application { inf( @"Received memory warning." ); @@ -266,10 +278,12 @@ - (void)applicationDidEnterBackground:(UIApplication *)application { - inf( @"Will background" ); + inf( @"Did background" ); if (![[MPiOSConfig get].rememberLogin boolValue]) [self signOutAnimated:NO]; + [self.hangDetector stop]; + // self.task = [application beginBackgroundTaskWithExpirationHandler:^{ // [application endBackgroundTask:self.task]; // dbg( @"background expiring" ); @@ -311,31 +325,6 @@ [super applicationDidEnterBackground:application]; } -- (void)applicationDidBecomeActive:(UIApplication *)application { - - inf( @"Re-activated" ); - [[NSNotificationCenter defaultCenter] postNotificationName:MPCheckConfigNotification object:nil]; - - PearlNotMainQueue( ^{ - NSString *importHeader = @"# Master Password site export"; - NSString *importedSitesString = [UIPasteboard generalPasteboard].string; - if ([importedSitesString length] > [importHeader length] && - [[importedSitesString substringToIndex:[importHeader length]] isEqualToString:importHeader]) - [PearlAlert showAlertWithTitle:@"Import Sites?" message: - @"We've detected Master Password import sites on your pasteboard, would you like to import them?" - viewStyle:UIAlertViewStyleDefault initAlert:nil - tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex) { - if (buttonIndex == [alert cancelButtonIndex]) - return; - - [self importSites:importedSitesString]; - [UIPasteboard generalPasteboard].string = @""; - } cancelTitle:@"No" otherTitles:@"Import Sites", nil]; - } ); - - [super applicationDidBecomeActive:application]; -} - #pragma mark - Behavior - (void)showFeedbackWithLogs:(BOOL)logs forVC:(UIViewController *)viewController { diff --git a/platform-darwin/Source/iOS/Storyboard.storyboard b/platform-darwin/Source/iOS/Storyboard.storyboard index 1a8a73aa..fd94ee1e 100644 --- a/platform-darwin/Source/iOS/Storyboard.storyboard +++ b/platform-darwin/Source/iOS/Storyboard.storyboard @@ -103,7 +103,7 @@ - +