summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Fischer <joeljfischer@gmail.com>2019-04-05 16:24:40 -0400
committerGitHub <noreply@github.com>2019-04-05 16:24:40 -0400
commit416b73e40351e0801fcc1ae1d91cac5fa9a8b658 (patch)
tree3385f714d975d70dcaed4cb1a4f0d2650828367a
parent4c0a0821c2909a4fcad11996b9a1591e38c7d27c (diff)
parent292a6cbfcbeb6133627ce01cd96235cf857fafa9 (diff)
downloadsdl_ios-416b73e40351e0801fcc1ae1d91cac5fa9a8b658.tar.gz
Merge pull request #1215 from smartdevicelink/feature/issue_1212_update_system_capability_manager_auto_caching
Update System Capability Manager to auto-cache`OnSystemCapability`
-rw-r--r--SmartDeviceLink/SDLSystemCapabilityManager.m184
-rw-r--r--SmartDeviceLinkTests/SDLSystemCapabilityManagerSpec.m218
2 files changed, 296 insertions, 106 deletions
diff --git a/SmartDeviceLink/SDLSystemCapabilityManager.m b/SmartDeviceLink/SDLSystemCapabilityManager.m
index 04d991e66..0a48ce71f 100644
--- a/SmartDeviceLink/SDLSystemCapabilityManager.m
+++ b/SmartDeviceLink/SDLSystemCapabilityManager.m
@@ -8,25 +8,34 @@
#import "SDLSystemCapabilityManager.h"
+#import "SDLAppServiceCapability.h"
+#import "SDLAppServiceRecord.h"
#import "SDLAppServicesCapabilities.h"
#import "SDLConnectionManagerType.h"
#import "SDLGenericResponse.h"
#import "SDLGetSystemCapability.h"
#import "SDLGetSystemCapabilityResponse.h"
+#import "SDLGlobals.h"
#import "SDLLogMacros.h"
#import "SDLNotificationConstants.h"
+#import "SDLOnHMIStatus.h"
+#import "SDLOnSystemCapabilityUpdated.h"
#import "SDLRegisterAppInterfaceResponse.h"
+#import "SDLRPCNotificationNotification.h"
#import "SDLRPCResponseNotification.h"
#import "SDLSetDisplayLayoutResponse.h"
#import "SDLSystemCapability.h"
+#import "SDLVersion.h"
#import "SDLVideoStreamingCapability.h"
+
NS_ASSUME_NONNULL_BEGIN
@interface SDLSystemCapabilityManager ()
+typedef NSString * SDLServiceID;
+
@property (weak, nonatomic) id<SDLConnectionManagerType> connectionManager;
-@property (copy, nonatomic, nullable) SDLUpdateCapabilityHandler systemCapabilityHandler;
@property (nullable, strong, nonatomic, readwrite) SDLDisplayCapabilities *displayCapabilities;
@property (nullable, strong, nonatomic, readwrite) SDLHMICapabilities *hmiCapabilities;
@@ -39,12 +48,15 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, assign, readwrite) BOOL vrCapability;
@property (nullable, copy, nonatomic, readwrite) NSArray<SDLAudioPassThruCapabilities *> *audioPassThruCapabilities;
@property (nullable, strong, nonatomic, readwrite) SDLAudioPassThruCapabilities *pcmStreamCapability;
-@property (nullable, strong, nonatomic, readwrite) SDLAppServicesCapabilities *appServicesCapabilities;
@property (nullable, strong, nonatomic, readwrite) SDLNavigationCapability *navigationCapability;
@property (nullable, strong, nonatomic, readwrite) SDLPhoneCapability *phoneCapability;
@property (nullable, strong, nonatomic, readwrite) SDLVideoStreamingCapability *videoStreamingCapability;
@property (nullable, strong, nonatomic, readwrite) SDLRemoteControlCapabilities *remoteControlCapability;
+@property (nullable, strong, nonatomic) NSMutableDictionary<SDLServiceID, SDLAppServiceCapability *> *appServicesCapabilitiesDictionary;
+
+@property (assign, nonatomic) BOOL isFirstHMILevelFull;
+
@end
@implementation SDLSystemCapabilityManager
@@ -58,11 +70,17 @@ NS_ASSUME_NONNULL_BEGIN
}
_connectionManager = manager;
+ _isFirstHMILevelFull = NO;
+ _appServicesCapabilitiesDictionary = [NSMutableDictionary dictionary];
+
[self sdl_registerForNotifications];
return self;
}
+/**
+ * Resets the capabilities when a transport session is closed.
+ */
- (void)stop {
SDLLogD(@"System Capability manager stopped");
_displayCapabilities = nil;
@@ -80,18 +98,36 @@ NS_ASSUME_NONNULL_BEGIN
_phoneCapability = nil;
_videoStreamingCapability = nil;
_remoteControlCapability = nil;
- _appServicesCapabilities = nil;
+ _appServicesCapabilitiesDictionary = [NSMutableDictionary dictionary];
+
+ _isFirstHMILevelFull = NO;
}
+#pragma mark - Getters
+
+- (nullable SDLAppServicesCapabilities *)appServicesCapabilities {
+ if (self.appServicesCapabilitiesDictionary.count == 0) { return nil; }
+
+ return [[SDLAppServicesCapabilities alloc] initWithAppServices:self.appServicesCapabilitiesDictionary.allValues];
+}
#pragma mark - Notifications
+/**
+ * Registers for notifications and responses from Core
+ */
-(void)sdl_registerForNotifications {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_registerResponse:) name:SDLDidReceiveRegisterAppInterfaceResponse object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_displayLayoutResponse:) name:SDLDidReceiveSetDisplayLayoutResponse object:nil];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_systemCapabilityResponse:) name:SDLDidReceiveGetSystemCapabilitiesResponse object:nil];
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_systemCapabilityUpdatedNotification:) name:SDLDidReceiveSystemCapabilityUpdatedNotification object:nil];
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_hmiStatusNotification:) name:SDLDidChangeHMIStatusNotification object:nil];
}
+/**
+ * Called when a `RegisterAppInterfaceResponse` response is received from Core. The head unit capabilities are saved.
+ *
+ * @param notification The `RegisterAppInterfaceResponse` response received from Core
+ */
- (void)sdl_registerResponse:(SDLRPCResponseNotification *)notification {
SDLRegisterAppInterfaceResponse *response = (SDLRegisterAppInterfaceResponse *)notification.response;
if (!response.success.boolValue) { return; }
@@ -109,6 +145,11 @@ NS_ASSUME_NONNULL_BEGIN
self.pcmStreamCapability = response.pcmStreamCapabilities;
}
+/**
+ * Called when a `SetDisplayLayoutResponse` response is received from Core. If the template was set successfully, the the new capabilities for the template are saved.
+ *
+ * @param notification The `SetDisplayLayoutResponse` response received from Core
+ */
- (void)sdl_displayLayoutResponse:(SDLRPCResponseNotification *)notification {
SDLSetDisplayLayoutResponse *response = (SDLSetDisplayLayoutResponse *)notification.response;
if (!response.success.boolValue) { return; }
@@ -119,41 +160,132 @@ NS_ASSUME_NONNULL_BEGIN
self.presetBankCapabilities = response.presetBankCapabilities;
}
-- (void)sdl_systemCapabilityResponse:(SDLRPCResponseNotification *)notification {
- SDLGetSystemCapabilityResponse *response = (SDLGetSystemCapabilityResponse *)notification.response;
- if (!response.success.boolValue) { return; }
+/**
+ * Called when an `OnSystemCapabilityUpdated` notification is received from Core. The updated system capabilty is saved.
+ *
+ * @param notification The `OnSystemCapabilityUpdated` notification received from Core
+ */
+- (void)sdl_systemCapabilityUpdatedNotification:(SDLRPCNotificationNotification *)notification {
+ SDLOnSystemCapabilityUpdated *systemCapabilityUpdatedNotification = (SDLOnSystemCapabilityUpdated *)notification.notification;
+ [self sdl_saveSystemCapability:systemCapabilityUpdatedNotification.systemCapability completionHandler:nil];
+}
+
+/**
+ * Called when an `OnHMIStatus` notification is received from Core. The first time the `hmiLevel` is `FULL` attempt to subscribe to system capabilty updates.
+ *
+ * @param notification The `OnHMIStatus` notification received from Core
+ */
+- (void)sdl_hmiStatusNotification:(SDLRPCNotificationNotification *)notification {
+ SDLOnHMIStatus *hmiStatus = (SDLOnHMIStatus *)notification.notification;
+ if (self.isFirstHMILevelFull || ![hmiStatus.hmiLevel isEqualToEnum:SDLHMILevelFull]) {
+ return;
+ }
+
+ self.isFirstHMILevelFull = YES;
+ [self sdl_subscribeToSystemCapabilityUpdates];
+}
+
+#pragma mark - System Capabilities
+
+- (void)updateCapabilityType:(SDLSystemCapabilityType)type completionHandler:(SDLUpdateCapabilityHandler)handler {
+ SDLVersion *onSystemCapabilityNotificationRPCVersion = [SDLVersion versionWithString:@"5.1.0"];
+ SDLVersion *headUnitRPCVersion = SDLGlobals.sharedGlobals.rpcVersion;
+ if ([headUnitRPCVersion isGreaterThanOrEqualToVersion:onSystemCapabilityNotificationRPCVersion]) {
+ // Just return the cached data because we get `onSystemCapability` callbacks
+ handler(nil, self);
+ } else {
+ // Go and get the actual data
+ SDLGetSystemCapability *getSystemCapability = [[SDLGetSystemCapability alloc] initWithType:type];
+ [self sdl_sendGetSystemCapability:getSystemCapability completionHandler:handler];
+ }
+}
+
+/**
+ * A list of all possible system capability types.
+ *
+ * @return An array of all possible system capability types
+ */
++ (NSArray<SDLSystemCapabilityType> *)sdl_systemCapabilityTypes {
+ return @[SDLSystemCapabilityTypeAppServices, SDLSystemCapabilityTypeNavigation, SDLSystemCapabilityTypePhoneCall, SDLSystemCapabilityTypeVideoStreaming, SDLSystemCapabilityTypeRemoteControl];
+}
+
+/**
+ * Sends a subscribe request for all possible system capabilites. If connecting to Core versions 4.5+, the requested capability will be returned in the response. If connecting to Core versions 5.1+, the manager will received `OnSystemCapabilityUpdated` notifications when the capability updates if the subscription was successful.
+ */
+- (void)sdl_subscribeToSystemCapabilityUpdates {
+ for (SDLSystemCapabilityType type in [self.class sdl_systemCapabilityTypes]) {
+ SDLGetSystemCapability *getSystemCapability = [[SDLGetSystemCapability alloc] initWithType:type];
+ SDLVersion *onSystemCapabilityNotificationRPCVersion = [SDLVersion versionWithString:@"5.1.0"];
+ SDLVersion *headUnitRPCVersion = SDLGlobals.sharedGlobals.rpcVersion;
+ if ([headUnitRPCVersion isGreaterThanOrEqualToVersion:onSystemCapabilityNotificationRPCVersion]) {
+ getSystemCapability.subscribe = @YES;
+ }
- SDLSystemCapability *systemCapabilityResponse = ((SDLGetSystemCapabilityResponse *)response).systemCapability;
- SDLSystemCapabilityType systemCapabilityType = systemCapabilityResponse.systemCapabilityType;
+ [self sdl_sendGetSystemCapability:getSystemCapability completionHandler:nil];
+ }
+}
+
+/**
+ * Sends a `GetSystemCapability` to Core and handles the response by saving the returned data and notifying the subscriber.
+ *
+ * @param getSystemCapability The `GetSystemCapability` request to send
+ */
+- (void)sdl_sendGetSystemCapability:(SDLGetSystemCapability *)getSystemCapability completionHandler:(nullable SDLUpdateCapabilityHandler)handler {
+ [self.connectionManager sendConnectionRequest:getSystemCapability withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) {
+ if (error != nil) {
+ // An error is returned if the request was unsuccessful or if a Generic Response was returned
+ if (handler == nil) { return; }
+ handler(error, self);
+ return;
+ }
+
+ SDLGetSystemCapabilityResponse *getSystemCapabilityResponse = (SDLGetSystemCapabilityResponse *)response;
+ if (!getSystemCapabilityResponse.success.boolValue) { return; }
+ [self sdl_saveSystemCapability:getSystemCapabilityResponse.systemCapability completionHandler:handler];
+ }];
+}
+
+/**
+ * Saves a system capability. All system capabilities will update with the full object except for app services. For app services only the updated app service capabilities will be included in the `SystemCapability` sent from Core. The cached `appServicesCapabilities` will be updated with the new `appService` data.
+ *
+ * @param systemCapability The system capability
+ */
+- (void)sdl_saveSystemCapability:(SDLSystemCapability *)systemCapability completionHandler:(nullable SDLUpdateCapabilityHandler)handler {
+ SDLSystemCapabilityType systemCapabilityType = systemCapability.systemCapabilityType;
if ([systemCapabilityType isEqualToEnum:SDLSystemCapabilityTypePhoneCall]) {
- self.phoneCapability = systemCapabilityResponse.phoneCapability;
+ self.phoneCapability = systemCapability.phoneCapability;
} else if ([systemCapabilityType isEqualToEnum:SDLSystemCapabilityTypeNavigation]) {
- self.navigationCapability = systemCapabilityResponse.navigationCapability;
+ self.navigationCapability = systemCapability.navigationCapability;
} else if ([systemCapabilityType isEqualToEnum:SDLSystemCapabilityTypeRemoteControl]) {
- self.remoteControlCapability = systemCapabilityResponse.remoteControlCapability;
+ self.remoteControlCapability = systemCapability.remoteControlCapability;
} else if ([systemCapabilityType isEqualToEnum:SDLSystemCapabilityTypeVideoStreaming]) {
- self.videoStreamingCapability = systemCapabilityResponse.videoStreamingCapability;
+ self.videoStreamingCapability = systemCapability.videoStreamingCapability;
} else if ([systemCapabilityType isEqualToEnum:SDLSystemCapabilityTypeAppServices]) {
- self.appServicesCapabilities = systemCapabilityResponse.appServicesCapabilities;
+ [self sdl_saveAppServicesCapabilitiesUpdate:systemCapability.appServicesCapabilities];
} else {
SDLLogW(@"Received response for unknown System Capability Type: %@", systemCapabilityType);
+ return;
}
- if (self.systemCapabilityHandler == nil) { return; }
- self.systemCapabilityHandler(nil, self);
-}
+ SDLLogD(@"Updated system capability manager with new data: %@", systemCapability);
-#pragma mark - Capability Request
+ if (handler == nil) { return; }
+ handler(nil, self);
+}
-- (void)updateCapabilityType:(SDLSystemCapabilityType)type completionHandler:(SDLUpdateCapabilityHandler)handler {
- self.systemCapabilityHandler = handler;
- SDLGetSystemCapability *getSystemCapability = [[SDLGetSystemCapability alloc] initWithType:type];
- [self.connectionManager sendConnectionRequest:getSystemCapability withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) {
- if (error == nil) { return; }
- // An error is returned if the request was unsuccessful or a Generic Response is returned
- handler(error, self);
- }];
+- (void)sdl_saveAppServicesCapabilitiesUpdate:(SDLAppServicesCapabilities *)newCapabilities {
+ for (SDLAppServiceCapability *capability in newCapabilities.appServices) {
+ if (capability.updateReason == nil) {
+ // First update, new capability
+ self.appServicesCapabilitiesDictionary[capability.updatedAppServiceRecord.serviceID] = capability;
+ } else if ([capability.updateReason isEqualToEnum:SDLServiceUpdateRemoved]) {
+ self.appServicesCapabilitiesDictionary[capability.updatedAppServiceRecord.serviceID] = nil;
+ } else {
+ // Everything else involves adding or updating the existing service record
+ self.appServicesCapabilitiesDictionary[capability.updatedAppServiceRecord.serviceID] = capability;
+ }
+ }
}
@end
diff --git a/SmartDeviceLinkTests/SDLSystemCapabilityManagerSpec.m b/SmartDeviceLinkTests/SDLSystemCapabilityManagerSpec.m
index a3bb55c58..109b8ea2d 100644
--- a/SmartDeviceLinkTests/SDLSystemCapabilityManagerSpec.m
+++ b/SmartDeviceLinkTests/SDLSystemCapabilityManagerSpec.m
@@ -1,14 +1,21 @@
#import <Quick/Quick.h>
#import <Nimble/Nimble.h>
+#import "SDLAppServiceCapability.h"
+#import "SDLAppServiceManifest.h"
+#import "SDLAppServiceRecord.h"
+#import "SDLAppServicesCapabilities.h"
#import "SDLAudioPassThruCapabilities.h"
#import "SDLButtonCapabilities.h"
#import "SDLDisplayCapabilities.h"
#import "SDLGetSystemCapability.h"
#import "SDLGetSystemCapabilityResponse.h"
#import "SDLHMICapabilities.h"
+#import "SDLMediaServiceManifest.h"
#import "SDLNavigationCapability.h"
#import "SDLNotificationConstants.h"
+#import "SDLOnHMIStatus.h"
+#import "SDLOnSystemCapabilityUpdated.h"
#import "SDLPhoneCapability.h"
#import "SDLPresetBankCapabilities.h"
#import "SDLRegisterAppInterfaceResponse.h"
@@ -256,12 +263,12 @@ describe(@"System capability manager", ^{
});
});
- context(@"When notified of a Get System Capability Response", ^{
+ context(@"When sending a Get System Capability request", ^{
__block SDLGetSystemCapabilityResponse *testGetSystemCapabilityResponse;
__block SDLPhoneCapability *testPhoneCapability = nil;
beforeEach(^{
- testPhoneCapability = [[SDLPhoneCapability alloc] initWithDialNumber:YES];
+ testPhoneCapability = [[SDLPhoneCapability alloc] initWithDialNumber:YES];
testGetSystemCapabilityResponse = [[SDLGetSystemCapabilityResponse alloc] init];
testGetSystemCapabilityResponse.systemCapability = [[SDLSystemCapability alloc] init];
@@ -269,69 +276,45 @@ describe(@"System capability manager", ^{
testGetSystemCapabilityResponse.systemCapability.systemCapabilityType = SDLSystemCapabilityTypePhoneCall;
});
- describe(@"If a Get System Capability Response notification is received", ^{
- context(@"If the request failed", ^{
- beforeEach(^{
- testGetSystemCapabilityResponse.success = @NO;
- SDLRPCResponseNotification *notification = [[SDLRPCResponseNotification alloc] initWithName:SDLDidReceiveGetSystemCapabilitiesResponse object:self rpcResponse:testGetSystemCapabilityResponse];
- [[NSNotificationCenter defaultCenter] postNotification:notification];
- });
+ context(@"If the request failed with an error", ^{
+ __block NSError *testError = nil;
- it(@"should should not save the capabilities", ^{
- expect(testSystemCapabilityManager.phoneCapability).to(beNil());
- });
+ beforeEach(^{
+ testGetSystemCapabilityResponse.success = @NO;
+ testError = [NSError errorWithDomain:NSCocoaErrorDomain code:-234 userInfo:nil];
});
- context(@"If the request succeeded", ^{
- beforeEach(^{
- testGetSystemCapabilityResponse.success = @YES;
- SDLRPCResponseNotification *notification = [[SDLRPCResponseNotification alloc] initWithName:SDLDidReceiveGetSystemCapabilitiesResponse object:self rpcResponse:testGetSystemCapabilityResponse];
- [[NSNotificationCenter defaultCenter] postNotification:notification];
- });
+ it(@"should should not save the capabilities", ^{
+ waitUntilTimeout(1, ^(void (^done)(void)) {
+ [testSystemCapabilityManager updateCapabilityType:testGetSystemCapabilityResponse.systemCapability.systemCapabilityType completionHandler:^(NSError * _Nullable error, SDLSystemCapabilityManager * _Nonnull systemCapabilityManager) {
+ expect(error).to(equal(testConnectionManager.defaultError));
+ expect(systemCapabilityManager.phoneCapability).to(beNil());
+ done();
+ }];
+
+ [NSThread sleepForTimeInterval:0.1];
- it(@"should should save the capabilities", ^{
- expect(testSystemCapabilityManager.phoneCapability).to(equal(testPhoneCapability));
+ [testConnectionManager respondToLastRequestWithResponse:testGetSystemCapabilityResponse];
});
});
});
- describe(@"If a response is received for a sent Get System Capability request", ^{
- context(@"If the request failed with an error", ^{
- __block NSError *testError = nil;
-
- beforeEach(^{
- testGetSystemCapabilityResponse.success = @NO;
- testError = [NSError errorWithDomain:NSCocoaErrorDomain code:-234 userInfo:nil];
-
- waitUntilTimeout(1.0, ^(void (^done)(void)) {
- [testSystemCapabilityManager updateCapabilityType:testGetSystemCapabilityResponse.systemCapability.systemCapabilityType completionHandler:^(NSError * _Nullable error, SDLSystemCapabilityManager * _Nonnull systemCapabilityManager) {
- expect(error).to(equal(testConnectionManager.defaultError));
- expect(systemCapabilityManager.phoneCapability).to(beNil());
- done();
- }];
-
- [testConnectionManager respondToLastRequestWithResponse:testGetSystemCapabilityResponse];
- });
- });
-
- it(@"should should not save the capabilities", ^{
- expect(testSystemCapabilityManager.phoneCapability).to(beNil());
- });
+ context(@"If the request succeeded", ^{
+ beforeEach(^{
+ testGetSystemCapabilityResponse.success = @YES;
});
- context(@"If the request succeeded", ^{
- beforeEach(^{
- testGetSystemCapabilityResponse.success = @YES;
-
+ it(@"should save the capabilitity", ^{
+ waitUntilTimeout(1, ^(void (^done)(void)){
[testSystemCapabilityManager updateCapabilityType:testGetSystemCapabilityResponse.systemCapability.systemCapabilityType completionHandler:^(NSError * _Nullable error, SDLSystemCapabilityManager * _Nonnull systemCapabilityManager) {
- // The handler will not be notifified
+ expect(testSystemCapabilityManager.phoneCapability).to(equal(testPhoneCapability));
+ expect(error).to(beNil());
+ done();
}];
- [testConnectionManager respondToLastRequestWithResponse:testGetSystemCapabilityResponse];
- });
+ [NSThread sleepForTimeInterval:0.1];
- it(@"should not save the capabilities because a successful Get System Capability Response notification will be intercepted by the manager and be handled there", ^{
- expect(testSystemCapabilityManager.phoneCapability).to(beNil());
+ [testConnectionManager respondToLastRequestWithResponse:testGetSystemCapabilityResponse];
});
});
});
@@ -356,46 +339,121 @@ describe(@"System capability manager", ^{
});
});
- context(@"When the system capability manager is stopped after being started", ^{
+ describe(@"updating the SCM through OnSystemCapability", ^{
+ __block SDLPhoneCapability *phoneCapability = nil;
+
beforeEach(^{
- SDLDisplayCapabilities *testDisplayCapabilities = [[SDLDisplayCapabilities alloc] init];
- testDisplayCapabilities.graphicSupported = @NO;
+ phoneCapability = [[SDLPhoneCapability alloc] initWithDialNumber:YES];
+ SDLSystemCapability *newCapability = [[SDLSystemCapability alloc] initWithPhoneCapability:phoneCapability];
+ SDLOnSystemCapabilityUpdated *update = [[SDLOnSystemCapabilityUpdated alloc] initWithSystemCapability:newCapability];
+ SDLRPCNotificationNotification *notification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveSystemCapabilityUpdatedNotification object:nil rpcNotification:update];
+ [[NSNotificationCenter defaultCenter] postNotification:notification];
+ });
- SDLRegisterAppInterfaceResponse *testRegisterAppInterfaceResponse = [[SDLRegisterAppInterfaceResponse alloc] init];
- testRegisterAppInterfaceResponse.displayCapabilities = testDisplayCapabilities;
- testRegisterAppInterfaceResponse.success = @YES;
+ it(@"should properly update phone capability", ^{
+ expect(testSystemCapabilityManager.phoneCapability).toEventually(equal(phoneCapability));
+ });
+ });
+
+ describe(@"merging app services capability changes", ^{
+ __block SDLAppServicesCapabilities *baseAppServices = nil;
+ __block SDLAppServiceCapability *deleteCapability = nil;
+ __block SDLAppServiceCapability *updateCapability = nil;
+ __block SDLAppServiceCapability *newCapability = nil;
- SDLRPCResponseNotification *notification = [[SDLRPCResponseNotification alloc] initWithName:SDLDidReceiveRegisterAppInterfaceResponse object:self rpcResponse:testRegisterAppInterfaceResponse];
+ beforeEach(^{
+ SDLAppServiceManifest *deleteCapabilityManifest = [[SDLAppServiceManifest alloc] initWithMediaServiceName:@"Delete me" serviceIcon:nil allowAppConsumers:YES rpcSpecVersion:nil handledRPCs:nil mediaServiceManifest:[[SDLMediaServiceManifest alloc] init]];
+ SDLAppServiceRecord *deleteCapabilityRecord = [[SDLAppServiceRecord alloc] initWithServiceID:@"1234" serviceManifest:deleteCapabilityManifest servicePublished:YES serviceActive:YES];
+ deleteCapability = [[SDLAppServiceCapability alloc] initWithUpdatedAppServiceRecord:deleteCapabilityRecord];
+
+ SDLAppServiceManifest *updateCapabilityManifest = [[SDLAppServiceManifest alloc] initWithMediaServiceName:@"Update me" serviceIcon:nil allowAppConsumers:YES rpcSpecVersion:nil handledRPCs:nil mediaServiceManifest:[[SDLMediaServiceManifest alloc] init]];
+ SDLAppServiceRecord *updateCapabilityRecord = [[SDLAppServiceRecord alloc] initWithServiceID:@"2345" serviceManifest:updateCapabilityManifest servicePublished:YES serviceActive:NO];
+ updateCapability = [[SDLAppServiceCapability alloc] initWithUpdatedAppServiceRecord:updateCapabilityRecord];
+
+ baseAppServices = [[SDLAppServicesCapabilities alloc] initWithAppServices:@[deleteCapability, updateCapability]];
+ SDLSystemCapability *appServiceCapability = [[SDLSystemCapability alloc] initWithAppServicesCapabilities:baseAppServices];
+ SDLOnSystemCapabilityUpdated *update = [[SDLOnSystemCapabilityUpdated alloc] initWithSystemCapability:appServiceCapability];
+ SDLRPCNotificationNotification *notification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveSystemCapabilityUpdatedNotification object:nil rpcNotification:update];
[[NSNotificationCenter defaultCenter] postNotification:notification];
+ });
- expect(testSystemCapabilityManager.displayCapabilities).to(equal(testDisplayCapabilities));
+ it(@"should have the correct base services", ^{
+ expect(testSystemCapabilityManager.appServicesCapabilities).to(equal(baseAppServices));
});
- describe(@"When stopped", ^{
- beforeEach(^{
- [testSystemCapabilityManager stop];
- });
+ describe(@"when sending the merge update", ^{
+ it(@"should correctly merge", ^{
+ deleteCapability.updateReason = SDLServiceUpdateRemoved;
+ deleteCapability.updatedAppServiceRecord.servicePublished = @NO;
+ deleteCapability.updatedAppServiceRecord.serviceActive = @NO;
- it(@"It should reset the system capability manager properties correctly", ^{
- expect(testSystemCapabilityManager.displayCapabilities).to(beNil());
- expect(testSystemCapabilityManager.hmiCapabilities).to(beNil());
- expect(testSystemCapabilityManager.softButtonCapabilities).to(beNil());
- expect(testSystemCapabilityManager.buttonCapabilities).to(beNil());
- expect(testSystemCapabilityManager.presetBankCapabilities).to(beNil());
- expect(testSystemCapabilityManager.hmiZoneCapabilities).to(beNil());
- expect(testSystemCapabilityManager.speechCapabilities).to(beNil());
- expect(testSystemCapabilityManager.prerecordedSpeechCapabilities).to(beNil());
- expect(testSystemCapabilityManager.vrCapability).to(beFalse());
- expect(testSystemCapabilityManager.audioPassThruCapabilities).to(beNil());
- expect(testSystemCapabilityManager.pcmStreamCapability).to(beNil());
- expect(testSystemCapabilityManager.phoneCapability).to(beNil());
- expect(testSystemCapabilityManager.navigationCapability).to(beNil());
- expect(testSystemCapabilityManager.videoStreamingCapability).to(beNil());
- expect(testSystemCapabilityManager.remoteControlCapability).to(beNil());
- expect(testSystemCapabilityManager.appServicesCapabilities).to(beNil());
+ updateCapability.updateReason = SDLServiceUpdateActivated;
+ updateCapability.updatedAppServiceRecord.serviceActive = @YES;
+
+ SDLAppServiceManifest *newCapabilityManifest = [[SDLAppServiceManifest alloc] initWithMediaServiceName:@"New me" serviceIcon:nil allowAppConsumers:YES rpcSpecVersion:nil handledRPCs:nil mediaServiceManifest:[[SDLMediaServiceManifest alloc] init]];
+ SDLAppServiceRecord *newCapabilityRecord = [[SDLAppServiceRecord alloc] initWithServiceID:@"3456" serviceManifest:newCapabilityManifest servicePublished:YES serviceActive:NO];
+ newCapability = [[SDLAppServiceCapability alloc] initWithUpdateReason:SDLServiceUpdatePublished updatedAppServiceRecord:newCapabilityRecord];
+
+ SDLAppServicesCapabilities *appServicesUpdate = [[SDLAppServicesCapabilities alloc] initWithAppServices:@[deleteCapability, updateCapability, newCapability]];
+ SDLSystemCapability *appServiceCapability = [[SDLSystemCapability alloc] initWithAppServicesCapabilities:appServicesUpdate];
+ SDLOnSystemCapabilityUpdated *update = [[SDLOnSystemCapabilityUpdated alloc] initWithSystemCapability:appServiceCapability];
+ SDLRPCNotificationNotification *notification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveSystemCapabilityUpdatedNotification object:nil rpcNotification:update];
+ [[NSNotificationCenter defaultCenter] postNotification:notification];
+
+ expect(testSystemCapabilityManager.appServicesCapabilities.appServices).toNot(contain(deleteCapability));
+ expect(testSystemCapabilityManager.appServicesCapabilities.appServices).to(haveCount(2));
+
+ SDLAppServiceCapability *firstCapability = testSystemCapabilityManager.appServicesCapabilities.appServices.firstObject;
+ SDLAppServiceCapability *secondCapability = testSystemCapabilityManager.appServicesCapabilities.appServices.lastObject;
+
+ expect(firstCapability.updateReason).to(equal(SDLServiceUpdatePublished));
+ expect(firstCapability.updatedAppServiceRecord.serviceID).to(equal(@"3456"));
+
+ expect(secondCapability.updateReason).to(equal(SDLServiceUpdateActivated));
+ expect(secondCapability.updatedAppServiceRecord.serviceID).to(equal(@"2345"));
+ expect(secondCapability.updatedAppServiceRecord.serviceActive).to(beTrue());
});
});
});
+
+ describe(@"when entering HMI FULL", ^{
+ beforeEach(^{
+ SDLOnHMIStatus *fullStatus = [[SDLOnHMIStatus alloc] init];
+ fullStatus.hmiLevel = SDLHMILevelFull;
+ SDLRPCNotificationNotification *notification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidChangeHMIStatusNotification object:nil rpcNotification:fullStatus];
+ [[NSNotificationCenter defaultCenter] postNotification:notification];
+ });
+
+ it(@"should send GetSystemCapability subscriptions for all known capabilities", ^{
+ expect(testConnectionManager.receivedRequests).to(haveCount(5));
+ expect(testConnectionManager.receivedRequests.lastObject).to(beAnInstanceOf([SDLGetSystemCapability class]));
+ });
+ });
+
+ describe(@"when the system capability manager is stopped after being started", ^{
+ beforeEach(^{
+ [testSystemCapabilityManager stop];
+ });
+
+ it(@"It should reset the system capability manager properties correctly", ^{
+ expect(testSystemCapabilityManager.displayCapabilities).to(beNil());
+ expect(testSystemCapabilityManager.hmiCapabilities).to(beNil());
+ expect(testSystemCapabilityManager.softButtonCapabilities).to(beNil());
+ expect(testSystemCapabilityManager.buttonCapabilities).to(beNil());
+ expect(testSystemCapabilityManager.presetBankCapabilities).to(beNil());
+ expect(testSystemCapabilityManager.hmiZoneCapabilities).to(beNil());
+ expect(testSystemCapabilityManager.speechCapabilities).to(beNil());
+ expect(testSystemCapabilityManager.prerecordedSpeechCapabilities).to(beNil());
+ expect(testSystemCapabilityManager.vrCapability).to(beFalse());
+ expect(testSystemCapabilityManager.audioPassThruCapabilities).to(beNil());
+ expect(testSystemCapabilityManager.pcmStreamCapability).to(beNil());
+ expect(testSystemCapabilityManager.phoneCapability).to(beNil());
+ expect(testSystemCapabilityManager.navigationCapability).to(beNil());
+ expect(testSystemCapabilityManager.videoStreamingCapability).to(beNil());
+ expect(testSystemCapabilityManager.remoteControlCapability).to(beNil());
+ expect(testSystemCapabilityManager.appServicesCapabilities).to(beNil());
+ });
+ });
});
QuickSpecEnd