Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tweak IAP transport to only delay control sessions, not data sessions #1385

Merged
merged 4 commits into from
Oct 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions SmartDeviceLink/SDLIAPDataSession.m
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ - (void)sdl_stopAndDestroySession {
[self sdl_isIOThreadCanceled:self.canceledSemaphore completionHandler:^(BOOL success) {
if (success == NO) {
SDLLogE(@"Destroying thread (IOStreamThread) for data session when I/O streams have not yet closed.");

// FIX: Try to close the session if the canceledSemaphore is never triggered by the `sdl_accessoryEventLoop`
[self sdl_closeSession];
}
self.ioStreamThread = nil;
[super cleanupClosedSession];
Expand Down
17 changes: 11 additions & 6 deletions SmartDeviceLink/SDLIAPTransport.m
Original file line number Diff line number Diff line change
Expand Up @@ -91,18 +91,15 @@ - (void)sdl_stopEventListening {
* @param notification Contains information about the connected accessory
*/
- (void)sdl_accessoryConnected:(NSNotification *)notification {
EAAccessory *newAccessory = [notification.userInfo objectForKey:EAAccessoryKey];
EAAccessory *newAccessory = notification.userInfo[EAAccessoryKey];

if ([self sdl_isDataSessionActive:self.dataSession newAccessory:newAccessory]) {
self.accessoryConnectDuringActiveSession = YES;
return;
}

double retryDelay = self.sdl_retryDelay;
SDLLogD(@"Accessory Connected (%@), Opening in %0.03fs", notification.userInfo[EAAccessoryKey], retryDelay);

self.retryCounter = 0;
[self performSelector:@selector(sdl_connect:) withObject:nil afterDelay:retryDelay];
[self sdl_connect:newAccessory];
}

/**
Expand Down Expand Up @@ -304,6 +301,7 @@ - (void)controlSessionShouldRetry {
* @param protocolString The protocol string to be used to open the data session
*/
- (void)controlSession:(nonnull SDLIAPControlSession *)controlSession didReceiveProtocolString:(nonnull NSString *)protocolString {
SDLLogD(@"Control transport session received data session number: %@", protocolString);
self.dataSession = [[SDLIAPDataSession alloc] initWithAccessory:controlSession.accessory delegate:self forProtocol:protocolString];
[self.dataSession startSession];
}
Expand Down Expand Up @@ -495,14 +493,21 @@ - (BOOL)createSessionWithAccessory:(EAAccessory *)accessory protocolString:(NSSt

if ([protocolString isEqualToString:MultiSessionProtocolString] && SDL_SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"9")) {
self.dataSession = [[SDLIAPDataSession alloc] initWithAccessory:accessory delegate:self forProtocol:protocolString];

SDLLogD(@"Accessory Connected (%@), Opening immediately", accessory);
[self.dataSession startSession];
return YES;
} else if ([protocolString isEqualToString:ControlProtocolString]) {
self.controlSession = [[SDLIAPControlSession alloc] initWithAccessory:accessory delegate:self];
[self.controlSession startSession];

double retryDelay = [self sdl_retryDelay];
SDLLogD(@"Accessory Connected (%@), Opening in %0.03fs", accessory, retryDelay);
[self.controlSession performSelector:@selector(startSession) withObject:nil afterDelay:retryDelay];
return YES;
} else if ([protocolString isEqualToString:LegacyProtocolString]) {
self.dataSession = [[SDLIAPDataSession alloc] initWithAccessory:accessory delegate:self forProtocol:protocolString];

SDLLogD(@"Accessory Connected (%@), Opening immediately", accessory);
[self.dataSession startSession];
return YES;
}
Expand Down
120 changes: 64 additions & 56 deletions SmartDeviceLink/SDLLifecycleManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,8 @@ - (void)didEnterStateStarted {
[self.backgroundTaskManager startBackgroundTask];

// Start up the internal proxy object
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
self.secondaryTransportManager = nil;
if (self.configuration.lifecycleConfig.tcpDebugMode) {
self.proxy = [SDLProxy tcpProxyWithListener:self.notificationDispatcher
Expand All @@ -237,7 +237,7 @@ - (void)didEnterStateStarted {
self.secondaryTransportManager = [[SDLSecondaryTransportManager alloc] initWithStreamingProtocolDelegate:self serialQueue:self.lifecycleQueue];
self.proxy = [SDLProxy iapProxyWithListener:self.notificationDispatcher secondaryTransportManager:self.secondaryTransportManager];
}
#pragma clang diagnostic pop
#pragma clang diagnostic pop
}

- (void)didEnterStateStopped {
Expand Down Expand Up @@ -316,25 +316,25 @@ - (void)didEnterStateConnected {
// Send the request and depending on the response, post the notification
__weak typeof(self) weakSelf = self;
[self sdl_sendRequest:regRequest
withResponseHandler:^(__kindof SDLRPCRequest *_Nullable request, __kindof SDLRPCResponse *_Nullable response, NSError *_Nullable error) {
// If the success BOOL is NO or we received an error at this point, we failed. Call the ready handler and transition to the DISCONNECTED state.
if (error != nil || ![response.success boolValue]) {
SDLLogE(@"Failed to register the app. Error: %@, Response: %@", error, response);
if (weakSelf.readyHandler) {
weakSelf.readyHandler(NO, error);
}

if (weakSelf.lifecycleState != SDLLifecycleStateReconnecting) {
[weakSelf sdl_transitionToState:SDLLifecycleStateStopped];
}
withResponseHandler:^(__kindof SDLRPCRequest *_Nullable request, __kindof SDLRPCResponse *_Nullable response, NSError *_Nullable error) {
// If the success BOOL is NO or we received an error at this point, we failed. Call the ready handler and transition to the DISCONNECTED state.
if (error != nil || ![response.success boolValue]) {
SDLLogE(@"Failed to register the app. Error: %@, Response: %@", error, response);
if (weakSelf.readyHandler) {
weakSelf.readyHandler(NO, error);
}

return;
if (weakSelf.lifecycleState != SDLLifecycleStateReconnecting) {
[weakSelf sdl_transitionToState:SDLLifecycleStateStopped];
}

weakSelf.registerResponse = (SDLRegisterAppInterfaceResponse *)response;
[SDLGlobals sharedGlobals].rpcVersion = [SDLVersion versionWithSDLMsgVersion:weakSelf.registerResponse.sdlMsgVersion];
[weakSelf sdl_transitionToState:SDLLifecycleStateRegistered];
}];
return;
}

weakSelf.registerResponse = (SDLRegisterAppInterfaceResponse *)response;
[SDLGlobals sharedGlobals].rpcVersion = [SDLVersion versionWithSDLMsgVersion:weakSelf.registerResponse.sdlMsgVersion];
[weakSelf sdl_transitionToState:SDLLifecycleStateRegistered];
}];
}

- (void)didEnterStateRegistered {
Expand All @@ -359,33 +359,41 @@ - (void)didEnterStateRegistered {
}

- (void)didEnterStateUpdatingConfiguration {
// we can expect that the delegate has implemented the update method and the actual language is a supported language
// We can expect that the delegate has implemented the update method and the actual language is a supported language
SDLLanguage actualLanguage = self.registerResponse.language;
SDLLogD(@"Updating configuration due to language mismatch. New langugage: %@", actualLanguage);

SDLLifecycleConfigurationUpdate *configUpdate = [self.delegate managerShouldUpdateLifecycleToLanguage:actualLanguage];
SDLLifecycleConfigurationUpdate *configUpdate = [self.delegate managerShouldUpdateLifecycleToLanguage:actualLanguage];

if (configUpdate) {
self.configuration.lifecycleConfig.language = actualLanguage;
if (configUpdate.appName) {
self.configuration.lifecycleConfig.appName = configUpdate.appName;
}
if (configUpdate.shortAppName) {
self.configuration.lifecycleConfig.shortAppName = configUpdate.shortAppName;
}
if (configUpdate.ttsName) {
self.configuration.lifecycleConfig.ttsName = configUpdate.ttsName;
}
if (configUpdate.voiceRecognitionCommandNames) {
self.configuration.lifecycleConfig.voiceRecognitionCommandNames = configUpdate.voiceRecognitionCommandNames;
}
if (configUpdate) {
self.configuration.lifecycleConfig.language = actualLanguage;
if (configUpdate.appName) {
self.configuration.lifecycleConfig.appName = configUpdate.appName;
}
if (configUpdate.shortAppName) {
self.configuration.lifecycleConfig.shortAppName = configUpdate.shortAppName;
}
if (configUpdate.ttsName) {
self.configuration.lifecycleConfig.ttsName = configUpdate.ttsName;
}
if (configUpdate.voiceRecognitionCommandNames) {
self.configuration.lifecycleConfig.voiceRecognitionCommandNames = configUpdate.voiceRecognitionCommandNames;
}

SDLChangeRegistration *changeRegistration = [[SDLChangeRegistration alloc] initWithLanguage:actualLanguage hmiDisplayLanguage:actualLanguage];
changeRegistration.appName = configUpdate.appName;
changeRegistration.ngnMediaScreenAppName = configUpdate.shortAppName;
changeRegistration.ttsName = configUpdate.ttsName;
changeRegistration.vrSynonyms = configUpdate.voiceRecognitionCommandNames;
SDLChangeRegistration *changeRegistration = [[SDLChangeRegistration alloc] initWithLanguage:actualLanguage hmiDisplayLanguage:actualLanguage];
changeRegistration.appName = configUpdate.appName;
changeRegistration.ngnMediaScreenAppName = configUpdate.shortAppName;
changeRegistration.ttsName = configUpdate.ttsName;
changeRegistration.vrSynonyms = configUpdate.voiceRecognitionCommandNames;

[self sendConnectionManagerRequest:changeRegistration withResponseHandler:nil];
[self sendConnectionManagerRequest:changeRegistration withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) {
if (error != nil) {
SDLLogW(@"Failed to update language with change registration. Request: %@, Response: %@, error: %@", request, response, error);
return;
}

SDLLogD(@"Successfully updated language with change registration. Request sent: %@", request);
}];
}

[self sdl_transitionToState:SDLLifecycleStateSettingUpManagers];
Expand Down Expand Up @@ -424,7 +432,7 @@ - (void)didEnterStateSettingUpManagers {
[self videoServiceProtocolDidUpdateFromOldProtocol:nil toNewProtocol:self.proxy.protocol];
}

dispatch_group_enter(managerGroup);
dispatch_group_enter(managerGroup);
[self.screenManager startWithCompletionHandler:^(NSError * _Nullable error) {
if (error != nil) {
SDLLogW(@"Screen Manager was unable to start; error: %@", error);
Expand Down Expand Up @@ -460,7 +468,7 @@ - (void)didEnterStateSettingUpAppIcon {
[weakself sdl_transitionToState:SDLLifecycleStateSettingUpHMI];
}
});
}];
}];
}

- (void)didEnterStateSettingUpHMI {
Expand Down Expand Up @@ -497,7 +505,7 @@ - (void)didEnterStateReady {
[self.delegate audioStreamingState:SDLAudioStreamingStateNotAudible didChangeToState:self.audioStreamingState];
}

// Stop the background task now that setup has completed
// Stop the background task now that setup has completed
[self.backgroundTaskManager endBackgroundTask];
}

Expand All @@ -506,13 +514,13 @@ - (void)didEnterStateUnregistering {

__weak typeof(self) weakSelf = self;
[self sdl_sendRequest:unregisterRequest
withResponseHandler:^(__kindof SDLRPCRequest *_Nullable request, __kindof SDLRPCResponse *_Nullable response, NSError *_Nullable error) {
if (error != nil || ![response.success boolValue]) {
SDLLogE(@"SDL Error unregistering, we are going to hard disconnect: %@, response: %@", error, response);
}
withResponseHandler:^(__kindof SDLRPCRequest *_Nullable request, __kindof SDLRPCResponse *_Nullable response, NSError *_Nullable error) {
if (error != nil || ![response.success boolValue]) {
SDLLogE(@"SDL Error unregistering, we are going to hard disconnect: %@, response: %@", error, response);
}

[weakSelf sdl_transitionToState:SDLLifecycleStateStopped];
}];
[weakSelf sdl_transitionToState:SDLLifecycleStateStopped];
}];
}


Expand Down Expand Up @@ -546,13 +554,13 @@ - (void)sdl_sendAppIcon:(nullable SDLFile *)appIcon withCompletion:(void (^)(voi

[self sdl_sendRequest:setAppIcon
withResponseHandler:^(__kindof SDLRPCRequest *_Nullable request, __kindof SDLRPCResponse *_Nullable response, NSError *_Nullable error) {
if (error != nil) {
SDLLogW(@"Error setting up app icon: %@", error);
}
if (error != nil) {
SDLLogW(@"Error setting up app icon: %@", error);
}

// We've succeeded or failed
completion();
}];
// We've succeeded or failed
completion();
}];
}];
}

Expand Down