diff options
author | Muller, Alexander (A.) <amulle19@ford.com> | 2017-01-25 12:22:35 -0800 |
---|---|---|
committer | Muller, Alexander (A.) <amulle19@ford.com> | 2017-01-25 12:22:35 -0800 |
commit | 782fe40e9e044bfbd6ee15af97a6cf867c664b33 (patch) | |
tree | a57376f8d7b986fefa1ab10cdd5846caf37c7dc2 | |
parent | a802bd47a1bacac9052b15f2e1243498b59c8bdd (diff) | |
download | sdl_ios-782fe40e9e044bfbd6ee15af97a6cf867c664b33.tar.gz |
Updated lifecycle manager states to handle stopping the manager correctly.
-rw-r--r-- | SmartDeviceLink/SDLLifecycleManager.h | 5 | ||||
-rw-r--r-- | SmartDeviceLink/SDLLifecycleManager.m | 82 | ||||
-rw-r--r-- | SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m | 31 |
3 files changed, 63 insertions, 55 deletions
diff --git a/SmartDeviceLink/SDLLifecycleManager.h b/SmartDeviceLink/SDLLifecycleManager.h index 9ee943a13..a761ba63c 100644 --- a/SmartDeviceLink/SDLLifecycleManager.h +++ b/SmartDeviceLink/SDLLifecycleManager.h @@ -37,8 +37,9 @@ NS_ASSUME_NONNULL_BEGIN typedef NSString SDLLifecycleState; extern SDLLifecycleState *const SDLLifecycleStateReconnecting; -extern SDLLifecycleState *const SDLLifecycleStateDisconnected; -extern SDLLifecycleState *const SDLLifecycleStateTransportConnected; +extern SDLLifecycleState *const SDLLifecycleStateStopped; +extern SDLLifecycleState *const SDLLifecycleStateStarted; +extern SDLLifecycleState *const SDLLifecycleStateConnected; extern SDLLifecycleState *const SDLLifecycleStateRegistered; extern SDLLifecycleState *const SDLLifecycleStateSettingUpManagers; extern SDLLifecycleState *const SDLLifecycleStatePostManagerProcessing; diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m index 4fc9879fa..66e6a10a2 100644 --- a/SmartDeviceLink/SDLLifecycleManager.m +++ b/SmartDeviceLink/SDLLifecycleManager.m @@ -44,8 +44,9 @@ NS_ASSUME_NONNULL_BEGIN SDLLifecycleState *const SDLLifecycleStateReconnecting = @"Reconnecting"; -SDLLifecycleState *const SDLLifecycleStateDisconnected = @"TransportDisconnected"; -SDLLifecycleState *const SDLLifecycleStateTransportConnected = @"TransportConnected"; +SDLLifecycleState *const SDLLifecycleStateStopped = @"Stopped"; +SDLLifecycleState *const SDLLifecycleStateStarted = @"Started"; +SDLLifecycleState *const SDLLifecycleStateConnected = @"Connected"; SDLLifecycleState *const SDLLifecycleStateRegistered = @"Registered"; SDLLifecycleState *const SDLLifecycleStateSettingUpManagers = @"SettingUpManagers"; SDLLifecycleState *const SDLLifecycleStatePostManagerProcessing = @"PostManagerProcessing"; @@ -99,7 +100,7 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; _delegate = delegate; // Private properties - _lifecycleStateMachine = [[SDLStateMachine alloc] initWithTarget:self initialState:SDLLifecycleStateDisconnected states:[self.class sdl_stateTransitionDictionary]]; + _lifecycleStateMachine = [[SDLStateMachine alloc] initWithTarget:self initialState:SDLLifecycleStateStopped states:[self.class sdl_stateTransitionDictionary]]; _lastCorrelationId = 0; _notificationDispatcher = [[SDLNotificationDispatcher alloc] init]; _responseDispatcher = [[SDLResponseDispatcher alloc] initWithNotificationDispatcher:_notificationDispatcher]; @@ -119,23 +120,9 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; } - (void)startWithReadyHandler:(SDLManagerReadyBlock)readyHandler { - // We will always try to restart the proxy, unless stop is called. - _restartProxy = YES; - self.readyHandler = [readyHandler copy]; - // Set up our logging capabilities based on the config - [self.class sdl_updateLoggingWithFlags:self.configuration.lifecycleConfig.logFlags]; - -// Start up the internal proxy object -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - if (self.configuration.lifecycleConfig.tcpDebugMode) { - self.proxy = [SDLProxyFactory buildSDLProxyWithListener:self.notificationDispatcher tcpIPAddress:self.configuration.lifecycleConfig.tcpDebugIPAddress tcpPort:[@(self.configuration.lifecycleConfig.tcpDebugPort) stringValue]]; - } else { - self.proxy = [SDLProxyFactory buildSDLProxyWithListener:self.notificationDispatcher]; - } -#pragma clang diagnostic pop + [self.lifecycleStateMachine transitionToState:SDLLifecycleStateStarted]; } - (void)stop { @@ -143,7 +130,7 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; if ([self.lifecycleStateMachine isCurrentState:SDLLifecycleStateReady]) { [self.lifecycleStateMachine transitionToState:SDLLifecycleStateUnregistering]; } else { - [self.lifecycleStateMachine transitionToState:SDLLifecycleStateDisconnected]; + [self.lifecycleStateMachine transitionToState:SDLLifecycleStateStopped]; } } @@ -163,22 +150,41 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; + (NSDictionary<SDLState *, SDLAllowableStateTransitions *> *)sdl_stateTransitionDictionary { return @{ - SDLLifecycleStateReconnecting: @[SDLLifecycleStateTransportConnected], - SDLLifecycleStateDisconnected: @[SDLLifecycleStateReconnecting, SDLLifecycleStateTransportConnected], - SDLLifecycleStateTransportConnected: @[SDLLifecycleStateDisconnected, SDLLifecycleStateRegistered], - SDLLifecycleStateRegistered: @[SDLLifecycleStateDisconnected, SDLLifecycleStateSettingUpManagers], - SDLLifecycleStateSettingUpManagers: @[SDLLifecycleStateDisconnected, SDLLifecycleStatePostManagerProcessing], - SDLLifecycleStatePostManagerProcessing: @[SDLLifecycleStateDisconnected, SDLLifecycleStateReady], - SDLLifecycleStateUnregistering: @[SDLLifecycleStateDisconnected], - SDLLifecycleStateReady: @[SDLLifecycleStateUnregistering, SDLLifecycleStateDisconnected] + SDLLifecycleStateReconnecting: @[SDLLifecycleStateStarted], + SDLLifecycleStateStopped: @[SDLLifecycleStateReconnecting, SDLLifecycleStateStarted], + SDLLifecycleStateStarted : @[SDLLifecycleStateConnected, SDLLifecycleStateStopped], + SDLLifecycleStateConnected: @[SDLLifecycleStateStopped, SDLLifecycleStateRegistered], + SDLLifecycleStateRegistered: @[SDLLifecycleStateStopped, SDLLifecycleStateSettingUpManagers], + SDLLifecycleStateSettingUpManagers: @[SDLLifecycleStateStopped, SDLLifecycleStatePostManagerProcessing], + SDLLifecycleStatePostManagerProcessing: @[SDLLifecycleStateStopped, SDLLifecycleStateReady], + SDLLifecycleStateUnregistering: @[SDLLifecycleStateStopped], + SDLLifecycleStateReady: @[SDLLifecycleStateUnregistering, SDLLifecycleStateStopped] }; } - (void)didEnterStateReconnecting { - [self startWithReadyHandler:self.readyHandler]; + [self.lifecycleStateMachine transitionToState:SDLLifecycleStateStarted]; +} + +- (void)didEnterStateStarted { + // We will always try to restart the proxy, unless stop is called. + _restartProxy = YES; + + // Set up our logging capabilities based on the config + [self.class sdl_updateLoggingWithFlags:self.configuration.lifecycleConfig.logFlags]; + + // Start up the internal proxy object +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + if (self.configuration.lifecycleConfig.tcpDebugMode) { + self.proxy = [SDLProxyFactory buildSDLProxyWithListener:self.notificationDispatcher tcpIPAddress:self.configuration.lifecycleConfig.tcpDebugIPAddress tcpPort:[@(self.configuration.lifecycleConfig.tcpDebugPort) stringValue]]; + } else { + self.proxy = [SDLProxyFactory buildSDLProxyWithListener:self.notificationDispatcher]; + } +#pragma clang diagnostic pop } -- (void)didEnterStateTransportDisconnected { +- (void)didEnterStateStopped { [self.fileManager stop]; [self.permissionManager stop]; [self.lockScreenManager stop]; @@ -196,7 +202,7 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; } } -- (void)didEnterStateTransportConnected { +- (void)didEnterStateConnected { // If we have security managers, add them to the proxy if (self.configuration.lifecycleConfig.securityManagers != nil) { [self.proxy addSecurityManagers:self.configuration.lifecycleConfig.securityManagers forAppId:self.configuration.lifecycleConfig.appId]; @@ -211,7 +217,7 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; withResponseHandler:^(__kindof SDLRPCRequest *_Nullable request, __kindof SDLRPCResponse *_Nullable response, NSError *_Nullable error) { if (error != nil || ![response.success boolValue]) { [SDLDebugTool logFormat:@"Failed to register the app. Error: %@, Response: %@", error, response]; - [weakSelf.lifecycleStateMachine transitionToState:SDLLifecycleStateDisconnected]; + [weakSelf.lifecycleStateMachine transitionToState:SDLLifecycleStateStopped]; return; } @@ -312,7 +318,7 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; [SDLDebugTool logFormat:@"SDL Error unregistering, we are going to hard disconnect: %@, response: %@", error, response]; } - [weakSelf.lifecycleStateMachine transitionToState:SDLLifecycleStateDisconnected]; + [weakSelf.lifecycleStateMachine transitionToState:SDLLifecycleStateStopped]; }]; } @@ -380,7 +386,7 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; } - (void)sdl_sendRequest:(SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler { - // We will allow things to be sent in a "SDLLifeCycleStateTransportConnected" state in the private method, but block it in the public method sendRequest:withCompletionHandler: so that the lifecycle manager can complete its setup without being bothered by developer error + // We will allow things to be sent in a "SDLLifeCycleStateConnected" state in the private method, but block it in the public method sendRequest:withCompletionHandler: so that the lifecycle manager can complete its setup without being bothered by developer error NSParameterAssert(request != nil); @@ -417,7 +423,7 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; return @(++self.lastCorrelationId); } -+ (BOOL)sdl_checkNotification:(NSNotification *)notification containsKindOfClass:(Class) class { ++ (BOOL)sdl_checkNotification:(NSNotification *)notification containsKindOfClass:(Class)class { NSAssert([notification.userInfo[SDLNotificationUserInfoObject] isKindOfClass:class], @"A notification was sent with an unanticipated object"); if (![notification.userInfo[SDLNotificationUserInfoObject] isKindOfClass:class]) { return NO; @@ -426,7 +432,7 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; return YES; } - + (void)sdl_updateLoggingWithFlags : (SDLLogOutput)logFlags { ++ (void)sdl_updateLoggingWithFlags:(SDLLogOutput)logFlags { [SDLDebugTool disable]; if ((logFlags & SDLLogOutputConsole) == SDLLogOutputConsole) { @@ -453,11 +459,11 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; #pragma mark SDL notification observers - (void)transportDidConnect { - [self.lifecycleStateMachine transitionToState:SDLLifecycleStateTransportConnected]; + [self.lifecycleStateMachine transitionToState:SDLLifecycleStateConnected]; } - (void)transportDidDisconnect { - [self.lifecycleStateMachine transitionToState:SDLLifecycleStateDisconnected]; + [self.lifecycleStateMachine transitionToState:SDLLifecycleStateStopped]; } - (void)hmiStatusDidChange:(SDLRPCNotificationNotification *)notification { @@ -484,7 +490,7 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; SDLOnAppInterfaceUnregistered *appUnregisteredNotification = notification.notification; [SDLDebugTool logFormat:@"Remote Device forced unregistration for reason: %@", appUnregisteredNotification.reason]; - [self.lifecycleStateMachine transitionToState:SDLLifecycleStateDisconnected]; + [self.lifecycleStateMachine transitionToState:SDLLifecycleStateStopped]; } @end diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m index 91320c955..58dd68ad1 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m @@ -82,7 +82,7 @@ describe(@"a lifecycle manager", ^{ it(@"should initialize properties", ^{ expect(testManager.configuration).to(equal(testConfig)); expect(testManager.delegate).to(equal(managerDelegateMock)); // TODO: Broken on OCMock 3.3.1 & Swift 3 Quick / Nimble - expect(testManager.lifecycleState).to(match(SDLLifecycleStateDisconnected)); + expect(testManager.lifecycleState).to(match(SDLLifecycleStateStopped)); expect(@(testManager.lastCorrelationId)).to(equal(@0)); expect(testManager.fileManager).toNot(beNil()); expect(testManager.permissionManager).toNot(beNil()); @@ -151,7 +151,8 @@ describe(@"a lifecycle manager", ^{ }); it(@"should do nothing", ^{ - expect(testManager.lifecycleState).to(match(SDLLifecycleStateDisconnected)); + expect(testManager.lifecycleState).to(match(SDLLifecycleStateStopped)); + expect(testManager.lifecycleState).toEventuallyNot(match(SDLLifecycleStateStarted)); }); }); @@ -162,7 +163,7 @@ describe(@"a lifecycle manager", ^{ it(@"should initialize the proxy property", ^{ expect(testManager.proxy).toNot(beNil()); - expect(testManager.lifecycleState).to(match(SDLLifecycleStateDisconnected)); + expect(testManager.lifecycleState).to(match(SDLLifecycleStateStarted)); }); describe(@"after receiving a connect notification", ^{ @@ -176,7 +177,7 @@ describe(@"a lifecycle manager", ^{ it(@"should send a register app interface request and be in the connected state", ^{ OCMVerifyAllWithDelay(proxyMock, 0.5); - expect(testManager.lifecycleState).to(match(SDLLifecycleStateTransportConnected)); + expect(testManager.lifecycleState).to(match(SDLLifecycleStateConnected)); }); itBehavesLike(@"unable to send an RPC", ^{ return @{ @"manager": testManager }; }); @@ -187,8 +188,8 @@ describe(@"a lifecycle manager", ^{ [NSThread sleepForTimeInterval:0.1]; }); - it(@"should be in the disconnect state", ^{ - expect(testManager.lifecycleState).to(match(SDLLifecycleStateDisconnected)); + it(@"should be in the started state", ^{ + expect(testManager.lifecycleState).to(match(SDLLifecycleStateStarted)); }); }); @@ -197,15 +198,15 @@ describe(@"a lifecycle manager", ^{ [testManager stop]; }); - it(@"should simply disconnect", ^{ - expect(testManager.lifecycleState).to(match(SDLLifecycleStateDisconnected)); + it(@"should simply stop", ^{ + expect(testManager.lifecycleState).to(match(SDLLifecycleStateStopped)); }); }); }); describe(@"in the connected state", ^{ beforeEach(^{ - [testManager.lifecycleStateMachine setToState:SDLLifecycleStateTransportConnected]; + [testManager.lifecycleStateMachine setToState:SDLLifecycleStateConnected]; }); describe(@"after receiving a register app interface response", ^{ @@ -237,8 +238,8 @@ describe(@"a lifecycle manager", ^{ [testManager.notificationDispatcher postNotificationName:SDLTransportDidDisconnect infoObject:nil]; }); - it(@"should enter the disconnect state", ^{ - expect(testManager.lifecycleState).toEventually(match(SDLLifecycleStateDisconnected)); + it(@"should enter the started state", ^{ + expect(testManager.lifecycleState).toEventually(match(SDLLifecycleStateStarted)); }); }); @@ -247,8 +248,8 @@ describe(@"a lifecycle manager", ^{ [testManager stop]; }); - it(@"should enter the disconnect state", ^{ - expect(testManager.lifecycleState).to(match(SDLLifecycleStateDisconnected)); + it(@"should enter the stopped state", ^{ + expect(testManager.lifecycleState).to(match(SDLLifecycleStateStopped)); }); }); }); @@ -292,8 +293,8 @@ describe(@"a lifecycle manager", ^{ [testManager.notificationDispatcher postRPCResponseNotification:SDLDidReceiveUnregisterAppInterfaceResponse response:testUnregisterResponse]; }); - it(@"should disconnect", ^{ - expect(testManager.lifecycleState).toEventually(match(SDLLifecycleStateDisconnected)); + it(@"should stop", ^{ + expect(testManager.lifecycleState).toEventually(match(SDLLifecycleStateStopped)); }); }); }); |