summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicoleYarroch <nicole@livio.io>2018-04-19 13:13:40 -0400
committerNicoleYarroch <nicole@livio.io>2018-04-19 13:13:40 -0400
commita007b1c2e6ea7585fde6b5733df43d70cad9f1c8 (patch)
tree9dfb034bb92262caf487444d869ecebf2c9e312b
parent088ceb23fde8ef6c01ca89b4063902adeae8bdb3 (diff)
parent2a3fb785a1de5968a343d061e12ebc9e9213a708 (diff)
downloadsdl_ios-a007b1c2e6ea7585fde6b5733df43d70cad9f1c8.tar.gz
Merge branch 'develop' into feature/issue_620_swift_sdl_example_app
Signed-off-by: NicoleYarroch <nicole@livio.io> # Conflicts: # SmartDeviceLink-iOS.xcodeproj/project.pbxproj # SmartDeviceLink_Example/Classes/ProxyManager.m
-rw-r--r--SmartDeviceLink-iOS.podspec1
-rw-r--r--SmartDeviceLink-iOS.xcodeproj/project.pbxproj32
-rw-r--r--SmartDeviceLink.podspec1
-rw-r--r--SmartDeviceLink/SDLLifecycleManager.h2
-rw-r--r--SmartDeviceLink/SDLLifecycleManager.m3
-rw-r--r--SmartDeviceLink/SDLManager.h9
-rw-r--r--SmartDeviceLink/SDLManager.m4
-rw-r--r--SmartDeviceLink/SDLSystemCapabilityManager.h194
-rw-r--r--SmartDeviceLink/SDLSystemCapabilityManager.m156
-rw-r--r--SmartDeviceLink/SmartDeviceLink.h3
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m126
-rw-r--r--SmartDeviceLinkTests/SDLScreenManagerSpec.m6
-rw-r--r--SmartDeviceLinkTests/SDLSystemCapabilityManagerSpec.m397
-rw-r--r--SmartDeviceLink_Example/AppConstants.h4
-rw-r--r--SmartDeviceLink_Example/AppConstants.m4
-rw-r--r--SmartDeviceLink_Example/Classes/ProxyManager.m56
-rw-r--r--SmartDeviceLink_Example/VehicleDataManager.swift20
17 files changed, 950 insertions, 68 deletions
diff --git a/SmartDeviceLink-iOS.podspec b/SmartDeviceLink-iOS.podspec
index 3ac9fc85d..18afc1790 100644
--- a/SmartDeviceLink-iOS.podspec
+++ b/SmartDeviceLink-iOS.podspec
@@ -292,6 +292,7 @@ ss.public_header_files = [
'SmartDeviceLink/SDLSyncPDataResponse.h',
'SmartDeviceLink/SDLSystemAction.h',
'SmartDeviceLink/SDLSystemCapability.h',
+'SmartDeviceLink/SDLSystemCapabilityManager.h',
'SmartDeviceLink/SDLSystemCapabilityType.h',
'SmartDeviceLink/SDLSystemContext.h',
'SmartDeviceLink/SDLTBTState.h',
diff --git a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
index 3abd25de2..1ce843d5f 100644
--- a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
+++ b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
@@ -1050,6 +1050,9 @@
5DEF69611FD6FB75004B8C2F /* SDLAudioStreamManagerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DEF69601FD6FB75004B8C2F /* SDLAudioStreamManagerSpec.m */; };
5DEF69661FD6FEF7004B8C2F /* SDLStreamingAudioManagerMock.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DEF69651FD6FEF7004B8C2F /* SDLStreamingAudioManagerMock.m */; };
5DFFB9151BD7C89700DB3F04 /* SDLConnectionManagerType.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DFFB9141BD7C89700DB3F04 /* SDLConnectionManagerType.h */; };
+ 880E35B42088F75A00181259 /* SDLSystemCapabilityManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 880E35B22088F75A00181259 /* SDLSystemCapabilityManager.m */; };
+ 880E35B52088F75A00181259 /* SDLSystemCapabilityManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 880E35B32088F75A00181259 /* SDLSystemCapabilityManager.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 880E35B82088F78E00181259 /* SDLSystemCapabilityManagerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 880E35B72088F78E00181259 /* SDLSystemCapabilityManagerSpec.m */; };
88166B00207E41E900076236 /* MenuManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88166AFF207E41E900076236 /* MenuManager.swift */; };
8829568B207CF68800EF056C /* SmartDeviceLink.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D61FA1C1A84237100846EE7 /* SmartDeviceLink.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
88295690207CF68800EF056C /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5D4029D31A76F0340006B0C2 /* Images.xcassets */; };
@@ -2373,6 +2376,9 @@
5DEF69651FD6FEF7004B8C2F /* SDLStreamingAudioManagerMock.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLStreamingAudioManagerMock.m; sourceTree = "<group>"; };
5DF2BB9C1B94E38A00CE5994 /* SDLURLSessionSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLURLSessionSpec.m; path = "UtilitiesSpecs/HTTP Connection/SDLURLSessionSpec.m"; sourceTree = "<group>"; };
5DFFB9141BD7C89700DB3F04 /* SDLConnectionManagerType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLConnectionManagerType.h; sourceTree = "<group>"; };
+ 880E35B22088F75A00181259 /* SDLSystemCapabilityManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLSystemCapabilityManager.m; sourceTree = "<group>"; };
+ 880E35B32088F75A00181259 /* SDLSystemCapabilityManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLSystemCapabilityManager.h; sourceTree = "<group>"; };
+ 880E35B72088F78E00181259 /* SDLSystemCapabilityManagerSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLSystemCapabilityManagerSpec.m; sourceTree = "<group>"; };
88166AFF207E41E900076236 /* MenuManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuManager.swift; sourceTree = "<group>"; };
88295697207CF68800EF056C /* SmartDeviceLink-Example-Swift.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "SmartDeviceLink-Example-Swift.app"; sourceTree = BUILT_PRODUCTS_DIR; };
88295698207CF68800EF056C /* SmartDeviceLink-Example-Swift-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "SmartDeviceLink-Example-Swift-Info.plist"; path = "/Users/nicolelivioradio.com/sdl_ios/SmartDeviceLink-Example-Swift-Info.plist"; sourceTree = "<absolute>"; };
@@ -4589,6 +4595,7 @@
5D8204291BCEA91400D0A41B /* Permissions */,
DA8966E71E56937100413EAB /* Streaming */,
5D0A736F203F0C450001595D /* Screen */,
+ 880E35B12088F73400181259 /* System Capabilities */,
);
name = Managers;
sourceTree = "<group>";
@@ -4607,6 +4614,7 @@
children = (
5DAD5F8120507DE40025624C /* Show */,
DA8966ED1E5693D100413EAB /* Streaming */,
+ 880E35B62088F77C00181259 /* System Capabilities */,
5D1654541D3E753100554D93 /* Lifecycle */,
5D76E31A1D3805E600647CFA /* LockScreen */,
5D9F507F1BE7E6C900FEF399 /* Permissions */,
@@ -4754,6 +4762,23 @@
name = Mocks;
sourceTree = "<group>";
};
+ 880E35B12088F73400181259 /* System Capabilities */ = {
+ isa = PBXGroup;
+ children = (
+ 880E35B32088F75A00181259 /* SDLSystemCapabilityManager.h */,
+ 880E35B22088F75A00181259 /* SDLSystemCapabilityManager.m */,
+ );
+ name = "System Capabilities";
+ sourceTree = "<group>";
+ };
+ 880E35B62088F77C00181259 /* System Capabilities */ = {
+ isa = PBXGroup;
+ children = (
+ 880E35B72088F78E00181259 /* SDLSystemCapabilityManagerSpec.m */,
+ );
+ name = "System Capabilities";
+ sourceTree = "<group>";
+ };
88295677207CF46C00EF056C /* Objective-C */ = {
isa = PBXGroup;
children = (
@@ -5240,6 +5265,7 @@
5DD67CB81E661C4A009CD394 /* SDLLogTargetFile.h in Headers */,
5D61FD591A84238C00846EE7 /* SDLReadDID.h in Headers */,
5D82041A1BCD80BA00D0A41B /* SDLLockScreenConfiguration.h in Headers */,
+ 880E35B52088F75A00181259 /* SDLSystemCapabilityManager.h in Headers */,
5D61FC611A84238C00846EE7 /* SDLChoice.h in Headers */,
5D1BF6AF204742FB00D36881 /* SDLDisplayCapabilities+ShowManagerExtensions.h in Headers */,
5D7F87F31CE3C29E002DD7C4 /* SDLFileWrapper.h in Headers */,
@@ -6001,6 +6027,7 @@
5D61FC931A84238C00846EE7 /* SDLDisplayType.m in Sources */,
5D61FCE31A84238C00846EE7 /* SDLKeyboardLayout.m in Sources */,
5D61FE0C1A84238C00846EE7 /* SDLVehicleType.m in Sources */,
+ 880E35B42088F75A00181259 /* SDLSystemCapabilityManager.m in Sources */,
DA9F7E941DCC04E400ACAE48 /* SDLUnsubscribeWayPoints.m in Sources */,
5D61FDCC1A84238C00846EE7 /* SDLTextFieldName.m in Sources */,
5D61FC751A84238C00846EE7 /* SDLDeleteCommandResponse.m in Sources */,
@@ -6094,6 +6121,7 @@
162E836E1A9BDE8B00906325 /* SDLUnsubscribeButtonResponseSpec.m in Sources */,
5DEF69611FD6FB75004B8C2F /* SDLAudioStreamManagerSpec.m in Sources */,
162E835B1A9BDE8B00906325 /* SDLPerformInteractionResponseSpec.m in Sources */,
+ 880E35B82088F78E00181259 /* SDLSystemCapabilityManagerSpec.m in Sources */,
162E832D1A9BDE8B00906325 /* SDLEncodedSyncPDataSpec.m in Sources */,
1EE8C44C1F385C7100FDC2CF /* SDLRDSDataSpec.m in Sources */,
5DB92D241AC47B2C00C15BB0 /* SDLHexUtilitySpec.m in Sources */,
@@ -6713,7 +6741,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
- DEVELOPMENT_TEAM = "";
+ DEVELOPMENT_TEAM = NCVC2MHU7M;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(DEVELOPER_FRAMEWORKS_DIR)",
@@ -6749,7 +6777,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
- DEVELOPMENT_TEAM = "";
+ DEVELOPMENT_TEAM = NCVC2MHU7M;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(DEVELOPER_FRAMEWORKS_DIR)",
diff --git a/SmartDeviceLink.podspec b/SmartDeviceLink.podspec
index a94f95b85..fe5054cf4 100644
--- a/SmartDeviceLink.podspec
+++ b/SmartDeviceLink.podspec
@@ -292,6 +292,7 @@ ss.public_header_files = [
'SmartDeviceLink/SDLSyncPDataResponse.h',
'SmartDeviceLink/SDLSystemAction.h',
'SmartDeviceLink/SDLSystemCapability.h',
+'SmartDeviceLink/SDLSystemCapabilityManager.h',
'SmartDeviceLink/SDLSystemCapabilityType.h',
'SmartDeviceLink/SDLSystemContext.h',
'SmartDeviceLink/SDLTBTState.h',
diff --git a/SmartDeviceLink/SDLLifecycleManager.h b/SmartDeviceLink/SDLLifecycleManager.h
index c41c2d971..594dccba3 100644
--- a/SmartDeviceLink/SDLLifecycleManager.h
+++ b/SmartDeviceLink/SDLLifecycleManager.h
@@ -32,6 +32,7 @@
@class SDLScreenManager;
@class SDLStateMachine;
@class SDLStreamingMediaManager;
+@class SDLSystemCapabilityManager;
@protocol SDLManagerDelegate;
@@ -67,6 +68,7 @@ typedef void (^SDLManagerReadyBlock)(BOOL success, NSError *_Nullable error);
@property (strong, nonatomic, nullable) SDLStreamingMediaManager *streamManager;
@property (strong, nonatomic) SDLLockScreenManager *lockScreenManager;
@property (strong, nonatomic, readonly) SDLScreenManager *screenManager;
+@property (strong, nonatomic) SDLSystemCapabilityManager *systemCapabilityManager;
@property (strong, nonatomic, readonly) SDLNotificationDispatcher *notificationDispatcher;
@property (strong, nonatomic, readonly) SDLResponseDispatcher *responseDispatcher;
diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m
index e321854a1..ccc95293c 100644
--- a/SmartDeviceLink/SDLLifecycleManager.m
+++ b/SmartDeviceLink/SDLLifecycleManager.m
@@ -48,6 +48,7 @@
#import "SDLStateMachine.h"
#import "SDLStreamingMediaConfiguration.h"
#import "SDLStreamingMediaManager.h"
+#import "SDLSystemCapabilityManager.h"
#import "SDLUnregisterAppInterface.h"
@@ -122,6 +123,7 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready";
_permissionManager = [[SDLPermissionManager alloc] init];
_lockScreenManager = [[SDLLockScreenManager alloc] initWithConfiguration:_configuration.lockScreenConfig notificationDispatcher:_notificationDispatcher presenter:[[SDLLockScreenPresenter alloc] init]];
_screenManager = [[SDLScreenManager alloc] initWithConnectionManager:self fileManager:_fileManager];
+ _systemCapabilityManager = [[SDLSystemCapabilityManager alloc] initWithConnectionManager:self];
if ([configuration.lifecycleConfig.appType isEqualToEnum:SDLAppHMITypeNavigation] ||
[configuration.lifecycleConfig.appType isEqualToEnum:SDLAppHMITypeProjection] ||
@@ -227,6 +229,7 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready";
[self.permissionManager stop];
[self.lockScreenManager stop];
[self.streamManager stop];
+ [self.systemCapabilityManager stop];
[self.responseDispatcher clear];
[self.rpcOperationQueue cancelAllOperations];
diff --git a/SmartDeviceLink/SDLManager.h b/SmartDeviceLink/SDLManager.h
index 32a91ce2d..332e153b8 100644
--- a/SmartDeviceLink/SDLManager.h
+++ b/SmartDeviceLink/SDLManager.h
@@ -20,6 +20,7 @@
@class SDLRPCResponse;
@class SDLScreenManager;
@class SDLStreamingMediaManager;
+@class SDLSystemCapabilityManager;
@protocol SDLManagerDelegate;
@@ -95,9 +96,17 @@ typedef void (^SDLManagerReadyBlock)(BOOL success, NSError *_Nullable error);
*/
@property (strong, nonatomic, readonly, nullable) SDLStreamingMediaManager *streamManager;
+/**
+ * The screen manager for sending UI related RPCs.
+ */
@property (strong, nonatomic, readonly) SDLScreenManager *screenManager;
/**
+ * Centralized manager for retrieving all system capabilities.
+ */
+@property (strong, nonatomic, readonly) SDLSystemCapabilityManager *systemCapabilityManager;
+
+/**
* The response of a register call after it has been received.
*/
@property (strong, nonatomic, readonly, nullable) SDLRegisterAppInterfaceResponse *registerResponse;
diff --git a/SmartDeviceLink/SDLManager.m b/SmartDeviceLink/SDLManager.m
index 575711abb..e30ae87ea 100644
--- a/SmartDeviceLink/SDLManager.m
+++ b/SmartDeviceLink/SDLManager.m
@@ -88,6 +88,10 @@ NS_ASSUME_NONNULL_BEGIN
return self.lifecycleManager.screenManager;
}
+- (SDLSystemCapabilityManager *)systemCapabilityManager {
+ return self.lifecycleManager.systemCapabilityManager;
+}
+
- (nullable SDLRegisterAppInterfaceResponse *)registerResponse {
return self.lifecycleManager.registerResponse;
}
diff --git a/SmartDeviceLink/SDLSystemCapabilityManager.h b/SmartDeviceLink/SDLSystemCapabilityManager.h
new file mode 100644
index 000000000..36f58a735
--- /dev/null
+++ b/SmartDeviceLink/SDLSystemCapabilityManager.h
@@ -0,0 +1,194 @@
+//
+// SDLSystemCapabilityManager.h
+// SmartDeviceLink
+//
+// Created by Nicole on 3/26/18.
+// Copyright Ā© 2018 smartdevicelink. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+#import "SDLHMIZoneCapabilities.h"
+#import "SDLPrerecordedSpeech.h"
+#import "SDLSpeechCapabilities.h"
+#import "SDLSystemCapabilityType.h"
+#import "SDLVrCapabilities.h"
+
+@class SDLAudioPassThruCapabilities;
+@class SDLButtonCapabilities;
+@class SDLDisplayCapabilities;
+@class SDLHMICapabilities;
+@class SDLNavigationCapability;
+@class SDLPhoneCapability;
+@class SDLPresetBankCapabilities;
+@class SDLRemoteControlCapabilities;
+@class SDLSoftButtonCapabilities;
+@class SDLSystemCapabilityManager;
+@class SDLVideoStreamingCapability;
+
+@protocol SDLConnectionManagerType;
+
+NS_ASSUME_NONNULL_BEGIN
+
+
+/**
+ * A completion handler called after a request for the capability type is returned from the remote system.
+ *
+ * @param error The error returned if the request for a capability type failed. The error is nil if the request was successful.
+ * @param systemCapabilityManager The system capability manager
+ */
+typedef void (^SDLUpdateCapabilityHandler)(NSError * _Nullable error, SDLSystemCapabilityManager *systemCapabilityManager);
+
+
+@interface SDLSystemCapabilityManager : NSObject
+
+/**
+ * @see SDLDisplayCapabilities
+ *
+ * Optional
+ */
+@property (nullable, strong, nonatomic, readonly) SDLDisplayCapabilities *displayCapabilities;
+
+/**
+ * @see SDLHMICapabilities
+ *
+ * Optional
+ */
+@property (nullable, strong, nonatomic, readonly) SDLHMICapabilities *hmiCapabilities;
+
+/**
+ * If returned, the platform supports on-screen SoftButtons
+ *
+ * @see SDLSoftButtonCapabilities
+ *
+ * Optional, Array of length 1 - 100, of SDLSoftButtonCapabilities
+ */
+@property (nullable, copy, nonatomic, readonly) NSArray<SDLSoftButtonCapabilities *> *softButtonCapabilities;
+
+/**
+ * @see SDLButtonCapabilities
+ *
+ * Optional, Array of length 1 - 100, of SDLButtonCapabilities
+ */
+@property (nullable, copy, nonatomic, readonly) NSArray<SDLButtonCapabilities *> *buttonCapabilities;
+
+/**
+ * If returned, the platform supports custom on-screen Presets
+ *
+ * @see SDLPresetBankCapabilities
+ *
+ * Optional
+ */
+@property (nullable, strong, nonatomic, readonly) SDLPresetBankCapabilities *presetBankCapabilities;
+
+/**
+ * @see SDLHMIZoneCapabilities
+ *
+ * Optional, Array of length 1 - 100, of SDLHMIZoneCapabilities
+ */
+@property (nullable, copy, nonatomic, readonly) NSArray<SDLHMIZoneCapabilities> *hmiZoneCapabilities;
+
+/**
+ * @see SDLSpeechCapabilities
+ *
+ * Optional, Array of length 1 - 100, of SDLSpeechCapabilities
+ */
+@property (nullable, copy, nonatomic, readonly) NSArray<SDLSpeechCapabilities> *speechCapabilities;
+
+/**
+ * @see SDLPrerecordedSpeech
+ *
+ * Optional, Array of length 1 - 100, of SDLPrerecordedSpeech
+ */
+@property (nullable, copy, nonatomic, readonly) NSArray<SDLPrerecordedSpeech> *prerecordedSpeechCapabilities;
+
+/**
+ * @see SDLVRCapabilities
+ *
+ * True if the head unit supports voice recognition; false if not.
+ */
+@property (nonatomic, assign, readonly) BOOL vrCapability;
+
+/**
+ * @see SDLAudioPassThruCapabilities
+ *
+ * Optional, Array of length 1 - 100, of SDLAudioPassThruCapabilities
+ */
+@property (nullable, copy, nonatomic, readonly) NSArray<SDLAudioPassThruCapabilities *> *audioPassThruCapabilities;
+
+/**
+ * @see SDLAudioPassThruCapabilities
+ *
+ * Optional, Array of length 1 - 100, of SDLAudioPassThruCapabilities
+ */
+@property (nullable, strong, nonatomic, readonly) SDLAudioPassThruCapabilities *pcmStreamCapability;
+
+/**
+ * If returned, the platform supports navigation
+ *
+ * @see SDLNavigationCapability
+ *
+ * Optional
+ */
+@property (nullable, strong, nonatomic, readonly) SDLNavigationCapability *navigationCapability;
+
+/**
+ * If returned, the platform supports making phone calls
+ *
+ * @see SDLPhoneCapability
+ *
+ * Optional
+ */
+@property (nullable, strong, nonatomic, readonly) SDLPhoneCapability *phoneCapability;
+
+/**
+ * If returned, the platform supports video streaming
+ *
+ * @see SDLVideoStreamingCapability
+ *
+ * Optional
+ */
+@property (nullable, strong, nonatomic, readonly) SDLVideoStreamingCapability *videoStreamingCapability;
+
+/**
+ * If returned, the platform supports remote control capabilities
+ *
+ * @see SDLRemoteControlCapabilities
+ *
+ * Optional
+ */
+@property (nullable, strong, nonatomic, readonly) SDLRemoteControlCapabilities *remoteControlCapability;
+
+/**
+ * Init is unavailable. Dependencies must be injected using initWithConnectionManager:
+ *
+ * @return nil
+ */
+- (instancetype)init NS_UNAVAILABLE;
+
+/**
+ * Creates a new system capability manager with a specified connection manager
+ *
+ * @param manager A connection manager to use to forward on RPCs
+ *
+ * @return An instance of SDLSystemCapabilityManager
+ */
+- (instancetype)initWithConnectionManager:(id<SDLConnectionManagerType>)manager NS_DESIGNATED_INITIALIZER;
+
+/**
+ * Stops the manager. This method is used internally.
+ */
+- (void)stop;
+
+/**
+ * Retrieves a capability type from the remote system. This function must be called in order to retrieve the values of `navigationCapability`, `phoneCapability`, `videoStreamingCapability` and `remoteControlCapability`. If you do not call this method first, those values will be nil. After calling this method, assuming there is no error in the handler, you may retrieve the capability you requested from the manager within the handler.
+ *
+ * @param type The type of capability to retrieve
+ * @param handler The handler to be called when the retrieval is complete
+ */
+- (void)updateCapabilityType:(SDLSystemCapabilityType)type completionHandler:(SDLUpdateCapabilityHandler)handler;
+
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLSystemCapabilityManager.m b/SmartDeviceLink/SDLSystemCapabilityManager.m
new file mode 100644
index 000000000..9168fd81e
--- /dev/null
+++ b/SmartDeviceLink/SDLSystemCapabilityManager.m
@@ -0,0 +1,156 @@
+//
+// SDLSystemCapabilityManager.m
+// SmartDeviceLink
+//
+// Created by Nicole on 3/26/18.
+// Copyright Ā© 2018 smartdevicelink. All rights reserved.
+//
+
+#import "SDLSystemCapabilityManager.h"
+
+#import "SDLConnectionManagerType.h"
+#import "SDLGenericResponse.h"
+#import "SDLGetSystemCapability.h"
+#import "SDLGetSystemCapabilityResponse.h"
+#import "SDLLogMacros.h"
+#import "SDLNotificationConstants.h"
+#import "SDLRegisterAppInterfaceResponse.h"
+#import "SDLRPCResponseNotification.h"
+#import "SDLSetDisplayLayoutResponse.h"
+#import "SDLSystemCapability.h"
+#import "SDLVideoStreamingCapability.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface SDLSystemCapabilityManager ()
+
+@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;
+@property (nullable, copy, nonatomic, readwrite) NSArray<SDLSoftButtonCapabilities *> *softButtonCapabilities;
+@property (nullable, copy, nonatomic, readwrite) NSArray<SDLButtonCapabilities *> *buttonCapabilities;
+@property (nullable, strong, nonatomic, readwrite) SDLPresetBankCapabilities *presetBankCapabilities;
+@property (nullable, copy, nonatomic, readwrite) NSArray<SDLHMIZoneCapabilities> *hmiZoneCapabilities;
+@property (nullable, copy, nonatomic, readwrite) NSArray<SDLSpeechCapabilities> *speechCapabilities;
+@property (nullable, copy, nonatomic, readwrite) NSArray<SDLPrerecordedSpeech> *prerecordedSpeechCapabilities;
+@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) SDLNavigationCapability *navigationCapability;
+@property (nullable, strong, nonatomic, readwrite) SDLPhoneCapability *phoneCapability;
+@property (nullable, strong, nonatomic, readwrite) SDLVideoStreamingCapability *videoStreamingCapability;
+@property (nullable, strong, nonatomic, readwrite) SDLRemoteControlCapabilities *remoteControlCapability;
+
+@end
+
+@implementation SDLSystemCapabilityManager
+
+#pragma mark - Lifecycle
+
+- (instancetype)initWithConnectionManager:(id<SDLConnectionManagerType>)manager {
+ self = [super init];
+ if (!self) {
+ return nil;
+ }
+
+ _connectionManager = manager;
+ [self sdl_registerForNotifications];
+
+ return self;
+}
+
+- (void)stop {
+ SDLLogD(@"System Capability manager stopped");
+ _displayCapabilities = nil;
+ _hmiCapabilities = nil;
+ _softButtonCapabilities = nil;
+ _buttonCapabilities = nil;
+ _presetBankCapabilities = nil;
+ _hmiZoneCapabilities = nil;
+ _speechCapabilities = nil;
+ _prerecordedSpeechCapabilities = nil;
+ _vrCapability = NO;
+ _audioPassThruCapabilities = nil;
+ _pcmStreamCapability = nil;
+ _navigationCapability = nil;
+ _phoneCapability = nil;
+ _videoStreamingCapability = nil;
+ _remoteControlCapability = nil;
+}
+
+
+#pragma mark - Notifications
+
+-(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];
+}
+
+- (void)sdl_registerResponse:(SDLRPCResponseNotification *)notification {
+ SDLRegisterAppInterfaceResponse *response = (SDLRegisterAppInterfaceResponse *)notification.response;
+ if (!response.success.boolValue) { return; }
+
+ self.displayCapabilities = response.displayCapabilities;
+ self.hmiCapabilities = response.hmiCapabilities;
+ self.softButtonCapabilities = response.softButtonCapabilities;
+ self.buttonCapabilities = response.buttonCapabilities;
+ self.presetBankCapabilities = response.presetBankCapabilities;
+ self.hmiZoneCapabilities = response.hmiZoneCapabilities;
+ self.speechCapabilities = response.speechCapabilities;
+ self.prerecordedSpeechCapabilities = response.prerecordedSpeech;
+ self.vrCapability = (response.vrCapabilities.count > 0 && response.vrCapabilities.firstObject == SDLVRCapabilitiesText) ? YES : NO;
+ self.audioPassThruCapabilities = response.audioPassThruCapabilities;
+ self.pcmStreamCapability = response.pcmStreamCapabilities;
+}
+
+- (void)sdl_displayLayoutResponse:(SDLRPCResponseNotification *)notification {
+ SDLSetDisplayLayoutResponse *response = (SDLSetDisplayLayoutResponse *)notification.response;
+ if (!response.success.boolValue) { return; }
+
+ self.displayCapabilities = response.displayCapabilities;
+ self.buttonCapabilities = response.buttonCapabilities;
+ self.softButtonCapabilities = response.softButtonCapabilities;
+ self.presetBankCapabilities = response.presetBankCapabilities;
+}
+
+- (void)sdl_systemCapabilityResponse:(SDLRPCResponseNotification *)notification {
+ SDLGetSystemCapabilityResponse *response = (SDLGetSystemCapabilityResponse *)notification.response;
+ if (!response.success.boolValue) { return; }
+
+ SDLSystemCapability *systemCapabilityResponse = ((SDLGetSystemCapabilityResponse *)response).systemCapability;
+ SDLSystemCapabilityType systemCapabilityType = systemCapabilityResponse.systemCapabilityType;
+
+ if ([systemCapabilityType isEqualToEnum:SDLSystemCapabilityTypePhoneCall]) {
+ self.phoneCapability = systemCapabilityResponse.phoneCapability;
+ } else if ([systemCapabilityType isEqualToEnum:SDLSystemCapabilityTypeNavigation]) {
+ self.navigationCapability = systemCapabilityResponse.navigationCapability;
+ } else if ([systemCapabilityType isEqualToEnum:SDLSystemCapabilityTypeRemoteControl]) {
+ self.remoteControlCapability = systemCapabilityResponse.remoteControlCapability;
+ } else if ([systemCapabilityType isEqualToEnum:SDLSystemCapabilityTypeVideoStreaming]) {
+ self.videoStreamingCapability = systemCapabilityResponse.videoStreamingCapability;
+ } else {
+ SDLLogW(@"Received response for unknown System Capability Type: %@", systemCapabilityType);
+ }
+
+ if (self.systemCapabilityHandler == nil) { return; }
+ self.systemCapabilityHandler(nil, self);
+}
+
+#pragma mark - Capability Request
+
+- (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);
+ }];
+}
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SmartDeviceLink.h b/SmartDeviceLink/SmartDeviceLink.h
index 339f23910..a46e7e554 100644
--- a/SmartDeviceLink/SmartDeviceLink.h
+++ b/SmartDeviceLink/SmartDeviceLink.h
@@ -343,6 +343,9 @@ FOUNDATION_EXPORT const unsigned char SmartDeviceLinkVersionString[];
#import "SDLManager.h"
#import "SDLManagerDelegate.h"
+// System Capabilities
+#import "SDLSystemCapabilityManager.h"
+
// Permissions
#import "SDLPermissionConstants.h"
#import "SDLPermissionManager.h"
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m
index 1ba37a291..dd2f11dbf 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m
@@ -28,7 +28,9 @@
#import "SDLStateMachine.h"
#import "SDLStreamingMediaConfiguration.h"
#import "SDLStreamingMediaManager.h"
+#import "SDLSystemCapabilityManager.h"
#import "SDLTextAlignment.h"
+#import "SDLTTSChunk.h"
#import "SDLUnregisterAppInterface.h"
#import "SDLUnregisterAppInterfaceResponse.h"
@@ -61,7 +63,6 @@ describe(@"a lifecycle manager", ^{
__block SDLLifecycleManager *testManager = nil;
__block SDLConfiguration *testConfig = nil;
- __block id managerDelegateMock = OCMProtocolMock(@protocol(SDLManagerDelegate));
__block id protocolMock = OCMClassMock([SDLAbstractProtocol class]);
__block id proxyBuilderClassMock = OCMStrictClassMock([SDLProxyFactory class]);
__block id proxyMock = OCMClassMock([SDLProxy class]);
@@ -69,6 +70,7 @@ describe(@"a lifecycle manager", ^{
__block id fileManagerMock = OCMClassMock([SDLFileManager class]);
__block id permissionManagerMock = OCMClassMock([SDLPermissionManager class]);
__block id streamingManagerMock = OCMClassMock([SDLStreamingMediaManager class]);
+ __block id systemCapabilityMock = OCMClassMock([SDLSystemCapabilityManager class]);
beforeEach(^{
OCMStub([proxyBuilderClassMock buildSDLProxyWithListener:[OCMArg any]]).andReturn(proxyMock);
@@ -81,16 +83,17 @@ describe(@"a lifecycle manager", ^{
testConfig = [SDLConfiguration configurationWithLifecycle:testLifecycleConfig lockScreen:[SDLLockScreenConfiguration disabledConfiguration] logging:[SDLLogConfiguration defaultConfiguration] streamingMedia:[SDLStreamingMediaConfiguration insecureConfiguration]];
testConfig.lifecycleConfig.languagesSupported = @[SDLLanguageEnUs, SDLLanguageEnGb];
testConfig.lifecycleConfig.language = SDLLanguageEnUs;
- testManager = [[SDLLifecycleManager alloc] initWithConfiguration:testConfig delegate:managerDelegateMock];
+ testManager = [[SDLLifecycleManager alloc] initWithConfiguration:testConfig delegate:OCMProtocolMock(@protocol(SDLManagerDelegate))];
testManager.lockScreenManager = lockScreenManagerMock;
testManager.fileManager = fileManagerMock;
testManager.permissionManager = permissionManagerMock;
testManager.streamManager = streamingManagerMock;
+ testManager.systemCapabilityManager = systemCapabilityMock;
});
- xit(@"should initialize properties", ^{
+ it(@"should initialize properties", ^{
expect(testManager.configuration).toNot(equal(testConfig)); // This is copied
- expect(testManager.delegate).to(equal(managerDelegateMock)); // TODO: Broken on OCMock 3.3.1 & Swift 3 Quick / Nimble
+ expect(testManager.delegate).toNot(beNil());
expect(testManager.lifecycleState).to(match(SDLLifecycleStateStopped));
expect(@(testManager.lastCorrelationId)).to(equal(@0));
expect(testManager.fileManager).toNot(beNil());
@@ -102,6 +105,7 @@ describe(@"a lifecycle manager", ^{
expect(testManager.notificationDispatcher).toNot(beNil());
expect(testManager.responseDispatcher).toNot(beNil());
expect(testManager.streamManager).toNot(beNil());
+ expect(testManager.systemCapabilityManager).toNot(beNil());
expect(@([testManager conformsToProtocol:@protocol(SDLConnectionManagerType)])).to(equal(@YES));
});
@@ -344,50 +348,58 @@ describe(@"a lifecycle manager", ^{
});
});
- context(@"when the register response is of another language", ^{
- xit(@"should call config update delegate method before saying it's ready", ^{
- SDLRegisterAppInterfaceResponse *response = [[SDLRegisterAppInterfaceResponse alloc] init];
- response.success = @YES;
- response.resultCode = SDLResultWrongLanguage;
- response.info = @"Language mismatch";
- response.language = SDLLanguageEnGb;
-
- testManager.registerResponse = response;
-
- SDLLifecycleConfigurationUpdate *update = [[SDLLifecycleConfigurationUpdate alloc] initWithAppName:@"EnGb" shortAppName:nil ttsName:nil voiceRecognitionCommandNames:nil];
-
- OCMStub([managerDelegateMock managerShouldUpdateLifecycleToLanguage:[OCMArg any]]).andReturn(update);
- expect(testManager.configuration.lifecycleConfig.language).to(be(SDLLanguageEnUs));
-
- [testManager.lifecycleStateMachine setToState:SDLLifecycleStateRegistered fromOldState:SDLLifecycleStateConnected callEnterTransition:YES];
+ context(@"when the register response returns different language than the one passed with the lifecycle configuration", ^{
+ beforeEach(^{
+ expect(testManager.configuration.lifecycleConfig.appName).to(equal(testConfig.lifecycleConfig.appName));
+ expect(testManager.configuration.lifecycleConfig.shortAppName).to(equal(testConfig.lifecycleConfig.shortAppName));
+ expect(testManager.configuration.lifecycleConfig.ttsName).to(beNil());
+ expect(testManager.configuration.lifecycleConfig.language).to(equal(testConfig.lifecycleConfig.language));
+ expect(testManager.configuration.lifecycleConfig.languagesSupported).to(equal(testConfig.lifecycleConfig.languagesSupported));
+ });
+
+ it(@"should should update the configuration when the app supports the head unit language", ^{
+ SDLRegisterAppInterfaceResponse *registerAppInterfaceResponse = [[SDLRegisterAppInterfaceResponse alloc] init];
+ registerAppInterfaceResponse.success = @YES;
+ registerAppInterfaceResponse.resultCode = SDLResultWrongLanguage;
+ registerAppInterfaceResponse.info = @"Language mismatch";
+ registerAppInterfaceResponse.language = SDLLanguageEnGb;
+ testManager.registerResponse = registerAppInterfaceResponse;
+
+ SDLLifecycleConfigurationUpdate *update = [[SDLLifecycleConfigurationUpdate alloc] initWithAppName:@"EnGb" shortAppName:@"E" ttsName:[SDLTTSChunk textChunksFromString:@"EnGb ttsName"] voiceRecognitionCommandNames:nil];
+ OCMStub([testManager.delegate managerShouldUpdateLifecycleToLanguage:[OCMArg any]]).andReturn(update);
- // TODO: testManager delgate broken on OCMock 3.3.1 & Swift 3 Quick / Nimble
- OCMVerify([managerDelegateMock managerShouldUpdateLifecycleToLanguage:[OCMArg any]]);
+ [testManager.lifecycleStateMachine setToState:SDLLifecycleStateUpdatingConfiguration fromOldState:SDLLifecycleStateRegistered callEnterTransition:YES];
+ // Transition to StateSettingUpManagers to prevent assert error from the lifecycle machine
+ [testManager.lifecycleStateMachine setToState:SDLLifecycleStateSettingUpManagers fromOldState:SDLLifecycleStateUpdatingConfiguration callEnterTransition:NO];
+
+ expect(testManager.configuration.lifecycleConfig.language).to(equal(SDLLanguageEnGb));
expect(testManager.configuration.lifecycleConfig.appName).to(equal(@"EnGb"));
- expect(testManager.configuration.lifecycleConfig.language).to(be(SDLLanguageEnGb));
+ expect(testManager.configuration.lifecycleConfig.shortAppName).to(equal(@"E"));
+ expect(testManager.configuration.lifecycleConfig.ttsName).to(equal([SDLTTSChunk textChunksFromString:@"EnGb ttsName"]));
+
+ OCMVerify([testManager.delegate managerShouldUpdateLifecycleToLanguage:[OCMArg any]]);
});
- });
-
- context(@"when the register response is of another not supported language", ^{
- xit(@"should not update configuration as language is not supported", ^{
- SDLRegisterAppInterfaceResponse *response = [[SDLRegisterAppInterfaceResponse alloc] init];
- response.success = @YES;
- response.resultCode = SDLResultWrongLanguage;
- response.info = @"Language mismatch";
- response.language = SDLLanguageDeDe;
-
- testManager.registerResponse = response;
-
- SDLLifecycleConfigurationUpdate *update = nil;
- // TODO: testManager delgate broken on OCMock 3.3.1 & Swift 3 Quick / Nimble
- OCMStub([managerDelegateMock managerShouldUpdateLifecycleToLanguage:[OCMArg any]]).andReturn(update);
- expect(testManager.configuration.lifecycleConfig.language).to(be(SDLLanguageEnUs));
-
- [testManager.lifecycleStateMachine setToState:SDLLifecycleStateRegistered fromOldState:SDLLifecycleStateConnected callEnterTransition:YES];
-
- OCMVerify([managerDelegateMock managerShouldUpdateLifecycleToLanguage:[OCMArg any]]);
- expect(testManager.configuration.lifecycleConfig.language).to(be(SDLLanguageEnUs));
+ it(@"should not update the configuration when the app does not support the head unit language", ^{
+ SDLRegisterAppInterfaceResponse *registerAppInterfaceResponse = [[SDLRegisterAppInterfaceResponse alloc] init];
+ registerAppInterfaceResponse.success = @YES;
+ registerAppInterfaceResponse.resultCode = SDLResultWrongLanguage;
+ registerAppInterfaceResponse.info = @"Language mismatch";
+ registerAppInterfaceResponse.language = SDLLanguageDeDe;
+ testManager.registerResponse = registerAppInterfaceResponse;
+
+ OCMStub([testManager.delegate managerShouldUpdateLifecycleToLanguage:[OCMArg any]]).andReturn(nil);
+
+ [testManager.lifecycleStateMachine setToState:SDLLifecycleStateUpdatingConfiguration fromOldState:SDLLifecycleStateRegistered callEnterTransition:YES];
+ // Transition to StateSettingUpManagers to prevent assert error from the lifecycle machine
+ [testManager.lifecycleStateMachine setToState:SDLLifecycleStateSettingUpManagers fromOldState:SDLLifecycleStateUpdatingConfiguration callEnterTransition:NO];
+
+ expect(testManager.configuration.lifecycleConfig.language).to(equal(SDLLanguageEnUs));
+ expect(testManager.configuration.lifecycleConfig.appName).to(equal(@"Test App"));
+ expect(testManager.configuration.lifecycleConfig.shortAppName).to(equal(@"Short Name"));
+ expect(testManager.configuration.lifecycleConfig.ttsName).to(beNil());
+
+ OCMVerify([testManager.delegate managerShouldUpdateLifecycleToLanguage:[OCMArg any]]);
});
});
});
@@ -396,11 +408,11 @@ describe(@"a lifecycle manager", ^{
beforeEach(^{
[testManager.lifecycleStateMachine setToState:SDLLifecycleStateReady fromOldState:nil callEnterTransition:NO];
});
-
+
it(@"can send an RPC", ^{
SDLShow *testShow = [[SDLShow alloc] initWithMainField1:@"test" mainField2:nil alignment:nil];
[testManager sendRequest:testShow];
-
+
OCMVerify([proxyMock sendRPC:[OCMArg isKindOfClass:[SDLShow class]]]);
});
@@ -454,7 +466,9 @@ describe(@"a lifecycle manager", ^{
});
it(@"should call the delegate", ^{
- OCMVerify([managerDelegateMock hmiLevel:oldHMILevel didChangeToLevel:testHMILevel]);
+ // Since notifications are sent to SDLManagerDelegate observers on the main thread, force the block to execute manually on the main thread. If this is not done, the test case may fail.
+ [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]];
+ OCMVerify([testManager.delegate hmiLevel:[OCMArg any] didChangeToLevel:[OCMArg any]]);
});
});
});
@@ -482,7 +496,10 @@ describe(@"a lifecycle manager", ^{
});
it(@"should call the delegate", ^{
- OCMVerify([managerDelegateMock audioStreamingState:oldAudioStreamingState didChangeToState:testAudioStreamingState]);
+ // Since notifications are sent to SDLManagerDelegate observers on the main thread, force the block to execute manually on the main thread. If this is not done, the test case may fail.
+ [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]];
+
+ OCMVerify([testManager.delegate audioStreamingState:oldAudioStreamingState didChangeToState:testAudioStreamingState]);
});
});
});
@@ -491,7 +508,7 @@ describe(@"a lifecycle manager", ^{
__block SDLOnHMIStatus *testHMIStatus = nil;
__block SDLSystemContext testSystemContext = nil;
__block SDLSystemContext oldSystemContext = nil;
-
+
beforeEach(^{
oldSystemContext = testManager.systemContext;
testHMIStatus = [[SDLOnHMIStatus alloc] init];
@@ -499,6 +516,9 @@ describe(@"a lifecycle manager", ^{
context(@"a alert system context state", ^{
beforeEach(^{
+ expect(testManager.lifecycleStateMachine.currentState).to(equal(SDLLifecycleStateReady));
+ expect(testManager.systemContext).to(beNil());
+
testSystemContext = SDLSystemContextAlert;
testHMIStatus.systemContext = testSystemContext;
@@ -510,7 +530,13 @@ describe(@"a lifecycle manager", ^{
});
it(@"should call the delegate", ^{
- OCMVerify([managerDelegateMock systemContext:oldSystemContext didChangeToContext:testSystemContext]);
+ // Since notifications are sent to SDLManagerDelegate observers on the main thread, force the block to execute manually on the main thread. If this is not done, the test case may fail.
+ [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]];
+ OCMVerify([testManager.delegate systemContext:[OCMArg any] didChangeToContext:[OCMArg any]]);
+ });
+
+ afterEach(^{
+ expect(testManager.delegate).toNot(beNil());
});
});
});
diff --git a/SmartDeviceLinkTests/SDLScreenManagerSpec.m b/SmartDeviceLinkTests/SDLScreenManagerSpec.m
index 6e56ea140..481295539 100644
--- a/SmartDeviceLinkTests/SDLScreenManagerSpec.m
+++ b/SmartDeviceLinkTests/SDLScreenManagerSpec.m
@@ -3,6 +3,7 @@
#import <OCMock/OCMock.h>
#import "SDLFileManager.h"
+#import "SDLHMILevel.h"
#import "SDLScreenManager.h"
#import "SDLShow.h"
#import "SDLSoftButtonManager.h"
@@ -17,6 +18,7 @@
@property (weak, nonatomic) SDLFileManager *fileManager;
@property (strong, nonatomic, nullable) SDLShow *inProgressUpdate;
+@property (copy, nonatomic, nullable) SDLHMILevel currentLevel;
@end
@@ -26,6 +28,7 @@
@property (weak, nonatomic) SDLFileManager *fileManager;
@property (strong, nonatomic, nullable) SDLShow *inProgressUpdate;
+@property (copy, nonatomic, nullable) SDLHMILevel currentLevel;
@end
@@ -77,6 +80,9 @@ describe(@"screen manager", ^{
describe(@"batching updates", ^{
beforeEach(^{
+ SDLHMILevel hmiLevelFull = SDLHMILevelFull;
+ testScreenManager.softButtonManager.currentLevel = hmiLevelFull;
+ testScreenManager.textAndGraphicManager.currentLevel = hmiLevelFull;
[testScreenManager beginUpdates];
});
diff --git a/SmartDeviceLinkTests/SDLSystemCapabilityManagerSpec.m b/SmartDeviceLinkTests/SDLSystemCapabilityManagerSpec.m
new file mode 100644
index 000000000..ae6ba1ca9
--- /dev/null
+++ b/SmartDeviceLinkTests/SDLSystemCapabilityManagerSpec.m
@@ -0,0 +1,397 @@
+#import <Quick/Quick.h>
+#import <Nimble/Nimble.h>
+
+#import "SDLAudioPassThruCapabilities.h"
+#import "SDLButtonCapabilities.h"
+#import "SDLDisplayCapabilities.h"
+#import "SDLGetSystemCapability.h"
+#import "SDLGetSystemCapabilityResponse.h"
+#import "SDLHMICapabilities.h"
+#import "SDLNavigationCapability.h"
+#import "SDLNotificationConstants.h"
+#import "SDLPhoneCapability.h"
+#import "SDLPresetBankCapabilities.h"
+#import "SDLRegisterAppInterfaceResponse.h"
+#import "SDLRemoteControlCapabilities.h"
+#import "SDLRPCNotificationNotification.h"
+#import "SDLRPCResponseNotification.h"
+#import "SDLScreenParams.h"
+#import "SDLSetDisplayLayoutResponse.h"
+#import "SDLSoftButtonCapabilities.h"
+#import "SDLSystemCapability.h"
+#import "SDLSystemCapabilityManager.h"
+#import "SDLVideoStreamingCapability.h"
+#import "TestConnectionManager.h"
+
+
+QuickSpecBegin(SDLSystemCapabilityManagerSpec)
+
+describe(@"System capability manager", ^{
+ __block SDLSystemCapabilityManager *testSystemCapabilityManager = nil;
+ __block TestConnectionManager *testConnectionManager = nil;
+
+ beforeEach(^{
+ testConnectionManager = [[TestConnectionManager alloc] init];
+ testSystemCapabilityManager = [[SDLSystemCapabilityManager alloc] initWithConnectionManager:testConnectionManager];
+ });
+
+ it(@"should initialize 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());
+ });
+
+ context(@"When notified of a register app interface response", ^{
+ __block SDLRegisterAppInterfaceResponse *testRegisterAppInterfaceResponse = nil;
+ __block SDLDisplayCapabilities *testDisplayCapabilities = nil;
+ __block SDLHMICapabilities *testHMICapabilities = nil;
+ __block NSArray<SDLSoftButtonCapabilities *> *testSoftButtonCapabilities = nil;
+ __block NSArray<SDLButtonCapabilities *> *testButtonCapabilities = nil;
+ __block SDLPresetBankCapabilities *testPresetBankCapabilities = nil;
+ __block NSArray<SDLHMIZoneCapabilities> *testHMIZoneCapabilities = nil;
+ __block NSArray<SDLSpeechCapabilities> *testSpeechCapabilities = nil;
+ __block NSArray<SDLPrerecordedSpeech> *testPrerecordedSpeechCapabilities = nil;
+ __block NSArray<SDLVRCapabilities> *testVRCapabilities = nil;
+ __block NSArray<SDLAudioPassThruCapabilities *> *testAudioPassThruCapabilities = nil;
+ __block SDLAudioPassThruCapabilities *testPCMStreamCapability = nil;
+
+ beforeEach(^{
+ testDisplayCapabilities = [[SDLDisplayCapabilities alloc] init];
+ testDisplayCapabilities.graphicSupported = @NO;
+
+ testHMICapabilities = [[SDLHMICapabilities alloc] init];
+ testHMICapabilities.navigation = @NO;
+ testHMICapabilities.phoneCall = @YES;
+ testHMICapabilities.videoStreaming = @YES;
+
+ SDLSoftButtonCapabilities *softButtonCapability = [[SDLSoftButtonCapabilities alloc] init];
+ softButtonCapability.shortPressAvailable = @YES;
+ softButtonCapability.longPressAvailable = @NO;
+ softButtonCapability.upDownAvailable = @NO;
+ softButtonCapability.imageSupported = @YES;
+ testSoftButtonCapabilities = @[softButtonCapability];
+
+ SDLButtonCapabilities *buttonCapabilities = [[SDLButtonCapabilities alloc] init];
+ buttonCapabilities.name = SDLButtonNameOk;
+ buttonCapabilities.shortPressAvailable = @YES;
+ buttonCapabilities.longPressAvailable = @YES;
+ buttonCapabilities.upDownAvailable = @YES;
+ testButtonCapabilities = @[buttonCapabilities];
+
+ testPresetBankCapabilities = [[SDLPresetBankCapabilities alloc] init];
+ testPresetBankCapabilities.onScreenPresetsAvailable = @NO;
+
+ testHMIZoneCapabilities = @[SDLHMIZoneCapabilitiesFront, SDLHMIZoneCapabilitiesBack];
+ testSpeechCapabilities = @[SDLSpeechCapabilitiesText, SDLSpeechCapabilitiesSilence];
+ testPrerecordedSpeechCapabilities = @[SDLPrerecordedSpeechHelp, SDLPrerecordedSpeechInitial];
+ testVRCapabilities = @[SDLVRCapabilitiesText];
+
+ SDLAudioPassThruCapabilities *audioPassThruCapability = [[SDLAudioPassThruCapabilities alloc] init];
+ audioPassThruCapability.samplingRate = SDLSamplingRate8KHZ;
+ audioPassThruCapability.bitsPerSample = SDLBitsPerSample8Bit;
+ audioPassThruCapability.audioType = SDLAudioTypePCM;
+ testAudioPassThruCapabilities = @[audioPassThruCapability];
+ testPCMStreamCapability = audioPassThruCapability;
+
+ testRegisterAppInterfaceResponse = [[SDLRegisterAppInterfaceResponse alloc] init];
+ testRegisterAppInterfaceResponse.displayCapabilities = testDisplayCapabilities;
+ testRegisterAppInterfaceResponse.hmiCapabilities = testHMICapabilities;
+ testRegisterAppInterfaceResponse.softButtonCapabilities = testSoftButtonCapabilities;
+ testRegisterAppInterfaceResponse.buttonCapabilities = testButtonCapabilities;
+ testRegisterAppInterfaceResponse.presetBankCapabilities = testPresetBankCapabilities;
+ testRegisterAppInterfaceResponse.hmiZoneCapabilities = testHMIZoneCapabilities;
+ testRegisterAppInterfaceResponse.speechCapabilities = testSpeechCapabilities;
+ testRegisterAppInterfaceResponse.prerecordedSpeech = testPrerecordedSpeechCapabilities;
+ testRegisterAppInterfaceResponse.vrCapabilities = testVRCapabilities;
+ testRegisterAppInterfaceResponse.audioPassThruCapabilities = testAudioPassThruCapabilities;
+ testRegisterAppInterfaceResponse.pcmStreamCapabilities = testPCMStreamCapability;
+ });
+
+ describe(@"If the Register App Interface request fails", ^{
+ beforeEach(^{
+ testRegisterAppInterfaceResponse.success = @NO;
+ SDLRPCResponseNotification *notification = [[SDLRPCResponseNotification alloc] initWithName:SDLDidReceiveRegisterAppInterfaceResponse object:self rpcResponse:testRegisterAppInterfaceResponse];
+ [[NSNotificationCenter defaultCenter] postNotification:notification];
+ });
+
+ it(@"should not save any of the RAIR capabilities", ^{
+ 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());
+ });
+ });
+
+ describe(@"If the Register App Interface request succeeds", ^{
+ beforeEach(^{
+ testRegisterAppInterfaceResponse.success = @YES;
+ SDLRPCResponseNotification *notification = [[SDLRPCResponseNotification alloc] initWithName:SDLDidReceiveRegisterAppInterfaceResponse object:self rpcResponse:testRegisterAppInterfaceResponse];
+ [[NSNotificationCenter defaultCenter] postNotification:notification];
+ });
+
+ it(@"should should save the RAIR capabilities", ^{
+ expect(testSystemCapabilityManager.displayCapabilities).to(equal(testDisplayCapabilities));
+ expect(testSystemCapabilityManager.hmiCapabilities).to(equal(testHMICapabilities));
+ expect(testSystemCapabilityManager.softButtonCapabilities).to(equal(testSoftButtonCapabilities));
+ expect(testSystemCapabilityManager.buttonCapabilities).to(equal(testButtonCapabilities));
+ expect(testSystemCapabilityManager.presetBankCapabilities).to(equal(testPresetBankCapabilities));
+ expect(testSystemCapabilityManager.hmiZoneCapabilities).to(equal(testHMIZoneCapabilities));
+ expect(testSystemCapabilityManager.speechCapabilities).to(equal(testSpeechCapabilities));
+ expect(testSystemCapabilityManager.prerecordedSpeechCapabilities).to(equal(testPrerecordedSpeechCapabilities));
+ expect(testSystemCapabilityManager.vrCapability).to(beTrue());
+ expect(testSystemCapabilityManager.audioPassThruCapabilities).to(equal(testAudioPassThruCapabilities));
+ expect(testSystemCapabilityManager.pcmStreamCapability).to(equal(testPCMStreamCapability));
+ });
+ });
+
+ afterEach(^{
+ // Make sure the system capabilities properties were not inadverdently set
+ expect(testSystemCapabilityManager.phoneCapability).to(beNil());
+ expect(testSystemCapabilityManager.navigationCapability).to(beNil());
+ expect(testSystemCapabilityManager.videoStreamingCapability).to(beNil());
+ expect(testSystemCapabilityManager.remoteControlCapability).to(beNil());
+ });
+ });
+
+ context(@"When notified of a Set Display Layout Response", ^ {
+ __block SDLSetDisplayLayoutResponse *testSetDisplayLayoutResponse = nil;
+ __block SDLDisplayCapabilities *testDisplayCapabilities = nil;
+ __block NSArray<SDLSoftButtonCapabilities *> *testSoftButtonCapabilities = nil;
+ __block NSArray<SDLButtonCapabilities *> *testButtonCapabilities = nil;
+ __block SDLPresetBankCapabilities *testPresetBankCapabilities = nil;
+
+ beforeEach(^{
+ testDisplayCapabilities = [[SDLDisplayCapabilities alloc] init];
+ testDisplayCapabilities.graphicSupported = @NO;
+
+ SDLSoftButtonCapabilities *softButtonCapability = [[SDLSoftButtonCapabilities alloc] init];
+ softButtonCapability.shortPressAvailable = @NO;
+ softButtonCapability.longPressAvailable = @NO;
+ softButtonCapability.upDownAvailable = @NO;
+ softButtonCapability.imageSupported = @NO;
+ testSoftButtonCapabilities = @[softButtonCapability];
+
+ SDLButtonCapabilities *buttonCapabilities = [[SDLButtonCapabilities alloc] init];
+ buttonCapabilities.name = SDLButtonNameOk;
+ buttonCapabilities.shortPressAvailable = @NO;
+ buttonCapabilities.longPressAvailable = @NO;
+ buttonCapabilities.upDownAvailable = @NO;
+ testButtonCapabilities = @[buttonCapabilities];
+
+ testPresetBankCapabilities = [[SDLPresetBankCapabilities alloc] init];
+ testPresetBankCapabilities.onScreenPresetsAvailable = @NO;
+
+ testSetDisplayLayoutResponse = [[SDLSetDisplayLayoutResponse alloc] init];
+ testSetDisplayLayoutResponse.displayCapabilities = testDisplayCapabilities;
+ testSetDisplayLayoutResponse.buttonCapabilities = testButtonCapabilities;
+ testSetDisplayLayoutResponse.softButtonCapabilities = testSoftButtonCapabilities;
+ testSetDisplayLayoutResponse.presetBankCapabilities = testPresetBankCapabilities;
+ });
+
+ describe(@"If the Set Display Layout request fails", ^{
+ beforeEach(^{
+ testSetDisplayLayoutResponse.success = @NO;
+ SDLRPCResponseNotification *notification = [[SDLRPCResponseNotification alloc] initWithName:SDLDidReceiveSetDisplayLayoutResponse object:self rpcResponse:testSetDisplayLayoutResponse];
+ [[NSNotificationCenter defaultCenter] postNotification:notification];
+ });
+
+ it(@"should not save any capabilities", ^{
+ expect(testSystemCapabilityManager.displayCapabilities).to(beNil());
+ expect(testSystemCapabilityManager.softButtonCapabilities).to(beNil());
+ expect(testSystemCapabilityManager.buttonCapabilities).to(beNil());
+ expect(testSystemCapabilityManager.presetBankCapabilities).to(beNil());
+ });
+ });
+
+ describe(@"If the Set Display Layout request succeeds", ^{
+ beforeEach(^{
+ testSetDisplayLayoutResponse.success = @YES;
+ SDLRPCResponseNotification *notification = [[SDLRPCResponseNotification alloc] initWithName:SDLDidReceiveSetDisplayLayoutResponse object:self rpcResponse:testSetDisplayLayoutResponse];
+ [[NSNotificationCenter defaultCenter] postNotification:notification];
+ });
+
+ it(@"should should save the capabilities", ^{
+ expect(testSystemCapabilityManager.displayCapabilities).to(equal(testDisplayCapabilities));
+ expect(testSystemCapabilityManager.softButtonCapabilities).to(equal(testSoftButtonCapabilities));
+ expect(testSystemCapabilityManager.buttonCapabilities).to(equal(testButtonCapabilities));
+ expect(testSystemCapabilityManager.presetBankCapabilities).to(equal(testPresetBankCapabilities));
+ });
+ });
+
+ afterEach(^{
+ // Make sure the other RAIR properties and system capabilities were not inadverdently set
+ expect(testSystemCapabilityManager.hmiCapabilities).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());
+ });
+ });
+
+ context(@"When notified of a Get System Capability Response", ^{
+ __block SDLGetSystemCapabilityResponse *testGetSystemCapabilityResponse;
+ __block SDLPhoneCapability *testPhoneCapability = nil;
+
+ beforeEach(^{
+ testPhoneCapability = [[SDLPhoneCapability alloc] initWithDialNumber:YES];
+
+ testGetSystemCapabilityResponse = [[SDLGetSystemCapabilityResponse alloc] init];
+ testGetSystemCapabilityResponse.systemCapability = [[SDLSystemCapability alloc] init];
+ testGetSystemCapabilityResponse.systemCapability.phoneCapability = testPhoneCapability;
+ 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];
+ });
+
+ it(@"should should not save the capabilities", ^{
+ expect(testSystemCapabilityManager.phoneCapability).to(beNil());
+ });
+ });
+
+ 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 save the capabilities", ^{
+ expect(testSystemCapabilityManager.phoneCapability).to(equal(testPhoneCapability));
+ });
+ });
+ });
+
+ 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(testError));
+ expect(systemCapabilityManager.phoneCapability).to(beNil());
+ done();
+ }];
+
+ [testConnectionManager respondToLastRequestWithResponse:testGetSystemCapabilityResponse error:testError];
+ });
+ });
+
+ it(@"should should not save the capabilities", ^{
+ expect(testSystemCapabilityManager.phoneCapability).to(beNil());
+ });
+ });
+
+ context(@"If the request succeeded", ^{
+ beforeEach(^{
+ testGetSystemCapabilityResponse.success = @YES;
+
+ [testSystemCapabilityManager updateCapabilityType:testGetSystemCapabilityResponse.systemCapability.systemCapabilityType completionHandler:^(NSError * _Nullable error, SDLSystemCapabilityManager * _Nonnull systemCapabilityManager) {
+ // The handler will not be notifified
+ }];
+
+ [testConnectionManager respondToLastRequestWithResponse:testGetSystemCapabilityResponse error:nil];
+ });
+
+ 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());
+ });
+ });
+ });
+
+ afterEach(^{
+ // Make sure the RAIR properties and other system capabilities were not inadverdently set
+ 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.navigationCapability).to(beNil());
+ expect(testSystemCapabilityManager.videoStreamingCapability).to(beNil());
+ expect(testSystemCapabilityManager.remoteControlCapability).to(beNil());
+ });
+ });
+
+ context(@"When the system capability manager is stopped after being started", ^{
+ beforeEach(^{
+ SDLDisplayCapabilities *testDisplayCapabilities = [[SDLDisplayCapabilities alloc] init];
+ testDisplayCapabilities.graphicSupported = @NO;
+
+ SDLRegisterAppInterfaceResponse *testRegisterAppInterfaceResponse = [[SDLRegisterAppInterfaceResponse alloc] init];
+ testRegisterAppInterfaceResponse.displayCapabilities = testDisplayCapabilities;
+ testRegisterAppInterfaceResponse.success = @YES;
+
+ SDLRPCResponseNotification *notification = [[SDLRPCResponseNotification alloc] initWithName:SDLDidReceiveRegisterAppInterfaceResponse object:self rpcResponse:testRegisterAppInterfaceResponse];
+ [[NSNotificationCenter defaultCenter] postNotification:notification];
+
+ expect(testSystemCapabilityManager.displayCapabilities).to(equal(testDisplayCapabilities));
+ });
+
+ describe(@"When stopped", ^{
+ 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());
+ });
+ });
+ });
+});
+
+QuickSpecEnd
+
diff --git a/SmartDeviceLink_Example/AppConstants.h b/SmartDeviceLink_Example/AppConstants.h
index 166fa7bca..56dbe486a 100644
--- a/SmartDeviceLink_Example/AppConstants.h
+++ b/SmartDeviceLink_Example/AppConstants.h
@@ -76,6 +76,10 @@ extern NSString * const WheelIconImageName;
extern NSString * const ExampleAppNameSpanish;
extern NSString * const ExampleAppNameFrench;
+#pragma mark - SDL Vehicle Data
+extern NSString * const VehicleDataOdometerName;
+extern NSString * const VehicleDataSpeedName;
+
@interface AppConstants : NSObject
@end
diff --git a/SmartDeviceLink_Example/AppConstants.m b/SmartDeviceLink_Example/AppConstants.m
index 63abd5c18..178d76dc9 100644
--- a/SmartDeviceLink_Example/AppConstants.m
+++ b/SmartDeviceLink_Example/AppConstants.m
@@ -74,6 +74,10 @@ NSString * const WheelIconImageName = @"wheel_icon";
NSString * const ExampleAppNameSpanish = @"SDL AplicaciĆ³n de ejemplo";
NSString * const ExampleAppNameFrench = @"SDL Exemple App";
+#pragma mark - SDL Vehicle Data
+NSString * const VehicleDataOdometerName = @"Odometer";
+NSString * const VehicleDataSpeedName = @"Speed";
+
@implementation AppConstants
@end
diff --git a/SmartDeviceLink_Example/Classes/ProxyManager.m b/SmartDeviceLink_Example/Classes/ProxyManager.m
index effcae40d..8d8af2389 100644
--- a/SmartDeviceLink_Example/Classes/ProxyManager.m
+++ b/SmartDeviceLink_Example/Classes/ProxyManager.m
@@ -144,10 +144,12 @@ NS_ASSUME_NONNULL_BEGIN
self.sdlManager.screenManager.textField1 = self.isTextEnabled ? SmartDeviceLinkText : nil;
self.sdlManager.screenManager.textField2 = self.isTextEnabled ? [NSString stringWithFormat:@"Obj-C %@", ExampleAppText] : nil;
- self.sdlManager.screenManager.primaryGraphic = self.areImagesEnabled ? [SDLArtwork persistentArtworkWithImage:[UIImage imageNamed:ExampleAppLogoName] asImageFormat:SDLArtworkImageFormatPNG] : nil;
+ if (self.sdlManager.systemCapabilityManager.displayCapabilities.graphicSupported) {
+ self.sdlManager.screenManager.primaryGraphic = self.areImagesEnabled ? [SDLArtwork persistentArtworkWithImage:[UIImage imageNamed:@"sdl_logo_green"] asImageFormat:SDLArtworkImageFormatPNG] : nil;
+ }
[self.sdlManager.screenManager endUpdatesWithCompletionHandler:^(NSError * _Nullable error) {
- NSLog(@"Updated text and graphics, error? %@", error);
+ SDLLogD(@"Updated text and graphics, error? %@", error);
}];
}
@@ -258,6 +260,40 @@ NS_ASSUME_NONNULL_BEGIN
return getVehicleDataCommand;
}
++ (SDLAddCommand *)sdlex_dialNumberCommandWithManager:(SDLManager *)manager {
+ NSString *menuName = @"Dial Number";
+ SDLMenuParams *commandMenuParams = [[SDLMenuParams alloc] initWithMenuName:menuName];
+
+ SDLAddCommand *dialNumberCommand = [[SDLAddCommand alloc] init];
+ dialNumberCommand.vrCommands = [NSMutableArray arrayWithObject:menuName];
+ dialNumberCommand.menuParams = commandMenuParams;
+ dialNumberCommand.cmdID = @3;
+ dialNumberCommand.handler = ^(SDLOnCommand * _Nonnull command) {
+ SDLLogD(@"Checking if app has permission to dial a number");
+ if (![manager.permissionManager isRPCAllowed:@"DialNumber"]) {
+ SDLAlert* alert = [[SDLAlert alloc] init];
+ alert.alertText1 = @"This app does not have the required permissions to dial a number";
+ [manager sendRequest:alert];
+ return;
+ }
+
+ SDLLogD(@"Checking phone call capability");
+ [manager.systemCapabilityManager updateCapabilityType:SDLSystemCapabilityTypePhoneCall completionHandler:^(NSError * _Nullable error, SDLSystemCapabilityManager *systemCapabilityManager) {
+ SDLPhoneCapability *phoneCapability = systemCapabilityManager.phoneCapability;
+ if (phoneCapability.dialNumberEnabled) {
+ SDLLogD(@"Dialing number");
+ [self.class sdlex_sendDialNumberWithManager:manager];
+ } else {
+ SDLAlert* alert = [[SDLAlert alloc] init];
+ alert.alertText1 = @"The dial number feature is unavailable for this head unit";
+ [manager sendRequest:alert];
+ }
+ }];
+ };
+
+ return dialNumberCommand;
+}
+
+ (SDLSpeak *)sdlex_appNameSpeak {
SDLSpeak *speak = [[SDLSpeak alloc] init];
speak.ttsChunks = [SDLTTSChunk textChunksFromString:ExampleAppNameTTS];
@@ -379,16 +415,22 @@ NS_ASSUME_NONNULL_BEGIN
SDLGetVehicleData *getVehicleData = [[SDLGetVehicleData alloc] initWithAccelerationPedalPosition:YES airbagStatus:YES beltStatus:YES bodyInformation:YES clusterModeStatus:YES deviceStatus:YES driverBraking:YES eCallInfo:YES emergencyEvent:YES engineTorque:YES externalTemperature:YES fuelLevel:YES fuelLevelState:YES gps:YES headLampStatus:YES instantFuelConsumption:YES myKey:YES odometer:YES prndl:YES rpm:YES speed:YES steeringWheelAngle:YES tirePressure:YES vin:YES wiperStatus:YES];
[manager sendRequest:getVehicleData withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) {
- NSLog(@"vehicle data response: %@", response);
+ SDLLogD(@"vehicle data response: %@", response);
+ }];
+}
+
++ (void)sdlex_sendDialNumberWithManager:(SDLManager *)manager {
+ SDLDialNumber *dialNumber = [[SDLDialNumber alloc] initWithNumber:@"5555555555"];
+ [manager sendRequest:dialNumber withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) {
+ SDLLogD(@"Dial number response: %@", response);
}];
}
- (void)sdlex_prepareRemoteSystem {
- [self.sdlManager sendRequests:@[[self.class sdlex_speakNameCommandWithManager:self.sdlManager], [self.class sdlex_interactionSetCommandWithManager:self.sdlManager], [self.class sdlex_vehicleDataCommandWithManager:self.sdlManager], [self.class sdlex_createOnlyChoiceInteractionSet]]
+ [self.sdlManager sendRequests:@[[self.class sdlex_speakNameCommandWithManager:self.sdlManager], [self.class sdlex_interactionSetCommandWithManager:self.sdlManager], [self.class sdlex_vehicleDataCommandWithManager:self.sdlManager], [self.class sdlex_dialNumberCommandWithManager:self.sdlManager], [self.class sdlex_createOnlyChoiceInteractionSet]]
progressHandler:^(__kindof SDLRPCRequest * _Nonnull request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error, float percentComplete) {
- NSLog(@"Commands sent updated, percent complete %f%%", percentComplete * 100);
- }
- completionHandler:nil];
+ SDLLogD(@"Commands sent updated, percent complete %f%%", percentComplete * 100);
+ } completionHandler:nil];
}
diff --git a/SmartDeviceLink_Example/VehicleDataManager.swift b/SmartDeviceLink_Example/VehicleDataManager.swift
index 0d829c6c1..603e29156 100644
--- a/SmartDeviceLink_Example/VehicleDataManager.swift
+++ b/SmartDeviceLink_Example/VehicleDataManager.swift
@@ -45,27 +45,29 @@ extension VehicleDataManager {
sdlManager.send(request: subscribeToVehicleOdometer) { [unowned self] (request, response, error) in
guard let result = response?.resultCode else { return }
+ var message = "\(VehicleDataOdometerName): "
switch result {
case .success:
SDLLog.d("Subscribed to vehicle odometer data")
- self.vehicleOdometerData += "Subscribed"
+ message += "Subscribed"
case .disallowed:
SDLLog.d("SubAccess to vehicle data disallowed")
- self.vehicleOdometerData += "Disallowed"
+ message += "Disallowed"
case .userDisallowed:
SDLLog.d("Vehicle user disabled access to vehicle data")
- self.vehicleOdometerData += "Disabled"
+ message += "Disabled"
case .ignored:
SDLLog.d("Already subscribed to odometer data")
- self.vehicleOdometerData += "Subscribed"
+ message += "Subscribed"
case .dataNotAvailable:
SDLLog.d("You have permission to access to vehicle data, but the vehicle you are connected to did not provide any data")
- self.vehicleOdometerData += "Unknown"
+ message += "Unknown"
default:
SDLLog.d("Unknown reason for failure to get vehicle data: \(error != nil ? error!.localizedDescription : "no error message")")
- self.vehicleOdometerData += "Unsubscribed"
+ message += "Unsubscribed"
return
}
+ self.vehicleOdometerData = message
guard let handler = self.refreshUIHandler else { return }
handler()
@@ -87,12 +89,12 @@ extension VehicleDataManager {
return
}
- vehicleOdometerData = "Odometer: \(odometer) km"
+ vehicleOdometerData = "\(VehicleDataOdometerName): \(odometer) km"
handler()
}
fileprivate func resetOdometer() {
- vehicleOdometerData = "Odometer: Unsubscribed"
+ vehicleOdometerData = "\(VehicleDataOdometerName): Unsubscribed"
}
}
@@ -120,7 +122,7 @@ extension VehicleDataManager {
return
}
- var alertMessage = "Speed: "
+ var alertMessage = "\(VehicleDataSpeedName): "
switch response.resultCode {
case .rejected:
SDLLog.d("The request for vehicle speed was rejected")