summaryrefslogtreecommitdiff
path: root/SmartDeviceLink/SDLProxy.m
diff options
context:
space:
mode:
authorSho Amano <samano@xevo.com>2018-09-26 11:02:23 +0900
committerSho Amano <samano@xevo.com>2018-09-26 11:02:23 +0900
commit0bb6170e002fa13ac3c3bc39e8baa1e6ba7ac2b4 (patch)
tree4973697f32e6bf526e8a5496a14e2dcef07adecc /SmartDeviceLink/SDLProxy.m
parent518015176789e425626989205cf0659616f63be8 (diff)
parent3aebf547fbe8ff12d9a28cdf8ad4fb20541c3e7f (diff)
downloadsdl_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.m218
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 {