diff options
author | NicoleYarroch <nicole@livio.io> | 2020-04-06 11:30:09 -0400 |
---|---|---|
committer | NicoleYarroch <nicole@livio.io> | 2020-04-06 11:30:09 -0400 |
commit | 4ff78c0d2caa6aa04fa7204d77fe77ceed973f8b (patch) | |
tree | 5b4e66b393a68fe7a6317f834812ef5416c72e33 | |
parent | 672ca06da1c0cd7a0b2283a3bcefd886149ab341 (diff) | |
download | sdl_ios-4ff78c0d2caa6aa04fa7204d77fe77ceed973f8b.tar.gz |
Added background task ended tests to sec. trans.
Added background task ended tests to secondary transport manager unit tests
-rw-r--r-- | SmartDeviceLink/SDLSecondaryTransportManager.m | 33 | ||||
-rw-r--r-- | SmartDeviceLinkTests/ProxySpecs/SDLSecondaryTransportManagerSpec.m | 93 |
2 files changed, 100 insertions, 26 deletions
diff --git a/SmartDeviceLink/SDLSecondaryTransportManager.m b/SmartDeviceLink/SDLSecondaryTransportManager.m index bf8b5a5eb..ba5624f4b 100644 --- a/SmartDeviceLink/SDLSecondaryTransportManager.m +++ b/SmartDeviceLink/SDLSecondaryTransportManager.m @@ -682,20 +682,10 @@ struct TransportProtocolUpdated { dispatch_async(self.stateMachineQueue, ^{ __strong typeof(self) strongSelf = weakSelf; if (notification.name == UIApplicationWillResignActiveNotification) { + SDLLogD(@"App will enter the background"); if ([strongSelf sdl_isTransportOpened] && strongSelf.secondaryTransportType == SDLSecondaryTransportTypeTCP) { - SDLLogD(@"App will enter the background"); - // Start a background task so we can tear down the TCP socket successfully before the app is suspended - [strongSelf.backgroundTaskManager setTaskEndedHandler:^{ - __strong typeof(self) strongSelf = weakSelf; - if (self.sdl_getAppState == UIApplicationStateActive) { - SDLLogD(@"App has been foregrounded. Ignoring notification that the background task ended."); - } else { - SDLLogD(@"Disconnecting TCP transport due to the background task ending."); - [strongSelf.stateMachine transitionToState:SDLSecondaryTransportStateConfigured]; - } - }]; - - SDLLogD(@"Starting background task to keep TCP transport alive: %@", self.backgroundTaskManager); + SDLLogD(@"Starting background task to keep TCP transport alive"); + strongSelf.backgroundTaskManager.taskEndedHandler = [strongSelf sdl_backgroundTaskEndedHandler]; [strongSelf.backgroundTaskManager startBackgroundTask]; } else { SDLLogD(@"TCP transport already disconnected"); @@ -719,6 +709,23 @@ struct TransportProtocolUpdated { }); } +/// Handles a notification that the background task has ended. If the app is still in the background, the TCP transport disconnects. If the app has re-entered the foreground or the manager has shutdown then the notification is ignored. +/// @return A background task ended handler +- (nullable void (^)(void))sdl_backgroundTaskEndedHandler { + __weak typeof(self) weakSelf = self; + return ^{ + __strong typeof(self) strongSelf = weakSelf; + if (strongSelf.sdl_getAppState == UIApplicationStateActive) { + SDLLogD(@"App has been foregrounded. Ignoring notification that the background task ended."); + } else if ([strongSelf.stateMachine isCurrentState:SDLSecondaryTransportStateStopped]) { + SDLLogD(@"Manager has been stopped. Ignoring notification that the background task ended."); + } else { + SDLLogD(@"Disconnecting TCP transport due to the background task ending."); + [strongSelf.stateMachine transitionToState:SDLSecondaryTransportStateConfigured]; + } + }; +} + #pragma mark - Utility methods - (SDLSecondaryTransportType)sdl_convertTransportType:(NSString *)transportString { diff --git a/SmartDeviceLinkTests/ProxySpecs/SDLSecondaryTransportManagerSpec.m b/SmartDeviceLinkTests/ProxySpecs/SDLSecondaryTransportManagerSpec.m index d94d04926..44cc43f27 100644 --- a/SmartDeviceLinkTests/ProxySpecs/SDLSecondaryTransportManagerSpec.m +++ b/SmartDeviceLinkTests/ProxySpecs/SDLSecondaryTransportManagerSpec.m @@ -68,22 +68,37 @@ static const int TCPPortUnspecified = -1; @interface SDLSecondaryTransportManager (ForTest) // Swap sdl_getAppState method to dummy implementation. -// Since the test runs on the main thread, dispatch_sync()-ing to the main thread doesn't work. -+ (void)swapGetAppStateMethod; +// Since the test runs on the main thread, dispatch_sync()-ing to the main thread freezes the tests. ++ (void)swapGetActiveAppStateMethod; ++ (void)swapGetInactiveAppStateMethod; @end @implementation SDLSecondaryTransportManager (ForTest) -- (UIApplicationState)dummyGetAppState { - NSLog(@"Testing: app state for secondary transport manager is always ACTIVE"); + +- (UIApplicationState)dummyGetActiveAppState { + NSLog(@"Testing: app state for secondary transport manager is ACTIVE"); return UIApplicationStateActive; } -+ (void)swapGetAppStateMethod { ++ (void)swapGetActiveAppStateMethod { SEL selector = NSSelectorFromString(@"sdl_getAppState"); Method from = class_getInstanceMethod(self, selector); - Method to = class_getInstanceMethod(self, @selector(dummyGetAppState)); + Method to = class_getInstanceMethod(self, @selector(dummyGetActiveAppState)); method_exchangeImplementations(from, to); } + +- (UIApplicationState)dummyGetInactiveAppState { + NSLog(@"Testing: app state for secondary transport manager is INACTIVE"); + return UIApplicationStateBackground; +} + ++ (void)swapGetInactiveAppStateMethod { + SEL selector = NSSelectorFromString(@"sdl_getAppState"); + Method from = class_getInstanceMethod(self, selector); + Method to = class_getInstanceMethod(self, @selector(dummyGetInactiveAppState)); + method_exchangeImplementations(from, to); +} + @end @interface SDLTCPTransport (ConnectionDisabled) @@ -154,7 +169,7 @@ describe(@"the secondary transport manager ", ^{ }; beforeEach(^{ - [SDLSecondaryTransportManager swapGetAppStateMethod]; + [SDLSecondaryTransportManager swapGetActiveAppStateMethod]; [SDLTCPTransport swapConnectionMethods]; [SDLIAPTransport swapConnectionMethods]; @@ -176,7 +191,7 @@ describe(@"the secondary transport manager ", ^{ [SDLIAPTransport swapConnectionMethods]; [SDLTCPTransport swapConnectionMethods]; - [SDLSecondaryTransportManager swapGetAppStateMethod]; + [SDLSecondaryTransportManager swapGetActiveAppStateMethod]; }); @@ -1096,7 +1111,7 @@ describe(@"the secondary transport manager ", ^{ }); }); - describe(@"App lifecycle state change", ^{ + describe(@"app lifecycle state change", ^{ __block SDLBackgroundTaskManager *mockBackgroundTaskManager = nil; beforeEach(^{ @@ -1109,11 +1124,11 @@ describe(@"the secondary transport manager ", ^{ [manager startWithPrimaryProtocol:testPrimaryProtocol]; }); - mockBackgroundTaskManager = OCMClassMock([SDLBackgroundTaskManager class]); + mockBackgroundTaskManager = OCMPartialMock([[SDLBackgroundTaskManager alloc] initWithBackgroundTaskName:@"com.test.backgroundTask"]); manager.backgroundTaskManager = mockBackgroundTaskManager; }); - context(@"App enters the background", ^{ + context(@"app enters the background", ^{ beforeEach(^{ manager.secondaryTransportType = SDLTransportSelectionTCP; }); @@ -1149,9 +1164,61 @@ describe(@"the secondary transport manager ", ^{ expect(manager.stateMachine.currentState).to(equal(SDLSecondaryTransportStateConfigured)); }); }); + + describe(@"when the background task ends", ^{ + context(@"If the app is still in the background", ^{ + beforeEach(^{ + [SDLSecondaryTransportManager swapGetInactiveAppStateMethod]; + }); + + it(@"should stop the TCP transport if the app is still in the background", ^{ + [manager.stateMachine setToState:SDLSecondaryTransportStateRegistered fromOldState:nil callEnterTransition:NO]; + [[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationWillResignActiveNotification object:nil]; + + // Wait for the notification to propagate + [NSThread sleepForTimeInterval:0.1]; + + [manager.backgroundTaskManager endBackgroundTask]; + + expect(manager.stateMachine.currentState).to(equal(SDLSecondaryTransportStateConfigured)); + }); + + it(@"should ignore the notification if the manager has stopped before the background task ended", ^{ + [manager.stateMachine setToState:SDLSecondaryTransportStateRegistered fromOldState:nil callEnterTransition:NO]; + [[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationWillResignActiveNotification object:nil]; + + // Wait for the notification to propagate + [NSThread sleepForTimeInterval:0.1]; + + [manager.stateMachine setToState:SDLSecondaryTransportStateStopped fromOldState:nil callEnterTransition:NO]; + + [manager.backgroundTaskManager endBackgroundTask]; + + expect(manager.stateMachine.currentState).to(equal(SDLSecondaryTransportStateStopped)); + }); + + afterEach(^{ + [SDLSecondaryTransportManager swapGetInactiveAppStateMethod]; + }); + }); + + context(@"If the app is has entered the foreground", ^{ + it(@"should ignore the notification if the app has returned to the foreground", ^{ + [manager.stateMachine setToState:SDLSecondaryTransportStateRegistered fromOldState:nil callEnterTransition:NO]; + [[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationWillResignActiveNotification object:nil]; + + // Wait for the notification to propagate + [NSThread sleepForTimeInterval:0.1]; + + [manager.backgroundTaskManager endBackgroundTask]; + + expect(manager.stateMachine.currentState).to(equal(SDLSecondaryTransportStateRegistered)); + }); + }); + }); }); - context(@"App enters the foreground", ^{ + context(@"app enters the foreground", ^{ describe(@"if the secondary transport is still connected", ^{ beforeEach(^{ [manager.stateMachine setToState:SDLSecondaryTransportStateRegistered fromOldState:nil callEnterTransition:NO]; @@ -1168,7 +1235,7 @@ describe(@"the secondary transport manager ", ^{ }); }); - describe(@"if the secondary transport not connected but is configured", ^{ + describe(@"if the secondary transport is not connected but is configured", ^{ beforeEach(^{ manager.ipAddress = @"192.555.23.1"; manager.tcpPort = 54321; |