diff options
author | Sho Amano <samano@xevo.com> | 2018-09-26 11:02:23 +0900 |
---|---|---|
committer | Sho Amano <samano@xevo.com> | 2018-09-26 11:02:23 +0900 |
commit | 0bb6170e002fa13ac3c3bc39e8baa1e6ba7ac2b4 (patch) | |
tree | 4973697f32e6bf526e8a5496a14e2dcef07adecc /SmartDeviceLink/SDLProxy.m | |
parent | 518015176789e425626989205cf0659616f63be8 (diff) | |
parent | 3aebf547fbe8ff12d9a28cdf8ad4fb20541c3e7f (diff) | |
download | sdl_ios-0bb6170e002fa13ac3c3bc39e8baa1e6ba7ac2b4.tar.gz |
Merge branch 'develop' into feature/multiple_transports
Conflicts:
SmartDeviceLink/SDLGlobals.m
Diffstat (limited to 'SmartDeviceLink/SDLProxy.m')
-rw-r--r-- | SmartDeviceLink/SDLProxy.m | 218 |
1 files changed, 208 insertions, 10 deletions
diff --git a/SmartDeviceLink/SDLProxy.m b/SmartDeviceLink/SDLProxy.m index f7f272c79..5a837b298 100644 --- a/SmartDeviceLink/SDLProxy.m +++ b/SmartDeviceLink/SDLProxy.m @@ -6,7 +6,6 @@ #import <UIKit/UIKit.h> #import <objc/runtime.h> -#import "SDLTransportType.h" #import "SDLAudioStreamingState.h" #import "SDLLogMacros.h" #import "SDLEncodedSyncPData.h" @@ -18,6 +17,8 @@ #import "SDLLanguage.h" #import "SDLLayoutMode.h" #import "SDLLockScreenStatusManager.h" +#import "SDLOnButtonEvent.h" +#import "SDLOnButtonPress.h" #import "SDLOnHMIStatus.h" #import "SDLOnSystemRequest.h" #import "SDLPolicyDataParser.h" @@ -30,10 +31,13 @@ #import "SDLRequestType.h" #import "SDLSecondaryTransportManager.h" #import "SDLStreamingMediaManager.h" +#import "SDLSubscribeButton.h" #import "SDLSystemContext.h" #import "SDLSystemRequest.h" #import "SDLTCPTransport.h" #import "SDLTimer.h" +#import "SDLTransportType.h" +#import "SDLUnsubscribeButton.h" #import "SDLVehicleType.h" NS_ASSUME_NONNULL_BEGIN @@ -43,7 +47,7 @@ typedef NSString SDLVehicleMake; typedef void (^URLSessionTaskCompletionHandler)(NSData *data, NSURLResponse *response, NSError *error); typedef void (^URLSessionDownloadTaskCompletionHandler)(NSURL *location, NSURLResponse *response, NSError *error); -NSString *const SDLProxyVersion = @"6.0.1"; +NSString *const SDLProxyVersion = @"6.0.2"; const float StartSessionTime = 10.0; const float NotifyProxyClosedDelay = (float)0.1; const int PoliciesCorrelationId = 65535; @@ -272,8 +276,16 @@ static float DefaultConnectionTimeout = 45.0; } -#pragma mark - Message sending and recieving +#pragma mark - Message sending - (void)sendRPC:(SDLRPCMessage *)message { + if ([message.getFunctionName isEqualToString:@"SubscribeButton"]) { + BOOL handledRPC = [self sdl_adaptButtonSubscribeMessage:(SDLSubscribeButton *)message]; + if (handledRPC) { return; } + } else if ([message.getFunctionName isEqualToString:@"UnsubscribeButton"]) { + BOOL handledRPC = [self sdl_adaptButtonUnsubscribeMessage:(SDLUnsubscribeButton *)message]; + if (handledRPC) { return; } + } + @try { [self.protocol sendRPC:message]; } @catch (NSException *exception) { @@ -281,6 +293,85 @@ static float DefaultConnectionTimeout = 45.0; } } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +- (BOOL)sdl_adaptButtonSubscribeMessage:(SDLSubscribeButton *)message { + if ([SDLGlobals sharedGlobals].rpcVersion.majorVersion.intValue >= 5) { + if ([message.buttonName isEqualToEnum:SDLButtonNameOk]) { + SDLSubscribeButton *playPauseMessage = [message copy]; + playPauseMessage.buttonName = SDLButtonNamePlayPause; + + @try { + [self.protocol sendRPC:message]; + [self.protocol sendRPC:playPauseMessage]; + } @catch (NSException *exception) { + SDLLogE(@"Proxy: Failed to send RPC message: %@", message.name); + } + + return YES; + } else if ([message.buttonName isEqualToEnum:SDLButtonNamePlayPause]) { + return NO; + } + } else { // Major version < 5 + if ([message.buttonName isEqualToEnum:SDLButtonNameOk]) { + return NO; + } else if ([message.buttonName isEqualToEnum:SDLButtonNamePlayPause]) { + SDLSubscribeButton *okMessage = [message copy]; + okMessage.buttonName = SDLButtonNameOk; + + @try { + [self.protocol sendRPC:okMessage]; + } @catch (NSException *exception) { + SDLLogE(@"Proxy: Failed to send RPC message: %@", message.name); + } + + return YES; + } + } + + return NO; +} + +- (BOOL)sdl_adaptButtonUnsubscribeMessage:(SDLUnsubscribeButton *)message { + if ([SDLGlobals sharedGlobals].rpcVersion.majorVersion.intValue >= 5) { + if ([message.buttonName isEqualToEnum:SDLButtonNameOk]) { + SDLUnsubscribeButton *playPauseMessage = [message copy]; + playPauseMessage.buttonName = SDLButtonNamePlayPause; + + @try { + [self.protocol sendRPC:message]; + [self.protocol sendRPC:playPauseMessage]; + } @catch (NSException *exception) { + SDLLogE(@"Proxy: Failed to send RPC message: %@", message.name); + } + + return YES; + } else if ([message.buttonName isEqualToEnum:SDLButtonNamePlayPause]) { + return NO; + } + } else { // Major version < 5 + if ([message.buttonName isEqualToEnum:SDLButtonNameOk]) { + return NO; + } else if ([message.buttonName isEqualToEnum:SDLButtonNamePlayPause]) { + SDLUnsubscribeButton *okMessage = [message copy]; + okMessage.buttonName = SDLButtonNameOk; + + @try { + [self.protocol sendRPC:okMessage]; + } @catch (NSException *exception) { + SDLLogE(@"Proxy: Failed to send RPC message: %@", message.name); + } + + return YES; + } + } + + return NO; +} +#pragma clang diagnostic pop + +#pragma mark - Message Receiving + - (void)handleProtocolMessage:(SDLProtocolMessage *)incomingMessage { // Convert protocol message to dictionary NSDictionary<NSString *, id> *rpcMessageAsDictionary = [incomingMessage rpcDictionary]; @@ -304,9 +395,6 @@ static float DefaultConnectionTimeout = 45.0; NSString *functionClassName = [NSString stringWithFormat:@"SDL%@", functionName]; SDLRPCMessage *newMessage = [[NSClassFromString(functionClassName) alloc] initWithDictionary:[dict mutableCopy]]; - // Log the RPC message - SDLLogV(@"Message received: %@", newMessage); - // Intercept and handle several messages ourselves if ([functionName isEqualToString:SDLNameOnAppInterfaceUnregistered] || [functionName isEqualToString:SDLNameUnregisterAppInterface]) { [self handleRPCUnregistered:dict]; @@ -328,10 +416,30 @@ static float DefaultConnectionTimeout = 45.0; [self handleSystemRequestResponse:newMessage]; } - // Formulate the name of the method to call and invoke the method on the delegate(s) - NSString *handlerName = [NSString stringWithFormat:@"on%@:", functionName]; - SEL handlerSelector = NSSelectorFromString(handlerName); - [self invokeMethodOnDelegates:handlerSelector withObject:newMessage]; + + if ([functionName isEqualToString:@"OnButtonPress"]) { + SDLOnButtonPress *message = (SDLOnButtonPress *)newMessage; + if ([SDLGlobals sharedGlobals].rpcVersion.majorVersion.intValue >= 5) { + BOOL handledRPC = [self sdl_handleOnButtonPressPostV5:message]; + if (handledRPC) { return; } + } else { // RPC version of 4 or less (connected to an old head unit) + BOOL handledRPC = [self sdl_handleOnButtonPressPreV5:message]; + if (handledRPC) { return; } + } + } + + if ([functionName isEqualToString:@"OnButtonEvent"]) { + SDLOnButtonEvent *message = (SDLOnButtonEvent *)newMessage; + if ([SDLGlobals sharedGlobals].rpcVersion.majorVersion.intValue >= 5) { + BOOL handledRPC = [self sdl_handleOnButtonEventPostV5:message]; + if (handledRPC) { return; } + } else { + BOOL handledRPC = [self sdl_handleOnButtonEventPreV5:message]; + if (handledRPC) { return; } + } + } + + [self sdl_invokeDelegateMethodsWithFunction:functionName message:newMessage]; // When an OnHMIStatus notification comes in, after passing it on (above), generate an "OnLockScreenNotification" if ([functionName isEqualToString:@"OnHMIStatus"]) { @@ -344,6 +452,13 @@ static float DefaultConnectionTimeout = 45.0; } } +- (void)sdl_invokeDelegateMethodsWithFunction:(NSString *)functionName message:(SDLRPCMessage *)message { + // Formulate the name of the method to call and invoke the method on the delegate(s) + NSString *handlerName = [NSString stringWithFormat:@"on%@:", functionName]; + SEL handlerSelector = NSSelectorFromString(handlerName); + [self invokeMethodOnDelegates:handlerSelector withObject:message]; +} + #pragma mark - RPC Handlers @@ -403,6 +518,89 @@ static float DefaultConnectionTimeout = 45.0; SDLLogV(@"SystemRequestResponse to be discarded"); } +#pragma mark BackCompatability ButtonName Helpers + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +- (BOOL)sdl_handleOnButtonPressPreV5:(SDLOnButtonPress *)message { + // Drop PlayPause, this shouldn't come in + if ([message.buttonName isEqualToEnum:SDLButtonNamePlayPause]) { + return YES; + } else if ([message.buttonName isEqualToEnum:SDLButtonNameOk]) { + // Send Ok and Play/Pause notifications + SDLOnButtonPress *playPausePress = [message copy]; + playPausePress.buttonName = SDLButtonNamePlayPause; + + [self sdl_invokeDelegateMethodsWithFunction:message.getFunctionName message:playPausePress]; + [self sdl_invokeDelegateMethodsWithFunction:message.getFunctionName message:message]; + return YES; + } + + return NO; +} + +- (BOOL)sdl_handleOnButtonPressPostV5:(SDLOnButtonPress *)message { + if ([message.buttonName isEqualToEnum:SDLButtonNamePlayPause]) { + // Send PlayPause & OK notifications + SDLOnButtonPress *okPress = [message copy]; + okPress.buttonName = SDLButtonNameOk; + + [self sdl_invokeDelegateMethodsWithFunction:message.getFunctionName message:okPress]; + [self sdl_invokeDelegateMethodsWithFunction:message.getFunctionName message:message]; + return YES; + } else if ([message.buttonName isEqualToEnum:SDLButtonNameOk]) { + // Send PlayPause and OK notifications + SDLOnButtonPress *playPausePress = [message copy]; + playPausePress.buttonName = SDLButtonNamePlayPause; + + [self sdl_invokeDelegateMethodsWithFunction:message.getFunctionName message:playPausePress]; + [self sdl_invokeDelegateMethodsWithFunction:message.getFunctionName message:message]; + return YES; + } + + return NO; +} + +- (BOOL)sdl_handleOnButtonEventPreV5:(SDLOnButtonEvent *)message { + // Drop PlayPause, this shouldn't come in + if ([message.buttonName isEqualToEnum:SDLButtonNamePlayPause]) { + return YES; + } else if ([message.buttonName isEqualToEnum:SDLButtonNameOk]) { + // Send Ok and Play/Pause notifications + SDLOnButtonEvent *playPauseEvent = [message copy]; + playPauseEvent.buttonName = SDLButtonNamePlayPause; + + [self sdl_invokeDelegateMethodsWithFunction:message.getFunctionName message:playPauseEvent]; + [self sdl_invokeDelegateMethodsWithFunction:message.getFunctionName message:message]; + return YES; + } + + return NO; +} + +- (BOOL)sdl_handleOnButtonEventPostV5:(SDLOnButtonEvent *)message { + if ([message.buttonName isEqualToEnum:SDLButtonNamePlayPause]) { + // Send PlayPause & OK notifications + SDLOnButtonEvent *okEvent = [message copy]; + okEvent.buttonName = SDLButtonNameOk; + + [self sdl_invokeDelegateMethodsWithFunction:message.getFunctionName message:okEvent]; + [self sdl_invokeDelegateMethodsWithFunction:message.getFunctionName message:message]; + return YES; + } else if ([message.buttonName isEqualToEnum:SDLButtonNameOk]) { + // Send PlayPause and OK notifications + SDLOnButtonEvent *playPauseEvent = [message copy]; + playPauseEvent.buttonName = SDLButtonNamePlayPause; + + [self sdl_invokeDelegateMethodsWithFunction:message.getFunctionName message:playPauseEvent]; + [self sdl_invokeDelegateMethodsWithFunction:message.getFunctionName message:message]; + return YES; + } + + return NO; +} +#pragma clang diagnostic pop + #pragma mark Handle Post-Invoke of Delegate Methods - (void)handleAfterHMIStatus:(SDLRPCMessage *)message { |