summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicoleYarroch <nicole@livio.io>2020-04-06 11:30:09 -0400
committerNicoleYarroch <nicole@livio.io>2020-04-06 11:30:09 -0400
commit4ff78c0d2caa6aa04fa7204d77fe77ceed973f8b (patch)
tree5b4e66b393a68fe7a6317f834812ef5416c72e33
parent672ca06da1c0cd7a0b2283a3bcefd886149ab341 (diff)
downloadsdl_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.m33
-rw-r--r--SmartDeviceLinkTests/ProxySpecs/SDLSecondaryTransportManagerSpec.m93
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;