From f1e4647d674ae6ea502be1a4052fbb8221b1fda9 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Thu, 14 Feb 2019 14:52:32 -0500 Subject: Added the SDLRPCRequestNotification class --- SmartDeviceLink-iOS.xcodeproj/project.pbxproj | 16 +++++++ .../Requests/SDLRPCRequestNotification.h | 51 ++++++++++++++++++++++ .../Requests/SDLRPCRequestNotification.m | 49 +++++++++++++++++++++ SmartDeviceLink/SDLRPCResponseNotification.h | 2 +- 4 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 SmartDeviceLink/Requests/SDLRPCRequestNotification.h create mode 100644 SmartDeviceLink/Requests/SDLRPCRequestNotification.m diff --git a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj index 147b55bec..2921daf26 100644 --- a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj +++ b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj @@ -1334,6 +1334,8 @@ 88F65133220C6DC300CAF321 /* SDLWeatherAlertSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 88F65132220C6DC300CAF321 /* SDLWeatherAlertSpec.m */; }; 88F65136220C74FD00CAF321 /* SDLWeatherData.h in Headers */ = {isa = PBXBuildFile; fileRef = 88F65134220C74FD00CAF321 /* SDLWeatherData.h */; settings = {ATTRIBUTES = (Public, ); }; }; 88F65137220C74FD00CAF321 /* SDLWeatherData.m in Sources */ = {isa = PBXBuildFile; fileRef = 88F65135220C74FD00CAF321 /* SDLWeatherData.m */; }; + 88FF4E762215FB8200A71361 /* SDLRPCRequestNotification.h in Headers */ = {isa = PBXBuildFile; fileRef = 88FF4E742215FB8200A71361 /* SDLRPCRequestNotification.h */; }; + 88FF4E772215FB8200A71361 /* SDLRPCRequestNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = 88FF4E752215FB8200A71361 /* SDLRPCRequestNotification.m */; }; 8B7B319A1F2F7B5700BDC38D /* SDLVideoStreamingCodec.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B7B31981F2F7B5700BDC38D /* SDLVideoStreamingCodec.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8B7B319B1F2F7B5700BDC38D /* SDLVideoStreamingCodec.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B7B31991F2F7B5700BDC38D /* SDLVideoStreamingCodec.m */; }; 8B7B319E1F2F7CF700BDC38D /* SDLVideoStreamingProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B7B319C1F2F7CF700BDC38D /* SDLVideoStreamingProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -2908,6 +2910,8 @@ 88F65132220C6DC300CAF321 /* SDLWeatherAlertSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLWeatherAlertSpec.m; sourceTree = ""; }; 88F65134220C74FD00CAF321 /* SDLWeatherData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLWeatherData.h; sourceTree = ""; }; 88F65135220C74FD00CAF321 /* SDLWeatherData.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLWeatherData.m; sourceTree = ""; }; + 88FF4E742215FB8200A71361 /* SDLRPCRequestNotification.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLRPCRequestNotification.h; sourceTree = ""; }; + 88FF4E752215FB8200A71361 /* SDLRPCRequestNotification.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLRPCRequestNotification.m; sourceTree = ""; }; 8B7B31981F2F7B5700BDC38D /* SDLVideoStreamingCodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLVideoStreamingCodec.h; sourceTree = ""; }; 8B7B31991F2F7B5700BDC38D /* SDLVideoStreamingCodec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLVideoStreamingCodec.m; sourceTree = ""; }; 8B7B319C1F2F7CF700BDC38D /* SDLVideoStreamingProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLVideoStreamingProtocol.h; sourceTree = ""; }; @@ -5393,6 +5397,7 @@ 5DBAE0A71D355F0C00CE00BF /* Dispatchers */ = { isa = PBXGroup; children = ( + 88FF4E732215FB5B00A71361 /* Requests */, 5D3E48781D6F86EC0000BFEF /* Notifications */, 5D3E48821D74813B0000BFEF /* Responses */, ); @@ -5725,6 +5730,15 @@ name = Helpers; sourceTree = ""; }; + 88FF4E732215FB5B00A71361 /* Requests */ = { + isa = PBXGroup; + children = ( + 88FF4E742215FB8200A71361 /* SDLRPCRequestNotification.h */, + 88FF4E752215FB8200A71361 /* SDLRPCRequestNotification.m */, + ); + path = Requests; + sourceTree = ""; + }; DA1166D71D14601C00438CEA /* Touches */ = { isa = PBXGroup; children = ( @@ -6345,6 +6359,7 @@ 5D339CF3207C0ACE000CC364 /* SDLMenuManager.h in Headers */, 5D61FCF01A84238C00846EE7 /* SDLLockScreenStatusManager.h in Headers */, 5D61FD311A84238C00846EE7 /* SDLPolicyDataParser.h in Headers */, + 88FF4E762215FB8200A71361 /* SDLRPCRequestNotification.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6863,6 +6878,7 @@ 5DBF062E1E64A93A00A5CF03 /* SDLLogFilter.m in Sources */, 5D61FDFA1A84238C00846EE7 /* SDLV2ProtocolHeader.m in Sources */, 5D61FDD01A84238C00846EE7 /* SDLTireStatus.m in Sources */, + 88FF4E772215FB8200A71361 /* SDLRPCRequestNotification.m in Sources */, 5D92935F20B33FF700FCC775 /* SDLChoiceSet.m in Sources */, 8855F9E4220CB04000A5C897 /* SDLOnAppServiceData.m in Sources */, 5D61FC321A84238C00846EE7 /* SDLAddSubMenu.m in Sources */, diff --git a/SmartDeviceLink/Requests/SDLRPCRequestNotification.h b/SmartDeviceLink/Requests/SDLRPCRequestNotification.h new file mode 100644 index 000000000..e78cd2981 --- /dev/null +++ b/SmartDeviceLink/Requests/SDLRPCRequestNotification.h @@ -0,0 +1,51 @@ +// +// SDLRPCRequestNotification.h +// SmartDeviceLink +// +// Created by Nicole on 2/14/19. +// Copyright © 2019 smartdevicelink. All rights reserved. +// + +#import + +@class SDLRPCRequest; + +NS_ASSUME_NONNULL_BEGIN + +/** + * A NSNotification object that makes retrieving internal SDLRPCRequest data easier + */ +@interface SDLRPCRequestNotification : NSNotification + +/** + * The request to be included in the userinfo dictionary + */ +@property (copy, nonatomic, readonly) __kindof SDLRPCRequest *request; + +/** + * Create an NSNotification object containing an SDLRPCRequest + * + * @param name The NSNotification name + * @param object The NSNotification object + * @param request The SDLRPCRequest payload + * @return The NSNotification + */ +- (instancetype)initWithName:(NSString *)name object:(nullable id)object rpcRequest:(__kindof SDLRPCRequest *)request; + +/** + * Returns whether or not the containing response is equal to a class, not including subclasses. + * + * @param aClass the class you are questioning + */ +- (BOOL)isRequestMemberOfClass:(Class)aClass; + +/** + * Returns whether or not the containing response is a kind of class, including subclasses. + * + * @param aClass the class you are questioning + */ +- (BOOL)isRequestKindOfClass:(Class)aClass; + +@end + +NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/Requests/SDLRPCRequestNotification.m b/SmartDeviceLink/Requests/SDLRPCRequestNotification.m new file mode 100644 index 000000000..4ac6250c6 --- /dev/null +++ b/SmartDeviceLink/Requests/SDLRPCRequestNotification.m @@ -0,0 +1,49 @@ +// +// SDLRPCRequestNotification.m +// SmartDeviceLink +// +// Created by Nicole on 2/14/19. +// Copyright © 2019 smartdevicelink. All rights reserved. +// + +#import "SDLRPCRequestNotification.h" + +#import "SDLNotificationConstants.h" +#import "SDLRPCRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation SDLRPCRequestNotification + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wimplicit-atomic-properties" +@synthesize name = _name; +@synthesize object = _object; +@synthesize userInfo = _userInfo; +#pragma clang diagnostic pop + +- (instancetype)initWithName:(NSString *)name object:(nullable id)object rpcRequest:(__kindof SDLRPCRequest *)request { + _name = name; + _object = object; + _userInfo = @{SDLNotificationUserInfoObject: request}; + + return self; +} + +- (__kindof SDLRPCRequest *)request { + return _userInfo[SDLNotificationUserInfoObject]; +} + +- (BOOL)isRequestMemberOfClass:(Class)aClass { + NSAssert([self.request isMemberOfClass:aClass], @"A notification was sent with an unanticipated object"); + return [self.request isMemberOfClass:aClass]; +} + +- (BOOL)isRequestKindOfClass:(Class)aClass { + NSAssert([self.request isKindOfClass:aClass], @"A notification was sent with an unanticipated object"); + return [self.request isKindOfClass:aClass]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLRPCResponseNotification.h b/SmartDeviceLink/SDLRPCResponseNotification.h index 8d77dd767..4434f2a04 100644 --- a/SmartDeviceLink/SDLRPCResponseNotification.h +++ b/SmartDeviceLink/SDLRPCResponseNotification.h @@ -19,7 +19,7 @@ NS_ASSUME_NONNULL_BEGIN @interface SDLRPCResponseNotification : NSNotification /** - * The response within the userinfo dictionary + * The response to be included within the userinfo dictionary */ @property (copy, nonatomic, readonly) __kindof SDLRPCResponse *response; -- cgit v1.2.1 From 2fb1a7071c4a27321349ac57157912d53a9479ad Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Thu, 14 Feb 2019 15:17:30 -0500 Subject: Added test cases for SDLRPCRequestNotification class --- SmartDeviceLink-iOS.xcodeproj/project.pbxproj | 28 +- .../DevAPISpecs/SDLNotificationDispatcherSpec.m | 120 ---- .../DevAPISpecs/SDLResponseDispatcherSpec.m | 788 --------------------- .../Notifications/SDLNotificationDispatcherSpec.m | 120 ++++ .../Notifications/SDLResponseDispatcherSpec.m | 788 +++++++++++++++++++++ .../Requests/SDLRPCRequestNotificationSpec.m | 41 ++ 6 files changed, 973 insertions(+), 912 deletions(-) delete mode 100644 SmartDeviceLinkTests/DevAPISpecs/SDLNotificationDispatcherSpec.m delete mode 100644 SmartDeviceLinkTests/DevAPISpecs/SDLResponseDispatcherSpec.m create mode 100644 SmartDeviceLinkTests/Notifications/SDLNotificationDispatcherSpec.m create mode 100644 SmartDeviceLinkTests/Notifications/SDLResponseDispatcherSpec.m create mode 100644 SmartDeviceLinkTests/Requests/SDLRPCRequestNotificationSpec.m diff --git a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj index 2921daf26..009588195 100644 --- a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj +++ b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj @@ -1336,6 +1336,7 @@ 88F65137220C74FD00CAF321 /* SDLWeatherData.m in Sources */ = {isa = PBXBuildFile; fileRef = 88F65135220C74FD00CAF321 /* SDLWeatherData.m */; }; 88FF4E762215FB8200A71361 /* SDLRPCRequestNotification.h in Headers */ = {isa = PBXBuildFile; fileRef = 88FF4E742215FB8200A71361 /* SDLRPCRequestNotification.h */; }; 88FF4E772215FB8200A71361 /* SDLRPCRequestNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = 88FF4E752215FB8200A71361 /* SDLRPCRequestNotification.m */; }; + 88FF4E7C2215FEEA00A71361 /* SDLRPCRequestNotificationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 88FF4E7B2215FEEA00A71361 /* SDLRPCRequestNotificationSpec.m */; }; 8B7B319A1F2F7B5700BDC38D /* SDLVideoStreamingCodec.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B7B31981F2F7B5700BDC38D /* SDLVideoStreamingCodec.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8B7B319B1F2F7B5700BDC38D /* SDLVideoStreamingCodec.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B7B31991F2F7B5700BDC38D /* SDLVideoStreamingCodec.m */; }; 8B7B319E1F2F7CF700BDC38D /* SDLVideoStreamingProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B7B319C1F2F7CF700BDC38D /* SDLVideoStreamingProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -2733,8 +2734,8 @@ 5DB9965B1F268F97002D8795 /* SDLControlFramePayloadVideoStartService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLControlFramePayloadVideoStartService.m; sourceTree = ""; }; 5DB9965E1F28C6ED002D8795 /* SDLControlFramePayloadVideoStartServiceAck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLControlFramePayloadVideoStartServiceAck.h; sourceTree = ""; }; 5DB9965F1F28C6ED002D8795 /* SDLControlFramePayloadVideoStartServiceAck.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLControlFramePayloadVideoStartServiceAck.m; sourceTree = ""; }; - 5DBAE0AA1D3588AC00CE00BF /* SDLNotificationDispatcherSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLNotificationDispatcherSpec.m; path = DevAPISpecs/SDLNotificationDispatcherSpec.m; sourceTree = ""; }; - 5DBAE0AC1D368D1A00CE00BF /* SDLResponseDispatcherSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLResponseDispatcherSpec.m; path = DevAPISpecs/SDLResponseDispatcherSpec.m; sourceTree = ""; }; + 5DBAE0AA1D3588AC00CE00BF /* SDLNotificationDispatcherSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLNotificationDispatcherSpec.m; sourceTree = ""; }; + 5DBAE0AC1D368D1A00CE00BF /* SDLResponseDispatcherSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLResponseDispatcherSpec.m; sourceTree = ""; }; 5DBEFA531F434B9E009EE295 /* SDLStreamingMediaConfigurationSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLStreamingMediaConfigurationSpec.m; path = DevAPISpecs/SDLStreamingMediaConfigurationSpec.m; sourceTree = ""; }; 5DBEFA561F436132009EE295 /* SDLFakeSecurityManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDLFakeSecurityManager.h; path = DevAPISpecs/SDLFakeSecurityManager.h; sourceTree = ""; }; 5DBEFA571F436132009EE295 /* SDLFakeSecurityManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLFakeSecurityManager.m; path = DevAPISpecs/SDLFakeSecurityManager.m; sourceTree = ""; }; @@ -2912,6 +2913,7 @@ 88F65135220C74FD00CAF321 /* SDLWeatherData.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLWeatherData.m; sourceTree = ""; }; 88FF4E742215FB8200A71361 /* SDLRPCRequestNotification.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLRPCRequestNotification.h; sourceTree = ""; }; 88FF4E752215FB8200A71361 /* SDLRPCRequestNotification.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLRPCRequestNotification.m; sourceTree = ""; }; + 88FF4E7B2215FEEA00A71361 /* SDLRPCRequestNotificationSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLRPCRequestNotificationSpec.m; sourceTree = ""; }; 8B7B31981F2F7B5700BDC38D /* SDLVideoStreamingCodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLVideoStreamingCodec.h; sourceTree = ""; }; 8B7B31991F2F7B5700BDC38D /* SDLVideoStreamingCodec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLVideoStreamingCodec.m; sourceTree = ""; }; 8B7B319C1F2F7CF700BDC38D /* SDLVideoStreamingProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLVideoStreamingProtocol.h; sourceTree = ""; }; @@ -5422,8 +5424,8 @@ 5DBAE0A91D35888D00CE00BF /* Dispatchers */ = { isa = PBXGroup; children = ( - 5DBAE0AA1D3588AC00CE00BF /* SDLNotificationDispatcherSpec.m */, - 5DBAE0AC1D368D1A00CE00BF /* SDLResponseDispatcherSpec.m */, + 88FF4E7A2215FEC200A71361 /* Requests */, + 88FF4E792215FEAF00A71361 /* Notifications */, ); name = Dispatchers; sourceTree = ""; @@ -5739,6 +5741,23 @@ path = Requests; sourceTree = ""; }; + 88FF4E792215FEAF00A71361 /* Notifications */ = { + isa = PBXGroup; + children = ( + 5DBAE0AA1D3588AC00CE00BF /* SDLNotificationDispatcherSpec.m */, + 5DBAE0AC1D368D1A00CE00BF /* SDLResponseDispatcherSpec.m */, + ); + path = Notifications; + sourceTree = ""; + }; + 88FF4E7A2215FEC200A71361 /* Requests */ = { + isa = PBXGroup; + children = ( + 88FF4E7B2215FEEA00A71361 /* SDLRPCRequestNotificationSpec.m */, + ); + path = Requests; + sourceTree = ""; + }; DA1166D71D14601C00438CEA /* Touches */ = { isa = PBXGroup; children = ( @@ -7336,6 +7355,7 @@ 1EE8C4461F3837D200FDC2CF /* SDLModuleDataSpec.m in Sources */, EEA41D45210BA8CF0006CB6E /* TestTCPServer.m in Sources */, 1E89B0DE2031636000A47992 /* SDLSeatControlDataSpec.m in Sources */, + 88FF4E7C2215FEEA00A71361 /* SDLRPCRequestNotificationSpec.m in Sources */, 8831FA3D220207DA00B8FFB7 /* SDLServiceUpdateReasonSpec.m in Sources */, 162E831A1A9BDE8B00906325 /* SDLOnLockScreenStatusSpec.m in Sources */, 162E83431A9BDE8B00906325 /* SDLSyncPDataSpec.m in Sources */, diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLNotificationDispatcherSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLNotificationDispatcherSpec.m deleted file mode 100644 index 63d691ee0..000000000 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLNotificationDispatcherSpec.m +++ /dev/null @@ -1,120 +0,0 @@ -#import -#import - -#import "SDLNotificationConstants.h" -#import "SDLNotificationDispatcher.h" - - -QuickSpecBegin(SDLNotificationDispatcherSpec) - -describe(@"a notification dispatcher", ^{ - __block SDLNotificationDispatcher *testDispatcher = nil; - - beforeEach(^{ - testDispatcher = [[SDLNotificationDispatcher alloc] init]; - }); - - it(@"should conform to SDLProxyListener", ^{ - expect(@([testDispatcher conformsToProtocol:@protocol(SDLProxyListener)])).to(beTruthy()); - - expect(@([testDispatcher respondsToSelector:@selector(onOnDriverDistraction:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onOnHMIStatus:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onProxyClosed)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onProxyOpened)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onAddCommandResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onAddSubMenuResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onAlertManeuverResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onAlertResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onButtonPressResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onChangeRegistrationResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onCreateInteractionChoiceSetResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onDeleteCommandResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onDeleteInteractionChoiceSetResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onDeleteSubMenuResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onDiagnosticMessageResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onDialNumberResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onEncodedSyncPDataResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onEndAudioPassThruResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onError:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onGenericResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onGetAppServiceDataResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onGetDTCsResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onGetFileResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onGetInteriorVehicleDataResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onGetSystemCapabilityResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onGetVehicleDataResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onGetWayPointsResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onReceivedLockScreenIcon:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onOnAppInterfaceUnregistered:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onOnAppServiceData:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onOnAudioPassThru:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onOnButtonEvent:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onOnButtonPress:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onOnCommand:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onOnEncodedSyncPData:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onOnHashChange:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onOnLanguageChange:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onOnLockScreenNotification:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onOnSyncPData:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onOnRCStatus:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onOnSystemRequest:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onOnTBTClientState:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onOnTouchEvent:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onOnVehicleData:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onOnWayPointChange:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onPerformAppServiceInteractionResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onPerformAudioPassThruResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onPerformInteractionResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onPublishAppService:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onPutFileResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onReadDIDResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onRegisterAppInterfaceResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onResetGlobalPropertiesResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onScrollableMessageResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onSendHapticDataResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onSendLocationResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onSetAppIconResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onSetDisplayLayoutResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onSetGlobalPropertiesResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onSetInteriorVehicleDataResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onSetMediaClockTimerResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onShowConstantTBTResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onShowResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onSliderResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onSpeakResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onSubscribeButtonResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onSubscribeVehicleDataResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onSubscribeWayPointsResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onSyncPDataResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onUpdateTurnListResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onUnregisterAppInterfaceResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onUnsubscribeButtonResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onUnsubscribeVehicleDataResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onUnsubscribeWayPointsResponse:)])).to(beTruthy()); - }); - - describe(@"when told to post a notification", ^{ - __block NSString *testNotificationName = nil; - __block NSString *testUserInfo = nil; - - __block NSNotification *returnNotification = nil; - - beforeEach(^{ - testNotificationName = @"com.test.notification"; - testUserInfo = @"testuserinfo"; - - [[NSNotificationCenter defaultCenter] addObserverForName:testNotificationName object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) { - returnNotification = note; - }]; - - [testDispatcher postNotificationName:testNotificationName infoObject:testUserInfo]; - }); - - it(@"should post", ^{ - expect(returnNotification.userInfo[SDLNotificationUserInfoObject]).toEventually(match(testUserInfo)); - expect(returnNotification.object).toEventually(equal(testDispatcher)); - }); - }); -}); - -QuickSpecEnd diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLResponseDispatcherSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLResponseDispatcherSpec.m deleted file mode 100644 index 410d24386..000000000 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLResponseDispatcherSpec.m +++ /dev/null @@ -1,788 +0,0 @@ -#import -#import - -#import "SDLAddCommand.h" -#import "SDLAlert.h" -#import "SDLButtonName.h" -#import "SDLDeleteCommand.h" -#import "SDLDeleteCommandResponse.h" -#import "SDLNotificationConstants.h" -#import "SDLOnAudioPassThru.h" -#import "SDLOnButtonEvent.h" -#import "SDLOnButtonPress.h" -#import "SDLOnCommand.h" -#import "SDLPerformAudioPassThru.h" -#import "SDLPerformAudioPassThruResponse.h" -#import "SDLReadDID.h" -#import "SDLReadDIDResponse.h" -#import "SDLResponseDispatcher.h" -#import "SDLRPCNotificationNotification.h" -#import "SDLRPCResponseNotification.h" -#import "SDLScrollableMessage.h" -#import "SDLShow.h" -#import "SDLSoftButton.h" -#import "SDLSoftButtonType.h" -#import "SDLSubscribeButton.h" -#import "SDLSystemAction.h" -#import "SDLTextAlignment.h" -#import "SDLUnsubscribeButton.h" -#import "SDLUnsubscribeButtonResponse.h" - - -QuickSpecBegin(SDLResponseDispatcherSpec) - -describe(@"a response dispatcher", ^{ - __block SDLResponseDispatcher *testDispatcher = nil; - - beforeEach(^{ - testDispatcher = [[SDLResponseDispatcher alloc] init]; - }); - - it(@"should initialize the NSMapTable properties", ^{ - expect(testDispatcher.rpcResponseHandlerMap).toNot(beNil()); - expect(testDispatcher.rpcRequestDictionary).toNot(beNil()); - expect(testDispatcher.commandHandlerMap).toNot(beNil()); - expect(testDispatcher.buttonHandlerMap).toNot(beNil()); - expect(testDispatcher.customButtonHandlerMap).toNot(beNil()); -// expect(testDispatcher.audioPassThruHandler).to(beNil()); - - expect(testDispatcher.rpcResponseHandlerMap).to(haveCount(@0)); - expect(testDispatcher.rpcRequestDictionary).to(haveCount(@0)); - expect(testDispatcher.commandHandlerMap).to(haveCount(@0)); - expect(testDispatcher.buttonHandlerMap).to(haveCount(@0)); - expect(testDispatcher.customButtonHandlerMap).to(haveCount(@0)); - }); - - context(@"storing a request without a handler", ^{ - __block SDLReadDID *testRPC = nil; - __block NSNumber *testCorrelationId = nil; - - beforeEach(^{ - testRPC = [[SDLReadDID alloc] init]; - testCorrelationId = @111; - testRPC.correlationID = testCorrelationId; - }); - - it(@"should not store the request", ^{ - [testDispatcher storeRequest:testRPC handler:nil]; - - expect(testDispatcher.rpcResponseHandlerMap).to(haveCount(@0)); - expect(testDispatcher.rpcRequestDictionary).to(haveCount(@1)); - expect(testDispatcher.commandHandlerMap).to(haveCount(@0)); - expect(testDispatcher.buttonHandlerMap).to(haveCount(@0)); - expect(testDispatcher.customButtonHandlerMap).to(haveCount(@0)); - }); - }); - - context(@"storing a request with a handler", ^{ - __block SDLRPCRequest *testRequest = nil; - __block NSNumber *testCorrelationId = nil; - __block BOOL handlerCalled = NO; - - beforeEach(^{ - testRequest = [[SDLReadDID alloc] init]; - testCorrelationId = @42; - - testRequest.correlationID = testCorrelationId; - [testDispatcher storeRequest:testRequest handler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) { - handlerCalled = YES; - }]; - }); - - it(@"should store the request and response", ^{ - expect(testDispatcher.rpcRequestDictionary[testCorrelationId]).toNot(beNil()); - expect(testDispatcher.rpcRequestDictionary).to(haveCount(@1)); - - expect(testDispatcher.rpcResponseHandlerMap[testCorrelationId]).toNot(beNil()); - expect(testDispatcher.rpcResponseHandlerMap).to(haveCount(@1)); - }); - - describe(@"when a response arrives", ^{ - __block SDLRPCResponse *testResponse = nil; - - beforeEach(^{ - testResponse = [[SDLReadDIDResponse alloc] init]; - testResponse.correlationID = testCorrelationId; - - SDLRPCResponseNotification *responseNotification = [[SDLRPCResponseNotification alloc] initWithName:SDLDidReceiveReadDIDResponse object:nil rpcResponse:testResponse]; - [[NSNotificationCenter defaultCenter] postNotification:responseNotification]; - }); - - it(@"should run the handler", ^{ - expect(@(handlerCalled)).to(beTruthy()); - expect(testDispatcher.rpcRequestDictionary).to(haveCount(@0)); - expect(testDispatcher.rpcResponseHandlerMap).to(haveCount(@0)); - }); - }); - }); - - context(@"storing a show request", ^{ - __block SDLShow *testShow = nil; - __block SDLSoftButton *testSoftButton1 = nil; - __block NSUInteger numTimesHandlerCalled = 0; - - beforeEach(^{ - testShow = [[SDLShow alloc] initWithMainField1:@"Test Show" mainField2:nil alignment:SDLTextAlignmentCenter]; - testShow.correlationID = @1; - }); - - context(@"with a correct soft button and handler", ^{ - beforeEach(^{ - numTimesHandlerCalled = 0; - - testSoftButton1 = [[SDLSoftButton alloc] initWithType:SDLSoftButtonTypeText text:@"test" image:nil highlighted:NO buttonId:1 systemAction:SDLSystemActionDefaultAction handler:^(SDLOnButtonPress * _Nullable buttonPressNotification, SDLOnButtonEvent * _Nullable buttonEventNotification) { - numTimesHandlerCalled++; - }]; - testShow.softButtons = [@[testSoftButton1] mutableCopy]; - testShow.correlationID = @1; - [testDispatcher storeRequest:testShow handler:nil]; - }); - - it(@"should add the soft button to the map", ^{ - expect(testDispatcher.customButtonHandlerMap[testSoftButton1.softButtonID]).toNot(beNil()); - expect(testDispatcher.customButtonHandlerMap).to(haveCount(@1)); - }); - - describe(@"when button press and button event notifications arrive", ^{ - __block SDLOnButtonEvent *testButtonEvent = nil; - __block SDLOnButtonPress *testButtonPress = nil; - - context(@"that correspond to the created button", ^{ - beforeEach(^{ - testButtonEvent = [[SDLOnButtonEvent alloc] init]; - testButtonEvent.customButtonID = testSoftButton1.softButtonID; - testButtonEvent.buttonName = SDLButtonNameCustomButton; - - testButtonPress = [[SDLOnButtonPress alloc] init]; - testButtonPress.customButtonID = testSoftButton1.softButtonID; - testButtonPress.buttonName = SDLButtonNameCustomButton; - - SDLRPCNotificationNotification *buttonEventNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonEventNotification object:nil rpcNotification:testButtonEvent]; - SDLRPCNotificationNotification *buttonPressNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonPressNotification object:nil rpcNotification:testButtonPress]; - - [[NSNotificationCenter defaultCenter] postNotification:buttonEventNotification]; - [[NSNotificationCenter defaultCenter] postNotification:buttonPressNotification]; - }); - - it(@"should run the handler for each", ^{ - expect(@(numTimesHandlerCalled)).to(equal(@2)); - }); - }); - - context(@"that do not correspond to the created button", ^{ - beforeEach(^{ - testButtonEvent = [[SDLOnButtonEvent alloc] init]; - testButtonEvent.buttonName = SDLButtonNameOk; - - testButtonPress = [[SDLOnButtonPress alloc] init]; - testButtonPress.buttonName = SDLButtonNameOk; - - SDLRPCNotificationNotification *buttonEventNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonEventNotification object:nil rpcNotification:testButtonEvent]; - SDLRPCNotificationNotification *buttonPressNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonPressNotification object:nil rpcNotification:testButtonPress]; - - [[NSNotificationCenter defaultCenter] postNotification:buttonEventNotification]; - [[NSNotificationCenter defaultCenter] postNotification:buttonPressNotification]; - }); - - it(@"should not run the handler", ^{ - expect(@(numTimesHandlerCalled)).to(equal(@0)); - }); - }); - }); - }); - - context(@"with a correct soft button but no handler", ^{ - beforeEach(^{ - testSoftButton1 = [[SDLSoftButton alloc] initWithType:SDLSoftButtonTypeText text:@"test" image:nil highlighted:NO buttonId:1 systemAction:SDLSystemActionDefaultAction handler:nil]; - }); - - it(@"should not add the soft button", ^{ - expect(testDispatcher.customButtonHandlerMap).to(haveCount(@0)); - }); - }); - - context(@"with a malformed soft button", ^{ - beforeEach(^{ - testSoftButton1 = [[SDLSoftButton alloc] initWithType:SDLSoftButtonTypeText text:@"test" image:nil highlighted:NO buttonId:1 systemAction:SDLSystemActionDefaultAction handler:nil]; - }); - - it(@"should throw an exception if there's no button id", ^{ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wnonnull" - testSoftButton1.softButtonID = nil; -#pragma clang diagnostic pop - testShow.softButtons = [@[testSoftButton1] mutableCopy]; - - expectAction(^{ [testDispatcher storeRequest:testShow handler:nil]; }).to(raiseException().named(@"MissingIdException")); - }); - }); - - context(@"without soft buttons", ^{ - it(@"should not store the request", ^{ - [testDispatcher storeRequest:testShow handler:nil]; - - expect(testDispatcher.customButtonHandlerMap).to(haveCount(@0)); - }); - }); - }); - - context(@"storing a command request", ^{ - __block SDLAddCommand *testAddCommand = nil; - __block UInt32 testCommandId = 0; - __block NSUInteger numTimesHandlerCalled = 0; - - __block NSNumber *testAddCommandCorrelationId = nil; - __block NSNumber *testDeleteCommandCorrelationId = nil; - - context(@"with a handler", ^{ - beforeEach(^{ - testCommandId = 1; - testAddCommandCorrelationId = @42; - numTimesHandlerCalled = 0; - - testAddCommand = [[SDLAddCommand alloc] initWithId:testCommandId vrCommands:nil handler:^(__kindof SDLRPCNotification * _Nonnull notification) { - numTimesHandlerCalled++; - }]; - testAddCommand.correlationID = testAddCommandCorrelationId; - }); - - it(@"should add the command to the map", ^{ - [testDispatcher storeRequest:testAddCommand handler:nil]; - - expect(testDispatcher.commandHandlerMap[testAddCommand.cmdID]).toNot(beNil()); - expect(testDispatcher.commandHandlerMap).to(haveCount(@1)); - }); - - it(@"should throw an exception if there's no command id", ^{ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wnonnull" - testAddCommand.cmdID = nil; - -#pragma clang diagnostic pop - expectAction(^{ [testDispatcher storeRequest:testAddCommand handler:nil]; }).to(raiseException().named(@"MissingIdException")); - }); - - describe(@"when button press and button event notifications arrive", ^{ - __block SDLOnCommand *testOnCommand = nil; - - beforeEach(^{ - [testDispatcher storeRequest:testAddCommand handler:nil]; - }); - - context(@"that correspond to the created button", ^{ - beforeEach(^{ - testOnCommand = [[SDLOnCommand alloc] init]; - testOnCommand.cmdID = @(testCommandId); - testOnCommand.triggerSource = SDLTriggerSourceMenu; - - SDLRPCNotificationNotification *commandNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveCommandNotification object:nil rpcNotification:testOnCommand]; - - [[NSNotificationCenter defaultCenter] postNotification:commandNotification]; - }); - - it(@"should run the handler for each", ^{ - expect(@(numTimesHandlerCalled)).to(equal(@1)); - }); - }); - - context(@"that do not correspond to the created button", ^{ - beforeEach(^{ - testOnCommand = [[SDLOnCommand alloc] init]; - testOnCommand.cmdID = @999; - - SDLRPCNotificationNotification *commandNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveCommandNotification object:nil rpcNotification:testOnCommand]; - - [[NSNotificationCenter defaultCenter] postNotification:commandNotification]; - }); - - it(@"should not run the handler", ^{ - expect(@(numTimesHandlerCalled)).to(equal(@0)); - }); - }); - }); - - describe(@"then deleting the command", ^{ - __block SDLDeleteCommand *testDeleteCommand = nil; - __block SDLDeleteCommandResponse *testDeleteResponse = nil; - - beforeEach(^{ - [testDispatcher storeRequest:testAddCommand handler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) {}]; - - // We need both the delete command and the response for this to work - testDeleteCommandCorrelationId = @43; - - testDeleteCommand = [[SDLDeleteCommand alloc] init]; - testDeleteCommand.correlationID = testDeleteCommandCorrelationId; - testDeleteCommand.cmdID = @(testCommandId); - - [testDispatcher storeRequest:testDeleteCommand handler:nil]; - - testDeleteResponse = [[SDLDeleteCommandResponse alloc] init]; - testDeleteResponse.correlationID = testDeleteCommandCorrelationId; - testDeleteResponse.success = @YES; - - SDLRPCResponseNotification *deleteCommandNotification = [[SDLRPCResponseNotification alloc] initWithName:SDLDidReceiveDeleteCommandResponse object:nil rpcResponse:testDeleteResponse]; - - [[NSNotificationCenter defaultCenter] postNotification:deleteCommandNotification]; - }); - - it(@"should have removed all the handlers", ^{ - // There should still be the add command request & handler in the dictionaries since we never responded - expect(testDispatcher.commandHandlerMap).to(haveCount(@0)); - expect(testDispatcher.rpcRequestDictionary).to(haveCount(@1)); - expect(testDispatcher.rpcResponseHandlerMap).to(haveCount(@1)); - }); - }); - }); - - context(@"without a handler", ^{ - beforeEach(^{ - testAddCommand = [[SDLAddCommand alloc] initWithId:1 vrCommands:nil handler:nil]; - }); - - it(@"should not add the command", ^{ - expect(testDispatcher.commandHandlerMap).to(haveCount(@0)); - }); - }); - }); - - context(@"storing a subscribe button request", ^{ - __block SDLSubscribeButton *testSubscribeButton = nil; - __block SDLButtonName testButtonName = nil; - __block NSUInteger numTimesHandlerCalled = 0; - - __block NSNumber *testSubscribeCorrelationId = nil; - __block NSNumber *testUnsubscribeCorrelationId = nil; - - context(@"with a handler", ^{ - beforeEach(^{ - testButtonName = SDLButtonNameOk; - testSubscribeCorrelationId = @42; - numTimesHandlerCalled = 0; - - testSubscribeButton = [[SDLSubscribeButton alloc] initWithButtonName:testButtonName handler:^(SDLOnButtonPress * _Nullable buttonPressNotification, SDLOnButtonEvent * _Nullable buttonEventNotification) { - numTimesHandlerCalled++; - }]; - testSubscribeButton.correlationID = testSubscribeCorrelationId; - }); - - it(@"should add the subscription to the map", ^{ - [testDispatcher storeRequest:testSubscribeButton handler:nil]; - - expect(testDispatcher.buttonHandlerMap[testSubscribeButton.buttonName]).toNot(beNil()); - expect(testDispatcher.buttonHandlerMap).to(haveCount(@1)); - }); - - it(@"should throw an exception if there's no button name", ^{ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wnonnull" - testSubscribeButton.buttonName = nil; -#pragma clang diagnostic pop - - expectAction(^{ [testDispatcher storeRequest:testSubscribeButton handler:nil]; }).to(raiseException().named(@"MissingIdException")); - }); - - describe(@"when button press and button event notifications arrive", ^{ - __block SDLOnButtonEvent *testButtonEvent = nil; - __block SDLOnButtonPress *testButtonPress = nil; - - beforeEach(^{ - [testDispatcher storeRequest:testSubscribeButton handler:nil]; - }); - - context(@"that correspond to the created button", ^{ - beforeEach(^{ - testButtonEvent = [[SDLOnButtonEvent alloc] init]; - testButtonEvent.buttonName = testButtonName; - - testButtonPress = [[SDLOnButtonPress alloc] init]; - testButtonPress.buttonName = testButtonName; - - SDLRPCNotificationNotification *buttonEventNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonEventNotification object:nil rpcNotification:testButtonEvent]; - SDLRPCNotificationNotification *buttonPressNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonPressNotification object:nil rpcNotification:testButtonPress]; - - [[NSNotificationCenter defaultCenter] postNotification:buttonEventNotification]; - [[NSNotificationCenter defaultCenter] postNotification:buttonPressNotification]; - }); - - it(@"should run the handler for each", ^{ - expect(@(numTimesHandlerCalled)).to(equal(@2)); - }); - }); - - context(@"that do not correspond to the created button", ^{ - beforeEach(^{ - testButtonEvent = [[SDLOnButtonEvent alloc] init]; - testButtonEvent.buttonName = SDLButtonNamePreset0; - - testButtonPress = [[SDLOnButtonPress alloc] init]; - testButtonPress.buttonName = SDLButtonNamePreset0; - - SDLRPCNotificationNotification *buttonEventNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonEventNotification object:nil rpcNotification:testButtonEvent]; - SDLRPCNotificationNotification *buttonPressNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonPressNotification object:nil rpcNotification:testButtonPress]; - - [[NSNotificationCenter defaultCenter] postNotification:buttonEventNotification]; - [[NSNotificationCenter defaultCenter] postNotification:buttonPressNotification]; - }); - - it(@"should not run the handler", ^{ - expect(@(numTimesHandlerCalled)).to(equal(@0)); - }); - }); - }); - - describe(@"then unsubscribing", ^{ - __block SDLUnsubscribeButton *testUnsubscribe = nil; - __block SDLUnsubscribeButtonResponse *testUnsubscribeResponse = nil; - - beforeEach(^{ - [testDispatcher storeRequest:testSubscribeButton handler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) {}]; - - // We need both the delete command and the response for this to work - testUnsubscribeCorrelationId = @43; - - testUnsubscribe = [[SDLUnsubscribeButton alloc] init]; - testUnsubscribe.correlationID = testUnsubscribeCorrelationId; - testUnsubscribe.buttonName = testButtonName; - - [testDispatcher storeRequest:testUnsubscribe handler:nil]; - - testUnsubscribeResponse = [[SDLUnsubscribeButtonResponse alloc] init]; - testUnsubscribeResponse.correlationID = testUnsubscribeCorrelationId; - testUnsubscribeResponse.success = @YES; - - SDLRPCResponseNotification *unsubscribeNotification = [[SDLRPCResponseNotification alloc] initWithName:SDLDidReceiveUnsubscribeButtonResponse object:nil rpcResponse:testUnsubscribeResponse]; - [[NSNotificationCenter defaultCenter] postNotification:unsubscribeNotification]; - }); - - it(@"should have removed all the handlers", ^{ - // There should still be the add command request & handler in the dictionaries since we never responded - expect(testDispatcher.commandHandlerMap).to(haveCount(@0)); - expect(testDispatcher.rpcRequestDictionary).to(haveCount(@1)); - expect(testDispatcher.rpcResponseHandlerMap).to(haveCount(@1)); - }); - }); - }); - - context(@"without a handler", ^{ - beforeEach(^{ - testSubscribeButton = [[SDLSubscribeButton alloc] initWithButtonName:SDLButtonNameOk handler:nil]; - }); - - it(@"should not add the subscription", ^{ - expect(testDispatcher.buttonHandlerMap).to(haveCount(@0)); - }); - }); - }); - - context(@"storing an alert request", ^{ - __block SDLAlert *testAlert = nil; - __block SDLSoftButton *testSoftButton1 = nil; - - beforeEach(^{ - testAlert = [[SDLAlert alloc] initWithAlertText1:@"test 1" alertText2:@"test 1" alertText3:nil duration:1 softButtons:nil]; - testAlert.correlationID = @1; - }); - - context(@"with a correct soft button and handler", ^{ - __block NSUInteger numTimesHandlerCalled = 0; - - beforeEach(^{ - numTimesHandlerCalled = 0; - - testSoftButton1 = [[SDLSoftButton alloc] initWithType:SDLSoftButtonTypeText text:@"test" image:nil highlighted:NO buttonId:1 systemAction:SDLSystemActionDefaultAction handler:^(SDLOnButtonPress * _Nullable buttonPressNotification, SDLOnButtonEvent * _Nullable buttonEventNotification) { - numTimesHandlerCalled++; - }]; - - testAlert.softButtons = [@[testSoftButton1] mutableCopy]; - [testDispatcher storeRequest:testAlert handler:nil]; - }); - - it(@"should add the soft button to the map", ^{ - expect(testDispatcher.customButtonHandlerMap[testSoftButton1.softButtonID]).toNot(beNil()); - expect(testDispatcher.customButtonHandlerMap).to(haveCount(@1)); - }); - - describe(@"when button press and button event notifications arrive", ^{ - __block SDLOnButtonEvent *testButtonEvent = nil; - __block SDLOnButtonPress *testButtonPress = nil; - - context(@"that correspond to the created button", ^{ - beforeEach(^{ - testButtonEvent = [[SDLOnButtonEvent alloc] init]; - testButtonEvent.buttonName = SDLButtonNameCustomButton; - testButtonEvent.customButtonID = testSoftButton1.softButtonID; - - testButtonPress = [[SDLOnButtonPress alloc] init]; - testButtonPress.buttonName = SDLButtonNameCustomButton; - testButtonPress.customButtonID = testSoftButton1.softButtonID; - - SDLRPCNotificationNotification *buttonEventNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonEventNotification object:nil rpcNotification:testButtonEvent]; - SDLRPCNotificationNotification *buttonPressNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonPressNotification object:nil rpcNotification:testButtonPress]; - - [[NSNotificationCenter defaultCenter] postNotification:buttonEventNotification]; - [[NSNotificationCenter defaultCenter] postNotification:buttonPressNotification]; - }); - - it(@"should run the handler for each", ^{ - expect(@(numTimesHandlerCalled)).to(equal(@2)); - }); - }); - - context(@"that do not correspond to the created button", ^{ - beforeEach(^{ - testButtonEvent = [[SDLOnButtonEvent alloc] init]; - testButtonEvent.buttonName = SDLButtonNameOk; - - testButtonPress = [[SDLOnButtonPress alloc] init]; - testButtonPress.buttonName = SDLButtonNameOk; - - SDLRPCNotificationNotification *buttonEventNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonEventNotification object:nil rpcNotification:testButtonEvent]; - SDLRPCNotificationNotification *buttonPressNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonPressNotification object:nil rpcNotification:testButtonPress]; - - [[NSNotificationCenter defaultCenter] postNotification:buttonEventNotification]; - [[NSNotificationCenter defaultCenter] postNotification:buttonPressNotification]; - }); - - it(@"should not run the handler", ^{ - expect(@(numTimesHandlerCalled)).to(equal(@0)); - }); - }); - }); - }); - - context(@"with a correct soft button but no handler", ^{ - beforeEach(^{ - testSoftButton1 = [[SDLSoftButton alloc] initWithType:SDLSoftButtonTypeText text:@"test" image:nil highlighted:NO buttonId:1 systemAction:SDLSystemActionDefaultAction handler:nil]; - }); - - it(@"should not add the soft button", ^{ - expect(testDispatcher.customButtonHandlerMap).to(haveCount(@0)); - }); - }); - - context(@"with a malformed soft button", ^{ - beforeEach(^{ - testSoftButton1 = [[SDLSoftButton alloc] initWithType:SDLSoftButtonTypeText text:@"test" image:nil highlighted:NO buttonId:1 systemAction:SDLSystemActionDefaultAction handler:nil]; - }); - - it(@"should throw an exception if there's no button id", ^{ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wnonnull" - testSoftButton1.softButtonID = nil; -#pragma clang diagnostic pop - testAlert.softButtons = [@[testSoftButton1] mutableCopy]; - - expectAction(^{ [testDispatcher storeRequest:testAlert handler:nil]; }).to(raiseException().named(@"MissingIdException")); - }); - }); - - context(@"without soft buttons", ^{ - it(@"should not store the request", ^{ - [testDispatcher storeRequest:testAlert handler:nil]; - - expect(testDispatcher.customButtonHandlerMap).to(haveCount(@0)); - }); - }); - }); - - context(@"storing a scrollable message request", ^{ - __block SDLScrollableMessage *testScrollableMessage = nil; - __block SDLSoftButton *testSoftButton1 = nil; - - beforeEach(^{ - testScrollableMessage = [[SDLScrollableMessage alloc] initWithMessage:@"test" timeout:1 softButtons:nil]; - testScrollableMessage.correlationID = @1; - }); - - context(@"with a correct soft button and handler", ^{ - __block NSUInteger numTimesHandlerCalled = 0; - - beforeEach(^{ - numTimesHandlerCalled = 0; - - testSoftButton1 = [[SDLSoftButton alloc] initWithType:SDLSoftButtonTypeText text:@"test" image:nil highlighted:NO buttonId:1 systemAction:SDLSystemActionDefaultAction handler:^(SDLOnButtonPress * _Nullable buttonPressNotification, SDLOnButtonEvent * _Nullable buttonEventNotification) { - numTimesHandlerCalled++; - }]; - - testScrollableMessage.softButtons = [@[testSoftButton1] mutableCopy]; - [testDispatcher storeRequest:testScrollableMessage handler:nil]; - }); - - it(@"should add the soft button to the map", ^{ - expect(testDispatcher.customButtonHandlerMap[testSoftButton1.softButtonID]).toNot(beNil()); - expect(testDispatcher.customButtonHandlerMap).to(haveCount(@1)); - }); - - describe(@"when button press and button event notifications arrive", ^{ - __block SDLOnButtonEvent *testButtonEvent = nil; - __block SDLOnButtonPress *testButtonPress = nil; - - context(@"that correspond to the created button", ^{ - beforeEach(^{ - testButtonEvent = [[SDLOnButtonEvent alloc] init]; - testButtonEvent.buttonName = SDLButtonNameCustomButton; - testButtonEvent.customButtonID = testSoftButton1.softButtonID; - - testButtonPress = [[SDLOnButtonPress alloc] init]; - testButtonPress.buttonName = SDLButtonNameCustomButton; - testButtonPress.customButtonID = testSoftButton1.softButtonID; - - SDLRPCNotificationNotification *buttonEventNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonEventNotification object:nil rpcNotification:testButtonEvent]; - SDLRPCNotificationNotification *buttonPressNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonPressNotification object:nil rpcNotification:testButtonPress]; - - [[NSNotificationCenter defaultCenter] postNotification:buttonEventNotification]; - [[NSNotificationCenter defaultCenter] postNotification:buttonPressNotification]; - }); - - it(@"should run the handler for each", ^{ - expect(@(numTimesHandlerCalled)).to(equal(@2)); - }); - }); - - context(@"that do not correspond to the created button", ^{ - beforeEach(^{ - testButtonEvent = [[SDLOnButtonEvent alloc] init]; - testButtonEvent.buttonName = SDLButtonNameOk; - - testButtonPress = [[SDLOnButtonPress alloc] init]; - testButtonPress.buttonName = SDLButtonNameOk; - - SDLRPCNotificationNotification *buttonEventNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonEventNotification object:nil rpcNotification:testButtonEvent]; - SDLRPCNotificationNotification *buttonPressNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonPressNotification object:nil rpcNotification:testButtonPress]; - - [[NSNotificationCenter defaultCenter] postNotification:buttonEventNotification]; - [[NSNotificationCenter defaultCenter] postNotification:buttonPressNotification]; - }); - - it(@"should not run the handler", ^{ - expect(@(numTimesHandlerCalled)).to(equal(@0)); - }); - }); - }); - }); - - context(@"with a correct soft button but no handler", ^{ - beforeEach(^{ - testSoftButton1 = [[SDLSoftButton alloc] initWithType:SDLSoftButtonTypeText text:@"test" image:nil highlighted:NO buttonId:1 systemAction:SDLSystemActionDefaultAction handler:nil]; - }); - - it(@"should not add the soft button", ^{ - expect(testDispatcher.customButtonHandlerMap).to(haveCount(@0)); - }); - }); - - context(@"with a malformed soft button", ^{ - beforeEach(^{ - testSoftButton1 = [[SDLSoftButton alloc] initWithType:SDLSoftButtonTypeText text:@"test" image:nil highlighted:NO buttonId:1 systemAction:SDLSystemActionDefaultAction handler:nil]; - }); - - it(@"should throw an exception if there's no button id", ^{ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wnonnull" - testSoftButton1.softButtonID = nil; -#pragma clang diagnostic pop - testScrollableMessage.softButtons = [@[testSoftButton1] mutableCopy]; - - expectAction(^{ [testDispatcher storeRequest:testScrollableMessage handler:nil]; }).to(raiseException().named(@"MissingIdException")); - }); - }); - - context(@"without soft buttons", ^{ - it(@"should not store the request", ^{ - [testDispatcher storeRequest:testScrollableMessage handler:nil]; - - expect(testDispatcher.customButtonHandlerMap).to(haveCount(@0)); - }); - }); - }); - - context(@"storing an audio pass thru handler", ^{ - __block SDLPerformAudioPassThru* testPerformAudioPassThru = nil; - __block NSUInteger numTimesHandlerCalled = 0; - - context(@"with a handler", ^{ - beforeEach(^{ - testPerformAudioPassThru = [[SDLPerformAudioPassThru alloc] initWithSamplingRate:SDLSamplingRate8KHZ bitsPerSample:SDLBitsPerSample8Bit audioType:SDLAudioTypePCM maxDuration:1000 audioDataHandler:^(NSData * _Nullable audioData) { - numTimesHandlerCalled++; - }]; - - testPerformAudioPassThru.correlationID = @1; - [testDispatcher storeRequest:testPerformAudioPassThru handler:nil]; - }); - - it(@"should store the handler" ,^{ -// expect(testDispatcher.audioPassThruHandler).toNot(beNil()); -// expect(testDispatcher.audioPassThruHandler).to(equal(testPerformAudioPassThru.audioDataHandler)); - }); - - describe(@"when an on audio data notification arrives", ^{ - beforeEach(^{ - SDLOnAudioPassThru *testOnAudioPassThru = [[SDLOnAudioPassThru alloc] init]; - - SDLRPCNotificationNotification *notification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveAudioPassThruNotification object:nil rpcNotification:testOnAudioPassThru]; - [[NSNotificationCenter defaultCenter] postNotification:notification]; - }); - - it(@"should run the handler", ^{ - expect(@(numTimesHandlerCalled)).to(equal(@1)); - }); - }); - - describe(@"when an on audio data response arrives", ^{ - beforeEach(^{ - SDLPerformAudioPassThruResponse *performAudioPassThruResponse = [[SDLPerformAudioPassThruResponse alloc] init]; - performAudioPassThruResponse.success = @YES; - - SDLRPCResponseNotification *notification = [[SDLRPCResponseNotification alloc] initWithName:SDLDidReceivePerformAudioPassThruResponse object:nil rpcResponse:performAudioPassThruResponse]; - [[NSNotificationCenter defaultCenter] postNotification:notification]; - }); - - it(@"should clear the handler", ^{ -// expect(testDispatcher.audioPassThruHandler).to(beNil()); - }); - }); - }); - - context(@"without a handler", ^{ - beforeEach(^{ - numTimesHandlerCalled = 0; - - testPerformAudioPassThru = [[SDLPerformAudioPassThru alloc] initWithSamplingRate:SDLSamplingRate8KHZ bitsPerSample:SDLBitsPerSample8Bit audioType:SDLAudioTypePCM maxDuration:1000]; - - testPerformAudioPassThru.correlationID = @1; - [testDispatcher storeRequest:testPerformAudioPassThru handler:nil]; - }); - - describe(@"when an on audio data notification arrives", ^{ - beforeEach(^{ - SDLOnAudioPassThru *testOnAudioPassThru = [[SDLOnAudioPassThru alloc] init]; - - SDLRPCNotificationNotification *notification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveAudioPassThruNotification object:nil rpcNotification:testOnAudioPassThru]; - [[NSNotificationCenter defaultCenter] postNotification:notification]; - }); - - it(@"should not run a handler", ^{ - expect(@(numTimesHandlerCalled)).to(equal(@0)); - }); - }); - - describe(@"when an on audio data response arrives", ^{ - beforeEach(^{ - SDLPerformAudioPassThruResponse *performAudioPassThruResponse = [[SDLPerformAudioPassThruResponse alloc] init]; - performAudioPassThruResponse.success = @YES; - - SDLRPCResponseNotification *notification = [[SDLRPCResponseNotification alloc] initWithName:SDLDidReceivePerformAudioPassThruResponse object:nil rpcResponse:performAudioPassThruResponse]; - [[NSNotificationCenter defaultCenter] postNotification:notification]; - }); - - it(@"should clear the handler", ^{ -// expect(testDispatcher.audioPassThruHandler).to(beNil()); - }); - }); - - }); - }); -}); - -QuickSpecEnd diff --git a/SmartDeviceLinkTests/Notifications/SDLNotificationDispatcherSpec.m b/SmartDeviceLinkTests/Notifications/SDLNotificationDispatcherSpec.m new file mode 100644 index 000000000..63d691ee0 --- /dev/null +++ b/SmartDeviceLinkTests/Notifications/SDLNotificationDispatcherSpec.m @@ -0,0 +1,120 @@ +#import +#import + +#import "SDLNotificationConstants.h" +#import "SDLNotificationDispatcher.h" + + +QuickSpecBegin(SDLNotificationDispatcherSpec) + +describe(@"a notification dispatcher", ^{ + __block SDLNotificationDispatcher *testDispatcher = nil; + + beforeEach(^{ + testDispatcher = [[SDLNotificationDispatcher alloc] init]; + }); + + it(@"should conform to SDLProxyListener", ^{ + expect(@([testDispatcher conformsToProtocol:@protocol(SDLProxyListener)])).to(beTruthy()); + + expect(@([testDispatcher respondsToSelector:@selector(onOnDriverDistraction:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onOnHMIStatus:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onProxyClosed)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onProxyOpened)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onAddCommandResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onAddSubMenuResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onAlertManeuverResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onAlertResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onButtonPressResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onChangeRegistrationResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onCreateInteractionChoiceSetResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onDeleteCommandResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onDeleteInteractionChoiceSetResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onDeleteSubMenuResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onDiagnosticMessageResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onDialNumberResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onEncodedSyncPDataResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onEndAudioPassThruResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onError:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onGenericResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onGetAppServiceDataResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onGetDTCsResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onGetFileResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onGetInteriorVehicleDataResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onGetSystemCapabilityResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onGetVehicleDataResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onGetWayPointsResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onReceivedLockScreenIcon:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onOnAppInterfaceUnregistered:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onOnAppServiceData:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onOnAudioPassThru:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onOnButtonEvent:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onOnButtonPress:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onOnCommand:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onOnEncodedSyncPData:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onOnHashChange:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onOnLanguageChange:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onOnLockScreenNotification:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onOnSyncPData:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onOnRCStatus:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onOnSystemRequest:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onOnTBTClientState:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onOnTouchEvent:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onOnVehicleData:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onOnWayPointChange:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onPerformAppServiceInteractionResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onPerformAudioPassThruResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onPerformInteractionResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onPublishAppService:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onPutFileResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onReadDIDResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onRegisterAppInterfaceResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onResetGlobalPropertiesResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onScrollableMessageResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onSendHapticDataResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onSendLocationResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onSetAppIconResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onSetDisplayLayoutResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onSetGlobalPropertiesResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onSetInteriorVehicleDataResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onSetMediaClockTimerResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onShowConstantTBTResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onShowResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onSliderResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onSpeakResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onSubscribeButtonResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onSubscribeVehicleDataResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onSubscribeWayPointsResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onSyncPDataResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onUpdateTurnListResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onUnregisterAppInterfaceResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onUnsubscribeButtonResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onUnsubscribeVehicleDataResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onUnsubscribeWayPointsResponse:)])).to(beTruthy()); + }); + + describe(@"when told to post a notification", ^{ + __block NSString *testNotificationName = nil; + __block NSString *testUserInfo = nil; + + __block NSNotification *returnNotification = nil; + + beforeEach(^{ + testNotificationName = @"com.test.notification"; + testUserInfo = @"testuserinfo"; + + [[NSNotificationCenter defaultCenter] addObserverForName:testNotificationName object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) { + returnNotification = note; + }]; + + [testDispatcher postNotificationName:testNotificationName infoObject:testUserInfo]; + }); + + it(@"should post", ^{ + expect(returnNotification.userInfo[SDLNotificationUserInfoObject]).toEventually(match(testUserInfo)); + expect(returnNotification.object).toEventually(equal(testDispatcher)); + }); + }); +}); + +QuickSpecEnd diff --git a/SmartDeviceLinkTests/Notifications/SDLResponseDispatcherSpec.m b/SmartDeviceLinkTests/Notifications/SDLResponseDispatcherSpec.m new file mode 100644 index 000000000..410d24386 --- /dev/null +++ b/SmartDeviceLinkTests/Notifications/SDLResponseDispatcherSpec.m @@ -0,0 +1,788 @@ +#import +#import + +#import "SDLAddCommand.h" +#import "SDLAlert.h" +#import "SDLButtonName.h" +#import "SDLDeleteCommand.h" +#import "SDLDeleteCommandResponse.h" +#import "SDLNotificationConstants.h" +#import "SDLOnAudioPassThru.h" +#import "SDLOnButtonEvent.h" +#import "SDLOnButtonPress.h" +#import "SDLOnCommand.h" +#import "SDLPerformAudioPassThru.h" +#import "SDLPerformAudioPassThruResponse.h" +#import "SDLReadDID.h" +#import "SDLReadDIDResponse.h" +#import "SDLResponseDispatcher.h" +#import "SDLRPCNotificationNotification.h" +#import "SDLRPCResponseNotification.h" +#import "SDLScrollableMessage.h" +#import "SDLShow.h" +#import "SDLSoftButton.h" +#import "SDLSoftButtonType.h" +#import "SDLSubscribeButton.h" +#import "SDLSystemAction.h" +#import "SDLTextAlignment.h" +#import "SDLUnsubscribeButton.h" +#import "SDLUnsubscribeButtonResponse.h" + + +QuickSpecBegin(SDLResponseDispatcherSpec) + +describe(@"a response dispatcher", ^{ + __block SDLResponseDispatcher *testDispatcher = nil; + + beforeEach(^{ + testDispatcher = [[SDLResponseDispatcher alloc] init]; + }); + + it(@"should initialize the NSMapTable properties", ^{ + expect(testDispatcher.rpcResponseHandlerMap).toNot(beNil()); + expect(testDispatcher.rpcRequestDictionary).toNot(beNil()); + expect(testDispatcher.commandHandlerMap).toNot(beNil()); + expect(testDispatcher.buttonHandlerMap).toNot(beNil()); + expect(testDispatcher.customButtonHandlerMap).toNot(beNil()); +// expect(testDispatcher.audioPassThruHandler).to(beNil()); + + expect(testDispatcher.rpcResponseHandlerMap).to(haveCount(@0)); + expect(testDispatcher.rpcRequestDictionary).to(haveCount(@0)); + expect(testDispatcher.commandHandlerMap).to(haveCount(@0)); + expect(testDispatcher.buttonHandlerMap).to(haveCount(@0)); + expect(testDispatcher.customButtonHandlerMap).to(haveCount(@0)); + }); + + context(@"storing a request without a handler", ^{ + __block SDLReadDID *testRPC = nil; + __block NSNumber *testCorrelationId = nil; + + beforeEach(^{ + testRPC = [[SDLReadDID alloc] init]; + testCorrelationId = @111; + testRPC.correlationID = testCorrelationId; + }); + + it(@"should not store the request", ^{ + [testDispatcher storeRequest:testRPC handler:nil]; + + expect(testDispatcher.rpcResponseHandlerMap).to(haveCount(@0)); + expect(testDispatcher.rpcRequestDictionary).to(haveCount(@1)); + expect(testDispatcher.commandHandlerMap).to(haveCount(@0)); + expect(testDispatcher.buttonHandlerMap).to(haveCount(@0)); + expect(testDispatcher.customButtonHandlerMap).to(haveCount(@0)); + }); + }); + + context(@"storing a request with a handler", ^{ + __block SDLRPCRequest *testRequest = nil; + __block NSNumber *testCorrelationId = nil; + __block BOOL handlerCalled = NO; + + beforeEach(^{ + testRequest = [[SDLReadDID alloc] init]; + testCorrelationId = @42; + + testRequest.correlationID = testCorrelationId; + [testDispatcher storeRequest:testRequest handler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) { + handlerCalled = YES; + }]; + }); + + it(@"should store the request and response", ^{ + expect(testDispatcher.rpcRequestDictionary[testCorrelationId]).toNot(beNil()); + expect(testDispatcher.rpcRequestDictionary).to(haveCount(@1)); + + expect(testDispatcher.rpcResponseHandlerMap[testCorrelationId]).toNot(beNil()); + expect(testDispatcher.rpcResponseHandlerMap).to(haveCount(@1)); + }); + + describe(@"when a response arrives", ^{ + __block SDLRPCResponse *testResponse = nil; + + beforeEach(^{ + testResponse = [[SDLReadDIDResponse alloc] init]; + testResponse.correlationID = testCorrelationId; + + SDLRPCResponseNotification *responseNotification = [[SDLRPCResponseNotification alloc] initWithName:SDLDidReceiveReadDIDResponse object:nil rpcResponse:testResponse]; + [[NSNotificationCenter defaultCenter] postNotification:responseNotification]; + }); + + it(@"should run the handler", ^{ + expect(@(handlerCalled)).to(beTruthy()); + expect(testDispatcher.rpcRequestDictionary).to(haveCount(@0)); + expect(testDispatcher.rpcResponseHandlerMap).to(haveCount(@0)); + }); + }); + }); + + context(@"storing a show request", ^{ + __block SDLShow *testShow = nil; + __block SDLSoftButton *testSoftButton1 = nil; + __block NSUInteger numTimesHandlerCalled = 0; + + beforeEach(^{ + testShow = [[SDLShow alloc] initWithMainField1:@"Test Show" mainField2:nil alignment:SDLTextAlignmentCenter]; + testShow.correlationID = @1; + }); + + context(@"with a correct soft button and handler", ^{ + beforeEach(^{ + numTimesHandlerCalled = 0; + + testSoftButton1 = [[SDLSoftButton alloc] initWithType:SDLSoftButtonTypeText text:@"test" image:nil highlighted:NO buttonId:1 systemAction:SDLSystemActionDefaultAction handler:^(SDLOnButtonPress * _Nullable buttonPressNotification, SDLOnButtonEvent * _Nullable buttonEventNotification) { + numTimesHandlerCalled++; + }]; + testShow.softButtons = [@[testSoftButton1] mutableCopy]; + testShow.correlationID = @1; + [testDispatcher storeRequest:testShow handler:nil]; + }); + + it(@"should add the soft button to the map", ^{ + expect(testDispatcher.customButtonHandlerMap[testSoftButton1.softButtonID]).toNot(beNil()); + expect(testDispatcher.customButtonHandlerMap).to(haveCount(@1)); + }); + + describe(@"when button press and button event notifications arrive", ^{ + __block SDLOnButtonEvent *testButtonEvent = nil; + __block SDLOnButtonPress *testButtonPress = nil; + + context(@"that correspond to the created button", ^{ + beforeEach(^{ + testButtonEvent = [[SDLOnButtonEvent alloc] init]; + testButtonEvent.customButtonID = testSoftButton1.softButtonID; + testButtonEvent.buttonName = SDLButtonNameCustomButton; + + testButtonPress = [[SDLOnButtonPress alloc] init]; + testButtonPress.customButtonID = testSoftButton1.softButtonID; + testButtonPress.buttonName = SDLButtonNameCustomButton; + + SDLRPCNotificationNotification *buttonEventNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonEventNotification object:nil rpcNotification:testButtonEvent]; + SDLRPCNotificationNotification *buttonPressNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonPressNotification object:nil rpcNotification:testButtonPress]; + + [[NSNotificationCenter defaultCenter] postNotification:buttonEventNotification]; + [[NSNotificationCenter defaultCenter] postNotification:buttonPressNotification]; + }); + + it(@"should run the handler for each", ^{ + expect(@(numTimesHandlerCalled)).to(equal(@2)); + }); + }); + + context(@"that do not correspond to the created button", ^{ + beforeEach(^{ + testButtonEvent = [[SDLOnButtonEvent alloc] init]; + testButtonEvent.buttonName = SDLButtonNameOk; + + testButtonPress = [[SDLOnButtonPress alloc] init]; + testButtonPress.buttonName = SDLButtonNameOk; + + SDLRPCNotificationNotification *buttonEventNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonEventNotification object:nil rpcNotification:testButtonEvent]; + SDLRPCNotificationNotification *buttonPressNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonPressNotification object:nil rpcNotification:testButtonPress]; + + [[NSNotificationCenter defaultCenter] postNotification:buttonEventNotification]; + [[NSNotificationCenter defaultCenter] postNotification:buttonPressNotification]; + }); + + it(@"should not run the handler", ^{ + expect(@(numTimesHandlerCalled)).to(equal(@0)); + }); + }); + }); + }); + + context(@"with a correct soft button but no handler", ^{ + beforeEach(^{ + testSoftButton1 = [[SDLSoftButton alloc] initWithType:SDLSoftButtonTypeText text:@"test" image:nil highlighted:NO buttonId:1 systemAction:SDLSystemActionDefaultAction handler:nil]; + }); + + it(@"should not add the soft button", ^{ + expect(testDispatcher.customButtonHandlerMap).to(haveCount(@0)); + }); + }); + + context(@"with a malformed soft button", ^{ + beforeEach(^{ + testSoftButton1 = [[SDLSoftButton alloc] initWithType:SDLSoftButtonTypeText text:@"test" image:nil highlighted:NO buttonId:1 systemAction:SDLSystemActionDefaultAction handler:nil]; + }); + + it(@"should throw an exception if there's no button id", ^{ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnonnull" + testSoftButton1.softButtonID = nil; +#pragma clang diagnostic pop + testShow.softButtons = [@[testSoftButton1] mutableCopy]; + + expectAction(^{ [testDispatcher storeRequest:testShow handler:nil]; }).to(raiseException().named(@"MissingIdException")); + }); + }); + + context(@"without soft buttons", ^{ + it(@"should not store the request", ^{ + [testDispatcher storeRequest:testShow handler:nil]; + + expect(testDispatcher.customButtonHandlerMap).to(haveCount(@0)); + }); + }); + }); + + context(@"storing a command request", ^{ + __block SDLAddCommand *testAddCommand = nil; + __block UInt32 testCommandId = 0; + __block NSUInteger numTimesHandlerCalled = 0; + + __block NSNumber *testAddCommandCorrelationId = nil; + __block NSNumber *testDeleteCommandCorrelationId = nil; + + context(@"with a handler", ^{ + beforeEach(^{ + testCommandId = 1; + testAddCommandCorrelationId = @42; + numTimesHandlerCalled = 0; + + testAddCommand = [[SDLAddCommand alloc] initWithId:testCommandId vrCommands:nil handler:^(__kindof SDLRPCNotification * _Nonnull notification) { + numTimesHandlerCalled++; + }]; + testAddCommand.correlationID = testAddCommandCorrelationId; + }); + + it(@"should add the command to the map", ^{ + [testDispatcher storeRequest:testAddCommand handler:nil]; + + expect(testDispatcher.commandHandlerMap[testAddCommand.cmdID]).toNot(beNil()); + expect(testDispatcher.commandHandlerMap).to(haveCount(@1)); + }); + + it(@"should throw an exception if there's no command id", ^{ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnonnull" + testAddCommand.cmdID = nil; + +#pragma clang diagnostic pop + expectAction(^{ [testDispatcher storeRequest:testAddCommand handler:nil]; }).to(raiseException().named(@"MissingIdException")); + }); + + describe(@"when button press and button event notifications arrive", ^{ + __block SDLOnCommand *testOnCommand = nil; + + beforeEach(^{ + [testDispatcher storeRequest:testAddCommand handler:nil]; + }); + + context(@"that correspond to the created button", ^{ + beforeEach(^{ + testOnCommand = [[SDLOnCommand alloc] init]; + testOnCommand.cmdID = @(testCommandId); + testOnCommand.triggerSource = SDLTriggerSourceMenu; + + SDLRPCNotificationNotification *commandNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveCommandNotification object:nil rpcNotification:testOnCommand]; + + [[NSNotificationCenter defaultCenter] postNotification:commandNotification]; + }); + + it(@"should run the handler for each", ^{ + expect(@(numTimesHandlerCalled)).to(equal(@1)); + }); + }); + + context(@"that do not correspond to the created button", ^{ + beforeEach(^{ + testOnCommand = [[SDLOnCommand alloc] init]; + testOnCommand.cmdID = @999; + + SDLRPCNotificationNotification *commandNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveCommandNotification object:nil rpcNotification:testOnCommand]; + + [[NSNotificationCenter defaultCenter] postNotification:commandNotification]; + }); + + it(@"should not run the handler", ^{ + expect(@(numTimesHandlerCalled)).to(equal(@0)); + }); + }); + }); + + describe(@"then deleting the command", ^{ + __block SDLDeleteCommand *testDeleteCommand = nil; + __block SDLDeleteCommandResponse *testDeleteResponse = nil; + + beforeEach(^{ + [testDispatcher storeRequest:testAddCommand handler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) {}]; + + // We need both the delete command and the response for this to work + testDeleteCommandCorrelationId = @43; + + testDeleteCommand = [[SDLDeleteCommand alloc] init]; + testDeleteCommand.correlationID = testDeleteCommandCorrelationId; + testDeleteCommand.cmdID = @(testCommandId); + + [testDispatcher storeRequest:testDeleteCommand handler:nil]; + + testDeleteResponse = [[SDLDeleteCommandResponse alloc] init]; + testDeleteResponse.correlationID = testDeleteCommandCorrelationId; + testDeleteResponse.success = @YES; + + SDLRPCResponseNotification *deleteCommandNotification = [[SDLRPCResponseNotification alloc] initWithName:SDLDidReceiveDeleteCommandResponse object:nil rpcResponse:testDeleteResponse]; + + [[NSNotificationCenter defaultCenter] postNotification:deleteCommandNotification]; + }); + + it(@"should have removed all the handlers", ^{ + // There should still be the add command request & handler in the dictionaries since we never responded + expect(testDispatcher.commandHandlerMap).to(haveCount(@0)); + expect(testDispatcher.rpcRequestDictionary).to(haveCount(@1)); + expect(testDispatcher.rpcResponseHandlerMap).to(haveCount(@1)); + }); + }); + }); + + context(@"without a handler", ^{ + beforeEach(^{ + testAddCommand = [[SDLAddCommand alloc] initWithId:1 vrCommands:nil handler:nil]; + }); + + it(@"should not add the command", ^{ + expect(testDispatcher.commandHandlerMap).to(haveCount(@0)); + }); + }); + }); + + context(@"storing a subscribe button request", ^{ + __block SDLSubscribeButton *testSubscribeButton = nil; + __block SDLButtonName testButtonName = nil; + __block NSUInteger numTimesHandlerCalled = 0; + + __block NSNumber *testSubscribeCorrelationId = nil; + __block NSNumber *testUnsubscribeCorrelationId = nil; + + context(@"with a handler", ^{ + beforeEach(^{ + testButtonName = SDLButtonNameOk; + testSubscribeCorrelationId = @42; + numTimesHandlerCalled = 0; + + testSubscribeButton = [[SDLSubscribeButton alloc] initWithButtonName:testButtonName handler:^(SDLOnButtonPress * _Nullable buttonPressNotification, SDLOnButtonEvent * _Nullable buttonEventNotification) { + numTimesHandlerCalled++; + }]; + testSubscribeButton.correlationID = testSubscribeCorrelationId; + }); + + it(@"should add the subscription to the map", ^{ + [testDispatcher storeRequest:testSubscribeButton handler:nil]; + + expect(testDispatcher.buttonHandlerMap[testSubscribeButton.buttonName]).toNot(beNil()); + expect(testDispatcher.buttonHandlerMap).to(haveCount(@1)); + }); + + it(@"should throw an exception if there's no button name", ^{ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnonnull" + testSubscribeButton.buttonName = nil; +#pragma clang diagnostic pop + + expectAction(^{ [testDispatcher storeRequest:testSubscribeButton handler:nil]; }).to(raiseException().named(@"MissingIdException")); + }); + + describe(@"when button press and button event notifications arrive", ^{ + __block SDLOnButtonEvent *testButtonEvent = nil; + __block SDLOnButtonPress *testButtonPress = nil; + + beforeEach(^{ + [testDispatcher storeRequest:testSubscribeButton handler:nil]; + }); + + context(@"that correspond to the created button", ^{ + beforeEach(^{ + testButtonEvent = [[SDLOnButtonEvent alloc] init]; + testButtonEvent.buttonName = testButtonName; + + testButtonPress = [[SDLOnButtonPress alloc] init]; + testButtonPress.buttonName = testButtonName; + + SDLRPCNotificationNotification *buttonEventNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonEventNotification object:nil rpcNotification:testButtonEvent]; + SDLRPCNotificationNotification *buttonPressNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonPressNotification object:nil rpcNotification:testButtonPress]; + + [[NSNotificationCenter defaultCenter] postNotification:buttonEventNotification]; + [[NSNotificationCenter defaultCenter] postNotification:buttonPressNotification]; + }); + + it(@"should run the handler for each", ^{ + expect(@(numTimesHandlerCalled)).to(equal(@2)); + }); + }); + + context(@"that do not correspond to the created button", ^{ + beforeEach(^{ + testButtonEvent = [[SDLOnButtonEvent alloc] init]; + testButtonEvent.buttonName = SDLButtonNamePreset0; + + testButtonPress = [[SDLOnButtonPress alloc] init]; + testButtonPress.buttonName = SDLButtonNamePreset0; + + SDLRPCNotificationNotification *buttonEventNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonEventNotification object:nil rpcNotification:testButtonEvent]; + SDLRPCNotificationNotification *buttonPressNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonPressNotification object:nil rpcNotification:testButtonPress]; + + [[NSNotificationCenter defaultCenter] postNotification:buttonEventNotification]; + [[NSNotificationCenter defaultCenter] postNotification:buttonPressNotification]; + }); + + it(@"should not run the handler", ^{ + expect(@(numTimesHandlerCalled)).to(equal(@0)); + }); + }); + }); + + describe(@"then unsubscribing", ^{ + __block SDLUnsubscribeButton *testUnsubscribe = nil; + __block SDLUnsubscribeButtonResponse *testUnsubscribeResponse = nil; + + beforeEach(^{ + [testDispatcher storeRequest:testSubscribeButton handler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) {}]; + + // We need both the delete command and the response for this to work + testUnsubscribeCorrelationId = @43; + + testUnsubscribe = [[SDLUnsubscribeButton alloc] init]; + testUnsubscribe.correlationID = testUnsubscribeCorrelationId; + testUnsubscribe.buttonName = testButtonName; + + [testDispatcher storeRequest:testUnsubscribe handler:nil]; + + testUnsubscribeResponse = [[SDLUnsubscribeButtonResponse alloc] init]; + testUnsubscribeResponse.correlationID = testUnsubscribeCorrelationId; + testUnsubscribeResponse.success = @YES; + + SDLRPCResponseNotification *unsubscribeNotification = [[SDLRPCResponseNotification alloc] initWithName:SDLDidReceiveUnsubscribeButtonResponse object:nil rpcResponse:testUnsubscribeResponse]; + [[NSNotificationCenter defaultCenter] postNotification:unsubscribeNotification]; + }); + + it(@"should have removed all the handlers", ^{ + // There should still be the add command request & handler in the dictionaries since we never responded + expect(testDispatcher.commandHandlerMap).to(haveCount(@0)); + expect(testDispatcher.rpcRequestDictionary).to(haveCount(@1)); + expect(testDispatcher.rpcResponseHandlerMap).to(haveCount(@1)); + }); + }); + }); + + context(@"without a handler", ^{ + beforeEach(^{ + testSubscribeButton = [[SDLSubscribeButton alloc] initWithButtonName:SDLButtonNameOk handler:nil]; + }); + + it(@"should not add the subscription", ^{ + expect(testDispatcher.buttonHandlerMap).to(haveCount(@0)); + }); + }); + }); + + context(@"storing an alert request", ^{ + __block SDLAlert *testAlert = nil; + __block SDLSoftButton *testSoftButton1 = nil; + + beforeEach(^{ + testAlert = [[SDLAlert alloc] initWithAlertText1:@"test 1" alertText2:@"test 1" alertText3:nil duration:1 softButtons:nil]; + testAlert.correlationID = @1; + }); + + context(@"with a correct soft button and handler", ^{ + __block NSUInteger numTimesHandlerCalled = 0; + + beforeEach(^{ + numTimesHandlerCalled = 0; + + testSoftButton1 = [[SDLSoftButton alloc] initWithType:SDLSoftButtonTypeText text:@"test" image:nil highlighted:NO buttonId:1 systemAction:SDLSystemActionDefaultAction handler:^(SDLOnButtonPress * _Nullable buttonPressNotification, SDLOnButtonEvent * _Nullable buttonEventNotification) { + numTimesHandlerCalled++; + }]; + + testAlert.softButtons = [@[testSoftButton1] mutableCopy]; + [testDispatcher storeRequest:testAlert handler:nil]; + }); + + it(@"should add the soft button to the map", ^{ + expect(testDispatcher.customButtonHandlerMap[testSoftButton1.softButtonID]).toNot(beNil()); + expect(testDispatcher.customButtonHandlerMap).to(haveCount(@1)); + }); + + describe(@"when button press and button event notifications arrive", ^{ + __block SDLOnButtonEvent *testButtonEvent = nil; + __block SDLOnButtonPress *testButtonPress = nil; + + context(@"that correspond to the created button", ^{ + beforeEach(^{ + testButtonEvent = [[SDLOnButtonEvent alloc] init]; + testButtonEvent.buttonName = SDLButtonNameCustomButton; + testButtonEvent.customButtonID = testSoftButton1.softButtonID; + + testButtonPress = [[SDLOnButtonPress alloc] init]; + testButtonPress.buttonName = SDLButtonNameCustomButton; + testButtonPress.customButtonID = testSoftButton1.softButtonID; + + SDLRPCNotificationNotification *buttonEventNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonEventNotification object:nil rpcNotification:testButtonEvent]; + SDLRPCNotificationNotification *buttonPressNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonPressNotification object:nil rpcNotification:testButtonPress]; + + [[NSNotificationCenter defaultCenter] postNotification:buttonEventNotification]; + [[NSNotificationCenter defaultCenter] postNotification:buttonPressNotification]; + }); + + it(@"should run the handler for each", ^{ + expect(@(numTimesHandlerCalled)).to(equal(@2)); + }); + }); + + context(@"that do not correspond to the created button", ^{ + beforeEach(^{ + testButtonEvent = [[SDLOnButtonEvent alloc] init]; + testButtonEvent.buttonName = SDLButtonNameOk; + + testButtonPress = [[SDLOnButtonPress alloc] init]; + testButtonPress.buttonName = SDLButtonNameOk; + + SDLRPCNotificationNotification *buttonEventNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonEventNotification object:nil rpcNotification:testButtonEvent]; + SDLRPCNotificationNotification *buttonPressNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonPressNotification object:nil rpcNotification:testButtonPress]; + + [[NSNotificationCenter defaultCenter] postNotification:buttonEventNotification]; + [[NSNotificationCenter defaultCenter] postNotification:buttonPressNotification]; + }); + + it(@"should not run the handler", ^{ + expect(@(numTimesHandlerCalled)).to(equal(@0)); + }); + }); + }); + }); + + context(@"with a correct soft button but no handler", ^{ + beforeEach(^{ + testSoftButton1 = [[SDLSoftButton alloc] initWithType:SDLSoftButtonTypeText text:@"test" image:nil highlighted:NO buttonId:1 systemAction:SDLSystemActionDefaultAction handler:nil]; + }); + + it(@"should not add the soft button", ^{ + expect(testDispatcher.customButtonHandlerMap).to(haveCount(@0)); + }); + }); + + context(@"with a malformed soft button", ^{ + beforeEach(^{ + testSoftButton1 = [[SDLSoftButton alloc] initWithType:SDLSoftButtonTypeText text:@"test" image:nil highlighted:NO buttonId:1 systemAction:SDLSystemActionDefaultAction handler:nil]; + }); + + it(@"should throw an exception if there's no button id", ^{ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnonnull" + testSoftButton1.softButtonID = nil; +#pragma clang diagnostic pop + testAlert.softButtons = [@[testSoftButton1] mutableCopy]; + + expectAction(^{ [testDispatcher storeRequest:testAlert handler:nil]; }).to(raiseException().named(@"MissingIdException")); + }); + }); + + context(@"without soft buttons", ^{ + it(@"should not store the request", ^{ + [testDispatcher storeRequest:testAlert handler:nil]; + + expect(testDispatcher.customButtonHandlerMap).to(haveCount(@0)); + }); + }); + }); + + context(@"storing a scrollable message request", ^{ + __block SDLScrollableMessage *testScrollableMessage = nil; + __block SDLSoftButton *testSoftButton1 = nil; + + beforeEach(^{ + testScrollableMessage = [[SDLScrollableMessage alloc] initWithMessage:@"test" timeout:1 softButtons:nil]; + testScrollableMessage.correlationID = @1; + }); + + context(@"with a correct soft button and handler", ^{ + __block NSUInteger numTimesHandlerCalled = 0; + + beforeEach(^{ + numTimesHandlerCalled = 0; + + testSoftButton1 = [[SDLSoftButton alloc] initWithType:SDLSoftButtonTypeText text:@"test" image:nil highlighted:NO buttonId:1 systemAction:SDLSystemActionDefaultAction handler:^(SDLOnButtonPress * _Nullable buttonPressNotification, SDLOnButtonEvent * _Nullable buttonEventNotification) { + numTimesHandlerCalled++; + }]; + + testScrollableMessage.softButtons = [@[testSoftButton1] mutableCopy]; + [testDispatcher storeRequest:testScrollableMessage handler:nil]; + }); + + it(@"should add the soft button to the map", ^{ + expect(testDispatcher.customButtonHandlerMap[testSoftButton1.softButtonID]).toNot(beNil()); + expect(testDispatcher.customButtonHandlerMap).to(haveCount(@1)); + }); + + describe(@"when button press and button event notifications arrive", ^{ + __block SDLOnButtonEvent *testButtonEvent = nil; + __block SDLOnButtonPress *testButtonPress = nil; + + context(@"that correspond to the created button", ^{ + beforeEach(^{ + testButtonEvent = [[SDLOnButtonEvent alloc] init]; + testButtonEvent.buttonName = SDLButtonNameCustomButton; + testButtonEvent.customButtonID = testSoftButton1.softButtonID; + + testButtonPress = [[SDLOnButtonPress alloc] init]; + testButtonPress.buttonName = SDLButtonNameCustomButton; + testButtonPress.customButtonID = testSoftButton1.softButtonID; + + SDLRPCNotificationNotification *buttonEventNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonEventNotification object:nil rpcNotification:testButtonEvent]; + SDLRPCNotificationNotification *buttonPressNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonPressNotification object:nil rpcNotification:testButtonPress]; + + [[NSNotificationCenter defaultCenter] postNotification:buttonEventNotification]; + [[NSNotificationCenter defaultCenter] postNotification:buttonPressNotification]; + }); + + it(@"should run the handler for each", ^{ + expect(@(numTimesHandlerCalled)).to(equal(@2)); + }); + }); + + context(@"that do not correspond to the created button", ^{ + beforeEach(^{ + testButtonEvent = [[SDLOnButtonEvent alloc] init]; + testButtonEvent.buttonName = SDLButtonNameOk; + + testButtonPress = [[SDLOnButtonPress alloc] init]; + testButtonPress.buttonName = SDLButtonNameOk; + + SDLRPCNotificationNotification *buttonEventNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonEventNotification object:nil rpcNotification:testButtonEvent]; + SDLRPCNotificationNotification *buttonPressNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveButtonPressNotification object:nil rpcNotification:testButtonPress]; + + [[NSNotificationCenter defaultCenter] postNotification:buttonEventNotification]; + [[NSNotificationCenter defaultCenter] postNotification:buttonPressNotification]; + }); + + it(@"should not run the handler", ^{ + expect(@(numTimesHandlerCalled)).to(equal(@0)); + }); + }); + }); + }); + + context(@"with a correct soft button but no handler", ^{ + beforeEach(^{ + testSoftButton1 = [[SDLSoftButton alloc] initWithType:SDLSoftButtonTypeText text:@"test" image:nil highlighted:NO buttonId:1 systemAction:SDLSystemActionDefaultAction handler:nil]; + }); + + it(@"should not add the soft button", ^{ + expect(testDispatcher.customButtonHandlerMap).to(haveCount(@0)); + }); + }); + + context(@"with a malformed soft button", ^{ + beforeEach(^{ + testSoftButton1 = [[SDLSoftButton alloc] initWithType:SDLSoftButtonTypeText text:@"test" image:nil highlighted:NO buttonId:1 systemAction:SDLSystemActionDefaultAction handler:nil]; + }); + + it(@"should throw an exception if there's no button id", ^{ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnonnull" + testSoftButton1.softButtonID = nil; +#pragma clang diagnostic pop + testScrollableMessage.softButtons = [@[testSoftButton1] mutableCopy]; + + expectAction(^{ [testDispatcher storeRequest:testScrollableMessage handler:nil]; }).to(raiseException().named(@"MissingIdException")); + }); + }); + + context(@"without soft buttons", ^{ + it(@"should not store the request", ^{ + [testDispatcher storeRequest:testScrollableMessage handler:nil]; + + expect(testDispatcher.customButtonHandlerMap).to(haveCount(@0)); + }); + }); + }); + + context(@"storing an audio pass thru handler", ^{ + __block SDLPerformAudioPassThru* testPerformAudioPassThru = nil; + __block NSUInteger numTimesHandlerCalled = 0; + + context(@"with a handler", ^{ + beforeEach(^{ + testPerformAudioPassThru = [[SDLPerformAudioPassThru alloc] initWithSamplingRate:SDLSamplingRate8KHZ bitsPerSample:SDLBitsPerSample8Bit audioType:SDLAudioTypePCM maxDuration:1000 audioDataHandler:^(NSData * _Nullable audioData) { + numTimesHandlerCalled++; + }]; + + testPerformAudioPassThru.correlationID = @1; + [testDispatcher storeRequest:testPerformAudioPassThru handler:nil]; + }); + + it(@"should store the handler" ,^{ +// expect(testDispatcher.audioPassThruHandler).toNot(beNil()); +// expect(testDispatcher.audioPassThruHandler).to(equal(testPerformAudioPassThru.audioDataHandler)); + }); + + describe(@"when an on audio data notification arrives", ^{ + beforeEach(^{ + SDLOnAudioPassThru *testOnAudioPassThru = [[SDLOnAudioPassThru alloc] init]; + + SDLRPCNotificationNotification *notification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveAudioPassThruNotification object:nil rpcNotification:testOnAudioPassThru]; + [[NSNotificationCenter defaultCenter] postNotification:notification]; + }); + + it(@"should run the handler", ^{ + expect(@(numTimesHandlerCalled)).to(equal(@1)); + }); + }); + + describe(@"when an on audio data response arrives", ^{ + beforeEach(^{ + SDLPerformAudioPassThruResponse *performAudioPassThruResponse = [[SDLPerformAudioPassThruResponse alloc] init]; + performAudioPassThruResponse.success = @YES; + + SDLRPCResponseNotification *notification = [[SDLRPCResponseNotification alloc] initWithName:SDLDidReceivePerformAudioPassThruResponse object:nil rpcResponse:performAudioPassThruResponse]; + [[NSNotificationCenter defaultCenter] postNotification:notification]; + }); + + it(@"should clear the handler", ^{ +// expect(testDispatcher.audioPassThruHandler).to(beNil()); + }); + }); + }); + + context(@"without a handler", ^{ + beforeEach(^{ + numTimesHandlerCalled = 0; + + testPerformAudioPassThru = [[SDLPerformAudioPassThru alloc] initWithSamplingRate:SDLSamplingRate8KHZ bitsPerSample:SDLBitsPerSample8Bit audioType:SDLAudioTypePCM maxDuration:1000]; + + testPerformAudioPassThru.correlationID = @1; + [testDispatcher storeRequest:testPerformAudioPassThru handler:nil]; + }); + + describe(@"when an on audio data notification arrives", ^{ + beforeEach(^{ + SDLOnAudioPassThru *testOnAudioPassThru = [[SDLOnAudioPassThru alloc] init]; + + SDLRPCNotificationNotification *notification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveAudioPassThruNotification object:nil rpcNotification:testOnAudioPassThru]; + [[NSNotificationCenter defaultCenter] postNotification:notification]; + }); + + it(@"should not run a handler", ^{ + expect(@(numTimesHandlerCalled)).to(equal(@0)); + }); + }); + + describe(@"when an on audio data response arrives", ^{ + beforeEach(^{ + SDLPerformAudioPassThruResponse *performAudioPassThruResponse = [[SDLPerformAudioPassThruResponse alloc] init]; + performAudioPassThruResponse.success = @YES; + + SDLRPCResponseNotification *notification = [[SDLRPCResponseNotification alloc] initWithName:SDLDidReceivePerformAudioPassThruResponse object:nil rpcResponse:performAudioPassThruResponse]; + [[NSNotificationCenter defaultCenter] postNotification:notification]; + }); + + it(@"should clear the handler", ^{ +// expect(testDispatcher.audioPassThruHandler).to(beNil()); + }); + }); + + }); + }); +}); + +QuickSpecEnd diff --git a/SmartDeviceLinkTests/Requests/SDLRPCRequestNotificationSpec.m b/SmartDeviceLinkTests/Requests/SDLRPCRequestNotificationSpec.m new file mode 100644 index 000000000..4751c9361 --- /dev/null +++ b/SmartDeviceLinkTests/Requests/SDLRPCRequestNotificationSpec.m @@ -0,0 +1,41 @@ +// +// SDLRPCRequestNotificationSpec.m +// SmartDeviceLinkTests +// +// Created by Nicole on 2/14/19. +// Copyright © 2019 smartdevicelink. All rights reserved. +// + +#import +#import + +#import "SDLNotificationConstants.h" +#import "SDLAddCommand.h" +#import "SDLRPCRequestNotification.h" + + +QuickSpecBegin(SDLRPCRequestNotificationSpec) + +describe(@"A request notification", ^{ + __block SDLRPCRequest *testRequest = nil; + __block NSString *testName = nil; + + beforeEach(^{ + testRequest = [[SDLAddCommand alloc] initWithName:@"testRequest"]; + testName = SDLDidReceiveAddCommandResponse; + }); + + it(@"Should initialize correctly with initWithName:object:rpcRequest:", ^{ + SDLRPCRequestNotification *testNotification = [[SDLRPCRequestNotification alloc] initWithName:testName object:nil rpcRequest:testRequest]; + + expect(testNotification.name).to(equal(testName)); + expect(testNotification.userInfo).to(equal(@{SDLNotificationUserInfoObject: testRequest})); + expect(testNotification.object).to(beNil()); + expect(testNotification.request).to(equal(testRequest)); + expect([testNotification isRequestKindOfClass:SDLRPCRequest.class]).to(beTrue()); + expect([testNotification isRequestMemberOfClass:SDLAddCommand.class]).to(beTrue()); + }); +}); + +QuickSpecEnd + -- cgit v1.2.1 From 5d2bc0f27f2ce1f7279cf381b86499ae8405d4bb Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Fri, 15 Feb 2019 12:58:14 -0500 Subject: Added support for getting requests from Core * Library now posts a notification when a request is received from Core * Added support for the GetAppServiceData and the PerformAppServiceInteraction RPCs * Fixed `onPublishAppServiceResponse` not returning the correct response in _SDLProxyListener_ --- SmartDeviceLink-iOS.podspec | 1 + SmartDeviceLink-iOS.xcodeproj/project.pbxproj | 2 +- SmartDeviceLink.podspec | 1 + SmartDeviceLink/SDLNotificationConstants.h | 7 +++++++ SmartDeviceLink/SDLNotificationConstants.m | 7 ++++++- SmartDeviceLink/SDLNotificationDispatcher.h | 3 +++ SmartDeviceLink/SDLNotificationDispatcher.m | 20 ++++++++++++++++++-- SmartDeviceLink/SDLProxyListener.h | 20 ++++++++++++++++++-- SmartDeviceLink/SmartDeviceLink.h | 1 + .../Notifications/SDLNotificationDispatcherSpec.m | 5 +++-- 10 files changed, 59 insertions(+), 8 deletions(-) diff --git a/SmartDeviceLink-iOS.podspec b/SmartDeviceLink-iOS.podspec index 160f97cd5..499e5ea2f 100644 --- a/SmartDeviceLink-iOS.podspec +++ b/SmartDeviceLink-iOS.podspec @@ -275,6 +275,7 @@ ss.public_header_files = [ 'SmartDeviceLink/SDLRPCNotification.h', 'SmartDeviceLink/SDLRPCNotificationNotification.h', 'SmartDeviceLink/SDLRPCRequest.h', +'SmartDeviceLink/SDLRPCRequestNotification.h', 'SmartDeviceLink/SDLRPCResponse.h', 'SmartDeviceLink/SDLRPCResponseNotification.h', 'SmartDeviceLink/SDLRPCStruct.h', diff --git a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj index 009588195..db18cbcd3 100644 --- a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj +++ b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj @@ -1334,7 +1334,7 @@ 88F65133220C6DC300CAF321 /* SDLWeatherAlertSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 88F65132220C6DC300CAF321 /* SDLWeatherAlertSpec.m */; }; 88F65136220C74FD00CAF321 /* SDLWeatherData.h in Headers */ = {isa = PBXBuildFile; fileRef = 88F65134220C74FD00CAF321 /* SDLWeatherData.h */; settings = {ATTRIBUTES = (Public, ); }; }; 88F65137220C74FD00CAF321 /* SDLWeatherData.m in Sources */ = {isa = PBXBuildFile; fileRef = 88F65135220C74FD00CAF321 /* SDLWeatherData.m */; }; - 88FF4E762215FB8200A71361 /* SDLRPCRequestNotification.h in Headers */ = {isa = PBXBuildFile; fileRef = 88FF4E742215FB8200A71361 /* SDLRPCRequestNotification.h */; }; + 88FF4E762215FB8200A71361 /* SDLRPCRequestNotification.h in Headers */ = {isa = PBXBuildFile; fileRef = 88FF4E742215FB8200A71361 /* SDLRPCRequestNotification.h */; settings = {ATTRIBUTES = (Public, ); }; }; 88FF4E772215FB8200A71361 /* SDLRPCRequestNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = 88FF4E752215FB8200A71361 /* SDLRPCRequestNotification.m */; }; 88FF4E7C2215FEEA00A71361 /* SDLRPCRequestNotificationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 88FF4E7B2215FEEA00A71361 /* SDLRPCRequestNotificationSpec.m */; }; 8B7B319A1F2F7B5700BDC38D /* SDLVideoStreamingCodec.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B7B31981F2F7B5700BDC38D /* SDLVideoStreamingCodec.h */; settings = {ATTRIBUTES = (Public, ); }; }; diff --git a/SmartDeviceLink.podspec b/SmartDeviceLink.podspec index 8c4c289c8..34bf96d2c 100644 --- a/SmartDeviceLink.podspec +++ b/SmartDeviceLink.podspec @@ -275,6 +275,7 @@ sdefault.public_header_files = [ 'SmartDeviceLink/SDLRPCNotification.h', 'SmartDeviceLink/SDLRPCNotificationNotification.h', 'SmartDeviceLink/SDLRPCRequest.h', +'SmartDeviceLink/SDLRPCRequestNotification.h', 'SmartDeviceLink/SDLRPCResponse.h', 'SmartDeviceLink/SDLRPCResponseNotification.h', 'SmartDeviceLink/SDLRPCStruct.h', diff --git a/SmartDeviceLink/SDLNotificationConstants.h b/SmartDeviceLink/SDLNotificationConstants.h index 36be5c240..47129123d 100644 --- a/SmartDeviceLink/SDLNotificationConstants.h +++ b/SmartDeviceLink/SDLNotificationConstants.h @@ -170,6 +170,13 @@ extern SDLNotificationName const SDLDidReceiveUnsubscribeButtonResponse; extern SDLNotificationName const SDLDidReceiveUnsubscribeVehicleDataResponse; extern SDLNotificationName const SDLDidReceiveUnsubscribeWaypointsResponse; +/** + * NSNotification names associated with specific RPC requests. + */ +#pragma mark - RPC requests +extern SDLNotificationName const SDLDidReceivePublishAppServiceRequest; +extern SDLNotificationName const SDLDidReceiveGetAppServiceDataRequest; + /** * NSNotification names associated with specific RPC notifications. */ diff --git a/SmartDeviceLink/SDLNotificationConstants.m b/SmartDeviceLink/SDLNotificationConstants.m index 247e17fb0..5c47b1475 100644 --- a/SmartDeviceLink/SDLNotificationConstants.m +++ b/SmartDeviceLink/SDLNotificationConstants.m @@ -78,6 +78,10 @@ SDLNotificationName const SDLDidReceiveUnsubscribeButtonResponse = @"com.sdl.res SDLNotificationName const SDLDidReceiveUnsubscribeVehicleDataResponse = @"com.sdl.response.unsubscribeVehicleData"; SDLNotificationName const SDLDidReceiveUnsubscribeWaypointsResponse = @"com.sdl.response.unsubscribeWaypoints"; +#pragma mark - RPC Requests +SDLNotificationName const SDLDidReceivePublishAppServiceRequest = @"com.sdl.request.publishAppService"; +SDLNotificationName const SDLDidReceiveGetAppServiceDataRequest = @"com.sdl.request.getAppServiceData"; + #pragma mark - RPC Notifications SDLNotificationName const SDLDidChangeDriverDistractionStateNotification = @"com.sdl.notification.changeDriverDistractionStateNotification"; SDLNotificationName const SDLDidChangeHMIStatusNotification = @"com.sdl.notification.changeHMIStatus"; @@ -161,7 +165,8 @@ SDLNotificationName const SDLDidReceiveWaypointNotification = @"com.sdl.notifica } + (NSArray *)allRequestNames { - return @[]; + return @[SDLDidReceivePublishAppServiceRequest, + SDLDidReceiveGetAppServiceDataRequest]; } + (NSArray *)allButtonEventNotifications { diff --git a/SmartDeviceLink/SDLNotificationDispatcher.h b/SmartDeviceLink/SDLNotificationDispatcher.h index ba5089a25..a18363d13 100644 --- a/SmartDeviceLink/SDLNotificationDispatcher.h +++ b/SmartDeviceLink/SDLNotificationDispatcher.h @@ -10,6 +10,7 @@ #import "SDLProxyListener.h" +@class SDLRPCRequest; @class SDLRPCResponse; @class SDLRPCNotification; @@ -28,6 +29,8 @@ NS_ASSUME_NONNULL_BEGIN * @param info The object to be send along in the `userInfo` dictionary. */ - (void)postNotificationName:(NSString *)name infoObject:(nullable id)info; + +- (void)postRPCRequestNotification:(NSString *)name request:(__kindof SDLRPCRequest *)request; - (void)postRPCResponseNotification:(NSString *)name response:(__kindof SDLRPCResponse *)response; - (void)postRPCNotificationNotification:(NSString *)name notification:(__kindof SDLRPCNotification *)rpcNotification; diff --git a/SmartDeviceLink/SDLNotificationDispatcher.m b/SmartDeviceLink/SDLNotificationDispatcher.m index 8ca899476..d6b730363 100644 --- a/SmartDeviceLink/SDLNotificationDispatcher.m +++ b/SmartDeviceLink/SDLNotificationDispatcher.m @@ -12,6 +12,7 @@ #import "SDLNotificationConstants.h" #import "SDLRPCNotification.h" #import "SDLRPCNotificationNotification.h" +#import "SDLRPCRequestNotification.h" #import "SDLRPCResponseNotification.h" NS_ASSUME_NONNULL_BEGIN @@ -35,6 +36,13 @@ NS_ASSUME_NONNULL_BEGIN [[NSNotificationCenter defaultCenter] postNotificationName:name object:self userInfo:userInfo]; } +- (void)postRPCRequestNotification:(NSString *)name request:(__kindof SDLRPCRequest *)request { + SDLRPCRequestNotification *notification = [[SDLRPCRequestNotification alloc] initWithName:name object:self rpcRequest:request]; + + // Runs on `com.sdl.rpcProcessingQueue` + [[NSNotificationCenter defaultCenter] postNotification:notification]; +} + - (void)postRPCResponseNotification:(NSString *)name response:(__kindof SDLRPCResponse *)response { SDLRPCResponseNotification *notification = [[SDLRPCResponseNotification alloc] initWithName:name object:self rpcResponse:response]; @@ -149,6 +157,10 @@ NS_ASSUME_NONNULL_BEGIN [self postRPCResponseNotification:SDLDidReceiveGenericResponse response:response]; } +- (void)onGetAppServiceDataRequest:(SDLGetAppServiceData *)request { + [self postRPCRequestNotification:SDLDidReceiveGetAppServiceDataRequest request:request]; +} + - (void)onGetAppServiceDataResponse:(SDLGetAppServiceDataResponse *)response { [self postRPCResponseNotification:SDLDidReceiveGetAppServiceDataResponse response:response]; } @@ -181,8 +193,12 @@ NS_ASSUME_NONNULL_BEGIN [self postRPCResponseNotification:SDLDidReceiveListFilesResponse response:response]; } +- (void)onPerformAppServiceInteractionRequest:(SDLPerformAppServiceInteraction *)request { + [self postRPCRequestNotification:SDLDidReceivePublishAppServiceRequest request:request]; +} + - (void)onPerformAppServiceInteractionResponse:(SDLPerformAppServiceInteractionResponse *)response { - [self postRPCResponseNotification:SDLDidReceivePerformAppServiceInteractionResponse response:response]; + [self postRPCResponseNotification:SDLDidReceivePerformInteractionResponse response:response]; } - (void)onPerformAudioPassThruResponse:(SDLPerformAudioPassThruResponse *)response { @@ -193,7 +209,7 @@ NS_ASSUME_NONNULL_BEGIN [self postRPCResponseNotification:SDLDidReceivePerformInteractionResponse response:response]; } -- (void)onPublishAppService:(SDLPublishAppService *)response { +- (void)onPublishAppServiceResponse:(SDLPublishAppServiceResponse *)response { [self postRPCResponseNotification:SDLDidReceivePublishAppServiceResponse response:response]; } diff --git a/SmartDeviceLink/SDLProxyListener.h b/SmartDeviceLink/SDLProxyListener.h index 45d961638..9c044854a 100644 --- a/SmartDeviceLink/SDLProxyListener.h +++ b/SmartDeviceLink/SDLProxyListener.h @@ -19,6 +19,7 @@ @class SDLEncodedSyncPDataResponse; @class SDLEndAudioPassThruResponse; @class SDLGenericResponse; +@class SDLGetAppServiceData; @class SDLGetAppServiceDataResponse; @class SDLGetDTCsResponse; @class SDLGetFileResponse; @@ -50,10 +51,11 @@ @class SDLOnTouchEvent; @class SDLOnVehicleData; @class SDLOnWayPointChange; +@class SDLPerformAppServiceInteraction; @class SDLPerformAppServiceInteractionResponse; @class SDLPerformAudioPassThruResponse; @class SDLPerformInteractionResponse; -@class SDLPublishAppService; +@class SDLPublishAppServiceResponse; @class SDLPutFileResponse; @class SDLReadDIDResponse; @class SDLRegisterAppInterfaceResponse; @@ -229,6 +231,13 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)onGenericResponse:(SDLGenericResponse *)response; +/** + * Called when a Get App Service Data Request is received from Core + * + * @param request A SDLGetAppServiceData object + */ +- (void)onGetAppServiceDataRequest:(SDLGetAppServiceData *)request; + /** * Called when a Get App Service Data Response is received from Core * @@ -432,6 +441,13 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)onOnWayPointChange:(SDLOnWayPointChange *)notification; +/** + * Called when a Perform App Service Interaction Request is received from Core + * + * @param request A SDLPerformAppServiceInteraction object + */ +- (void)onPerformAppServiceInteractionRequest:(SDLPerformAppServiceInteraction *)request; + /** * Called when a Perform App Service Interaction Response is received from Core * @@ -458,7 +474,7 @@ NS_ASSUME_NONNULL_BEGIN * * @param response A SDLPublishAppService object */ -- (void)onPublishAppService:(SDLPublishAppService *)response; +- (void)onPublishAppServiceResponse:(SDLPublishAppServiceResponse *)response; /** * Called when a Put File Response is received from Core diff --git a/SmartDeviceLink/SmartDeviceLink.h b/SmartDeviceLink/SmartDeviceLink.h index 0b29f01cd..6958a961e 100644 --- a/SmartDeviceLink/SmartDeviceLink.h +++ b/SmartDeviceLink/SmartDeviceLink.h @@ -413,6 +413,7 @@ FOUNDATION_EXPORT const unsigned char SmartDeviceLinkVersionString[]; // Notifications #import "SDLRPCNotificationNotification.h" #import "SDLRPCResponseNotification.h" +#import "SDLRPCRequestNotification.h" // Logger #import "SDLLogConstants.h" diff --git a/SmartDeviceLinkTests/Notifications/SDLNotificationDispatcherSpec.m b/SmartDeviceLinkTests/Notifications/SDLNotificationDispatcherSpec.m index 63d691ee0..06fa35e59 100644 --- a/SmartDeviceLinkTests/Notifications/SDLNotificationDispatcherSpec.m +++ b/SmartDeviceLinkTests/Notifications/SDLNotificationDispatcherSpec.m @@ -37,6 +37,7 @@ describe(@"a notification dispatcher", ^{ expect(@([testDispatcher respondsToSelector:@selector(onEndAudioPassThruResponse:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onError:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onGenericResponse:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onGetAppServiceDataRequest:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onGetAppServiceDataResponse:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onGetDTCsResponse:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onGetFileResponse:)])).to(beTruthy()); @@ -62,10 +63,11 @@ describe(@"a notification dispatcher", ^{ expect(@([testDispatcher respondsToSelector:@selector(onOnTouchEvent:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onOnVehicleData:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onOnWayPointChange:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onPerformAppServiceInteractionRequest:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onPerformAppServiceInteractionResponse:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onPerformAudioPassThruResponse:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onPerformInteractionResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onPublishAppService:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onPublishAppServiceResponse:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onPutFileResponse:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onReadDIDResponse:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onRegisterAppInterfaceResponse:)])).to(beTruthy()); @@ -96,7 +98,6 @@ describe(@"a notification dispatcher", ^{ describe(@"when told to post a notification", ^{ __block NSString *testNotificationName = nil; __block NSString *testUserInfo = nil; - __block NSNotification *returnNotification = nil; beforeEach(^{ -- cgit v1.2.1 From a7571a80a47a7ecee12b491c26f0d2c84abbf56c Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Fri, 15 Feb 2019 12:58:55 -0500 Subject: Fixed incorrect parameter names --- SmartDeviceLink/SDLNotificationConstants.h | 2 +- SmartDeviceLink/SDLNotificationConstants.m | 4 ++-- SmartDeviceLink/SDLNotificationDispatcher.h | 26 +++++++++++++++++++++++--- SmartDeviceLink/SDLNotificationDispatcher.m | 4 ++-- 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/SmartDeviceLink/SDLNotificationConstants.h b/SmartDeviceLink/SDLNotificationConstants.h index 47129123d..1454330db 100644 --- a/SmartDeviceLink/SDLNotificationConstants.h +++ b/SmartDeviceLink/SDLNotificationConstants.h @@ -174,7 +174,7 @@ extern SDLNotificationName const SDLDidReceiveUnsubscribeWaypointsResponse; * NSNotification names associated with specific RPC requests. */ #pragma mark - RPC requests -extern SDLNotificationName const SDLDidReceivePublishAppServiceRequest; +extern SDLNotificationName const SDLDidReceivePerformAppServiceInteractionRequest; extern SDLNotificationName const SDLDidReceiveGetAppServiceDataRequest; /** diff --git a/SmartDeviceLink/SDLNotificationConstants.m b/SmartDeviceLink/SDLNotificationConstants.m index 5c47b1475..17f6ac79f 100644 --- a/SmartDeviceLink/SDLNotificationConstants.m +++ b/SmartDeviceLink/SDLNotificationConstants.m @@ -79,7 +79,7 @@ SDLNotificationName const SDLDidReceiveUnsubscribeVehicleDataResponse = @"com.sd SDLNotificationName const SDLDidReceiveUnsubscribeWaypointsResponse = @"com.sdl.response.unsubscribeWaypoints"; #pragma mark - RPC Requests -SDLNotificationName const SDLDidReceivePublishAppServiceRequest = @"com.sdl.request.publishAppService"; +SDLNotificationName const SDLDidReceivePerformAppServiceInteractionRequest = @"com.sdl.request.performAppServiceInteraction"; SDLNotificationName const SDLDidReceiveGetAppServiceDataRequest = @"com.sdl.request.getAppServiceData"; #pragma mark - RPC Notifications @@ -165,7 +165,7 @@ SDLNotificationName const SDLDidReceiveWaypointNotification = @"com.sdl.notifica } + (NSArray *)allRequestNames { - return @[SDLDidReceivePublishAppServiceRequest, + return @[SDLDidReceivePerformAppServiceInteractionRequest, SDLDidReceiveGetAppServiceDataRequest]; } diff --git a/SmartDeviceLink/SDLNotificationDispatcher.h b/SmartDeviceLink/SDLNotificationDispatcher.h index a18363d13..f820ddc91 100644 --- a/SmartDeviceLink/SDLNotificationDispatcher.h +++ b/SmartDeviceLink/SDLNotificationDispatcher.h @@ -23,15 +23,35 @@ NS_ASSUME_NONNULL_BEGIN @interface SDLNotificationDispatcher : NSObject /** - * Post a notification with a specified name and object. + * Posts a notification with a specified name and object. * - * @param name The name of the notification to be dispatched. - * @param info The object to be send along in the `userInfo` dictionary. + * @param name The name of the notification to be dispatched. + * @param info The notification object to be sent in the `userInfo` dictionary. */ - (void)postNotificationName:(NSString *)name infoObject:(nullable id)info; +/** + * Posts a request from Core with a specified name and request object + * + * @param name The name of the request to be dispatched + * @param request The request object to be sent in the `userInfo` dictionary + */ - (void)postRPCRequestNotification:(NSString *)name request:(__kindof SDLRPCRequest *)request; + +/** + * Posts a response from Core with a specified name and response object + * + * @param name The name of the response to be dispatched + * @param response The response object to be sent in the `userInfo` dictionary + */ - (void)postRPCResponseNotification:(NSString *)name response:(__kindof SDLRPCResponse *)response; + +/** + * Posts a notification from Core with a specified name and notification object + * + * @param name The name of the notification to be dispatched + * @param rpcNotification The notification object to be sent in the `userInfo` dictionary + */ - (void)postRPCNotificationNotification:(NSString *)name notification:(__kindof SDLRPCNotification *)rpcNotification; @end diff --git a/SmartDeviceLink/SDLNotificationDispatcher.m b/SmartDeviceLink/SDLNotificationDispatcher.m index d6b730363..4b42d0da9 100644 --- a/SmartDeviceLink/SDLNotificationDispatcher.m +++ b/SmartDeviceLink/SDLNotificationDispatcher.m @@ -194,11 +194,11 @@ NS_ASSUME_NONNULL_BEGIN } - (void)onPerformAppServiceInteractionRequest:(SDLPerformAppServiceInteraction *)request { - [self postRPCRequestNotification:SDLDidReceivePublishAppServiceRequest request:request]; + [self postRPCRequestNotification:SDLDidReceivePerformAppServiceInteractionRequest request:request]; } - (void)onPerformAppServiceInteractionResponse:(SDLPerformAppServiceInteractionResponse *)response { - [self postRPCResponseNotification:SDLDidReceivePerformInteractionResponse response:response]; + [self postRPCResponseNotification:SDLDidReceivePerformAppServiceInteractionResponse response:response]; } - (void)onPerformAudioPassThruResponse:(SDLPerformAudioPassThruResponse *)response { -- cgit v1.2.1 From 55a4cd991c31c2f7f0beee74f9e9dc883e79be42 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 19 Feb 2019 09:14:27 -0500 Subject: Basic fix for receiving requests and sending responses Implemented basic fixes to managers to allow sending RPC responses and notifications and to receive RPC requests. --- .../SDLAsynchronousRPCRequestOperation.h | 12 ++++++- .../SDLAsynchronousRPCRequestOperation.m | 38 +++++++++++++++------- SmartDeviceLink/SDLLifecycleManager.h | 5 +-- SmartDeviceLink/SDLLifecycleManager.m | 34 +++++++++++++------ SmartDeviceLink/SDLManager.h | 2 ++ SmartDeviceLink/SDLManager.m | 8 +++-- SmartDeviceLink/SDLNotificationDispatcher.m | 2 +- SmartDeviceLink/SDLProxyListener.h | 2 +- 8 files changed, 74 insertions(+), 29 deletions(-) diff --git a/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.h b/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.h index a24165dad..c69185a41 100644 --- a/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.h +++ b/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.h @@ -11,13 +11,23 @@ #import "SDLAsynchronousOperation.h" #import "SDLLifecycleManager.h" +@class SDLRPCMessage; + @protocol SDLConnectionManagerType; NS_ASSUME_NONNULL_BEGIN @interface SDLAsynchronousRPCRequestOperation : SDLAsynchronousOperation -@property (copy, nonatomic) NSArray *requests; +//@property (copy, nonatomic) NSArray *requests; +@property (copy, nonatomic) NSArray<__kindof SDLRPCMessage *> *rpcs; + +// TODO: NEW +- (instancetype)initWithConnectionManager:(id)connectionManager rpc:(__kindof SDLRPCMessage *)rpc responseHandler:(nullable SDLResponseHandler)responseHandler; + +- (instancetype)initWithConnectionManager:(id)connectionManager rpcs:(NSArray<__kindof SDLRPCMessage *> *)rpcs progressHandler:(nullable SDLMultipleAsyncRequestProgressHandler)progressHandler completionHandler:(nullable SDLMultipleRequestCompletionHandler)completionHandler; + +//// - (instancetype)initWithConnectionManager:(id)connectionManager requests:(NSArray *)requests progressHandler:(nullable SDLMultipleAsyncRequestProgressHandler)progressHandler completionHandler:(nullable SDLMultipleRequestCompletionHandler)completionHandler; diff --git a/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m b/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m index 5c67e3e8a..e8843d8c8 100644 --- a/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m +++ b/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m @@ -11,6 +11,8 @@ #import "SDLConnectionManagerType.h" #import "SDLError.h" #import "SDLGlobals.h" +#import "SDLRPCMessage.h" +#import "SDLRPCRequest.h" NS_ASSUME_NONNULL_BEGIN @@ -49,27 +51,35 @@ NS_ASSUME_NONNULL_BEGIN return self; } -- (instancetype)initWithConnectionManager:(id)connectionManager requests:(NSArray *)requests progressHandler:(nullable SDLMultipleAsyncRequestProgressHandler)progressHandler completionHandler:(nullable SDLMultipleRequestCompletionHandler)completionHandler { +- (instancetype)initWithConnectionManager:(id)connectionManager rpcs:(NSArray<__kindof SDLRPCMessage *> *)rpcs progressHandler:(nullable SDLMultipleAsyncRequestProgressHandler)progressHandler completionHandler:(nullable SDLMultipleRequestCompletionHandler)completionHandler { self = [self init]; _connectionManager = connectionManager; - _requests = requests; + _rpcs = rpcs; _progressHandler = progressHandler; _completionHandler = completionHandler; return self; } -- (instancetype)initWithConnectionManager:(id)connectionManager request:(SDLRPCRequest *)request responseHandler:(nullable SDLResponseHandler)responseHandler { +- (instancetype)initWithConnectionManager:(id)connectionManager rpc:(__kindof SDLRPCMessage *)rpc responseHandler:(nullable SDLResponseHandler)responseHandler { self = [self init]; _connectionManager = connectionManager; - _requests = @[request]; + _rpcs = @[rpc]; _responseHandler = responseHandler; return self; } +- (instancetype)initWithConnectionManager:(id)connectionManager requests:(NSArray *)requests progressHandler:(nullable SDLMultipleAsyncRequestProgressHandler)progressHandler completionHandler:(nullable SDLMultipleRequestCompletionHandler)completionHandler { + return [self initWithConnectionManager:connectionManager rpcs:requests progressHandler:progressHandler completionHandler:completionHandler]; +} + +- (instancetype)initWithConnectionManager:(id)connectionManager request:(SDLRPCRequest *)request responseHandler:(nullable SDLResponseHandler)responseHandler { + return [self initWithConnectionManager:connectionManager rpc:request responseHandler:responseHandler]; +} + - (void)start { [super start]; @@ -77,8 +87,9 @@ NS_ASSUME_NONNULL_BEGIN } - (void)sdl_sendRequests { - for (SDLRPCRequest *request in self.requests) { + for (id request in self.rpcs) { if (self.isCancelled) { + // FIXME: Deal with aborted responses [self sdl_abortOperationWithRequest:request]; return; } @@ -88,7 +99,7 @@ NS_ASSUME_NONNULL_BEGIN } } -- (void)sdl_sendRequest:(SDLRPCRequest *)request { +- (void)sdl_sendRequest:(__kindof SDLRPCMessage *)request { __weak typeof(self) weakSelf = self; [self.connectionManager sendConnectionRequest:request withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) { __strong typeof(self) strongSelf = weakSelf; @@ -112,7 +123,7 @@ NS_ASSUME_NONNULL_BEGIN } // If we've received responses for all requests, call the completion handler. - if (strongSelf.requestsComplete >= strongSelf.requests.count) { + if (strongSelf.requestsComplete >= strongSelf.rpcs.count) { [strongSelf finishOperation]; } }]; @@ -121,9 +132,12 @@ NS_ASSUME_NONNULL_BEGIN - (void)sdl_abortOperationWithRequest:(SDLRPCRequest *)request { self.requestFailed = YES; - for (NSUInteger i = self.requestsComplete; i < self.requests.count; i++) { + for (NSUInteger i = self.requestsComplete; i < self.rpcs.count; i++) { if (self.progressHandler != NULL) { - self.progressHandler(self.requests[i], nil, [NSError sdl_lifecycle_multipleRequestsCancelled], self.percentComplete); + id rpc = self.rpcs[i]; + SDLRPCRequest *abortedRequest = [rpc isMemberOfClass:[SDLRPCRequest class]] ? (SDLRPCRequest *)rpc : nil; + // FIXME: first param is not nullable + self.progressHandler(abortedRequest, nil, [NSError sdl_lifecycle_multipleRequestsCancelled], self.percentComplete); } if (self.responseHandler != NULL) { @@ -141,7 +155,7 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark - Getters - (float)percentComplete { - return (float)self.requestsComplete / (float)self.requests.count; + return (float)self.requestsComplete / (float)self.rpcs.count; } #pragma mark - Property Overrides @@ -163,11 +177,11 @@ NS_ASSUME_NONNULL_BEGIN } - (NSString *)description { - return [NSString stringWithFormat:@"%@, request count=%lu, requests started=%lu, finished=%lu, failed=%@", self.name, (unsigned long)self.requests.count, (unsigned long)self.requestsStarted, (unsigned long)self.requestsComplete, (self.requestFailed ? @"YES": @"NO")]; + return [NSString stringWithFormat:@"%@, request count=%lu, requests started=%lu, finished=%lu, failed=%@", self.name, (unsigned long)self.rpcs.count, (unsigned long)self.requestsStarted, (unsigned long)self.requestsComplete, (self.requestFailed ? @"YES": @"NO")]; } - (NSString *)debugDescription { - return [NSString stringWithFormat:@"%@, request count=%lu, requests started=%lu, finished=%lu, failed=%@, requests=%@", self.name, (unsigned long)self.requests.count, (unsigned long)self.requestsStarted, (unsigned long)self.requestsComplete, (self.requestFailed ? @"YES": @"NO"), self.requests]; + return [NSString stringWithFormat:@"%@, request count=%lu, requests started=%lu, finished=%lu, failed=%@, requests=%@", self.name, (unsigned long)self.rpcs.count, (unsigned long)self.requestsStarted, (unsigned long)self.requestsComplete, (self.requestFailed ? @"YES": @"NO"), self.rpcs]; } @end diff --git a/SmartDeviceLink/SDLLifecycleManager.h b/SmartDeviceLink/SDLLifecycleManager.h index 594dccba3..239e1a370 100644 --- a/SmartDeviceLink/SDLLifecycleManager.h +++ b/SmartDeviceLink/SDLLifecycleManager.h @@ -26,6 +26,7 @@ @class SDLPutFile; @class SDLRegisterAppInterfaceResponse; @class SDLResponseDispatcher; +@class SDLRPCMessage; @class SDLRPCNotification; @class SDLRPCRequest; @class SDLRPCResponse; @@ -121,7 +122,7 @@ typedef void (^SDLManagerReadyBlock)(BOOL success, NSError *_Nullable error); * * @param request The RPC request to send */ -- (void)sendRequest:(SDLRPCRequest *)request; +- (void)sendRequest:(__kindof SDLRPCMessage *)request; /** * Send an RPC request and set a completion handler that will be called with the response when the response returns. @@ -129,7 +130,7 @@ typedef void (^SDLManagerReadyBlock)(BOOL success, NSError *_Nullable error); * @param request The RPC request to send * @param handler The handler that will be called when the response returns */ -- (void)sendRequest:(SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler; +- (void)sendRequest:(__kindof SDLRPCMessage *)request withResponseHandler:(nullable SDLResponseHandler)handler; /** Send all of the requests given as quickly as possible, but in order. Call the completionHandler after all requests have either failed or given a response. diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m index d521244d0..1e20d8e5c 100644 --- a/SmartDeviceLink/SDLLifecycleManager.m +++ b/SmartDeviceLink/SDLLifecycleManager.m @@ -520,12 +520,13 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; #pragma mark Sending Requests -- (void)sendRequest:(SDLRPCRequest *)request { +- (void)sendRequest:(__kindof SDLRPCMessage *)request { [self sendRequest:request withResponseHandler:nil]; } -- (void)sendRequest:(__kindof SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler { - SDLAsynchronousRPCRequestOperation *op = [[SDLAsynchronousRPCRequestOperation alloc] initWithConnectionManager:self request:request responseHandler:handler]; +- (void)sendRequest:(__kindof SDLRPCMessage *)request withResponseHandler:(nullable SDLResponseHandler)handler { + SDLAsynchronousRPCRequestOperation *op = [[SDLAsynchronousRPCRequestOperation alloc] initWithConnectionManager:self rpc:request responseHandler:handler]; +// SDLAsynchronousRPCRequestOperation *op = [[SDLAsynchronousRPCRequestOperation alloc] initWithConnectionManager:self request:request responseHandler:handler]; [self.rpcOperationQueue addOperation:op]; } @@ -549,7 +550,7 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; [self.rpcOperationQueue addOperation:op]; } -- (void)sendConnectionRequest:(__kindof SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler { +- (void)sendConnectionRequest:(__kindof SDLRPCMessage *)request withResponseHandler:(nullable SDLResponseHandler)handler { if (![self.lifecycleStateMachine isCurrentState:SDLLifecycleStateReady]) { SDLLogW(@"Manager not ready, message not sent (%@)", request); if (handler) { @@ -567,13 +568,13 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; } // Managers need to avoid state checking. Part of . -- (void)sendConnectionManagerRequest:(__kindof SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler { +- (void)sendConnectionManagerRequest:(__kindof SDLRPCMessage *)request withResponseHandler:(nullable SDLResponseHandler)handler { dispatch_async(_lifecycleQueue, ^{ [self sdl_sendRequest:request withResponseHandler:handler]; }); } -- (void)sdl_sendRequest:(SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler { +- (void)sdl_sendRequest:(__kindof SDLRPCMessage *)request withResponseHandler:(nullable SDLResponseHandler)handler { // 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); @@ -590,11 +591,24 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; } // Add a correlation ID to the request - NSNumber *corrID = [self sdl_getNextCorrelationId]; - request.correlationID = corrID; + SDLRPCRequest *test = [request isKindOfClass:[SDLRPCRequest class]] ? (SDLRPCRequest *)request : nil; + if (test != nil) { + NSNumber *corrID = [self sdl_getNextCorrelationId]; + test.correlationID = corrID; - [self.responseDispatcher storeRequest:request handler:handler]; - [self.proxy sendRPC:request]; + [self.responseDispatcher storeRequest:test handler:handler]; + [self.proxy sendRPC:test]; + } + + SDLRPCResponse *testResponse = [request isKindOfClass:[SDLRPCResponse class]] ? (SDLRPCResponse *)request : nil; + if (testResponse != nil) { + [self.proxy sendRPC:testResponse]; + } + + SDLRPCNotification *testNotification = [request isKindOfClass:[SDLRPCNotification class]] ? (SDLRPCNotification *)request : nil; + if (testNotification != nil) { + [self.proxy sendRPC:testNotification]; + } } diff --git a/SmartDeviceLink/SDLManager.h b/SmartDeviceLink/SDLManager.h index b984a58a5..a97ef0c91 100644 --- a/SmartDeviceLink/SDLManager.h +++ b/SmartDeviceLink/SDLManager.h @@ -15,6 +15,7 @@ @class SDLProxy; @class SDLPutFile; @class SDLRegisterAppInterfaceResponse; +@class SDLRPCMessage; @class SDLRPCNotification; @class SDLRPCRequest; @class SDLRPCResponse; @@ -132,6 +133,7 @@ typedef void (^SDLManagerReadyBlock)(BOOL success, NSError *_Nullable error); #pragma mark Manually Send RPC Requests +- (void)sendRPC:(__kindof SDLRPCMessage *)rpc; /** * Send an RPC request and don't bother with the response or error. If you need the response or error, call sendRequest:withCompletionHandler: instead. * diff --git a/SmartDeviceLink/SDLManager.m b/SmartDeviceLink/SDLManager.m index fa7c9e8e0..92ab50480 100644 --- a/SmartDeviceLink/SDLManager.m +++ b/SmartDeviceLink/SDLManager.m @@ -119,12 +119,16 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark SDLConnectionManager Protocol +- (void)sendRPC:(__kindof SDLRPCMessage *)rpc { + [self.lifecycleManager sendRequest:rpc]; +} + - (void)sendRequest:(SDLRPCRequest *)request { [self sendRequest:request withResponseHandler:nil]; } -- (void)sendRequest:(__kindof SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler { - [self.lifecycleManager sendRequest:request withResponseHandler:handler]; +- (void)sendRequest:(SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler { + [self.lifecycleManager sendRequest:(__kindof SDLRPCMessage *)request withResponseHandler:handler]; } - (void)sendRequests:(NSArray *)requests progressHandler:(nullable SDLMultipleAsyncRequestProgressHandler)progressHandler completionHandler:(nullable SDLMultipleRequestCompletionHandler)completionHandler { diff --git a/SmartDeviceLink/SDLNotificationDispatcher.m b/SmartDeviceLink/SDLNotificationDispatcher.m index 4b42d0da9..d786d2f14 100644 --- a/SmartDeviceLink/SDLNotificationDispatcher.m +++ b/SmartDeviceLink/SDLNotificationDispatcher.m @@ -157,7 +157,7 @@ NS_ASSUME_NONNULL_BEGIN [self postRPCResponseNotification:SDLDidReceiveGenericResponse response:response]; } -- (void)onGetAppServiceDataRequest:(SDLGetAppServiceData *)request { +- (void)onGetAppServiceData:(SDLGetAppServiceData *)request { [self postRPCRequestNotification:SDLDidReceiveGetAppServiceDataRequest request:request]; } diff --git a/SmartDeviceLink/SDLProxyListener.h b/SmartDeviceLink/SDLProxyListener.h index 9c044854a..00e31c072 100644 --- a/SmartDeviceLink/SDLProxyListener.h +++ b/SmartDeviceLink/SDLProxyListener.h @@ -236,7 +236,7 @@ NS_ASSUME_NONNULL_BEGIN * * @param request A SDLGetAppServiceData object */ -- (void)onGetAppServiceDataRequest:(SDLGetAppServiceData *)request; +- (void)onGetAppServiceData:(SDLGetAppServiceData *)request; /** * Called when a Get App Service Data Response is received from Core -- cgit v1.2.1 From 632d404132cb75c94315a3791021cefe52a9b40e Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 19 Feb 2019 11:46:56 -0500 Subject: Added convenience inits for response RPCs * Added convenience inits for response RPCs and associated structs: `AppServiceData`, `GetAppServiceDataResponse`, `MediaServiceData` --- SmartDeviceLink/SDLAppServiceData.h | 11 +++++++++++ SmartDeviceLink/SDLAppServiceData.m | 14 ++++++++++++++ SmartDeviceLink/SDLGetAppServiceDataResponse.h | 8 ++++++++ SmartDeviceLink/SDLGetAppServiceDataResponse.m | 11 +++++++++++ SmartDeviceLink/SDLMediaServiceData.h | 19 +++++++++++++++++++ SmartDeviceLink/SDLMediaServiceData.m | 22 ++++++++++++++++++++++ .../Notifications/SDLNotificationDispatcherSpec.m | 2 +- .../SDLGetAppServiceDataResponseSpec.m | 6 ++++++ .../RPCSpecs/StructSpecs/SDLAppServiceDataSpec.m | 9 +++++++++ .../RPCSpecs/StructSpecs/SDLMediaServiceDataSpec.m | 17 +++++++++++++++++ 10 files changed, 118 insertions(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLAppServiceData.h b/SmartDeviceLink/SDLAppServiceData.h index 07581e0ce..287c388dd 100644 --- a/SmartDeviceLink/SDLAppServiceData.h +++ b/SmartDeviceLink/SDLAppServiceData.h @@ -19,6 +19,17 @@ NS_ASSUME_NONNULL_BEGIN */ @interface SDLAppServiceData : SDLRPCStruct +/** + * Convenience init. + * + * @param serviceType The type of service that is to be offered by this app. + * @param serviceId A unique ID tied to this specific service record. + * @param mediaServiceData The media service data + * @param weatherServiceData The weather service data + * @return A SDLAppServiceData object + */ +- (instancetype)initWithServiceType:(NSString *)serviceType serviceId:(NSString *)serviceId mediaServiceData:(nullable SDLMediaServiceData *)mediaServiceData weatherServiceData:(nullable SDLWeatherServiceData *)weatherServiceData; + /** * The type of service that is to be offered by this app. See AppServiceType. * diff --git a/SmartDeviceLink/SDLAppServiceData.m b/SmartDeviceLink/SDLAppServiceData.m index a4ad15460..a247dc988 100644 --- a/SmartDeviceLink/SDLAppServiceData.m +++ b/SmartDeviceLink/SDLAppServiceData.m @@ -17,6 +17,20 @@ NS_ASSUME_NONNULL_BEGIN @implementation SDLAppServiceData +- (instancetype)initWithServiceType:(NSString *)serviceType serviceId:(NSString *)serviceId mediaServiceData:(nullable SDLMediaServiceData *)mediaServiceData weatherServiceData:(nullable SDLWeatherServiceData *)weatherServiceData { + self = [self init]; + if (!self) { + return nil; + } + + self.serviceType = serviceType; + self.serviceId = serviceId; + self.mediaServiceData = mediaServiceData; + self.weatherServiceData = weatherServiceData; + + return self; +} + - (void)setServiceType:(NSString *)serviceType { [store sdl_setObject:serviceType forName:SDLNameServiceType]; } diff --git a/SmartDeviceLink/SDLGetAppServiceDataResponse.h b/SmartDeviceLink/SDLGetAppServiceDataResponse.h index 6057ed0c8..b5e47e104 100644 --- a/SmartDeviceLink/SDLGetAppServiceDataResponse.h +++ b/SmartDeviceLink/SDLGetAppServiceDataResponse.h @@ -16,6 +16,14 @@ NS_ASSUME_NONNULL_BEGIN */ @interface SDLGetAppServiceDataResponse : SDLRPCResponse +/** + * Convenience init. + * + * @param serviceData Contains all the current data of the app service + * @return A SDLGetAppServiceDataResponse object + */ +- (instancetype)initWithAppServiceData:(SDLAppServiceData *)serviceData; + /** * Contains all the current data of the app service. * diff --git a/SmartDeviceLink/SDLGetAppServiceDataResponse.m b/SmartDeviceLink/SDLGetAppServiceDataResponse.m index e62c6e340..ea94c23eb 100644 --- a/SmartDeviceLink/SDLGetAppServiceDataResponse.m +++ b/SmartDeviceLink/SDLGetAppServiceDataResponse.m @@ -20,6 +20,17 @@ NS_ASSUME_NONNULL_BEGIN return self; } +- (instancetype)initWithAppServiceData:(SDLAppServiceData *)serviceData { + self = [self init]; + if (!self) { + return nil; + } + + self.serviceData = serviceData; + + return self; +} + - (void)setServiceData:(SDLAppServiceData *)serviceData { [parameters sdl_setObject:serviceData forName:SDLNameServiceData]; } diff --git a/SmartDeviceLink/SDLMediaServiceData.h b/SmartDeviceLink/SDLMediaServiceData.h index 6df77c304..8b44a4aa9 100644 --- a/SmartDeviceLink/SDLMediaServiceData.h +++ b/SmartDeviceLink/SDLMediaServiceData.h @@ -18,6 +18,25 @@ NS_ASSUME_NONNULL_BEGIN */ @interface SDLMediaServiceData : SDLRPCStruct +/** + * Convenience init + * + * @param mediaType The type of the currently playing or paused track + * @param mediaTitle The name of the current playing media + * @param mediaArtist The name of the current media artist + * @param mediaAlbum The name of the current media album + * @param playlistName The name of the playlist + * @param isExplicit Whether or not the content currently playing contains explicit content + * @param trackPlaybackProgress The current progress of the track + * @param trackPlaybackDuration The total duration of the track + * @param queuePlaybackProgess The current progress of the playback queue in seconds + * @param queuePlaybackDuration The total duration of the playback queue in seconds + * @param queueCurrentTrackNumber The current number (1 based) of the track in the playback queue + * @param queueTotalTrackCount The total number of tracks in the playback queue + * @return A SDLMediaServiceData object + */ +- (instancetype)initWithMediaType:(nullable SDLMediaType)mediaType mediaTitle:(nullable NSString *)mediaTitle mediaArtist:(nullable NSString *)mediaArtist mediaAlbum:(nullable NSString *)mediaAlbum playlistName:(nullable NSString *)playlistName isExplicit:(BOOL)isExplicit trackPlaybackProgress:(UInt32)trackPlaybackProgress trackPlaybackDuration:(UInt32)trackPlaybackDuration queuePlaybackProgess:(UInt32)queuePlaybackProgess queuePlaybackDuration:(UInt32)queuePlaybackDuration queueCurrentTrackNumber:(UInt32)queueCurrentTrackNumber queueTotalTrackCount:(UInt32)queueTotalTrackCount; + /** * The type of the currently playing or paused track. * diff --git a/SmartDeviceLink/SDLMediaServiceData.m b/SmartDeviceLink/SDLMediaServiceData.m index 0a1ef3679..9df7d22be 100644 --- a/SmartDeviceLink/SDLMediaServiceData.m +++ b/SmartDeviceLink/SDLMediaServiceData.m @@ -15,6 +15,28 @@ NS_ASSUME_NONNULL_BEGIN @implementation SDLMediaServiceData +- (instancetype)initWithMediaType:(nullable SDLMediaType)mediaType mediaTitle:(nullable NSString *)mediaTitle mediaArtist:(nullable NSString *)mediaArtist mediaAlbum:(nullable NSString *)mediaAlbum playlistName:(nullable NSString *)playlistName isExplicit:(BOOL)isExplicit trackPlaybackProgress:(UInt32)trackPlaybackProgress trackPlaybackDuration:(UInt32)trackPlaybackDuration queuePlaybackProgess:(UInt32)queuePlaybackProgess queuePlaybackDuration:(UInt32)queuePlaybackDuration queueCurrentTrackNumber:(UInt32)queueCurrentTrackNumber queueTotalTrackCount:(UInt32)queueTotalTrackCount { + self = [self init]; + if (!self) { + return nil; + } + + self.mediaType = mediaType; + self.mediaTitle = mediaTitle; + self.mediaArtist = mediaArtist; + self.mediaAlbum = mediaAlbum; + self.playlistName = playlistName; + self.isExplicit = @(isExplicit); + self.trackPlaybackProgress = @(trackPlaybackProgress); + self.trackPlaybackDuration = @(trackPlaybackDuration); + self.queuePlaybackProgess = @(queuePlaybackProgess); + self.queuePlaybackDuration = @(queuePlaybackDuration); + self.queueCurrentTrackNumber = @(queueCurrentTrackNumber); + self.queueTotalTrackCount = @(queueTotalTrackCount); + + return self; +} + - (void)setMediaType:(nullable SDLMediaType)mediaType { [store sdl_setObject:mediaType forName:SDLNameMediaType]; } diff --git a/SmartDeviceLinkTests/Notifications/SDLNotificationDispatcherSpec.m b/SmartDeviceLinkTests/Notifications/SDLNotificationDispatcherSpec.m index 06fa35e59..be3fa4cb1 100644 --- a/SmartDeviceLinkTests/Notifications/SDLNotificationDispatcherSpec.m +++ b/SmartDeviceLinkTests/Notifications/SDLNotificationDispatcherSpec.m @@ -37,7 +37,7 @@ describe(@"a notification dispatcher", ^{ expect(@([testDispatcher respondsToSelector:@selector(onEndAudioPassThruResponse:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onError:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onGenericResponse:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onGetAppServiceDataRequest:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onGetAppServiceData:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onGetAppServiceDataResponse:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onGetDTCsResponse:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onGetFileResponse:)])).to(beTruthy()); diff --git a/SmartDeviceLinkTests/RPCSpecs/ResponseSpecs/SDLGetAppServiceDataResponseSpec.m b/SmartDeviceLinkTests/RPCSpecs/ResponseSpecs/SDLGetAppServiceDataResponseSpec.m index 41deb72d1..5f722514a 100644 --- a/SmartDeviceLinkTests/RPCSpecs/ResponseSpecs/SDLGetAppServiceDataResponseSpec.m +++ b/SmartDeviceLinkTests/RPCSpecs/ResponseSpecs/SDLGetAppServiceDataResponseSpec.m @@ -42,6 +42,12 @@ describe(@"Getter/Setter Tests", ^{ expect(testResponse.serviceData).to(equal(testAppServiceData)); }); + it(@"Should get correctly when initialized with initWithAppServiceData:", ^{ + SDLGetAppServiceDataResponse *testResponse = [[SDLGetAppServiceDataResponse alloc] initWithAppServiceData:testAppServiceData]; + + expect(testResponse.serviceData).to(equal(testAppServiceData)); + }); + it(@"Should return nil if not set", ^{ SDLGetAppServiceDataResponse *testResponse = [[SDLGetAppServiceDataResponse alloc] init]; diff --git a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLAppServiceDataSpec.m b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLAppServiceDataSpec.m index c9356b7a0..968190832 100644 --- a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLAppServiceDataSpec.m +++ b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLAppServiceDataSpec.m @@ -57,6 +57,15 @@ describe(@"Getter/Setter Tests", ^{ expect(testStruct.weatherServiceData).to(equal(testWeatherServiceData)); }); + it(@"Should get correctly when initialized with initWithServiceType:serviceId:mediaServiceData:weatherServiceData:", ^{ + SDLAppServiceData *testStruct = [[SDLAppServiceData alloc] initWithServiceType:testServiceType serviceId:testServiceId mediaServiceData:testMediaServiceData weatherServiceData:testWeatherServiceData]; + + expect(testStruct.serviceType).to(equal(testServiceType)); + expect(testStruct.serviceId).to(equal(testServiceId)); + expect(testStruct.mediaServiceData).to(equal(testMediaServiceData)); + expect(testStruct.weatherServiceData).to(equal(testWeatherServiceData)); + }); + it(@"Should return nil if not set", ^{ SDLAppServiceData *testStruct = [[SDLAppServiceData alloc] init]; diff --git a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLMediaServiceDataSpec.m b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLMediaServiceDataSpec.m index 9530a179d..dc2731c47 100644 --- a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLMediaServiceDataSpec.m +++ b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLMediaServiceDataSpec.m @@ -97,6 +97,23 @@ describe(@"Getter/Setter Tests", ^{ expect(testStruct.queueTotalTrackCount).to(equal(testQueueTotalTrackCount)); }); + it(@"Should get correctly when initialized with initWithMediaType:mediaTitle:mediaArtist:mediaAlbum:playlistName:isExplicit:trackPlaybackProgress:trackPlaybackDuration:queuePlaybackProgess:queuePlaybackDuration:queueCurrentTrackNumber:queueTotalTrackCount:", ^{ + SDLMediaServiceData *testStruct = [[SDLMediaServiceData alloc] initWithMediaType:testMediaType mediaTitle:testMediaTitle mediaArtist:testMediaArtist mediaAlbum:testMediaAlbum playlistName:testPlaylistName isExplicit:testIsExplicit trackPlaybackProgress:testTrackPlaybackProgress trackPlaybackDuration:testTrackPlaybackDuration queuePlaybackProgess:testQueuePlaybackProgress queuePlaybackDuration:testQueuePlaybackDuration queueCurrentTrackNumber:testQueueCurrentTrackNumber queueTotalTrackCount:testQueueTotalTrackCount]; + + expect(testStruct.mediaType).to(equal(testMediaType)); + expect(testStruct.mediaTitle).to(equal(testMediaTitle)); + expect(testStruct.mediaArtist).to(equal(testMediaArtist)); + expect(testStruct.mediaAlbum).to(equal(testMediaAlbum)); + expect(testStruct.playlistName).to(equal(testPlaylistName)); + expect(testStruct.isExplicit).to(equal(testIsExplicit)); + expect(testStruct.trackPlaybackProgress).to(equal(testTrackPlaybackProgress)); + expect(testStruct.trackPlaybackDuration).to(equal(testTrackPlaybackDuration)); + expect(testStruct.queuePlaybackProgess).to(equal(testQueuePlaybackProgress)); + expect(testStruct.queuePlaybackDuration).to(equal(testQueuePlaybackDuration)); + expect(testStruct.queueCurrentTrackNumber).to(equal(testQueueCurrentTrackNumber)); + expect(testStruct.queueTotalTrackCount).to(equal(testQueueTotalTrackCount)); + }); + it(@"Should return nil if not set", ^{ SDLMediaServiceData *testStruct = [[SDLMediaServiceData alloc] init]; -- cgit v1.2.1 From 1fe58b4044e02e0d99e30dda6f140e4feee8f9be Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 19 Feb 2019 12:01:36 -0500 Subject: Added a convenience init to `OnAppServiceData` RPC --- SmartDeviceLink/SDLOnAppServiceData.h | 11 ++++++++++- SmartDeviceLink/SDLOnAppServiceData.m | 13 +++++++++++++ .../RPCSpecs/NotificationSpecs/SDLOnAppServiceDataSpec.m | 7 +++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLOnAppServiceData.h b/SmartDeviceLink/SDLOnAppServiceData.h index d131b8749..5d2fd2d0d 100644 --- a/SmartDeviceLink/SDLOnAppServiceData.h +++ b/SmartDeviceLink/SDLOnAppServiceData.h @@ -7,7 +7,8 @@ // #import "SDLRPCNotification.h" -#import "SDLAppServiceData.h" + +@class SDLAppServiceData; NS_ASSUME_NONNULL_BEGIN @@ -16,6 +17,14 @@ NS_ASSUME_NONNULL_BEGIN */ @interface SDLOnAppServiceData : SDLRPCNotification +/** + * Convenience init + * + * @param serviceData The updated app service data + * @return A SDLOnAppServiceData object + */ +- (instancetype)initWithServiceData:(SDLAppServiceData *)serviceData; + /** * The updated app service data. * diff --git a/SmartDeviceLink/SDLOnAppServiceData.m b/SmartDeviceLink/SDLOnAppServiceData.m index b58c78a7c..aac381039 100644 --- a/SmartDeviceLink/SDLOnAppServiceData.m +++ b/SmartDeviceLink/SDLOnAppServiceData.m @@ -10,6 +10,8 @@ #import "NSMutableDictionary+Store.h" #import "SDLNames.h" +#import "SDLAppServiceData.h" + NS_ASSUME_NONNULL_BEGIN @implementation SDLOnAppServiceData @@ -20,6 +22,17 @@ NS_ASSUME_NONNULL_BEGIN return self; } +- (instancetype)initWithServiceData:(SDLAppServiceData *)serviceData { + self = [self init]; + if (!self) { + return nil; + } + + self.serviceData = serviceData; + + return self; +} + - (void)setServiceData:(SDLAppServiceData *)serviceData { [parameters sdl_setObject:serviceData forName:SDLNameServiceData]; } diff --git a/SmartDeviceLinkTests/RPCSpecs/NotificationSpecs/SDLOnAppServiceDataSpec.m b/SmartDeviceLinkTests/RPCSpecs/NotificationSpecs/SDLOnAppServiceDataSpec.m index 3ea76689f..6b68be0b9 100644 --- a/SmartDeviceLinkTests/RPCSpecs/NotificationSpecs/SDLOnAppServiceDataSpec.m +++ b/SmartDeviceLinkTests/RPCSpecs/NotificationSpecs/SDLOnAppServiceDataSpec.m @@ -9,6 +9,7 @@ #import #import +#import "SDLAppServiceData.h" #import "SDLOnAppServiceData.h" #import "SDLNames.h" @@ -40,6 +41,12 @@ describe(@"Getter/Setter Tests", ^{ expect(testNotification.serviceData).to(equal(testAppServiceData)); }); + it(@"Should get correctly when initialized with initWithServiceData:", ^{ + SDLOnAppServiceData *testNotification = [[SDLOnAppServiceData alloc] initWithServiceData:testAppServiceData]; + + expect(testNotification.serviceData).to(equal(testAppServiceData)); + }); + it(@"Should return nil if not set", ^{ SDLOnAppServiceData *testNotification = [[SDLOnAppServiceData alloc] init]; -- cgit v1.2.1 From 4943b8f68f9ff3a9231be05c02361ac616902387 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 19 Feb 2019 12:51:23 -0500 Subject: Added a convenience init to `WeatherServiceData` struct --- SmartDeviceLink/SDLWeatherServiceData.h | 15 ++++++++++++++- SmartDeviceLink/SDLWeatherServiceData.m | 16 ++++++++++++++++ .../RPCSpecs/StructSpecs/SDLWeatherServiceDataSpec.m | 11 +++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLWeatherServiceData.h b/SmartDeviceLink/SDLWeatherServiceData.h index cb09c5f24..f9b953816 100644 --- a/SmartDeviceLink/SDLWeatherServiceData.h +++ b/SmartDeviceLink/SDLWeatherServiceData.h @@ -19,6 +19,19 @@ NS_ASSUME_NONNULL_BEGIN */ @interface SDLWeatherServiceData : SDLRPCStruct +/** + * Convenience init. + * + * @param location The location + * @param currentForecast The current forecast + * @param minuteForecast A minute-by-minute array of forecasts + * @param hourlyForecast An hour-by-hour array of forecasts + * @param multidayForecast A day-by-day array of forecasts + * @param alerts An array of weather alerts + * @return A SDLWeatherServiceData object + */ +- (instancetype)initWithLocation:(SDLLocationDetails *)location currentForecast:(nullable SDLWeatherData *)currentForecast minuteForecast:(nullable NSArray *)minuteForecast hourlyForecast:(NSArray *)hourlyForecast multidayForecast:(nullable NSArray *)multidayForecast alerts:(NSArray *)alerts; + /** * The location. * @@ -48,7 +61,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nullable, strong, nonatomic) NSArray *hourlyForecast; /** - * An day-by-day array of forecasts. + * A day-by-day array of forecasts. * * Array of SDLWeatherData, Optional, minsize="1" maxsize="30" */ diff --git a/SmartDeviceLink/SDLWeatherServiceData.m b/SmartDeviceLink/SDLWeatherServiceData.m index 785a7f990..2932c1688 100644 --- a/SmartDeviceLink/SDLWeatherServiceData.m +++ b/SmartDeviceLink/SDLWeatherServiceData.m @@ -15,6 +15,22 @@ NS_ASSUME_NONNULL_BEGIN @implementation SDLWeatherServiceData +- (instancetype)initWithLocation:(SDLLocationDetails *)location currentForecast:(nullable SDLWeatherData *)currentForecast minuteForecast:(nullable NSArray *)minuteForecast hourlyForecast:(NSArray *)hourlyForecast multidayForecast:(nullable NSArray *)multidayForecast alerts:(NSArray *)alerts { + self = [self init]; + if (!self) { + return nil; + } + + self.location = location; + self.currentForecast = currentForecast; + self.minuteForecast = minuteForecast; + self.hourlyForecast = hourlyForecast; + self.multidayForecast = multidayForecast; + self.alerts = alerts; + + return self; +} + - (void)setLocation:(SDLLocationDetails *)location { [store sdl_setObject:location forName:SDLNameLocation]; } diff --git a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLWeatherServiceDataSpec.m b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLWeatherServiceDataSpec.m index 7b896ca28..530b516de 100644 --- a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLWeatherServiceDataSpec.m +++ b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLWeatherServiceDataSpec.m @@ -76,6 +76,17 @@ describe(@"Getter/Setter Tests", ^{ expect(testStruct.alerts).to(equal(testAlerts)); }); + it(@"Should get correctly when initialized with initWithLocation:currentForecast:currentForecast minuteForecast:hourlyForecast:multidayForecast:alerts:", ^{ + SDLWeatherServiceData *testStruct = [[SDLWeatherServiceData alloc] initWithLocation:testLocation currentForecast:testCurrentForecast minuteForecast:testMinuteForecast hourlyForecast:testHourlyForecast multidayForecast:testMultidayForecast alerts:testAlerts]; + + expect(testStruct.location).to(equal(testLocation)); + expect(testStruct.currentForecast).to(equal(testCurrentForecast)); + expect(testStruct.minuteForecast).to(equal(testMinuteForecast)); + expect(testStruct.hourlyForecast).to(equal(testHourlyForecast)); + expect(testStruct.multidayForecast).to(equal(testMultidayForecast)); + expect(testStruct.alerts).to(equal(testAlerts)); + }); + it(@"Should return nil if not set", ^{ SDLWeatherServiceData *testStruct = [[SDLWeatherServiceData alloc] init]; -- cgit v1.2.1 From b459bd9a75a4d483f599fa0e76c48c9a7c5accfc Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 19 Feb 2019 15:52:31 -0500 Subject: reverted edits to AsynchronousRPCRequestOperation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * reverted uneeded changes made to `SDLAsynchronousRPCRequestOperation` * reverted changes made to `SDLLifecycleManager`’s `sendRequest` --- .../SDLAsynchronousRPCRequestOperation.h | 13 ++------ .../SDLAsynchronousRPCRequestOperation.m | 39 ++++++++-------------- SmartDeviceLink/SDLLifecycleManager.m | 17 +++++++--- 3 files changed, 28 insertions(+), 41 deletions(-) diff --git a/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.h b/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.h index c69185a41..fb486f315 100644 --- a/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.h +++ b/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.h @@ -11,23 +11,13 @@ #import "SDLAsynchronousOperation.h" #import "SDLLifecycleManager.h" -@class SDLRPCMessage; - @protocol SDLConnectionManagerType; NS_ASSUME_NONNULL_BEGIN @interface SDLAsynchronousRPCRequestOperation : SDLAsynchronousOperation -//@property (copy, nonatomic) NSArray *requests; -@property (copy, nonatomic) NSArray<__kindof SDLRPCMessage *> *rpcs; - -// TODO: NEW -- (instancetype)initWithConnectionManager:(id)connectionManager rpc:(__kindof SDLRPCMessage *)rpc responseHandler:(nullable SDLResponseHandler)responseHandler; - -- (instancetype)initWithConnectionManager:(id)connectionManager rpcs:(NSArray<__kindof SDLRPCMessage *> *)rpcs progressHandler:(nullable SDLMultipleAsyncRequestProgressHandler)progressHandler completionHandler:(nullable SDLMultipleRequestCompletionHandler)completionHandler; - -//// +@property (copy, nonatomic) NSArray *requests; - (instancetype)initWithConnectionManager:(id)connectionManager requests:(NSArray *)requests progressHandler:(nullable SDLMultipleAsyncRequestProgressHandler)progressHandler completionHandler:(nullable SDLMultipleRequestCompletionHandler)completionHandler; @@ -36,3 +26,4 @@ NS_ASSUME_NONNULL_BEGIN @end NS_ASSUME_NONNULL_END + diff --git a/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m b/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m index e8843d8c8..5e7ba5dce 100644 --- a/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m +++ b/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m @@ -11,8 +11,6 @@ #import "SDLConnectionManagerType.h" #import "SDLError.h" #import "SDLGlobals.h" -#import "SDLRPCMessage.h" -#import "SDLRPCRequest.h" NS_ASSUME_NONNULL_BEGIN @@ -51,35 +49,27 @@ NS_ASSUME_NONNULL_BEGIN return self; } -- (instancetype)initWithConnectionManager:(id)connectionManager rpcs:(NSArray<__kindof SDLRPCMessage *> *)rpcs progressHandler:(nullable SDLMultipleAsyncRequestProgressHandler)progressHandler completionHandler:(nullable SDLMultipleRequestCompletionHandler)completionHandler { +- (instancetype)initWithConnectionManager:(id)connectionManager requests:(NSArray *)requests progressHandler:(nullable SDLMultipleAsyncRequestProgressHandler)progressHandler completionHandler:(nullable SDLMultipleRequestCompletionHandler)completionHandler { self = [self init]; _connectionManager = connectionManager; - _rpcs = rpcs; + _requests = requests; _progressHandler = progressHandler; _completionHandler = completionHandler; return self; } -- (instancetype)initWithConnectionManager:(id)connectionManager rpc:(__kindof SDLRPCMessage *)rpc responseHandler:(nullable SDLResponseHandler)responseHandler { +- (instancetype)initWithConnectionManager:(id)connectionManager request:(SDLRPCRequest *)request responseHandler:(nullable SDLResponseHandler)responseHandler { self = [self init]; _connectionManager = connectionManager; - _rpcs = @[rpc]; + _requests = @[request]; _responseHandler = responseHandler; return self; } -- (instancetype)initWithConnectionManager:(id)connectionManager requests:(NSArray *)requests progressHandler:(nullable SDLMultipleAsyncRequestProgressHandler)progressHandler completionHandler:(nullable SDLMultipleRequestCompletionHandler)completionHandler { - return [self initWithConnectionManager:connectionManager rpcs:requests progressHandler:progressHandler completionHandler:completionHandler]; -} - -- (instancetype)initWithConnectionManager:(id)connectionManager request:(SDLRPCRequest *)request responseHandler:(nullable SDLResponseHandler)responseHandler { - return [self initWithConnectionManager:connectionManager rpc:request responseHandler:responseHandler]; -} - - (void)start { [super start]; @@ -87,9 +77,8 @@ NS_ASSUME_NONNULL_BEGIN } - (void)sdl_sendRequests { - for (id request in self.rpcs) { + for (SDLRPCRequest *request in self.requests) { if (self.isCancelled) { - // FIXME: Deal with aborted responses [self sdl_abortOperationWithRequest:request]; return; } @@ -99,7 +88,7 @@ NS_ASSUME_NONNULL_BEGIN } } -- (void)sdl_sendRequest:(__kindof SDLRPCMessage *)request { +- (void)sdl_sendRequest:(SDLRPCRequest *)request { __weak typeof(self) weakSelf = self; [self.connectionManager sendConnectionRequest:request withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) { __strong typeof(self) strongSelf = weakSelf; @@ -123,7 +112,7 @@ NS_ASSUME_NONNULL_BEGIN } // If we've received responses for all requests, call the completion handler. - if (strongSelf.requestsComplete >= strongSelf.rpcs.count) { + if (strongSelf.requestsComplete >= strongSelf.requests.count) { [strongSelf finishOperation]; } }]; @@ -132,12 +121,9 @@ NS_ASSUME_NONNULL_BEGIN - (void)sdl_abortOperationWithRequest:(SDLRPCRequest *)request { self.requestFailed = YES; - for (NSUInteger i = self.requestsComplete; i < self.rpcs.count; i++) { + for (NSUInteger i = self.requestsComplete; i < self.requests.count; i++) { if (self.progressHandler != NULL) { - id rpc = self.rpcs[i]; - SDLRPCRequest *abortedRequest = [rpc isMemberOfClass:[SDLRPCRequest class]] ? (SDLRPCRequest *)rpc : nil; - // FIXME: first param is not nullable - self.progressHandler(abortedRequest, nil, [NSError sdl_lifecycle_multipleRequestsCancelled], self.percentComplete); + self.progressHandler(self.requests[i], nil, [NSError sdl_lifecycle_multipleRequestsCancelled], self.percentComplete); } if (self.responseHandler != NULL) { @@ -155,7 +141,7 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark - Getters - (float)percentComplete { - return (float)self.requestsComplete / (float)self.rpcs.count; + return (float)self.requestsComplete / (float)self.requests.count; } #pragma mark - Property Overrides @@ -177,13 +163,14 @@ NS_ASSUME_NONNULL_BEGIN } - (NSString *)description { - return [NSString stringWithFormat:@"%@, request count=%lu, requests started=%lu, finished=%lu, failed=%@", self.name, (unsigned long)self.rpcs.count, (unsigned long)self.requestsStarted, (unsigned long)self.requestsComplete, (self.requestFailed ? @"YES": @"NO")]; + return [NSString stringWithFormat:@"%@, request count=%lu, requests started=%lu, finished=%lu, failed=%@", self.name, (unsigned long)self.requests.count, (unsigned long)self.requestsStarted, (unsigned long)self.requestsComplete, (self.requestFailed ? @"YES": @"NO")]; } - (NSString *)debugDescription { - return [NSString stringWithFormat:@"%@, request count=%lu, requests started=%lu, finished=%lu, failed=%@, requests=%@", self.name, (unsigned long)self.rpcs.count, (unsigned long)self.requestsStarted, (unsigned long)self.requestsComplete, (self.requestFailed ? @"YES": @"NO"), self.rpcs]; + return [NSString stringWithFormat:@"%@, request count=%lu, requests started=%lu, finished=%lu, failed=%@, requests=%@", self.name, (unsigned long)self.requests.count, (unsigned long)self.requestsStarted, (unsigned long)self.requestsComplete, (self.requestFailed ? @"YES": @"NO"), self.requests]; } @end NS_ASSUME_NONNULL_END + diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m index 1e20d8e5c..a543cf890 100644 --- a/SmartDeviceLink/SDLLifecycleManager.m +++ b/SmartDeviceLink/SDLLifecycleManager.m @@ -521,12 +521,21 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; #pragma mark Sending Requests - (void)sendRequest:(__kindof SDLRPCMessage *)request { - [self sendRequest:request withResponseHandler:nil]; + // Add a correlation ID to the request + if ([request isKindOfClass:[SDLRPCRequest class]]) { + SDLRPCRequest *requestRPC = (SDLRPCRequest *)request; + [self sendRequest:requestRPC withResponseHandler:nil]; + } else if ([request isKindOfClass:[SDLRPCResponse class]] || [request isKindOfClass:[SDLRPCNotification class]]) { + + } else { + SDLLogE(@"Sending an unknown RPC type. The request should be of type request, response or notification"); + } + + // [self sendRequest:request withResponseHandler:nil]; } -- (void)sendRequest:(__kindof SDLRPCMessage *)request withResponseHandler:(nullable SDLResponseHandler)handler { - SDLAsynchronousRPCRequestOperation *op = [[SDLAsynchronousRPCRequestOperation alloc] initWithConnectionManager:self rpc:request responseHandler:handler]; -// SDLAsynchronousRPCRequestOperation *op = [[SDLAsynchronousRPCRequestOperation alloc] initWithConnectionManager:self request:request responseHandler:handler]; +- (void)sendRequest:(SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler { + SDLAsynchronousRPCRequestOperation *op = [[SDLAsynchronousRPCRequestOperation alloc] initWithConnectionManager:self request:request responseHandler:handler]; [self.rpcOperationQueue addOperation:op]; } -- cgit v1.2.1 From 3daeaf14894e2da0ac47cf563f1cd269d3efcb76 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Wed, 20 Feb 2019 10:56:35 -0500 Subject: Fixed sending multiple responses/notifications not working Can now send response + notifications via the `SDLAsynchronousRPCRequestOperation` without expecting response. Since responses and notifications sent from the library do not get a response from Core, the operation queue stopped sending RPCs when it did not get responses. --- .../SDLAsynchronousRPCRequestOperation.h | 7 ++-- .../SDLAsynchronousRPCRequestOperation.m | 14 +++++--- SmartDeviceLink/SDLLifecycleManager.m | 39 +++++++++++----------- 3 files changed, 33 insertions(+), 27 deletions(-) diff --git a/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.h b/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.h index fb486f315..6872ca093 100644 --- a/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.h +++ b/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.h @@ -17,13 +17,12 @@ NS_ASSUME_NONNULL_BEGIN @interface SDLAsynchronousRPCRequestOperation : SDLAsynchronousOperation -@property (copy, nonatomic) NSArray *requests; +@property (copy, nonatomic) NSArray<__kindof SDLRPCMessage *> *requests; -- (instancetype)initWithConnectionManager:(id)connectionManager requests:(NSArray *)requests progressHandler:(nullable SDLMultipleAsyncRequestProgressHandler)progressHandler completionHandler:(nullable SDLMultipleRequestCompletionHandler)completionHandler; +- (instancetype)initWithConnectionManager:(id)connectionManager requests:(NSArray<__kindof SDLRPCMessage *> *)requests progressHandler:(nullable SDLMultipleAsyncRequestProgressHandler)progressHandler completionHandler:(nullable SDLMultipleRequestCompletionHandler)completionHandler; -- (instancetype)initWithConnectionManager:(id)connectionManager request:(SDLRPCRequest *)request responseHandler:(nullable SDLResponseHandler)responseHandler; +- (instancetype)initWithConnectionManager:(id)connectionManager request:(__kindof SDLRPCMessage *)request responseHandler:(nullable SDLResponseHandler)responseHandler; @end NS_ASSUME_NONNULL_END - diff --git a/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m b/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m index 5e7ba5dce..d2cde0f6d 100644 --- a/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m +++ b/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m @@ -11,6 +11,7 @@ #import "SDLConnectionManagerType.h" #import "SDLError.h" #import "SDLGlobals.h" +#import "SDLRPCRequest.h" NS_ASSUME_NONNULL_BEGIN @@ -49,7 +50,7 @@ NS_ASSUME_NONNULL_BEGIN return self; } -- (instancetype)initWithConnectionManager:(id)connectionManager requests:(NSArray *)requests progressHandler:(nullable SDLMultipleAsyncRequestProgressHandler)progressHandler completionHandler:(nullable SDLMultipleRequestCompletionHandler)completionHandler { +- (instancetype)initWithConnectionManager:(id)connectionManager requests:(NSArray<__kindof SDLRPCMessage *> *)requests progressHandler:(nullable SDLMultipleAsyncRequestProgressHandler)progressHandler completionHandler:(nullable SDLMultipleRequestCompletionHandler)completionHandler { self = [self init]; _connectionManager = connectionManager; @@ -60,7 +61,7 @@ NS_ASSUME_NONNULL_BEGIN return self; } -- (instancetype)initWithConnectionManager:(id)connectionManager request:(SDLRPCRequest *)request responseHandler:(nullable SDLResponseHandler)responseHandler { +- (instancetype)initWithConnectionManager:(id)connectionManager request:(__kindof SDLRPCMessage *)request responseHandler:(nullable SDLResponseHandler)responseHandler { self = [self init]; _connectionManager = connectionManager; @@ -122,8 +123,14 @@ NS_ASSUME_NONNULL_BEGIN self.requestFailed = YES; for (NSUInteger i = self.requestsComplete; i < self.requests.count; i++) { + if (![self.requests[i] isKindOfClass:[SDLRPCRequest class]]) { + // Responses and notifications sent to Core do not get responses from Core + continue; + } + if (self.progressHandler != NULL) { - self.progressHandler(self.requests[i], nil, [NSError sdl_lifecycle_multipleRequestsCancelled], self.percentComplete); + SDLRPCRequest *sentRequest = (SDLRPCRequest *)self.requests[i]; + self.progressHandler(sentRequest, nil, [NSError sdl_lifecycle_multipleRequestsCancelled], self.percentComplete); } if (self.responseHandler != NULL) { @@ -173,4 +180,3 @@ NS_ASSUME_NONNULL_BEGIN @end NS_ASSUME_NONNULL_END - diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m index a543cf890..12a458534 100644 --- a/SmartDeviceLink/SDLLifecycleManager.m +++ b/SmartDeviceLink/SDLLifecycleManager.m @@ -528,7 +528,7 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; } else if ([request isKindOfClass:[SDLRPCResponse class]] || [request isKindOfClass:[SDLRPCNotification class]]) { } else { - SDLLogE(@"Sending an unknown RPC type. The request should be of type request, response or notification"); + SDLLogE(@"Attempting to send an RPC with unknown type. The request should be of type request, response or notification. Returning..."); } // [self sendRequest:request withResponseHandler:nil]; @@ -564,7 +564,11 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; SDLLogW(@"Manager not ready, message not sent (%@)", request); if (handler) { dispatch_async(dispatch_get_main_queue(), ^{ - handler(request, nil, [NSError sdl_lifecycle_notReadyError]); + if ([request isKindOfClass:[SDLRPCRequest class]]) { + handler(request, nil, [NSError sdl_lifecycle_notReadyError]); + } else { + handler(nil, nil, [NSError sdl_lifecycle_notReadyError]); + } }); } @@ -599,24 +603,21 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; return; } - // Add a correlation ID to the request - SDLRPCRequest *test = [request isKindOfClass:[SDLRPCRequest class]] ? (SDLRPCRequest *)request : nil; - if (test != nil) { + if ([request isKindOfClass:[SDLRPCRequest class]]) { + // Generate and add a correlation ID to the request. When a response for the request is returned from Core, it will have the same correlation ID + SDLRPCRequest *requestRPC = (SDLRPCRequest *)request; NSNumber *corrID = [self sdl_getNextCorrelationId]; - test.correlationID = corrID; - - [self.responseDispatcher storeRequest:test handler:handler]; - [self.proxy sendRPC:test]; - } - - SDLRPCResponse *testResponse = [request isKindOfClass:[SDLRPCResponse class]] ? (SDLRPCResponse *)request : nil; - if (testResponse != nil) { - [self.proxy sendRPC:testResponse]; - } - - SDLRPCNotification *testNotification = [request isKindOfClass:[SDLRPCNotification class]] ? (SDLRPCNotification *)request : nil; - if (testNotification != nil) { - [self.proxy sendRPC:testNotification]; + requestRPC.correlationID = corrID; + [self.responseDispatcher storeRequest:requestRPC handler:handler]; + [self.proxy sendRPC:requestRPC]; + } else if ([request isKindOfClass:[SDLRPCResponse class]] || [request isKindOfClass:[SDLRPCNotification class]]) { + [self.proxy sendRPC:request]; + if (handler) { + // Responses and notifications sent to Core do not get a response from Core so just call the handler + handler(nil, nil, nil); + } + } else { + SDLLogE(@"Attempting to send an RPC with unknown type. The request should be of type request, response or notification. Returning..."); } } -- cgit v1.2.1 From 7a547b239d00db587f6f3798d1e6c2a815544740 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Thu, 21 Feb 2019 13:36:10 -0500 Subject: `SDLManager` can now send non-requests * Added test cases to `SDLLifecyceManagerSpec` --- SmartDeviceLink-iOS.xcodeproj/project.pbxproj | 12 +++ .../SDLAsynchronousRPCRequestOperation.h | 6 +- .../SDLAsynchronousRPCRequestOperation.m | 13 +-- SmartDeviceLink/SDLConnectionManagerType.h | 28 ++++++- SmartDeviceLink/SDLLifecycleManager.m | 37 ++++----- SmartDeviceLink/SDLManager.h | 6 ++ SmartDeviceLink/SDLRPCResponseOperation.h | 26 ++++++ SmartDeviceLink/SDLRPCResponseOperation.m | 88 ++++++++++++++++++++ .../DevAPISpecs/SDLLifecycleManagerSpec.m | 44 +++++++++- SmartDeviceLinkTests/SDLRPCResponseOperationSpec.m | 95 ++++++++++++++++++++++ .../TestUtilities/TestConnectionManager.h | 2 +- .../TestUtilities/TestConnectionManager.m | 8 +- 12 files changed, 323 insertions(+), 42 deletions(-) create mode 100644 SmartDeviceLink/SDLRPCResponseOperation.h create mode 100644 SmartDeviceLink/SDLRPCResponseOperation.m create mode 100644 SmartDeviceLinkTests/SDLRPCResponseOperationSpec.m diff --git a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj index db18cbcd3..c47b31f37 100644 --- a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj +++ b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj @@ -1282,6 +1282,8 @@ 88802FF520853CD500E9EBC6 /* SmartDeviceLinkSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 88802FEF20853AE600E9EBC6 /* SmartDeviceLinkSwift.framework */; }; 88802FF620853CD500E9EBC6 /* SmartDeviceLinkSwift.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 88802FEF20853AE600E9EBC6 /* SmartDeviceLinkSwift.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 8886EB982111F4FA008294A5 /* SDLFileManagerConfigurationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 8886EB972111F4FA008294A5 /* SDLFileManagerConfigurationSpec.m */; }; + 888F86FE221DEE200052FE4C /* SDLRPCResponseOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 888F86FD221DEE1F0052FE4C /* SDLRPCResponseOperation.m */; }; + 888F8700221DF4880052FE4C /* SDLRPCResponseOperationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 888F86FF221DF4880052FE4C /* SDLRPCResponseOperationSpec.m */; }; 88A1CF1E21669AC7001ACC75 /* SDLLifecycleConfigurationUpdateSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 88A1CF1D21669AC7001ACC75 /* SDLLifecycleConfigurationUpdateSpec.m */; }; 88A5E7F4220B57F900495E8A /* SDLOnSystemCapabilityUpdatedSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 88A5E7F3220B57F900495E8A /* SDLOnSystemCapabilityUpdatedSpec.m */; }; 88A5E7F7220B5BBC00495E8A /* SDLGetAppServiceData.h in Headers */ = {isa = PBXBuildFile; fileRef = 88A5E7F5220B5BBC00495E8A /* SDLGetAppServiceData.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -1334,6 +1336,7 @@ 88F65133220C6DC300CAF321 /* SDLWeatherAlertSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 88F65132220C6DC300CAF321 /* SDLWeatherAlertSpec.m */; }; 88F65136220C74FD00CAF321 /* SDLWeatherData.h in Headers */ = {isa = PBXBuildFile; fileRef = 88F65134220C74FD00CAF321 /* SDLWeatherData.h */; settings = {ATTRIBUTES = (Public, ); }; }; 88F65137220C74FD00CAF321 /* SDLWeatherData.m in Sources */ = {isa = PBXBuildFile; fileRef = 88F65135220C74FD00CAF321 /* SDLWeatherData.m */; }; + 88F89103221DE29A00E056AD /* SDLRPCResponseOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 88F89101221DE29A00E056AD /* SDLRPCResponseOperation.h */; }; 88FF4E762215FB8200A71361 /* SDLRPCRequestNotification.h in Headers */ = {isa = PBXBuildFile; fileRef = 88FF4E742215FB8200A71361 /* SDLRPCRequestNotification.h */; settings = {ATTRIBUTES = (Public, ); }; }; 88FF4E772215FB8200A71361 /* SDLRPCRequestNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = 88FF4E752215FB8200A71361 /* SDLRPCRequestNotification.m */; }; 88FF4E7C2215FEEA00A71361 /* SDLRPCRequestNotificationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 88FF4E7B2215FEEA00A71361 /* SDLRPCRequestNotificationSpec.m */; }; @@ -2857,6 +2860,8 @@ 8877F5F01F34AA2D00DC128A /* SDLSendHapticDataResponseSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLSendHapticDataResponseSpec.m; sourceTree = ""; }; 88802FEF20853AE600E9EBC6 /* SmartDeviceLinkSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SmartDeviceLinkSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 8886EB972111F4FA008294A5 /* SDLFileManagerConfigurationSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLFileManagerConfigurationSpec.m; sourceTree = ""; }; + 888F86FD221DEE1F0052FE4C /* SDLRPCResponseOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLRPCResponseOperation.m; sourceTree = ""; }; + 888F86FF221DF4880052FE4C /* SDLRPCResponseOperationSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLRPCResponseOperationSpec.m; sourceTree = ""; }; 88A1CF1D21669AC7001ACC75 /* SDLLifecycleConfigurationUpdateSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLLifecycleConfigurationUpdateSpec.m; sourceTree = ""; }; 88A5E7F3220B57F900495E8A /* SDLOnSystemCapabilityUpdatedSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLOnSystemCapabilityUpdatedSpec.m; sourceTree = ""; }; 88A5E7F5220B5BBC00495E8A /* SDLGetAppServiceData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLGetAppServiceData.h; sourceTree = ""; }; @@ -2911,6 +2916,7 @@ 88F65132220C6DC300CAF321 /* SDLWeatherAlertSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLWeatherAlertSpec.m; sourceTree = ""; }; 88F65134220C74FD00CAF321 /* SDLWeatherData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLWeatherData.h; sourceTree = ""; }; 88F65135220C74FD00CAF321 /* SDLWeatherData.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLWeatherData.m; sourceTree = ""; }; + 88F89101221DE29A00E056AD /* SDLRPCResponseOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLRPCResponseOperation.h; sourceTree = ""; }; 88FF4E742215FB8200A71361 /* SDLRPCRequestNotification.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLRPCRequestNotification.h; sourceTree = ""; }; 88FF4E752215FB8200A71361 /* SDLRPCRequestNotification.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLRPCRequestNotification.m; sourceTree = ""; }; 88FF4E7B2215FEEA00A71361 /* SDLRPCRequestNotificationSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLRPCRequestNotificationSpec.m; sourceTree = ""; }; @@ -3564,6 +3570,8 @@ 5D07C0302044AD0C00D1ECDC /* SDLAsynchronousRPCRequestOperation.m */, 5D07C02B2044AC9000D1ECDC /* SDLSequentialRPCRequestOperation.h */, 5D07C02C2044AC9100D1ECDC /* SDLSequentialRPCRequestOperation.m */, + 88F89101221DE29A00E056AD /* SDLRPCResponseOperation.h */, + 888F86FD221DEE1F0052FE4C /* SDLRPCResponseOperation.m */, ); name = "Request Operations"; sourceTree = ""; @@ -3640,6 +3648,7 @@ 5D60DF23202B7A80001EDA01 /* SDLAsynchronousRPCRequestOperationSpec.m */, 5D60DF25202B7A97001EDA01 /* SDLSequentialRPCRequestOperationSpec.m */, 88A1CF1D21669AC7001ACC75 /* SDLLifecycleConfigurationUpdateSpec.m */, + 888F86FF221DF4880052FE4C /* SDLRPCResponseOperationSpec.m */, ); name = Lifecycle; sourceTree = ""; @@ -6374,6 +6383,7 @@ 5D61FCBF1A84238C00846EE7 /* SDLHexUtility.h in Headers */, 5D00AC6B1F141339004000D9 /* SDLSystemCapability.h in Headers */, 5DCD7AE01FCCA8D200A0FC7F /* SDLCarWindow.h in Headers */, + 88F89103221DE29A00E056AD /* SDLRPCResponseOperation.h in Headers */, 5D61FD6F1A84238C00846EE7 /* SDLRPCPayload.h in Headers */, 5D339CF3207C0ACE000CC364 /* SDLMenuManager.h in Headers */, 5D61FCF01A84238C00846EE7 /* SDLLockScreenStatusManager.h in Headers */, @@ -6725,6 +6735,7 @@ 5D61FE101A84238C00846EE7 /* SDLVrHelpItem.m in Sources */, 5D07C0322044AD0C00D1ECDC /* SDLAsynchronousRPCRequestOperation.m in Sources */, 1E5AD0691F2080B50029B8AF /* SDLRadioControlData.m in Sources */, + 888F86FE221DEE200052FE4C /* SDLRPCResponseOperation.m in Sources */, 5D61FCC01A84238C00846EE7 /* SDLHexUtility.m in Sources */, 5DB9964F1F26886C002D8795 /* SDLControlFramePayloadEndService.m in Sources */, 5D61FD821A84238C00846EE7 /* SDLSetAppIconResponse.m in Sources */, @@ -7132,6 +7143,7 @@ 5D6EB4CC1BF28DC600693731 /* NSMapTable+SubscriptingSpec.m in Sources */, 162E83051A9BDE8B00906325 /* SDLVehicleDataActiveStatusSpec.m in Sources */, 162E82E61A9BDE8B00906325 /* SDLInteractionModeSpec.m in Sources */, + 888F8700221DF4880052FE4C /* SDLRPCResponseOperationSpec.m in Sources */, 162E83931A9BDE8B00906325 /* SDLTouchEventSpec.m in Sources */, 5DCF76FE1ACDDB5A00BB647B /* SDLSendLocationResponseSpec.m in Sources */, 162E837D1A9BDE8B00906325 /* SDLEmergencyEventSpec.m in Sources */, diff --git a/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.h b/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.h index 6872ca093..a24165dad 100644 --- a/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.h +++ b/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.h @@ -17,11 +17,11 @@ NS_ASSUME_NONNULL_BEGIN @interface SDLAsynchronousRPCRequestOperation : SDLAsynchronousOperation -@property (copy, nonatomic) NSArray<__kindof SDLRPCMessage *> *requests; +@property (copy, nonatomic) NSArray *requests; -- (instancetype)initWithConnectionManager:(id)connectionManager requests:(NSArray<__kindof SDLRPCMessage *> *)requests progressHandler:(nullable SDLMultipleAsyncRequestProgressHandler)progressHandler completionHandler:(nullable SDLMultipleRequestCompletionHandler)completionHandler; +- (instancetype)initWithConnectionManager:(id)connectionManager requests:(NSArray *)requests progressHandler:(nullable SDLMultipleAsyncRequestProgressHandler)progressHandler completionHandler:(nullable SDLMultipleRequestCompletionHandler)completionHandler; -- (instancetype)initWithConnectionManager:(id)connectionManager request:(__kindof SDLRPCMessage *)request responseHandler:(nullable SDLResponseHandler)responseHandler; +- (instancetype)initWithConnectionManager:(id)connectionManager request:(SDLRPCRequest *)request responseHandler:(nullable SDLResponseHandler)responseHandler; @end diff --git a/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m b/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m index d2cde0f6d..5c67e3e8a 100644 --- a/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m +++ b/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m @@ -11,7 +11,6 @@ #import "SDLConnectionManagerType.h" #import "SDLError.h" #import "SDLGlobals.h" -#import "SDLRPCRequest.h" NS_ASSUME_NONNULL_BEGIN @@ -50,7 +49,7 @@ NS_ASSUME_NONNULL_BEGIN return self; } -- (instancetype)initWithConnectionManager:(id)connectionManager requests:(NSArray<__kindof SDLRPCMessage *> *)requests progressHandler:(nullable SDLMultipleAsyncRequestProgressHandler)progressHandler completionHandler:(nullable SDLMultipleRequestCompletionHandler)completionHandler { +- (instancetype)initWithConnectionManager:(id)connectionManager requests:(NSArray *)requests progressHandler:(nullable SDLMultipleAsyncRequestProgressHandler)progressHandler completionHandler:(nullable SDLMultipleRequestCompletionHandler)completionHandler { self = [self init]; _connectionManager = connectionManager; @@ -61,7 +60,7 @@ NS_ASSUME_NONNULL_BEGIN return self; } -- (instancetype)initWithConnectionManager:(id)connectionManager request:(__kindof SDLRPCMessage *)request responseHandler:(nullable SDLResponseHandler)responseHandler { +- (instancetype)initWithConnectionManager:(id)connectionManager request:(SDLRPCRequest *)request responseHandler:(nullable SDLResponseHandler)responseHandler { self = [self init]; _connectionManager = connectionManager; @@ -123,14 +122,8 @@ NS_ASSUME_NONNULL_BEGIN self.requestFailed = YES; for (NSUInteger i = self.requestsComplete; i < self.requests.count; i++) { - if (![self.requests[i] isKindOfClass:[SDLRPCRequest class]]) { - // Responses and notifications sent to Core do not get responses from Core - continue; - } - if (self.progressHandler != NULL) { - SDLRPCRequest *sentRequest = (SDLRPCRequest *)self.requests[i]; - self.progressHandler(sentRequest, nil, [NSError sdl_lifecycle_multipleRequestsCancelled], self.percentComplete); + self.progressHandler(self.requests[i], nil, [NSError sdl_lifecycle_multipleRequestsCancelled], self.percentComplete); } if (self.responseHandler != NULL) { diff --git a/SmartDeviceLink/SDLConnectionManagerType.h b/SmartDeviceLink/SDLConnectionManagerType.h index f7052f67d..84a30a404 100644 --- a/SmartDeviceLink/SDLConnectionManagerType.h +++ b/SmartDeviceLink/SDLConnectionManagerType.h @@ -10,6 +10,7 @@ #import @class SDLRPCRequest; +@class SDLRPCMessage; @class SDLRegisterAppInterfaceResponse; @@ -26,15 +27,36 @@ NS_ASSUME_NONNULL_BEGIN - (void)sendConnectionManagerRequest:(__kindof SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler; /** - Send an RPC without bypassing the block on RPC sends before managers complete setup. + * Sends an RPC of type `Request`, `Response` or `Notification` without bypassing the block on RPC sends before managers complete setup. + * + * @param rpc An RPC of type `SDLRPCRequest`, `SDLRPCResponse`, or `SDLRPCNotification` + */ +- (void)sendConnectionRPC:(__kindof SDLRPCMessage *)rpc; - @param request The RPC request to be sent to the remote head unit. - @param handler A completion block called when the response is received. +/** + * Sends an RPC of type `SDLRPCRequest` without bypassing the block on RPC sends before managers complete setup. + * + * @param request The RPC request to be sent to the remote head unit. + * @param handler A completion block called when the response is received. */ - (void)sendConnectionRequest:(__kindof SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler; +/** + * Sends an array of RPCs of type `Request` asynchronously. The requests are sent without bypassing the block on RPC sends before managers complete setup. + * + * @param requests An array of RPCs of type `Request` + * @param progressHandler The progress handler is called as each request gets a response from Core. + * @param completionHandler The completion handler is called when all requests have a response from Core. + */ - (void)sendRequests:(NSArray *)requests progressHandler:(nullable SDLMultipleAsyncRequestProgressHandler)progressHandler completionHandler:(nullable SDLMultipleRequestCompletionHandler)completionHandler; +/** + * Sends an array of RPCs of type `Request` sequentially. The requests are sent without bypassing the block on RPC sends before managers complete setup. + * + * @param requests An array of RPCs of type `Request` + * @param progressHandler The progress handler is called as each request gets a response from Core. + * @param completionHandler The completion handler is called when all requests have a response from Core. + */ - (void)sendSequentialRequests:(NSArray *)requests progressHandler:(nullable SDLMultipleSequentialRequestProgressHandler)progressHandler completionHandler:(nullable SDLMultipleRequestCompletionHandler)completionHandler; @end diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m index 12a458534..037e06865 100644 --- a/SmartDeviceLink/SDLLifecycleManager.m +++ b/SmartDeviceLink/SDLLifecycleManager.m @@ -43,6 +43,7 @@ #import "SDLRegisterAppInterface.h" #import "SDLRegisterAppInterfaceResponse.h" #import "SDLResponseDispatcher.h" +#import "SDLRPCResponseOperation.h" #import "SDLResult.h" #import "SDLScreenManager.h" #import "SDLSecondaryTransportManager.h" @@ -521,17 +522,19 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; #pragma mark Sending Requests - (void)sendRequest:(__kindof SDLRPCMessage *)request { - // Add a correlation ID to the request - if ([request isKindOfClass:[SDLRPCRequest class]]) { + if ([request isKindOfClass:SDLRPCRequest.class]) { SDLRPCRequest *requestRPC = (SDLRPCRequest *)request; [self sendRequest:requestRPC withResponseHandler:nil]; - } else if ([request isKindOfClass:[SDLRPCResponse class]] || [request isKindOfClass:[SDLRPCNotification class]]) { - + } else if ([request isKindOfClass:SDLRPCResponse.class] || [request isKindOfClass:SDLRPCNotification.class]) { + [self sdl_sendRPC:request]; } else { - SDLLogE(@"Attempting to send an RPC with unknown type. The request should be of type request, response or notification. Returning..."); + NSAssert(false, @"The request should be of type `Request`, `Response` or `Notification"); } +} - // [self sendRequest:request withResponseHandler:nil]; +- (void)sdl_sendRPC:(__kindof SDLRPCMessage *)rpc { + SDLRPCResponseOperation *op = [[SDLRPCResponseOperation alloc] initWithConnectionManager:self rpc:rpc]; + [self.rpcOperationQueue addOperation:op]; } - (void)sendRequest:(SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler { @@ -559,16 +562,16 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; [self.rpcOperationQueue addOperation:op]; } +- (void)sendConnectionRPC:(__kindof SDLRPCMessage *)rpc { + [self sendConnectionRequest:rpc withResponseHandler:nil]; +} + - (void)sendConnectionRequest:(__kindof SDLRPCMessage *)request withResponseHandler:(nullable SDLResponseHandler)handler { if (![self.lifecycleStateMachine isCurrentState:SDLLifecycleStateReady]) { SDLLogW(@"Manager not ready, message not sent (%@)", request); - if (handler) { + if (handler && [request isKindOfClass:SDLRPCRequest.class]) { dispatch_async(dispatch_get_main_queue(), ^{ - if ([request isKindOfClass:[SDLRPCRequest class]]) { - handler(request, nil, [NSError sdl_lifecycle_notReadyError]); - } else { - handler(nil, nil, [NSError sdl_lifecycle_notReadyError]); - } + handler(request, nil, [NSError sdl_lifecycle_notReadyError]); }); } @@ -603,21 +606,17 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; return; } - if ([request isKindOfClass:[SDLRPCRequest class]]) { + if ([request isKindOfClass:SDLRPCRequest.class]) { // Generate and add a correlation ID to the request. When a response for the request is returned from Core, it will have the same correlation ID SDLRPCRequest *requestRPC = (SDLRPCRequest *)request; NSNumber *corrID = [self sdl_getNextCorrelationId]; requestRPC.correlationID = corrID; [self.responseDispatcher storeRequest:requestRPC handler:handler]; [self.proxy sendRPC:requestRPC]; - } else if ([request isKindOfClass:[SDLRPCResponse class]] || [request isKindOfClass:[SDLRPCNotification class]]) { + } else if ([request isKindOfClass:SDLRPCResponse.class] || [request isKindOfClass:SDLRPCNotification.class]) { [self.proxy sendRPC:request]; - if (handler) { - // Responses and notifications sent to Core do not get a response from Core so just call the handler - handler(nil, nil, nil); - } } else { - SDLLogE(@"Attempting to send an RPC with unknown type. The request should be of type request, response or notification. Returning..."); + SDLLogE(@"Attempting to send an RPC with unknown type, %@. The request should be of type request, response or notification. Returning...", request.class); } } diff --git a/SmartDeviceLink/SDLManager.h b/SmartDeviceLink/SDLManager.h index a97ef0c91..b0a0fbe08 100644 --- a/SmartDeviceLink/SDLManager.h +++ b/SmartDeviceLink/SDLManager.h @@ -133,7 +133,13 @@ typedef void (^SDLManagerReadyBlock)(BOOL success, NSError *_Nullable error); #pragma mark Manually Send RPC Requests +/** + * Send an RPC of type `Response`, `Notification` or `Request`. Responses and notifications sent to Core do not a response back from Core. Each request sent to Core does get a response, so if you need the response and/or error, call `sendRequest:withResponseHandler:` instead. + * + * @param rpc An RPC of type `SDLRPCResponse`, `SDLRPCNotification` or `SDLRPCRequest` + */ - (void)sendRPC:(__kindof SDLRPCMessage *)rpc; + /** * Send an RPC request and don't bother with the response or error. If you need the response or error, call sendRequest:withCompletionHandler: instead. * diff --git a/SmartDeviceLink/SDLRPCResponseOperation.h b/SmartDeviceLink/SDLRPCResponseOperation.h new file mode 100644 index 000000000..ffb56e1ad --- /dev/null +++ b/SmartDeviceLink/SDLRPCResponseOperation.h @@ -0,0 +1,26 @@ +// +// SDLRPCResponseOperation.h +// SmartDeviceLink +// +// Created by Nicole on 2/20/19. +// Copyright © 2019 smartdevicelink. All rights reserved. +// + +#import + +#import "SDLAsynchronousOperation.h" +#import "SDLLifecycleManager.h" + +@protocol SDLConnectionManagerType; + +NS_ASSUME_NONNULL_BEGIN + +@interface SDLRPCResponseOperation : SDLAsynchronousOperation + +@property (copy, nonatomic) __kindof SDLRPCMessage *rpc; + +- (instancetype)initWithConnectionManager:(id)connectionManager rpc:(__kindof SDLRPCMessage *)rpc; + +@end + +NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLRPCResponseOperation.m b/SmartDeviceLink/SDLRPCResponseOperation.m new file mode 100644 index 000000000..6029de328 --- /dev/null +++ b/SmartDeviceLink/SDLRPCResponseOperation.m @@ -0,0 +1,88 @@ +// +// SDLRPCResponseOperation.m +// SmartDeviceLink +// +// Created by Nicole on 2/20/19. +// Copyright © 2019 smartdevicelink. All rights reserved. +// + +#import "SDLRPCResponseOperation.h" + +#import "SDLConnectionManagerType.h" +#import "SDLError.h" +#import "SDLRPCMessage.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface SDLRPCResponseOperation () + +@property (weak, nonatomic) id connectionManager; +@property (strong, nonatomic) NSUUID *operationId; + +@end + +@implementation SDLRPCResponseOperation { + BOOL executing; + BOOL finished; +} + +- (instancetype)init { + self = [super init]; + if (!self) { return nil; } + + executing = NO; + finished = NO; + + _operationId = [NSUUID UUID]; + + return self; +} + +- (instancetype)initWithConnectionManager:(id)connectionManager rpc:(__kindof SDLRPCMessage *)rpc { + self = [self init]; + + _rpc = rpc; + _connectionManager = connectionManager; + + return self; +} + +- (void)start { + [super start]; + [self sdl_sendRPC:self.rpc]; +} + +- (void)sdl_sendRPC:(__kindof SDLRPCMessage *)rpc { + if (self.isCancelled) { + [self sdl_abortOperation]; + return; + } + + [self.connectionManager sendConnectionRPC:rpc]; + [self finishOperation]; +} + +- (void)sdl_abortOperation { + [self finishOperation]; +} + +#pragma mark - Property Overrides +- (nullable NSString *)name { + return [NSString stringWithFormat:@"%@ - %@", self.class, self.operationId]; +} + +- (NSOperationQueuePriority)queuePriority { + return NSOperationQueuePriorityNormal; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"%@", self.name]; +} + +- (NSString *)debugDescription { + return [NSString stringWithFormat:@"%@, request type=%@", self.name, self.rpc.class]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m index 49892f366..ad703881d 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m @@ -4,6 +4,7 @@ #import "SDLLifecycleManager.h" +#import "SDLAppServiceData.h" #import "SDLConfiguration.h" #import "SDLConnectionManagerType.h" #import "SDLError.h" @@ -16,8 +17,10 @@ #import "SDLLogConfiguration.h" #import "SDLManagerDelegate.h" #import "SDLNotificationDispatcher.h" +#import "SDLOnAppServiceData.h" #import "SDLOnHashChange.h" #import "SDLOnHMIStatus.h" +#import "SDLPerformAppServiceInteractionResponse.h" #import "SDLPermissionManager.h" #import "SDLProxy.h" #import "SDLProtocol.h" @@ -75,7 +78,7 @@ describe(@"a lifecycle manager", ^{ __block SDLConfiguration *testConfig = nil; __block id protocolMock = OCMClassMock([SDLProtocol class]); - __block id proxyMock = OCMClassMock([SDLProxy class]); + __block id proxyMock = OCMClassMock([SDLProxy class]);; __block id lockScreenManagerMock = OCMClassMock([SDLLockScreenManager class]); __block id fileManagerMock = OCMClassMock([SDLFileManager class]); __block id permissionManagerMock = OCMClassMock([SDLPermissionManager class]); @@ -128,6 +131,8 @@ describe(@"a lifecycle manager", ^{ expect(testManager.responseDispatcher).toNot(beNil()); expect(testManager.streamManager).toNot(beNil()); expect(testManager.systemCapabilityManager).toNot(beNil()); + expect(testManager.rpcOperationQueue).toNot(beNil()); + expect(testManager.rpcOperationQueue.maxConcurrentOperationCount).to(equal(3)); expect(@([testManager conformsToProtocol:@protocol(SDLConnectionManagerType)])).to(equal(@YES)); }); @@ -441,13 +446,44 @@ describe(@"a lifecycle manager", ^{ [testManager.lifecycleStateMachine setToState:SDLLifecycleStateReady fromOldState:nil callEnterTransition:NO]; }); - it(@"can send an RPC", ^{ + it(@"can send an RPC of type Request", ^{ SDLShow *testShow = [[SDLShow alloc] initWithMainField1:@"test" mainField2:nil alignment:nil]; [testManager sendRequest:testShow]; - OCMVerify([proxyMock sendRPC:[OCMArg isKindOfClass:[SDLShow class]]]); + [NSThread sleepForTimeInterval:0.1]; + + OCMVerify([proxyMock sendRPC:[OCMArg isKindOfClass:SDLShow.class]]); }); - + + it(@"can send an RPC of type Response", ^{ + SDLPerformAppServiceInteractionResponse *testResponse = [[SDLPerformAppServiceInteractionResponse alloc] init]; + [testManager sendRequest:testResponse]; + testResponse.correlationID = @(2); + testResponse.success = @(true); + testResponse.resultCode = SDLResultSuccess; + testResponse.info = @"testResponse info"; + + [NSThread sleepForTimeInterval:0.1]; + + OCMVerify([proxyMock sendRPC:[OCMArg isKindOfClass:SDLPerformAppServiceInteractionResponse.class]]); + }); + + it(@"can send an RPC of type Notification", ^{ + SDLOnAppServiceData *testNotification = [[SDLOnAppServiceData alloc] initWithServiceData:[[SDLAppServiceData alloc] init]]; + [testManager sendRequest:testNotification]; + + [NSThread sleepForTimeInterval:0.1]; + + OCMVerify([proxyMock sendRPC:[OCMArg isKindOfClass:SDLOnAppServiceData.class]]); + }); + + it(@"should throw an exception if the RPC is not of type `Request`, `Response` or `Notification`", ^{ + SDLRPCMessage *testMessage = [[SDLRPCMessage alloc] init]; + expectAction(^{ + [testManager sendRequest:testMessage]; + }).to(raiseException()); + }); + describe(@"stopping the manager", ^{ beforeEach(^{ [testManager stop]; diff --git a/SmartDeviceLinkTests/SDLRPCResponseOperationSpec.m b/SmartDeviceLinkTests/SDLRPCResponseOperationSpec.m new file mode 100644 index 000000000..4805eeba2 --- /dev/null +++ b/SmartDeviceLinkTests/SDLRPCResponseOperationSpec.m @@ -0,0 +1,95 @@ +// +// SDLRPCResponseOperationSpec.m +// SmartDeviceLinkTests +// +// Created by Nicole on 2/20/19. +// Copyright © 2019 smartdevicelink. All rights reserved. +// + +#import +#import + +#import "SDLGetAppServiceDataResponse.h" +#import "SDLOnAppServiceData.h" +#import "SDLRPCResponseOperation.h" +#import "TestConnectionManager.h" + +QuickSpecBegin(SDLRPCResponseOperationSpec) + +describe(@"sending responses and notifications", ^{ + __block TestConnectionManager *testConnectionManager = nil; + __block SDLRPCResponseOperation *testOperation = nil; + __block NSOperationQueue *testOperationQueue = nil; + + beforeEach(^{ + testOperation = nil; + testConnectionManager = [[TestConnectionManager alloc] init]; + + testOperationQueue = [[NSOperationQueue alloc] init]; + testOperationQueue.name = @"com.sdl.RPCResponse.testqueue"; + testOperationQueue.maxConcurrentOperationCount = 3; + }); + + context(@"when a single request succeeds", ^{ + __block __kindof SDLRPCMessage *sendRPC = nil; + + beforeEach(^{ + sendRPC = [[SDLGetAppServiceDataResponse alloc] initWithAppServiceData:[[SDLAppServiceData alloc] init]]; + }); + + it(@"should correctly send the rpc", ^{ + testOperation = [[SDLRPCResponseOperation alloc] initWithConnectionManager:testConnectionManager rpc:sendRPC]; + + [testOperationQueue addOperation:testOperation]; + [NSThread sleepForTimeInterval:0.1]; + + expect(testConnectionManager.receivedRequests).toEventually(contain(sendRPC)); + }); + }); + + context(@"when multiple request succeed", ^{ + __block NSMutableArray< __kindof SDLRPCMessage *> *sendRPCs = nil; + __block int rpcCount = (int)testOperationQueue.maxConcurrentOperationCount + 3; + + beforeEach(^{ + sendRPCs = [NSMutableArray array]; + for (int i = 0; i < rpcCount; i += 1) { + [sendRPCs addObject:[[SDLGetAppServiceDataResponse alloc] initWithAppServiceData:[[SDLAppServiceData alloc] init]]]; + } + }); + + it(@"should correctly send all of the rpcs", ^{ + for (int i = 0; i < rpcCount; i += 1) { + testOperation = [[SDLRPCResponseOperation alloc] initWithConnectionManager:testConnectionManager rpc:sendRPCs[i]]; + [testOperationQueue addOperation:testOperation]; + } + + [NSThread sleepForTimeInterval:0.1]; + + expect(testConnectionManager.receivedRequests.count).toEventually(equal(rpcCount)); + expect(testConnectionManager.receivedRequests).toEventually(equal(sendRPCs)); + }); + }); + + context(@"when a requst is cancelled", ^{ + __block __kindof SDLRPCMessage *sendRPC = nil; + + beforeEach(^{ + sendRPC = [[SDLGetAppServiceDataResponse alloc] initWithAppServiceData:[[SDLAppServiceData alloc] init]]; + }); + + it(@"should not send the rpc", ^{ + testOperation = [[SDLRPCResponseOperation alloc] initWithConnectionManager:testConnectionManager rpc:sendRPC]; + + [testOperationQueue addOperation:testOperation]; + [testOperationQueue cancelAllOperations]; + + [NSThread sleepForTimeInterval:0.1]; + + expect(testConnectionManager.receivedRequests).toEventually(beEmpty()); + }); + }); +}); + +QuickSpecEnd + diff --git a/SmartDeviceLinkTests/TestUtilities/TestConnectionManager.h b/SmartDeviceLinkTests/TestUtilities/TestConnectionManager.h index e1a24418b..b538249b0 100644 --- a/SmartDeviceLinkTests/TestUtilities/TestConnectionManager.h +++ b/SmartDeviceLinkTests/TestUtilities/TestConnectionManager.h @@ -20,7 +20,7 @@ NS_ASSUME_NONNULL_BEGIN /** * All received requests. Chronological order. The 0th element will be the first request received; the nth request will be the n+1th request received. */ -@property (copy, nonatomic, readonly) NSMutableArray<__kindof SDLRPCRequest *> *receivedRequests; +@property (copy, nonatomic, readonly) NSMutableArray<__kindof SDLRPCMessage *> *receivedRequests; /** * The block passed for the last request send with sendRequest:withCompletionHandler: diff --git a/SmartDeviceLinkTests/TestUtilities/TestConnectionManager.m b/SmartDeviceLinkTests/TestUtilities/TestConnectionManager.m index 4c8ea3a50..484811c96 100644 --- a/SmartDeviceLinkTests/TestUtilities/TestConnectionManager.m +++ b/SmartDeviceLinkTests/TestUtilities/TestConnectionManager.m @@ -21,11 +21,15 @@ NS_ASSUME_NONNULL_BEGIN return nil; } - _receivedRequests = [NSMutableArray<__kindof SDLRPCRequest *> array]; + _receivedRequests = [NSMutableArray<__kindof SDLRPCMessage *> array]; return self; } +- (void)sendConnectionRPC:(__kindof SDLRPCMessage *)rpc { + [self.receivedRequests addObject:rpc]; +} + - (void)sendConnectionRequest:(__kindof SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler { self.lastRequestBlock = handler; request.correlationID = [self test_nextCorrelationID]; @@ -98,7 +102,7 @@ NS_ASSUME_NONNULL_BEGIN } - (void)reset { - _receivedRequests = [NSMutableArray<__kindof SDLRPCRequest *> array]; + _receivedRequests = [NSMutableArray<__kindof SDLRPCMessage *> array]; _lastRequestBlock = nil; } -- cgit v1.2.1 From d7bc8625da714666af5f6e9c51e4fa1e0a1df735 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Thu, 21 Feb 2019 13:57:51 -0500 Subject: Removed method from SDLConnectionManager protocol --- SmartDeviceLink/SDLConnectionManagerType.h | 9 +-------- SmartDeviceLink/SDLLifecycleManager.m | 4 ---- SmartDeviceLink/SDLRPCResponseOperation.m | 2 +- .../TestUtilities/TestConnectionManager.m | 15 ++++++++------- 4 files changed, 10 insertions(+), 20 deletions(-) diff --git a/SmartDeviceLink/SDLConnectionManagerType.h b/SmartDeviceLink/SDLConnectionManagerType.h index 84a30a404..9ae4eec06 100644 --- a/SmartDeviceLink/SDLConnectionManagerType.h +++ b/SmartDeviceLink/SDLConnectionManagerType.h @@ -26,20 +26,13 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)sendConnectionManagerRequest:(__kindof SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler; -/** - * Sends an RPC of type `Request`, `Response` or `Notification` without bypassing the block on RPC sends before managers complete setup. - * - * @param rpc An RPC of type `SDLRPCRequest`, `SDLRPCResponse`, or `SDLRPCNotification` - */ -- (void)sendConnectionRPC:(__kindof SDLRPCMessage *)rpc; - /** * Sends an RPC of type `SDLRPCRequest` without bypassing the block on RPC sends before managers complete setup. * * @param request The RPC request to be sent to the remote head unit. * @param handler A completion block called when the response is received. */ -- (void)sendConnectionRequest:(__kindof SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler; +- (void)sendConnectionRequest:(__kindof SDLRPCMessage *)request withResponseHandler:(nullable SDLResponseHandler)handler; /** * Sends an array of RPCs of type `Request` asynchronously. The requests are sent without bypassing the block on RPC sends before managers complete setup. diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m index 037e06865..ad3dc75f4 100644 --- a/SmartDeviceLink/SDLLifecycleManager.m +++ b/SmartDeviceLink/SDLLifecycleManager.m @@ -562,10 +562,6 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; [self.rpcOperationQueue addOperation:op]; } -- (void)sendConnectionRPC:(__kindof SDLRPCMessage *)rpc { - [self sendConnectionRequest:rpc withResponseHandler:nil]; -} - - (void)sendConnectionRequest:(__kindof SDLRPCMessage *)request withResponseHandler:(nullable SDLResponseHandler)handler { if (![self.lifecycleStateMachine isCurrentState:SDLLifecycleStateReady]) { SDLLogW(@"Manager not ready, message not sent (%@)", request); diff --git a/SmartDeviceLink/SDLRPCResponseOperation.m b/SmartDeviceLink/SDLRPCResponseOperation.m index 6029de328..6277b693c 100644 --- a/SmartDeviceLink/SDLRPCResponseOperation.m +++ b/SmartDeviceLink/SDLRPCResponseOperation.m @@ -58,7 +58,7 @@ NS_ASSUME_NONNULL_BEGIN return; } - [self.connectionManager sendConnectionRPC:rpc]; + [self.connectionManager sendConnectionRequest:rpc withResponseHandler:nil]; [self finishOperation]; } diff --git a/SmartDeviceLinkTests/TestUtilities/TestConnectionManager.m b/SmartDeviceLinkTests/TestUtilities/TestConnectionManager.m index 484811c96..e081b3ac5 100644 --- a/SmartDeviceLinkTests/TestUtilities/TestConnectionManager.m +++ b/SmartDeviceLinkTests/TestUtilities/TestConnectionManager.m @@ -26,14 +26,15 @@ NS_ASSUME_NONNULL_BEGIN return self; } -- (void)sendConnectionRPC:(__kindof SDLRPCMessage *)rpc { - [self.receivedRequests addObject:rpc]; -} - -- (void)sendConnectionRequest:(__kindof SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler { +- (void)sendConnectionRequest:(__kindof SDLRPCMessage *)request withResponseHandler:(nullable SDLResponseHandler)handler { self.lastRequestBlock = handler; - request.correlationID = [self test_nextCorrelationID]; - [self.receivedRequests addObject:request]; + if ([request isKindOfClass:SDLRPCRequest.class]) { + SDLRPCRequest *requestRPC = (SDLRPCRequest *)request; + requestRPC.correlationID = [self test_nextCorrelationID]; + [self.receivedRequests addObject:requestRPC]; + } else { + [self.receivedRequests addObject:request]; + } } - (void)sendConnectionManagerRequest:(__kindof SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler { -- cgit v1.2.1 From 29af71626eabb0bd7bd91038ac8323b0c27e82ec Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Thu, 21 Feb 2019 14:26:12 -0500 Subject: Removed unused code from SDLNotificationConstants * Removed unused code from SDLNotificationConstants * Reverted method param data type in SDLManager class --- SmartDeviceLink/SDLManager.m | 2 +- SmartDeviceLink/SDLNotificationConstants.h | 8 -------- SmartDeviceLink/SDLNotificationConstants.m | 5 ----- 3 files changed, 1 insertion(+), 14 deletions(-) diff --git a/SmartDeviceLink/SDLManager.m b/SmartDeviceLink/SDLManager.m index 92ab50480..a485efdcc 100644 --- a/SmartDeviceLink/SDLManager.m +++ b/SmartDeviceLink/SDLManager.m @@ -127,7 +127,7 @@ NS_ASSUME_NONNULL_BEGIN [self sendRequest:request withResponseHandler:nil]; } -- (void)sendRequest:(SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler { +- (void)sendRequest:(__kindof SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler { [self.lifecycleManager sendRequest:(__kindof SDLRPCMessage *)request withResponseHandler:handler]; } diff --git a/SmartDeviceLink/SDLNotificationConstants.h b/SmartDeviceLink/SDLNotificationConstants.h index 1454330db..9c3bf024e 100644 --- a/SmartDeviceLink/SDLNotificationConstants.h +++ b/SmartDeviceLink/SDLNotificationConstants.h @@ -213,14 +213,6 @@ extern SDLNotificationName const SDLDidReceiveWaypointNotification; */ + (NSArray *)allResponseNames; - -/** - All of the possible SDL RPC Request notification names - - @return All request notification names - */ -+ (NSArray *)allRequestNames; - /** All of the possible SDL Button event notification names diff --git a/SmartDeviceLink/SDLNotificationConstants.m b/SmartDeviceLink/SDLNotificationConstants.m index 17f6ac79f..fb7a43cca 100644 --- a/SmartDeviceLink/SDLNotificationConstants.m +++ b/SmartDeviceLink/SDLNotificationConstants.m @@ -164,11 +164,6 @@ SDLNotificationName const SDLDidReceiveWaypointNotification = @"com.sdl.notifica SDLDidReceiveUnsubscribeWaypointsResponse]; } -+ (NSArray *)allRequestNames { - return @[SDLDidReceivePerformAppServiceInteractionRequest, - SDLDidReceiveGetAppServiceDataRequest]; -} - + (NSArray *)allButtonEventNotifications { return @[SDLDidReceiveButtonEventNotification, SDLDidReceiveButtonPressNotification]; -- cgit v1.2.1 From 399a880d1dd739b13c706d5c7482e610bab7b4aa Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Thu, 21 Feb 2019 14:41:05 -0500 Subject: Fixed no notification when a PASI request received Fixed the notification dispatacher not being called when a PerformAppServiceInteraction request is received. Had to fix `onPerformAppServiceInteraction:` name in `ProxyListener`. --- SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m | 2 +- SmartDeviceLink/SDLNotificationDispatcher.m | 2 +- SmartDeviceLink/SDLProxyListener.h | 2 +- SmartDeviceLink/SDLSequentialRPCRequestOperation.m | 2 +- SmartDeviceLinkTests/Notifications/SDLNotificationDispatcherSpec.m | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m b/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m index 5c67e3e8a..44dc938d5 100644 --- a/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m +++ b/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m @@ -90,7 +90,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)sdl_sendRequest:(SDLRPCRequest *)request { __weak typeof(self) weakSelf = self; - [self.connectionManager sendConnectionRequest:request withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) { + [self.connectionManager sendConnectionRequest:(__kindof SDLRPCMessage *)request withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) { __strong typeof(self) strongSelf = weakSelf; if (strongSelf.isCancelled) { diff --git a/SmartDeviceLink/SDLNotificationDispatcher.m b/SmartDeviceLink/SDLNotificationDispatcher.m index d786d2f14..aff64f93f 100644 --- a/SmartDeviceLink/SDLNotificationDispatcher.m +++ b/SmartDeviceLink/SDLNotificationDispatcher.m @@ -193,7 +193,7 @@ NS_ASSUME_NONNULL_BEGIN [self postRPCResponseNotification:SDLDidReceiveListFilesResponse response:response]; } -- (void)onPerformAppServiceInteractionRequest:(SDLPerformAppServiceInteraction *)request { +- (void)onPerformAppServiceInteraction:(SDLPerformAppServiceInteraction *)request { [self postRPCRequestNotification:SDLDidReceivePerformAppServiceInteractionRequest request:request]; } diff --git a/SmartDeviceLink/SDLProxyListener.h b/SmartDeviceLink/SDLProxyListener.h index 00e31c072..493f59bd4 100644 --- a/SmartDeviceLink/SDLProxyListener.h +++ b/SmartDeviceLink/SDLProxyListener.h @@ -446,7 +446,7 @@ NS_ASSUME_NONNULL_BEGIN * * @param request A SDLPerformAppServiceInteraction object */ -- (void)onPerformAppServiceInteractionRequest:(SDLPerformAppServiceInteraction *)request; +- (void)onPerformAppServiceInteraction:(SDLPerformAppServiceInteraction *)request; /** * Called when a Perform App Service Interaction Response is received from Core diff --git a/SmartDeviceLink/SDLSequentialRPCRequestOperation.m b/SmartDeviceLink/SDLSequentialRPCRequestOperation.m index 142812d40..35c7638a1 100644 --- a/SmartDeviceLink/SDLSequentialRPCRequestOperation.m +++ b/SmartDeviceLink/SDLSequentialRPCRequestOperation.m @@ -81,7 +81,7 @@ NS_ASSUME_NONNULL_BEGIN // Send the next request SDLRPCRequest *request = self.requests[self.currentRequestIndex]; - [self.connectionManager sendConnectionRequest:request withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) { + [self.connectionManager sendConnectionRequest:(__kindof SDLRPCMessage *)request withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) { self.requestsComplete++; // If this request failed and no request has yet failed, set our internal request failed to YES diff --git a/SmartDeviceLinkTests/Notifications/SDLNotificationDispatcherSpec.m b/SmartDeviceLinkTests/Notifications/SDLNotificationDispatcherSpec.m index be3fa4cb1..8464a481d 100644 --- a/SmartDeviceLinkTests/Notifications/SDLNotificationDispatcherSpec.m +++ b/SmartDeviceLinkTests/Notifications/SDLNotificationDispatcherSpec.m @@ -63,7 +63,7 @@ describe(@"a notification dispatcher", ^{ expect(@([testDispatcher respondsToSelector:@selector(onOnTouchEvent:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onOnVehicleData:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onOnWayPointChange:)])).to(beTruthy()); - expect(@([testDispatcher respondsToSelector:@selector(onPerformAppServiceInteractionRequest:)])).to(beTruthy()); + expect(@([testDispatcher respondsToSelector:@selector(onPerformAppServiceInteraction:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onPerformAppServiceInteractionResponse:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onPerformAudioPassThruResponse:)])).to(beTruthy()); expect(@([testDispatcher respondsToSelector:@selector(onPerformInteractionResponse:)])).to(beTruthy()); -- cgit v1.2.1