summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Fischer <joeljfischer@gmail.com>2019-08-14 13:46:25 -0400
committerJoel Fischer <joeljfischer@gmail.com>2019-08-14 13:46:25 -0400
commita65a23a44de1fbdc2b734bc1d01e203910fb0497 (patch)
treecaaa79ecef2d8d391fd9653a80613fd958c32b2e
parent4ed7407a7b79e9e0aeb0947a1d2366b1b12b2eef (diff)
parentd68f9cf1836a31f6e65f477418c0bf519f5a2dd5 (diff)
downloadsdl_ios-a65a23a44de1fbdc2b734bc1d01e203910fb0497.tar.gz
Merge develop
-rw-r--r--CHANGELOG.md5
-rw-r--r--Example Apps/Example ObjC/AlertManager.h2
-rw-r--r--Example Apps/Example ObjC/AlertManager.m18
-rw-r--r--Example Apps/Example ObjC/AudioManager.m4
-rw-r--r--Example Apps/Example ObjC/ButtonManager.m8
-rw-r--r--Example Apps/Example ObjC/MenuManager.m28
-rw-r--r--Example Apps/Example ObjC/PerformInteractionManager.m27
-rw-r--r--Example Apps/Example ObjC/ProxyManager.m1
-rw-r--r--Example Apps/Example ObjC/SmartDeviceLink-Example-ObjC-Info.plist2
-rw-r--r--Example Apps/Example ObjC/VehicleDataManager.m10
-rw-r--r--Example Apps/Example Swift/AlertManager.swift7
-rw-r--r--Example Apps/Example Swift/ButtonManager.swift6
-rw-r--r--Example Apps/Example Swift/MenuManager.swift16
-rw-r--r--Example Apps/Example Swift/PerformInteractionManager.swift26
-rw-r--r--Example Apps/Example Swift/ProxyManager.swift1
-rw-r--r--Example Apps/Example Swift/SmartDeviceLink-Example-Swift-Info.plist2
-rw-r--r--Example Apps/Shared/AppConstants.h7
-rw-r--r--Example Apps/Shared/AppConstants.m7
-rw-r--r--SmartDeviceLink-iOS.podspec7
-rw-r--r--SmartDeviceLink-iOS.xcodeproj/project.pbxproj70
-rw-r--r--SmartDeviceLink-iOS.xcodeproj/xcshareddata/xcschemes/SmartDeviceLink.xcscheme2
-rw-r--r--SmartDeviceLink.podspec7
-rw-r--r--SmartDeviceLink/CVPixelBufferRef+SDLUtil.m2
-rw-r--r--SmartDeviceLink/Info.plist2
-rw-r--r--SmartDeviceLink/NSMutableDictionary+Store.h2
-rw-r--r--SmartDeviceLink/NSMutableDictionary+Store.m2
-rw-r--r--SmartDeviceLink/SDLAlert.h29
-rw-r--r--SmartDeviceLink/SDLAlert.m51
-rw-r--r--SmartDeviceLink/SDLAppServiceManifest.h73
-rw-r--r--SmartDeviceLink/SDLAppServiceManifest.m69
-rw-r--r--SmartDeviceLink/SDLAsynchronousOperation.m6
-rw-r--r--SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m23
-rwxr-xr-xSmartDeviceLink/SDLAudioStreamManager.m10
-rw-r--r--SmartDeviceLink/SDLButtonName.h76
-rw-r--r--SmartDeviceLink/SDLButtonName.m15
-rw-r--r--SmartDeviceLink/SDLCheckChoiceVROptionalOperation.m4
-rw-r--r--SmartDeviceLink/SDLChoiceSetManager.m5
-rw-r--r--SmartDeviceLink/SDLDeleteChoicesOperation.m4
-rw-r--r--SmartDeviceLink/SDLDeleteFileOperation.h17
-rw-r--r--SmartDeviceLink/SDLDeleteFileOperation.m2
-rw-r--r--SmartDeviceLink/SDLDisplayCapabilities.h6
-rw-r--r--SmartDeviceLink/SDLFile.m4
-rw-r--r--SmartDeviceLink/SDLFileManager.m88
-rw-r--r--SmartDeviceLink/SDLFocusableItemLocator.m8
-rw-r--r--SmartDeviceLink/SDLFunctionID.m2
-rw-r--r--SmartDeviceLink/SDLGlobals.h4
-rw-r--r--SmartDeviceLink/SDLGlobals.m9
-rw-r--r--SmartDeviceLink/SDLIAPTransport.m2
-rw-r--r--SmartDeviceLink/SDLImageFieldName.h5
-rw-r--r--SmartDeviceLink/SDLImageFieldName.m1
-rw-r--r--SmartDeviceLink/SDLKeyboardDelegate.h21
-rw-r--r--SmartDeviceLink/SDLKeyboardProperties.h32
-rw-r--r--SmartDeviceLink/SDLKeyboardProperties.m13
-rw-r--r--SmartDeviceLink/SDLLifecycleManager.m129
-rw-r--r--SmartDeviceLink/SDLListFilesOperation.h10
-rw-r--r--SmartDeviceLink/SDLListFilesOperation.m4
-rw-r--r--SmartDeviceLink/SDLLockScreenConfiguration.h17
-rw-r--r--SmartDeviceLink/SDLLockScreenConfiguration.m18
-rw-r--r--SmartDeviceLink/SDLLockScreenManager.h5
-rw-r--r--SmartDeviceLink/SDLLockScreenManager.m75
-rw-r--r--SmartDeviceLink/SDLLockScreenStatus.h2
-rw-r--r--SmartDeviceLink/SDLLockScreenStatusManager.h3
-rw-r--r--SmartDeviceLink/SDLLockScreenStatusManager.m3
-rw-r--r--SmartDeviceLink/SDLLockScreenViewController.h19
-rw-r--r--SmartDeviceLink/SDLLockScreenViewController.m37
-rw-r--r--SmartDeviceLink/SDLLogFileModuleMap.m2
-rw-r--r--SmartDeviceLink/SDLLogManager.m11
-rw-r--r--SmartDeviceLink/SDLMediaServiceData.h35
-rw-r--r--SmartDeviceLink/SDLMediaServiceData.m17
-rw-r--r--SmartDeviceLink/SDLMenuManager.h4
-rw-r--r--SmartDeviceLink/SDLMenuManager.m45
-rw-r--r--SmartDeviceLink/SDLMsgVersion.h52
-rw-r--r--SmartDeviceLink/SDLMsgVersion.m58
-rw-r--r--SmartDeviceLink/SDLNotificationConstants.h4
-rw-r--r--SmartDeviceLink/SDLNotificationConstants.m6
-rw-r--r--SmartDeviceLink/SDLNotificationDispatcher.m16
-rw-r--r--SmartDeviceLink/SDLOnDriverDistraction.h14
-rw-r--r--SmartDeviceLink/SDLOnDriverDistraction.m18
-rw-r--r--SmartDeviceLink/SDLOnLockScreenStatus.h1
-rw-r--r--SmartDeviceLink/SDLOnLockScreenStatus.m3
-rw-r--r--SmartDeviceLink/SDLPermissionManager.m32
-rw-r--r--SmartDeviceLink/SDLPreloadChoicesOperation.m4
-rw-r--r--SmartDeviceLink/SDLPresentChoiceSetOperation.m24
-rw-r--r--SmartDeviceLink/SDLPresentKeyboardOperation.m24
-rw-r--r--SmartDeviceLink/SDLProtocol.m20
-rw-r--r--SmartDeviceLink/SDLProxy.m32
-rw-r--r--SmartDeviceLink/SDLProxyListener.h35
-rw-r--r--SmartDeviceLink/SDLPublishAppService.h2
-rw-r--r--SmartDeviceLink/SDLRPCFunctionNames.h2
-rw-r--r--SmartDeviceLink/SDLRPCFunctionNames.m2
-rw-r--r--SmartDeviceLink/SDLRPCParameterNames.h6
-rw-r--r--SmartDeviceLink/SDLRPCParameterNames.m6
-rw-r--r--SmartDeviceLink/SDLRPCRequest.m4
-rw-r--r--SmartDeviceLink/SDLRPCResponse.m5
-rw-r--r--SmartDeviceLink/SDLRegisterAppInterface.h12
-rw-r--r--SmartDeviceLink/SDLRegisterAppInterface.m20
-rw-r--r--SmartDeviceLink/SDLRegisterAppInterfaceResponse.h12
-rw-r--r--SmartDeviceLink/SDLRegisterAppInterfaceResponse.m25
-rw-r--r--SmartDeviceLink/SDLResponseDispatcher.m6
-rw-r--r--SmartDeviceLink/SDLScreenManager.h18
-rw-r--r--SmartDeviceLink/SDLScreenManager.m16
-rw-r--r--SmartDeviceLink/SDLShow.h9
-rw-r--r--SmartDeviceLink/SDLShow.m8
-rw-r--r--SmartDeviceLink/SDLShowAppMenu.h35
-rw-r--r--SmartDeviceLink/SDLShowAppMenu.m48
-rw-r--r--SmartDeviceLink/SDLShowAppMenuResponse.h20
-rw-r--r--SmartDeviceLink/SDLShowAppMenuResponse.m23
-rw-r--r--SmartDeviceLink/SDLStreamingMediaManager.h5
-rw-r--r--SmartDeviceLink/SDLStreamingMediaManager.m9
-rw-r--r--SmartDeviceLink/SDLStreamingVideoLifecycleManager.h6
-rw-r--r--SmartDeviceLink/SDLStreamingVideoLifecycleManager.m5
-rw-r--r--SmartDeviceLink/SDLSyncMsgVersion.h1
-rw-r--r--SmartDeviceLink/SDLSyncMsgVersion.m3
-rw-r--r--SmartDeviceLink/SDLTextAndGraphicManager.h1
-rw-r--r--SmartDeviceLink/SDLTextAndGraphicManager.m17
-rw-r--r--SmartDeviceLink/SDLTextFieldName.h7
-rw-r--r--SmartDeviceLink/SDLTextFieldName.m1
-rw-r--r--SmartDeviceLink/SDLTouch.m4
-rw-r--r--SmartDeviceLink/SDLTouchManager.m176
-rw-r--r--SmartDeviceLink/SDLUnpublishAppService.h34
-rw-r--r--SmartDeviceLink/SDLUnpublishAppService.m49
-rw-r--r--SmartDeviceLink/SDLUnpublishAppServiceResponse.h20
-rw-r--r--SmartDeviceLink/SDLUnpublishAppServiceResponse.m27
-rw-r--r--SmartDeviceLink/SDLUploadFileOperation.h2
-rw-r--r--SmartDeviceLink/SDLUploadFileOperation.m17
-rw-r--r--SmartDeviceLink/SDLVersion.h10
-rw-r--r--SmartDeviceLink/SDLVersion.m17
-rw-r--r--SmartDeviceLink/SmartDeviceLink.h5
-rw-r--r--SmartDeviceLink/dispatch_timer.h18
-rw-r--r--SmartDeviceLink/dispatch_timer.m38
-rw-r--r--SmartDeviceLinkSwift/Info.plist2
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLAsynchronousRPCRequestOperationSpec.m18
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLFileManagerSpec.m1963
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m9
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLLockScreenConfigurationSpec.m24
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLLockScreenManagerSpec.m161
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m89
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLPermissionsManagerSpec.m31
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLPresentChoiceSetOperationSpec.m4
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLPresentKeyboardOperationSpec.m6
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m1
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLTextAndGraphicManagerSpec.m63
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLUploadFileOperationSpec.m335
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLVersionSpec.m18
-rw-r--r--SmartDeviceLinkTests/Notifications/SDLNotificationDispatcherSpec.m2
-rw-r--r--SmartDeviceLinkTests/ProxySpecs/SDLHapticManagerSpec.m2
-rw-r--r--SmartDeviceLinkTests/ProxySpecs/SDLLockScreenStatusManagerSpec.m4
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/EnumSpecs/SDLTextFieldNameSpec.m1
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/NotificationSpecs/SDLOnDriverDistractionSpec.m34
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/NotificationSpecs/SDLOnLockScreenStatusSpec.m10
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLAlertSpec.m374
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLRegisterAppInterfaceSpec.m149
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLShowAppMenuSpec.m50
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLShowSpec.m18
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLUnpublishAppServiceSpec.m55
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/ResponseSpecs/SDLRegisterAppInterfaceResponseSpec.m173
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/ResponseSpecs/SDLShowAppMenuResponseSpec.m19
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/ResponseSpecs/SDLUnpublishAppServiceResponseSpec.m38
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLAppServiceManifestSpec.m221
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLKeyboardPropertiesSpec.m53
-rw-r--r--SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLMediaServiceDataSpec.m34
-rwxr-xr-xSmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLSystemCapabilitySpec.m2
-rw-r--r--SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testAppAndVehicleIcons@2x.pngbin29249 -> 38911 bytes
-rw-r--r--SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testAppAndVehicleIcons@3x.pngbin65090 -> 65070 bytes
-rw-r--r--SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testLightBackgroundNoAppNoVehicleIcons@2x.pngbin29249 -> 38911 bytes
-rw-r--r--SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testLightBackgroundNoAppNoVehicleIcons@3x.pngbin65090 -> 65070 bytes
-rw-r--r--SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testNoAppNoVehicleIcons@2x.pngbin29249 -> 38911 bytes
-rw-r--r--SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testNoAppNoVehicleIcons@3x.pngbin65090 -> 65070 bytes
-rw-r--r--SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyAppIcon@2x.pngbin29249 -> 38911 bytes
-rw-r--r--SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyAppIcon@3x.pngbin65090 -> 65070 bytes
-rw-r--r--SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyVehicleIcon@2x.pngbin29249 -> 38911 bytes
-rw-r--r--SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyVehicleIcon@3x.pngbin65090 -> 65070 bytes
-rw-r--r--SmartDeviceLinkTests/SDLAsynchronousRPCOperationSpec.m9
-rw-r--r--SmartDeviceLinkTests/SDLRPCFunctionNamesSpec.m1
-rw-r--r--SmartDeviceLinkTests/SDLScreenManagerSpec.m6
-rw-r--r--SmartDeviceLinkTests/TestResponse.m4
-rw-r--r--SmartDeviceLinkTests/TestUtilities/TestRequestProgressResponse.m4
-rw-r--r--SmartDeviceLinkTests/UtilitiesSpecs/Touches/DispatchTimerSpec.m47
-rw-r--r--SmartDeviceLinkTests/UtilitiesSpecs/Touches/SDLTouchManagerSpec.m162
179 files changed, 4467 insertions, 2109 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3bcfbf9b8..b780fa9c4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,9 @@
# Changelog
+## 6.3.1
+### Bug Fixes
+* Fix unregistering for EATransport notifications can interfere with other apps' EATransport notifications (https://www.github.com/smartdevicelink/sdl_ios/issues/1329).
+* Fix issues related to the background task running when the device is in the process of making an IAP connection but is in the background (https://www.github.com/smartdevicelink/sdl_ios/issues/1326, https://www.github.com/smartdevicelink/sdl_ios/issues/1327).
+
## 6.3.0
### Versions
* Supports [SDL RPC Spec 5.1.0](https://github.com/smartdevicelink/rpc_spec/releases/tag/5.1.0) and [SDL Protocol Spec 5.2.0](https://github.com/smartdevicelink/protocol_spec/releases/tag/5.2.0).
diff --git a/Example Apps/Example ObjC/AlertManager.h b/Example Apps/Example ObjC/AlertManager.h
index 1d4471b95..bd803cec0 100644
--- a/Example Apps/Example ObjC/AlertManager.h
+++ b/Example Apps/Example ObjC/AlertManager.h
@@ -15,7 +15,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface AlertManager : NSObject
+ (SDLAlert *)alertWithMessage:(NSString *)textField1 textField2:(nullable NSString *)textField2;
-+ (SDLAlert *)alertWithMessageAndCloseButton:(NSString *)textField1 textField2:(nullable NSString *)textField2;
++ (SDLAlert *)alertWithMessageAndCloseButton:(NSString *)textField1 textField2:(nullable NSString *)textField2 iconName:(nullable NSString *)iconName;
@end
diff --git a/Example Apps/Example ObjC/AlertManager.m b/Example Apps/Example ObjC/AlertManager.m
index cab877a5e..d95bd2fc8 100644
--- a/Example Apps/Example ObjC/AlertManager.m
+++ b/Example Apps/Example ObjC/AlertManager.m
@@ -6,6 +6,7 @@
// Copyright © 2018 smartdevicelink. All rights reserved.
//
+#import "AppConstants.h"
#import "AlertManager.h"
#import "SmartDeviceLink.h"
@@ -21,18 +22,19 @@ NS_ASSUME_NONNULL_BEGIN
* @return An SDLAlert object
*/
+ (SDLAlert *)alertWithMessage:(NSString *)textField1 textField2:(nullable NSString *)textField2 {
- return [[SDLAlert alloc] initWithAlertText1:textField1 alertText2:textField2 duration:5000];
+ return [[SDLAlert alloc] initWithAlertText1:textField1 alertText2:textField2];
}
/**
- * Creates an alert with up to two lines of text and a close button that will dismiss the alert when tapped
- *
- * @param textField1 The first line of a message to display in the alert
- * @param textField2 The second line of a message to display in the alert
- * @return An SDLAlert object
+ Creates an alert with up to two lines of text and a close button that will dismiss the alert when tapped
+
+ @param textField1 The first line of a message to display in the alert
+ @param textField2 The second line of a message to display in the alert
+ @param iconName The name of the uploaded icon artwork
+ @return An SDLAlert object
*/
-+ (SDLAlert *)alertWithMessageAndCloseButton:(NSString *)textField1 textField2:(nullable NSString *)textField2 {
- return [[SDLAlert alloc] initWithAlertText1:textField1 alertText2:textField2 alertText3:nil duration:5000 softButtons:@[[self sdlex_okSoftButton]]];
++ (SDLAlert *)alertWithMessageAndCloseButton:(NSString *)textField1 textField2:(nullable NSString *)textField2 iconName:(nullable NSString *)iconName {
+ return [[SDLAlert alloc] initWithAlertText1:textField1 alertText2:textField2 alertText3:nil ttsChunks:nil playTone:NO progressIndicator:NO duration:5000 softButtons:@[[self sdlex_okSoftButton]] alertIcon:[[SDLImage alloc] initWithName:iconName isTemplate:YES]];
}
+ (SDLSoftButton *)sdlex_okSoftButton {
diff --git a/Example Apps/Example ObjC/AudioManager.m b/Example Apps/Example ObjC/AudioManager.m
index 6d1b66c48..cd6ec4ecf 100644
--- a/Example Apps/Example ObjC/AudioManager.m
+++ b/Example Apps/Example ObjC/AudioManager.m
@@ -86,7 +86,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)startRecording {
if (self.speechRecognitionAuthState != SpeechRecognitionAuthStateAuthorized) {
SDLLogW(@"This app does not have permission to access the Speech Recognition API");
- [self.sdlManager sendRequest:[AlertManager alertWithMessageAndCloseButton:@"You must give this app permission to access Speech Recognition" textField2:nil]];
+ [self.sdlManager sendRequest:[AlertManager alertWithMessageAndCloseButton:@"You must give this app permission to access Speech Recognition" textField2:nil iconName:nil]];
return;
}
@@ -155,7 +155,7 @@ NS_ASSUME_NONNULL_BEGIN
// The `PerformAudioPassThru` timed out or the "Done" button was pressed in the pop-up.
SDLLogD(@"Audio Pass Thru ended successfully");
NSString *alertMessage = [NSString stringWithFormat:@"You said: %@", weakSelf.speechTranscription.length == 0 ? @"No speech detected" : weakSelf.speechTranscription];
- [weakSelf.sdlManager sendRequest:[AlertManager alertWithMessageAndCloseButton:alertMessage textField2:nil]];
+ [weakSelf.sdlManager sendRequest:[AlertManager alertWithMessageAndCloseButton:alertMessage textField2:nil iconName:nil]];
} else if ([resultCode isEqualToEnum:SDLResultAborted]) {
// The "Cancel" button was pressed in the pop-up. Ignore this audio pass thru.
SDLLogD(@"Audio recording canceled");
diff --git a/Example Apps/Example ObjC/ButtonManager.m b/Example Apps/Example ObjC/ButtonManager.m
index 4befdf726..1809249db 100644
--- a/Example Apps/Example ObjC/ButtonManager.m
+++ b/Example Apps/Example ObjC/ButtonManager.m
@@ -73,14 +73,18 @@ NS_ASSUME_NONNULL_BEGIN
}
- (SDLSoftButtonObject *)sdlex_softButtonAlertWithManager:(SDLManager *)manager {
- SDLSoftButtonState *alertImageAndTextState = [[SDLSoftButtonState alloc] initWithStateName:AlertSoftButtonImageState text:AlertSoftButtonText artwork:[SDLArtwork artworkWithImage:[[UIImage imageNamed:CarBWIconImageName] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] asImageFormat:SDLArtworkImageFormatPNG]];
+ SDLSoftButtonState *alertImageAndTextState = [[SDLSoftButtonState alloc] initWithStateName:AlertSoftButtonImageState text:AlertSoftButtonText artwork:[SDLArtwork artworkWithImage:[[UIImage imageNamed:CarBWIconImageName] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] name:CarBWIconImageName asImageFormat:SDLArtworkImageFormatPNG]];
SDLSoftButtonState *alertTextState = [[SDLSoftButtonState alloc] initWithStateName:AlertSoftButtonTextState text:AlertSoftButtonText image:nil];
__weak typeof(self) weakself = self;
SDLSoftButtonObject *alertSoftButton = [[SDLSoftButtonObject alloc] initWithName:AlertSoftButton states:@[alertImageAndTextState, alertTextState] initialStateName:alertImageAndTextState.name handler:^(SDLOnButtonPress * _Nullable buttonPress, SDLOnButtonEvent * _Nullable buttonEvent) {
if (buttonPress == nil) { return; }
- [weakself.sdlManager sendRequest:[AlertManager alertWithMessageAndCloseButton:@"You pushed the soft button!" textField2:nil]];
+ [weakself.sdlManager.fileManager uploadArtwork:[SDLArtwork artworkWithImage:[UIImage imageNamed:CarBWIconImageName] asImageFormat:SDLArtworkImageFormatPNG] completionHandler:^(BOOL success, NSString * _Nonnull artworkName, NSUInteger bytesAvailable, NSError * _Nullable error) {
+ [weakself.sdlManager sendRequest:[AlertManager alertWithMessageAndCloseButton:@"You pushed the soft button!" textField2:nil iconName:artworkName] withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) {
+ NSLog(@"ALERT req: %@, res: %@, err: %@", request, response, error);
+ }];
+ }];
SDLLogD(@"Star icon soft button press fired");
}];
diff --git a/Example Apps/Example ObjC/MenuManager.m b/Example Apps/Example ObjC/MenuManager.m
index 7b626aef9..aa209a785 100644
--- a/Example Apps/Example ObjC/MenuManager.m
+++ b/Example Apps/Example ObjC/MenuManager.m
@@ -23,6 +23,8 @@ NS_ASSUME_NONNULL_BEGIN
return @[[self sdlex_menuCellSpeakNameWithManager:manager],
[self sdlex_menuCellGetAllVehicleDataWithManager:manager],
[self sdlex_menuCellShowPerformInteractionWithManager:manager performManager:performManager],
+ [self sdlex_sliderMenuCellWithManager:manager],
+ [self sdlex_scrollableMessageMenuCellWithManager:manager],
[self sdlex_menuCellRecordInCarMicrophoneAudioWithManager:manager],
[self sdlex_menuCellDialNumberWithManager:manager],
[self sdlex_menuCellChangeTemplateWithManager:manager],
@@ -79,7 +81,7 @@ NS_ASSUME_NONNULL_BEGIN
+ (SDLMenuCell *)sdlex_menuCellDialNumberWithManager:(SDLManager *)manager {
return [[SDLMenuCell alloc] initWithTitle:ACDialPhoneNumberMenuName icon:[SDLArtwork artworkWithImage:[[UIImage imageNamed:PhoneBWIconImageName] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] asImageFormat:SDLArtworkImageFormatPNG] voiceCommands:@[ACDialPhoneNumberMenuName] handler:^(SDLTriggerSource _Nonnull triggerSource) {
if (![RPCPermissionsManager isDialNumberRPCAllowedWithManager:manager]) {
- [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:@"This app does not have the required permissions to dial a number" textField2:nil]];
+ [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:@"This app does not have the required permissions to dial a number" textField2:nil iconName:nil]];
return;
}
@@ -98,7 +100,7 @@ NS_ASSUME_NONNULL_BEGIN
SDLSetDisplayLayout* display = [[SDLSetDisplayLayout alloc] initWithPredefinedLayout:SDLPredefinedLayoutNonMedia];
[manager sendRequest:display withResponseHandler:^(SDLRPCRequest *request, SDLRPCResponse *response, NSError *error) {
if (![response.resultCode isEqualToEnum:SDLResultSuccess]) {
- [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:errorMessage textField2:nil]];
+ [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:errorMessage textField2:nil iconName:nil]];
}
}];
}];
@@ -109,7 +111,7 @@ NS_ASSUME_NONNULL_BEGIN
SDLSetDisplayLayout* display = [[SDLSetDisplayLayout alloc] initWithPredefinedLayout:SDLPredefinedLayoutGraphicWithText];
[manager sendRequest:display withResponseHandler:^(SDLRPCRequest *request, SDLRPCResponse *response, NSError *error) {
if (![response.resultCode isEqualToEnum:SDLResultSuccess]) {
- [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:errorMessage textField2:nil]];
+ [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:errorMessage textField2:nil iconName:nil]];
}
}];
}];
@@ -122,7 +124,7 @@ NS_ASSUME_NONNULL_BEGIN
NSMutableArray *submenuItems = [NSMutableArray array];
for (int i = 0; i < 75; i++) {
SDLMenuCell *cell = [[SDLMenuCell alloc] initWithTitle:[NSString stringWithFormat:@"%@ %i", ACSubmenuItemMenuName, i] icon:[SDLArtwork artworkWithImage:[[UIImage imageNamed:MenuBWIconImageName] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] asImageFormat:SDLArtworkImageFormatPNG] voiceCommands:nil handler:^(SDLTriggerSource _Nonnull triggerSource) {
- [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:[NSString stringWithFormat:@"You selected %@ %i", ACSubmenuItemMenuName, i] textField2:nil]];
+ [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:[NSString stringWithFormat:@"You selected %@ %i", ACSubmenuItemMenuName, i] textField2:nil iconName:nil]];
}];
[submenuItems addObject:cell];
}
@@ -130,17 +132,31 @@ NS_ASSUME_NONNULL_BEGIN
return [[SDLMenuCell alloc] initWithTitle:ACSubmenuMenuName submenuLayout:SDLMenuLayoutList icon:[SDLArtwork artworkWithImage:[[UIImage imageNamed:MenuBWIconImageName] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] asImageFormat:SDLArtworkImageFormatPNG] subCells:[submenuItems copy]];
}
++ (SDLMenuCell *)sdlex_sliderMenuCellWithManager:(SDLManager *)manager {
+ return [[SDLMenuCell alloc] initWithTitle:ACSliderMenuName icon:nil voiceCommands:@[ACSliderMenuName] handler:^(SDLTriggerSource _Nonnull triggerSource) {
+ SDLSlider *sliderRPC = [[SDLSlider alloc] initWithNumTicks:3 position:1 sliderHeader:@"Select a letter" sliderFooters:@[@"A", @"B", @"C"] timeout:10000];
+ [manager sendRequest:sliderRPC];
+ }];
+}
+
++ (SDLMenuCell *)sdlex_scrollableMessageMenuCellWithManager:(SDLManager *)manager {
+ return [[SDLMenuCell alloc] initWithTitle:ACScrollableMessageMenuName icon:nil voiceCommands:@[ACScrollableMessageMenuName] handler:^(SDLTriggerSource _Nonnull triggerSource) {
+ SDLScrollableMessage *messageRPC = [[SDLScrollableMessage alloc] initWithMessage:@"This is a scrollable message\nIt can contain many lines" timeout:10000 softButtons:nil];
+ [manager sendRequest:messageRPC];
+ }];
+}
+
#pragma mark - Voice Commands
+ (SDLVoiceCommand *)sdlex_voiceCommandStartWithManager:(SDLManager *)manager {
return [[SDLVoiceCommand alloc] initWithVoiceCommands:@[VCStop] handler:^{
- [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:[NSString stringWithFormat:@"%@ voice command selected!", VCStop] textField2:nil]];
+ [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:[NSString stringWithFormat:@"%@ voice command selected!", VCStop] textField2:nil iconName:nil]];
}];
}
+ (SDLVoiceCommand *)sdlex_voiceCommandStopWithManager:(SDLManager *)manager {
return [[SDLVoiceCommand alloc] initWithVoiceCommands:@[VCStart] handler:^{
- [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:[NSString stringWithFormat:@"%@ voice command selected!", VCStart] textField2:nil]];
+ [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:[NSString stringWithFormat:@"%@ voice command selected!", VCStart] textField2:nil iconName:nil]];
}];
}
diff --git a/Example Apps/Example ObjC/PerformInteractionManager.m b/Example Apps/Example ObjC/PerformInteractionManager.m
index ea4c42503..0cc389f92 100644
--- a/Example Apps/Example ObjC/PerformInteractionManager.m
+++ b/Example Apps/Example ObjC/PerformInteractionManager.m
@@ -20,6 +20,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (strong, nonatomic, readonly) SDLChoiceSet *choiceSet;
@property (copy, nonatomic, readonly) NSArray<SDLChoiceCell *> *cells;
+@property (copy, nonatomic, readonly) NSArray<SDLVRHelpItem *> *vrHelpList;
@end
@@ -39,17 +40,25 @@ NS_ASSUME_NONNULL_BEGIN
}
- (SDLChoiceSet *)choiceSet {
- return [[SDLChoiceSet alloc] initWithTitle:PICSInitialPrompt delegate:self layout:SDLChoiceSetLayoutList timeout:10 initialPromptString:PICSInitialPrompt timeoutPromptString:PICSTimeoutPrompt helpPromptString:PICSHelpPrompt vrHelpList:nil choices:self.cells];
+ return [[SDLChoiceSet alloc] initWithTitle:PICSInitialPrompt delegate:self layout:SDLChoiceSetLayoutList timeout:10 initialPromptString:PICSInitialPrompt timeoutPromptString:PICSTimeoutPrompt helpPromptString:PICSHelpPrompt vrHelpList:self.vrHelpList choices:self.cells];
}
- (NSArray<SDLChoiceCell *> *)cells {
- SDLChoiceCell *firstChoice = [[SDLChoiceCell alloc] initWithText:PICSFirstChoice artwork:[SDLArtwork artworkWithStaticIcon:SDLStaticIconNameKey] voiceCommands:nil];
- SDLChoiceCell *secondChoice = [[SDLChoiceCell alloc] initWithText:PICSSecondChoice];
- SDLChoiceCell *thirdChoice = [[SDLChoiceCell alloc] initWithText:PICSThirdChoice];
+ SDLChoiceCell *firstChoice = [[SDLChoiceCell alloc] initWithText:PICSFirstChoice artwork:[SDLArtwork artworkWithStaticIcon:SDLStaticIconNameKey] voiceCommands:@[VCPICSFirstChoice]];
+ SDLChoiceCell *secondChoice = [[SDLChoiceCell alloc] initWithText:PICSSecondChoice artwork:[SDLArtwork artworkWithStaticIcon:SDLStaticIconNameMicrophone] voiceCommands:@[VCPICSecondChoice]];
+ SDLChoiceCell *thirdChoice = [[SDLChoiceCell alloc] initWithText:PICSThirdChoice artwork:[SDLArtwork artworkWithStaticIcon:SDLStaticIconNameKey] voiceCommands:@[VCPICSThirdChoice]];
return @[firstChoice, secondChoice, thirdChoice];
}
+- (NSArray<SDLVRHelpItem *> *)vrHelpList {
+ SDLVRHelpItem *vrHelpListFirst = [[SDLVRHelpItem alloc] initWithText:VCPICSFirstChoice image:nil];
+ SDLVRHelpItem *vrHelpListSecond = [[SDLVRHelpItem alloc] initWithText:VCPICSecondChoice image:nil];
+ SDLVRHelpItem *vrHelpListThird = [[SDLVRHelpItem alloc] initWithText:VCPICSThirdChoice image:nil];
+
+ return @[vrHelpListFirst, vrHelpListSecond, vrHelpListThird];
+}
+
- (SDLInteractionMode)modeForTriggerSource:(SDLTriggerSource)source {
return ([source isEqualToEnum:SDLTriggerSourceMenu] ? SDLInteractionModeManualOnly : SDLInteractionModeVoiceRecognitionOnly);
}
@@ -78,15 +87,15 @@ NS_ASSUME_NONNULL_BEGIN
[self.manager sendRequest:[[SDLSpeak alloc] initWithTTS:TTSYouMissed]];
}
-- (void)updateAutocompleteWithInput:(NSString *)currentInputText completionHandler:(SDLKeyboardAutocompleteCompletionHandler)completionHandler {
+- (void)updateAutocompleteWithInput:(NSString *)currentInputText autoCompleteResultsHandler:(SDLKeyboardAutoCompleteResultsHandler)resultsHandler {
if ([currentInputText.lowercaseString hasPrefix:@"f"]) {
- completionHandler(PICSFirstChoice);
+ resultsHandler(@[PICSFirstChoice]);
} else if ([currentInputText.lowercaseString hasPrefix:@"s"]) {
- completionHandler(PICSSecondChoice);
+ resultsHandler(@[PICSSecondChoice]);
} else if ([currentInputText.lowercaseString hasPrefix:@"t"]) {
- completionHandler(PICSThirdChoice);
+ resultsHandler(@[PICSThirdChoice]);
} else {
- completionHandler(nil);
+ resultsHandler(nil);
}
}
diff --git a/Example Apps/Example ObjC/ProxyManager.m b/Example Apps/Example ObjC/ProxyManager.m
index 453e843eb..980c5b137 100644
--- a/Example Apps/Example ObjC/ProxyManager.m
+++ b/Example Apps/Example ObjC/ProxyManager.m
@@ -188,6 +188,7 @@ NS_ASSUME_NONNULL_BEGIN
[screenManager beginUpdates];
screenManager.textAlignment = SDLTextAlignmentLeft;
+ screenManager.title = isTextEnabled ? @"Home" : nil;
screenManager.textField1 = isTextEnabled ? SmartDeviceLinkText : nil;
screenManager.textField2 = isTextEnabled ? [NSString stringWithFormat:@"Obj-C %@", ExampleAppText] : nil;
screenManager.textField3 = isTextEnabled ? self.vehicleDataManager.vehicleOdometerData : nil;
diff --git a/Example Apps/Example ObjC/SmartDeviceLink-Example-ObjC-Info.plist b/Example Apps/Example ObjC/SmartDeviceLink-Example-ObjC-Info.plist
index db70c2cae..ddf174213 100644
--- a/Example Apps/Example ObjC/SmartDeviceLink-Example-ObjC-Info.plist
+++ b/Example Apps/Example ObjC/SmartDeviceLink-Example-ObjC-Info.plist
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
- <string>6.3.0</string>
+ <string>6.3.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
diff --git a/Example Apps/Example ObjC/VehicleDataManager.m b/Example Apps/Example ObjC/VehicleDataManager.m
index fd82569d4..2ebb62422 100644
--- a/Example Apps/Example ObjC/VehicleDataManager.m
+++ b/Example Apps/Example ObjC/VehicleDataManager.m
@@ -137,7 +137,7 @@ NS_ASSUME_NONNULL_BEGIN
+ (void)getAllVehicleDataWithManager:(SDLManager *)manager triggerSource:(SDLTriggerSource)triggerSource vehicleDataType:(NSString *)vehicleDataType {
SDLLogD(@"Checking if app has permission to access vehicle data...");
if (![manager.permissionManager isRPCAllowed:@"GetVehicleData"]) {
- [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:@"This app does not have the required permissions to access vehicle data" textField2:nil]];
+ [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:@"This app does not have the required permissions to access vehicle data" textField2:nil iconName:nil]];
return;
}
@@ -146,7 +146,7 @@ NS_ASSUME_NONNULL_BEGIN
[manager sendRequest:getAllVehicleData withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) {
if (error || ![response isKindOfClass:SDLGetVehicleDataResponse.class]) {
- [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:@"Something went wrong while getting vehicle data" textField2:nil]];
+ [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:@"Something went wrong while getting vehicle data" textField2:nil iconName:nil]];
return;
}
@@ -176,7 +176,7 @@ NS_ASSUME_NONNULL_BEGIN
alertMessage = [TextValidator validateText:alertMessage length:200];
if ([triggerSource isEqualToEnum:SDLTriggerSourceMenu]) {
- [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:alertTitle textField2:alertMessage]];
+ [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:alertTitle textField2:alertMessage iconName:nil]];
} else {
NSString *spokenAlert = alertMessage ?: alertTitle;
[manager sendRequest:[[SDLSpeak alloc] initWithTTS:spokenAlert]];
@@ -258,7 +258,7 @@ NS_ASSUME_NONNULL_BEGIN
SDLLogD(@"Checking phone call capability");
[manager.systemCapabilityManager updateCapabilityType:SDLSystemCapabilityTypePhoneCall completionHandler:^(NSError * _Nullable error, SDLSystemCapabilityManager * _Nonnull systemCapabilityManager) {
if (!systemCapabilityManager.phoneCapability) {
- [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:@"The head unit does not support the phone call capability" textField2:nil]];
+ [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:@"The head unit does not support the phone call capability" textField2:nil iconName:nil]];
return;
}
@@ -266,7 +266,7 @@ NS_ASSUME_NONNULL_BEGIN
SDLLogD(@"Dialing phone number %@", phoneNumber);
[self sdlex_dialPhoneNumber:phoneNumber manager:manager];
} else {
- [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:@"The dial number feature is unavailable for this head unit" textField2:nil]];
+ [manager sendRequest:[AlertManager alertWithMessageAndCloseButton:@"The dial number feature is unavailable for this head unit" textField2:nil iconName:nil]];
}
}];
}
diff --git a/Example Apps/Example Swift/AlertManager.swift b/Example Apps/Example Swift/AlertManager.swift
index c463e7d36..820f69f40 100644
--- a/Example Apps/Example Swift/AlertManager.swift
+++ b/Example Apps/Example Swift/AlertManager.swift
@@ -21,7 +21,7 @@ class AlertManager {
/// - textField2: The second line of a message to display in the alert
/// - Returns: An SDLAlert object
class func alertWithMessage(_ textField1: String, textField2: String? = nil) -> SDLAlert {
- return SDLAlert(alertText1: textField1, alertText2: nil, alertText3: nil)
+ return SDLAlert(alertText1: textField1, alertText2: nil)
}
/// Creates an alert with up to two lines of text and a close button that will dismiss the alert when tapped
@@ -29,8 +29,9 @@ class AlertManager {
/// - Parameters:
/// - textField1: The first line of a message to display in the alert
/// - textField2: The second line of a message to display in the alert
+ /// - iconName: The name of the uploaded icon artwork
/// - Returns: An SDLAlert object
- class func alertWithMessageAndCloseButton(_ textField1: String, textField2: String? = nil) -> SDLAlert {
- return SDLAlert(alertText1: textField1, alertText2: textField2, alertText3: nil, duration: 5000, softButtons: [AlertManager.okSoftButton])
+ class func alertWithMessageAndCloseButton(_ textField1: String, textField2: String? = nil, iconName: String? = nil) -> SDLAlert {
+ return SDLAlert(alertText1: textField1, alertText2: textField2, alertText3: nil, ttsChunks: nil, playTone: false, progressIndicator: false, duration: 5000, softButtons: [AlertManager.okSoftButton], alertIcon: (iconName != nil) ? SDLImage(name: iconName!, isTemplate: true) : nil)
}
}
diff --git a/Example Apps/Example Swift/ButtonManager.swift b/Example Apps/Example Swift/ButtonManager.swift
index 2a7b7ccf7..e0953accc 100644
--- a/Example Apps/Example Swift/ButtonManager.swift
+++ b/Example Apps/Example Swift/ButtonManager.swift
@@ -70,8 +70,10 @@ private extension ButtonManager {
let textSoftButtonState = SDLSoftButtonState(stateName: AlertSoftButtonTextState, text: AlertSoftButtonText, image: nil)
return SDLSoftButtonObject(name: AlertSoftButton, states: [imageSoftButtonState, textSoftButtonState], initialStateName: imageSoftButtonState.name) { (buttonPress, buttonEvent) in
guard buttonPress != nil else { return }
- let alert = AlertManager.alertWithMessageAndCloseButton("You pressed the button!")
- manager.send(alert)
+ manager.fileManager.upload(artwork: SDLArtwork(image: UIImage(named: CarBWIconImageName)!, persistent: false, as: .PNG), completionHandler: { (success, artworkName, bytesAvailable, err) in
+ let alert = AlertManager.alertWithMessageAndCloseButton("You pressed the button!", iconName: artworkName)
+ manager.send(alert)
+ })
}
}
diff --git a/Example Apps/Example Swift/MenuManager.swift b/Example Apps/Example Swift/MenuManager.swift
index 7d93fa308..d39081ccd 100644
--- a/Example Apps/Example Swift/MenuManager.swift
+++ b/Example Apps/Example Swift/MenuManager.swift
@@ -19,6 +19,8 @@ class MenuManager: NSObject {
return [menuCellSpeakName(with: manager),
menuCellGetAllVehicleData(with: manager),
menuCellShowPerformInteraction(with: manager, choiceSetManager: choiceSetManager),
+ sliderMenuCell(with: manager),
+ scrollableMessageMenuCell(with: manager),
menuCellRecordInCarMicrophoneAudio(with: manager),
menuCellDialNumber(with: manager),
menuCellChangeTemplate(with: manager),
@@ -174,6 +176,20 @@ private extension MenuManager {
return SDLMenuCell(title: ACSubmenuMenuName, submenuLayout: .list, icon: SDLArtwork(image: #imageLiteral(resourceName: "choice_set").withRenderingMode(.alwaysTemplate), persistent: true, as: .PNG), subCells: submenuItems)
}
+
+ private class func sliderMenuCell(with manager: SDLManager) -> SDLMenuCell {
+ return SDLMenuCell(title: ACSliderMenuName, icon: nil, voiceCommands: [ACSliderMenuName], handler: { _ in
+ let slider = SDLSlider(numTicks: 3, position: 1, sliderHeader: "Select a letter", sliderFooters: ["A", "B", "C"], timeout: 10000)
+ manager.send(slider)
+ })
+ }
+
+ private class func scrollableMessageMenuCell(with manager: SDLManager) -> SDLMenuCell {
+ return SDLMenuCell(title: ACScrollableMessageMenuName, icon: nil, voiceCommands: [ACScrollableMessageMenuName], handler: { _ in
+ let scrollableMessage = SDLScrollableMessage(message: "This is a scrollable message\nIt can contain many lines", timeout: 10000, softButtons: nil)
+ manager.send(scrollableMessage)
+ })
+ }
}
// MARK: - Menu Voice Commands
diff --git a/Example Apps/Example Swift/PerformInteractionManager.swift b/Example Apps/Example Swift/PerformInteractionManager.swift
index 13e26e7fe..793f6526c 100644
--- a/Example Apps/Example Swift/PerformInteractionManager.swift
+++ b/Example Apps/Example Swift/PerformInteractionManager.swift
@@ -30,15 +30,23 @@ class PerformInteractionManager: NSObject {
private extension PerformInteractionManager {
/// The PICS menu items
var choiceCells: [SDLChoiceCell] {
- let firstChoice = SDLChoiceCell(text: PICSFirstChoice, artwork: SDLArtwork(staticIcon: .key), voiceCommands: nil)
- let secondChoice = SDLChoiceCell(text: PICSSecondChoice)
- let thirdChoice = SDLChoiceCell(text: PICSThirdChoice)
+ let firstChoice = SDLChoiceCell(text: PICSFirstChoice, artwork: SDLArtwork(staticIcon: .key), voiceCommands: [VCPICSFirstChoice])
+ let secondChoice = SDLChoiceCell(text: PICSSecondChoice, artwork: SDLArtwork(staticIcon: .microphone), voiceCommands: [VCPICSecondChoice])
+ let thirdChoice = SDLChoiceCell(text: PICSThirdChoice, artwork: SDLArtwork(staticIcon: .key), voiceCommands: [VCPICSThirdChoice])
return [firstChoice, secondChoice, thirdChoice]
}
+ var vrHelpList: [SDLVRHelpItem] {
+ let vrHelpListFirst = SDLVRHelpItem(text: VCPICSFirstChoice, image: nil)
+ let vrHelpListSecond = SDLVRHelpItem(text: VCPICSecondChoice, image: nil)
+ let vrHelpListThird = SDLVRHelpItem(text: VCPICSThirdChoice, image: nil)
+
+ return [vrHelpListFirst, vrHelpListSecond, vrHelpListThird]
+ }
+
/// Creates a PICS with three menu items and customized voice commands
var choiceSet: SDLChoiceSet {
- return SDLChoiceSet(title: PICSInitialPrompt, delegate: self, layout: .list, timeout: 10, initialPromptString: PICSInitialPrompt, timeoutPromptString: PICSTimeoutPrompt, helpPromptString: PICSHelpPrompt, vrHelpList: nil, choices: choiceCells)
+ return SDLChoiceSet(title: PICSInitialPrompt, delegate: self, layout: .list, timeout: 10, initialPromptString: PICSInitialPrompt, timeoutPromptString: PICSTimeoutPrompt, helpPromptString: PICSHelpPrompt, vrHelpList: vrHelpList, choices: choiceCells)
}
func interactionMode(for triggerSource: SDLTriggerSource) -> SDLInteractionMode {
@@ -77,15 +85,15 @@ extension PerformInteractionManager: SDLKeyboardDelegate {
}
}
- func updateAutocomplete(withInput currentInputText: String, completionHandler: @escaping SDLKeyboardAutocompleteCompletionHandler) {
+ func updateAutocomplete(withInput currentInputText: String, autoCompleteResultsHandler resultsHandler: @escaping SDLKeyboardAutoCompleteResultsHandler) {
if currentInputText.lowercased().hasPrefix("f") {
- completionHandler(PICSFirstChoice)
+ resultsHandler([PICSFirstChoice])
} else if currentInputText.lowercased().hasPrefix("s") {
- completionHandler(PICSSecondChoice)
+ resultsHandler([PICSSecondChoice])
} else if currentInputText.lowercased().hasPrefix("t") {
- completionHandler(PICSThirdChoice)
+ resultsHandler([PICSThirdChoice])
} else {
- completionHandler(nil)
+ resultsHandler(nil)
}
}
}
diff --git a/Example Apps/Example Swift/ProxyManager.swift b/Example Apps/Example Swift/ProxyManager.swift
index 40a703e4a..77d4f7976 100644
--- a/Example Apps/Example Swift/ProxyManager.swift
+++ b/Example Apps/Example Swift/ProxyManager.swift
@@ -266,6 +266,7 @@ private extension ProxyManager {
screenManager.beginUpdates()
screenManager.textAlignment = .left
+ screenManager.title = isTextVisible ? "Home" : nil
screenManager.textField1 = isTextVisible ? SmartDeviceLinkText : nil
screenManager.textField2 = isTextVisible ? "Swift \(ExampleAppText)" : nil
screenManager.textField3 = isTextVisible ? vehicleDataManager.vehicleOdometerData : nil
diff --git a/Example Apps/Example Swift/SmartDeviceLink-Example-Swift-Info.plist b/Example Apps/Example Swift/SmartDeviceLink-Example-Swift-Info.plist
index d3ab6c871..34a7b097a 100644
--- a/Example Apps/Example Swift/SmartDeviceLink-Example-Swift-Info.plist
+++ b/Example Apps/Example Swift/SmartDeviceLink-Example-Swift-Info.plist
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
- <string>6.3.0</string>
+ <string>6.3.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
diff --git a/Example Apps/Shared/AppConstants.h b/Example Apps/Shared/AppConstants.h
index 1c557c969..9e7ec3d28 100644
--- a/Example Apps/Shared/AppConstants.h
+++ b/Example Apps/Shared/AppConstants.h
@@ -64,6 +64,11 @@ extern NSString * const PICSFirstChoice;
extern NSString * const PICSSecondChoice;
extern NSString * const PICSThirdChoice;
+#pragma mark - SDL Perform Interaction Choice Set Menu VR Commands
+extern NSString * const VCPICSFirstChoice;
+extern NSString * const VCPICSecondChoice;
+extern NSString * const VCPICSThirdChoice;
+
#pragma mark - SDL Add Command Menu
extern NSString * const ACSpeakAppNameMenuName;
extern NSString * const ACShowChoiceSetMenuName;
@@ -74,6 +79,8 @@ extern NSString * const ACDialPhoneNumberMenuName;
extern NSString * const ACSubmenuMenuName;
extern NSString * const ACSubmenuItemMenuName;
extern NSString * const ACSubmenuTemplateMenuName;
+extern NSString * const ACSliderMenuName;
+extern NSString * const ACScrollableMessageMenuName;
extern NSString * const ACAccelerationPedalPositionMenuName;
extern NSString * const ACAirbagStatusMenuName;
diff --git a/Example Apps/Shared/AppConstants.m b/Example Apps/Shared/AppConstants.m
index 7e81eba13..1760ecb42 100644
--- a/Example Apps/Shared/AppConstants.m
+++ b/Example Apps/Shared/AppConstants.m
@@ -61,6 +61,11 @@ NSString * const PICSFirstChoice = @"First Choice";
NSString * const PICSSecondChoice = @"Second Choice";
NSString * const PICSThirdChoice = @"Third Choice";
+#pragma mark - SDL Perform Interaction Choice Set Menu VR Commands
+NSString * const VCPICSFirstChoice = @"First";
+NSString * const VCPICSecondChoice = @"Second";
+NSString * const VCPICSThirdChoice = @"Third";
+
#pragma mark - SDL Add Command Menu
NSString * const ACSpeakAppNameMenuName = @"Speak App Name";
NSString * const ACShowChoiceSetMenuName = @"Show Perform Interaction Choice Set";
@@ -71,6 +76,8 @@ NSString * const ACDialPhoneNumberMenuName = @"Dial Phone Number";
NSString * const ACSubmenuMenuName = @"Submenu";
NSString * const ACSubmenuItemMenuName = @"Item";
NSString * const ACSubmenuTemplateMenuName = @"Change Template";
+NSString * const ACSliderMenuName = @"Show Slider";
+NSString * const ACScrollableMessageMenuName = @"Show Scrollable Message";
NSString * const ACAccelerationPedalPositionMenuName = @"Acceleration Pedal Position";
NSString * const ACAirbagStatusMenuName = @"Airbag Status";
diff --git a/SmartDeviceLink-iOS.podspec b/SmartDeviceLink-iOS.podspec
index b51b523f6..903a63e7a 100644
--- a/SmartDeviceLink-iOS.podspec
+++ b/SmartDeviceLink-iOS.podspec
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "SmartDeviceLink-iOS"
-s.version = "6.3.0"
+s.version = "6.3.1"
s.summary = "Connect your app with cars!"
s.homepage = "https://github.com/smartdevicelink/SmartDeviceLink-iOS"
s.license = { :type => "New BSD", :file => "LICENSE" }
@@ -327,6 +327,8 @@ ss.public_header_files = [
'SmartDeviceLink/SDLSetMediaClockTimer.h',
'SmartDeviceLink/SDLSetMediaClockTimerResponse.h',
'SmartDeviceLink/SDLShow.h',
+'SmartDeviceLink/SDLShowAppMenu.h',
+'SmartDeviceLink/SDLShowAppMenuResponse.h',
'SmartDeviceLink/SDLShowConstantTBT.h',
'SmartDeviceLink/SDLShowConstantTBTResponse.h',
'SmartDeviceLink/SDLShowResponse.h',
@@ -356,6 +358,7 @@ ss.public_header_files = [
'SmartDeviceLink/SDLSubscribeWaypoints.h',
'SmartDeviceLink/SDLSubscribeWaypointsResponse.h',
'SmartDeviceLink/SDLSyncMsgVersion.h',
+'SmartDeviceLink/SDLMsgVersion.h',
'SmartDeviceLink/SDLSyncPData.h',
'SmartDeviceLink/SDLSyncPDataResponse.h',
'SmartDeviceLink/SDLSystemAction.h',
@@ -385,6 +388,8 @@ ss.public_header_files = [
'SmartDeviceLink/SDLTTSChunk.h',
'SmartDeviceLink/SDLTurn.h',
'SmartDeviceLink/SDLTurnSignal.h',
+'SmartDeviceLink/SDLUnpublishAppService.h',
+'SmartDeviceLink/SDLUnpublishAppServiceResponse.h',
'SmartDeviceLink/SDLUnregisterAppInterface.h',
'SmartDeviceLink/SDLUnregisterAppInterfaceResponse.h',
'SmartDeviceLink/SDLUnsubscribeButton.h',
diff --git a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
index 528d4940a..f8709a031 100644
--- a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
+++ b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
@@ -1239,9 +1239,17 @@
752ECDB7228B4D6B00D945F4 /* SDLDynamicMenuUpdateAlgorithm.m in Sources */ = {isa = PBXBuildFile; fileRef = 752ECDB5228B4D6B00D945F4 /* SDLDynamicMenuUpdateAlgorithm.m */; };
752ECDB9228C42E100D945F4 /* SDLMenuRunScoreSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 752ECDB8228C42E100D945F4 /* SDLMenuRunScoreSpec.m */; };
752ECDBB228C532600D945F4 /* SDLMenuUpdateAlgorithmSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 752ECDBA228C532600D945F4 /* SDLMenuUpdateAlgorithmSpec.m */; };
+ 7538764F22D8CEDB00FE8484 /* SDLShowAppMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = 7538764D22D8CEDB00FE8484 /* SDLShowAppMenu.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 7538765022D8CEDB00FE8484 /* SDLShowAppMenu.m in Sources */ = {isa = PBXBuildFile; fileRef = 7538764E22D8CEDB00FE8484 /* SDLShowAppMenu.m */; };
+ 7538765322D8D95100FE8484 /* SDLShowAppMenuResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 7538765122D8D95100FE8484 /* SDLShowAppMenuResponse.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 7538765422D8D95100FE8484 /* SDLShowAppMenuResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 7538765222D8D95100FE8484 /* SDLShowAppMenuResponse.m */; };
+ 7538765622DCAF5400FE8484 /* SDLShowAppMenuSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 7538765522DCAF5400FE8484 /* SDLShowAppMenuSpec.m */; };
755F176222A00B7C0041B9CB /* SDLMenuManagerConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 755F176122A00B7C0041B9CB /* SDLMenuManagerConstants.h */; settings = {ATTRIBUTES = (Public, ); }; };
756C62762289F11F008B57A2 /* SDLDynamicMenuUpdateRunScore.h in Headers */ = {isa = PBXBuildFile; fileRef = 756C62742289F11F008B57A2 /* SDLDynamicMenuUpdateRunScore.h */; };
756C62772289F11F008B57A2 /* SDLDynamicMenuUpdateRunScore.m in Sources */ = {isa = PBXBuildFile; fileRef = 756C62752289F11F008B57A2 /* SDLDynamicMenuUpdateRunScore.m */; };
+ 75FF2E3822DF9D5900D0C13B /* SDLShowAppMenuResponseSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 75FF2E3722DF9D5900D0C13B /* SDLShowAppMenuResponseSpec.m */; };
+ 75FF2E3B22E0DD5400D0C13B /* SDLMsgVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = 75FF2E3922E0DD5400D0C13B /* SDLMsgVersion.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 75FF2E3C22E0DD5400D0C13B /* SDLMsgVersion.m in Sources */ = {isa = PBXBuildFile; fileRef = 75FF2E3A22E0DD5400D0C13B /* SDLMsgVersion.m */; };
880245A420F79C3400ED195B /* SDLFileManagerConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 880245A220F79C3400ED195B /* SDLFileManagerConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; };
880245A520F79C3400ED195B /* SDLFileManagerConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 880245A320F79C3400ED195B /* SDLFileManagerConfiguration.m */; };
8803DCEF22C2B84B00FBB7CE /* SDLBackgroundTaskManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 8803DCED22C2B84B00FBB7CE /* SDLBackgroundTaskManager.h */; };
@@ -1427,6 +1435,7 @@
88F65136220C74FD00CAF321 /* SDLWeatherData.h in Headers */ = {isa = PBXBuildFile; fileRef = 88F65134220C74FD00CAF321 /* SDLWeatherData.h */; settings = {ATTRIBUTES = (Public, ); }; };
88F65137220C74FD00CAF321 /* SDLWeatherData.m in Sources */ = {isa = PBXBuildFile; fileRef = 88F65135220C74FD00CAF321 /* SDLWeatherData.m */; };
88F89103221DE29A00E056AD /* SDLAsynchronousRPCOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 88F89101221DE29A00E056AD /* SDLAsynchronousRPCOperation.h */; };
+ 8B05F88922DD011300666CD8 /* SDLUnpublishAppServiceSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B05F88822DD011300666CD8 /* SDLUnpublishAppServiceSpec.m */; };
8B7B319A1F2F7B5700BDC38D /* SDLVideoStreamingCodec.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B7B31981F2F7B5700BDC38D /* SDLVideoStreamingCodec.h */; settings = {ATTRIBUTES = (Public, ); }; };
8B7B319B1F2F7B5700BDC38D /* SDLVideoStreamingCodec.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B7B31991F2F7B5700BDC38D /* SDLVideoStreamingCodec.m */; };
8B7B319E1F2F7CF700BDC38D /* SDLVideoStreamingProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B7B319C1F2F7CF700BDC38D /* SDLVideoStreamingProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -1442,6 +1451,11 @@
8B9376D71F3349FC009605C4 /* SDLMetadataTags.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B9376D51F3349FC009605C4 /* SDLMetadataTags.h */; settings = {ATTRIBUTES = (Public, ); }; };
8B9376D81F3349FC009605C4 /* SDLMetadataTags.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B9376D61F3349FC009605C4 /* SDLMetadataTags.m */; };
8B9376DB1F33656C009605C4 /* SDLMetadataTagsSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B9376DA1F33656C009605C4 /* SDLMetadataTagsSpec.m */; };
+ 8BA12B1122DCCE1F00371E82 /* SDLUnpublishAppService.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BA12B0F22DCCE1F00371E82 /* SDLUnpublishAppService.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 8BA12B1222DCCE1F00371E82 /* SDLUnpublishAppService.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BA12B1022DCCE1F00371E82 /* SDLUnpublishAppService.m */; };
+ 8BA12B1522DCEACB00371E82 /* SDLUnpublishAppServiceResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BA12B1322DCEACB00371E82 /* SDLUnpublishAppServiceResponse.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 8BA12B1622DCEACB00371E82 /* SDLUnpublishAppServiceResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BA12B1422DCEACB00371E82 /* SDLUnpublishAppServiceResponse.m */; };
+ 8BA12B1822DCF59700371E82 /* SDLUnpublishAppServiceResponseSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BA12B1722DCF59700371E82 /* SDLUnpublishAppServiceResponseSpec.m */; };
8BBEA6061F324165003EEA26 /* SDLMetadataType.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BBEA6041F324165003EEA26 /* SDLMetadataType.h */; settings = {ATTRIBUTES = (Public, ); }; };
8BBEA6071F324165003EEA26 /* SDLMetadataType.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BBEA6051F324165003EEA26 /* SDLMetadataType.m */; };
8BBEA6091F324832003EEA26 /* SDLMetadataTypeSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BBEA6081F324832003EEA26 /* SDLMetadataTypeSpec.m */; };
@@ -1453,7 +1467,6 @@
DA318C201DD0F06C00C035AC /* NSMutableDictionary+Store.m in Sources */ = {isa = PBXBuildFile; fileRef = DA318C1E1DD0F06C00C035AC /* NSMutableDictionary+Store.m */; };
DA4353DF1D271FD10099B8C4 /* CGPointUtilSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = DA4353DE1D271FD10099B8C4 /* CGPointUtilSpec.m */; };
DA4353E31D2720A30099B8C4 /* SDLPinchGestureSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = DA4353E21D2720A30099B8C4 /* SDLPinchGestureSpec.m */; };
- DA4353E91D2721680099B8C4 /* DispatchTimerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = DA4353E61D2721680099B8C4 /* DispatchTimerSpec.m */; };
DA4353EA1D2721680099B8C4 /* SDLTouchManagerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = DA4353E71D2721680099B8C4 /* SDLTouchManagerSpec.m */; };
DA4353EB1D2721680099B8C4 /* SDLTouchSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = DA4353E81D2721680099B8C4 /* SDLTouchSpec.m */; };
DA4F47961E771AA100FC809E /* SDLEnum.m in Sources */ = {isa = PBXBuildFile; fileRef = DA4F47951E771AA100FC809E /* SDLEnum.m */; };
@@ -1511,8 +1524,6 @@
DAC572631D10C5020004288B /* SDLPinchGesture.h in Headers */ = {isa = PBXBuildFile; fileRef = DAC572611D10C5020004288B /* SDLPinchGesture.h */; settings = {ATTRIBUTES = (Public, ); }; };
DAC572661D10C5640004288B /* CGPoint_Util.m in Sources */ = {isa = PBXBuildFile; fileRef = DAC572641D10C5640004288B /* CGPoint_Util.m */; };
DAC572671D10C5640004288B /* CGPoint_Util.h in Headers */ = {isa = PBXBuildFile; fileRef = DAC572651D10C5640004288B /* CGPoint_Util.h */; };
- DAC5726A1D10D5FC0004288B /* dispatch_timer.m in Sources */ = {isa = PBXBuildFile; fileRef = DAC572681D10D5FC0004288B /* dispatch_timer.m */; };
- DAC5726B1D10D5FC0004288B /* dispatch_timer.h in Headers */ = {isa = PBXBuildFile; fileRef = DAC572691D10D5FC0004288B /* dispatch_timer.h */; };
DAC5726C1D11B4840004288B /* SDLTouchManagerDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = DAC5725F1D10BD690004288B /* SDLTouchManagerDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };
E4139D1D1F6017770005B6EA /* SDLLifecycleConfigurationUpdate.h in Headers */ = {isa = PBXBuildFile; fileRef = E4139D1B1F6017770005B6EA /* SDLLifecycleConfigurationUpdate.h */; settings = {ATTRIBUTES = (Public, ); }; };
E4139D1E1F6017770005B6EA /* SDLLifecycleConfigurationUpdate.m in Sources */ = {isa = PBXBuildFile; fileRef = E4139D1C1F6017770005B6EA /* SDLLifecycleConfigurationUpdate.m */; };
@@ -2907,9 +2918,17 @@
752ECDB5228B4D6B00D945F4 /* SDLDynamicMenuUpdateAlgorithm.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLDynamicMenuUpdateAlgorithm.m; sourceTree = "<group>"; };
752ECDB8228C42E100D945F4 /* SDLMenuRunScoreSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLMenuRunScoreSpec.m; sourceTree = "<group>"; };
752ECDBA228C532600D945F4 /* SDLMenuUpdateAlgorithmSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLMenuUpdateAlgorithmSpec.m; sourceTree = "<group>"; };
+ 7538764D22D8CEDB00FE8484 /* SDLShowAppMenu.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLShowAppMenu.h; sourceTree = "<group>"; };
+ 7538764E22D8CEDB00FE8484 /* SDLShowAppMenu.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLShowAppMenu.m; sourceTree = "<group>"; };
+ 7538765122D8D95100FE8484 /* SDLShowAppMenuResponse.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLShowAppMenuResponse.h; sourceTree = "<group>"; };
+ 7538765222D8D95100FE8484 /* SDLShowAppMenuResponse.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLShowAppMenuResponse.m; sourceTree = "<group>"; };
+ 7538765522DCAF5400FE8484 /* SDLShowAppMenuSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLShowAppMenuSpec.m; sourceTree = "<group>"; };
755F176122A00B7C0041B9CB /* SDLMenuManagerConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLMenuManagerConstants.h; sourceTree = "<group>"; };
756C62742289F11F008B57A2 /* SDLDynamicMenuUpdateRunScore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLDynamicMenuUpdateRunScore.h; sourceTree = "<group>"; };
756C62752289F11F008B57A2 /* SDLDynamicMenuUpdateRunScore.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLDynamicMenuUpdateRunScore.m; sourceTree = "<group>"; };
+ 75FF2E3722DF9D5900D0C13B /* SDLShowAppMenuResponseSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLShowAppMenuResponseSpec.m; sourceTree = "<group>"; };
+ 75FF2E3922E0DD5400D0C13B /* SDLMsgVersion.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLMsgVersion.h; sourceTree = "<group>"; };
+ 75FF2E3A22E0DD5400D0C13B /* SDLMsgVersion.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLMsgVersion.m; sourceTree = "<group>"; };
880245A220F79C3400ED195B /* SDLFileManagerConfiguration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLFileManagerConfiguration.h; sourceTree = "<group>"; };
880245A320F79C3400ED195B /* SDLFileManagerConfiguration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLFileManagerConfiguration.m; sourceTree = "<group>"; };
8803DCED22C2B84B00FBB7CE /* SDLBackgroundTaskManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLBackgroundTaskManager.h; sourceTree = "<group>"; };
@@ -3090,6 +3109,7 @@
88F65134220C74FD00CAF321 /* SDLWeatherData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLWeatherData.h; sourceTree = "<group>"; };
88F65135220C74FD00CAF321 /* SDLWeatherData.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLWeatherData.m; sourceTree = "<group>"; };
88F89101221DE29A00E056AD /* SDLAsynchronousRPCOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLAsynchronousRPCOperation.h; sourceTree = "<group>"; };
+ 8B05F88822DD011300666CD8 /* SDLUnpublishAppServiceSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLUnpublishAppServiceSpec.m; sourceTree = "<group>"; };
8B7B31981F2F7B5700BDC38D /* SDLVideoStreamingCodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLVideoStreamingCodec.h; sourceTree = "<group>"; };
8B7B31991F2F7B5700BDC38D /* SDLVideoStreamingCodec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLVideoStreamingCodec.m; sourceTree = "<group>"; };
8B7B319C1F2F7CF700BDC38D /* SDLVideoStreamingProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLVideoStreamingProtocol.h; sourceTree = "<group>"; };
@@ -3105,6 +3125,11 @@
8B9376D51F3349FC009605C4 /* SDLMetadataTags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLMetadataTags.h; sourceTree = "<group>"; };
8B9376D61F3349FC009605C4 /* SDLMetadataTags.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLMetadataTags.m; sourceTree = "<group>"; };
8B9376DA1F33656C009605C4 /* SDLMetadataTagsSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLMetadataTagsSpec.m; sourceTree = "<group>"; };
+ 8BA12B0F22DCCE1F00371E82 /* SDLUnpublishAppService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLUnpublishAppService.h; sourceTree = "<group>"; };
+ 8BA12B1022DCCE1F00371E82 /* SDLUnpublishAppService.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLUnpublishAppService.m; sourceTree = "<group>"; };
+ 8BA12B1322DCEACB00371E82 /* SDLUnpublishAppServiceResponse.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLUnpublishAppServiceResponse.h; sourceTree = "<group>"; };
+ 8BA12B1422DCEACB00371E82 /* SDLUnpublishAppServiceResponse.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLUnpublishAppServiceResponse.m; sourceTree = "<group>"; };
+ 8BA12B1722DCF59700371E82 /* SDLUnpublishAppServiceResponseSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLUnpublishAppServiceResponseSpec.m; sourceTree = "<group>"; };
8BBEA6041F324165003EEA26 /* SDLMetadataType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLMetadataType.h; sourceTree = "<group>"; };
8BBEA6051F324165003EEA26 /* SDLMetadataType.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLMetadataType.m; sourceTree = "<group>"; };
8BBEA6081F324832003EEA26 /* SDLMetadataTypeSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLMetadataTypeSpec.m; sourceTree = "<group>"; };
@@ -3117,7 +3142,6 @@
DA318C1E1DD0F06C00C035AC /* NSMutableDictionary+Store.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableDictionary+Store.m"; sourceTree = "<group>"; };
DA4353DE1D271FD10099B8C4 /* CGPointUtilSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CGPointUtilSpec.m; path = UtilitiesSpecs/Touches/CGPointUtilSpec.m; sourceTree = "<group>"; };
DA4353E21D2720A30099B8C4 /* SDLPinchGestureSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLPinchGestureSpec.m; path = UtilitiesSpecs/Touches/SDLPinchGestureSpec.m; sourceTree = "<group>"; };
- DA4353E61D2721680099B8C4 /* DispatchTimerSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DispatchTimerSpec.m; path = UtilitiesSpecs/Touches/DispatchTimerSpec.m; sourceTree = "<group>"; };
DA4353E71D2721680099B8C4 /* SDLTouchManagerSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLTouchManagerSpec.m; path = UtilitiesSpecs/Touches/SDLTouchManagerSpec.m; sourceTree = "<group>"; };
DA4353E81D2721680099B8C4 /* SDLTouchSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLTouchSpec.m; path = UtilitiesSpecs/Touches/SDLTouchSpec.m; sourceTree = "<group>"; };
DA4F47951E771AA100FC809E /* SDLEnum.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLEnum.m; sourceTree = "<group>"; };
@@ -3178,8 +3202,6 @@
DAC572611D10C5020004288B /* SDLPinchGesture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLPinchGesture.h; sourceTree = "<group>"; };
DAC572641D10C5640004288B /* CGPoint_Util.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CGPoint_Util.m; sourceTree = "<group>"; };
DAC572651D10C5640004288B /* CGPoint_Util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CGPoint_Util.h; sourceTree = "<group>"; };
- DAC572681D10D5FC0004288B /* dispatch_timer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = dispatch_timer.m; sourceTree = "<group>"; };
- DAC572691D10D5FC0004288B /* dispatch_timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dispatch_timer.h; sourceTree = "<group>"; };
E4139D1B1F6017770005B6EA /* SDLLifecycleConfigurationUpdate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLLifecycleConfigurationUpdate.h; sourceTree = "<group>"; };
E4139D1C1F6017770005B6EA /* SDLLifecycleConfigurationUpdate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLLifecycleConfigurationUpdate.m; sourceTree = "<group>"; };
E9C32B891AB20BA200F283AF /* SDLIAPSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLIAPSession.h; sourceTree = "<group>"; };
@@ -3466,6 +3488,7 @@
162E82581A9BDE8A00906325 /* SDLSetMediaClockTimerSpec.m */,
162E82591A9BDE8A00906325 /* SDLShowConstantTBTSpec.m */,
162E825A1A9BDE8A00906325 /* SDLShowSpec.m */,
+ 7538765522DCAF5400FE8484 /* SDLShowAppMenuSpec.m */,
162E825B1A9BDE8A00906325 /* SDLSliderSpec.m */,
162E825C1A9BDE8A00906325 /* SDLSpeakSpec.m */,
162E825D1A9BDE8A00906325 /* SDLSubscribeButtonSpec.m */,
@@ -3480,6 +3503,7 @@
162E82641A9BDE8A00906325 /* SDLUpdateTurnListSpec.m */,
1EE8C45E1F3884FF00FDC2CF /* SDLSetInteriorVehicleDataSpec.m */,
8877F5EA1F34A3BE00DC128A /* SDLSendHapticDataSpec.m */,
+ 8B05F88822DD011300666CD8 /* SDLUnpublishAppServiceSpec.m */,
);
path = RequestSpecs;
sourceTree = "<group>";
@@ -3531,6 +3555,7 @@
162E82811A9BDE8A00906325 /* SDLSetMediaClockTimerResponseSpec.m */,
162E82821A9BDE8A00906325 /* SDLShowConstantTBTResponseSpec.m */,
162E82831A9BDE8A00906325 /* SDLShowResponseSpec.m */,
+ 75FF2E3722DF9D5900D0C13B /* SDLShowAppMenuResponseSpec.m */,
162E82841A9BDE8A00906325 /* SDLSliderResponseSpec.m */,
162E82851A9BDE8A00906325 /* SDLSpeakResponseSpec.m */,
162E82861A9BDE8A00906325 /* SDLSubscribeButtonResponseSpec.m */,
@@ -3544,6 +3569,7 @@
DA9F7EAB1DCC062400ACAE48 /* SDLUnsubscribeWaypointsResponseSpec.m */,
162E828D1A9BDE8A00906325 /* SDLUpdateTurnListResponseSpec.m */,
8877F5F01F34AA2D00DC128A /* SDLSendHapticDataResponseSpec.m */,
+ 8BA12B1722DCF59700371E82 /* SDLUnpublishAppServiceResponseSpec.m */,
);
path = ResponseSpecs;
sourceTree = "<group>";
@@ -4205,6 +4231,8 @@
DA9F7E6E1DCBFFDB00ACAE48 /* SDLGetWayPoints.m */,
5D61FAFF1A84238A00846EE7 /* SDLListFiles.h */,
5D61FB001A84238A00846EE7 /* SDLListFiles.m */,
+ 7538764D22D8CEDB00FE8484 /* SDLShowAppMenu.h */,
+ 7538764E22D8CEDB00FE8484 /* SDLShowAppMenu.m */,
88AF11DA220B6B3D00A59985 /* SDLPerformAppServiceInteraction.h */,
88AF11DB220B6B3D00A59985 /* SDLPerformAppServiceInteraction.m */,
5D61FB381A84238B00846EE7 /* SDLPerformAudioPassThru.h */,
@@ -4267,6 +4295,8 @@
DA9F7E921DCC04E400ACAE48 /* SDLUnsubscribeWayPoints.m */,
5D61FC041A84238C00846EE7 /* SDLUpdateTurnList.h */,
5D61FC051A84238C00846EE7 /* SDLUpdateTurnList.m */,
+ 8BA12B0F22DCCE1F00371E82 /* SDLUnpublishAppService.h */,
+ 8BA12B1022DCCE1F00371E82 /* SDLUnpublishAppService.m */,
);
name = Requests;
sourceTree = "<group>";
@@ -4364,6 +4394,8 @@
5D61FBA71A84238B00846EE7 /* SDLShowConstantTBTResponse.m */,
5D61FBA81A84238B00846EE7 /* SDLShowResponse.h */,
5D61FBA91A84238B00846EE7 /* SDLShowResponse.m */,
+ 7538765122D8D95100FE8484 /* SDLShowAppMenuResponse.h */,
+ 7538765222D8D95100FE8484 /* SDLShowAppMenuResponse.m */,
5D61FBB01A84238B00846EE7 /* SDLSliderResponse.h */,
5D61FBB11A84238B00846EE7 /* SDLSliderResponse.m */,
5D61FBBA1A84238B00846EE7 /* SDLSpeakResponse.h */,
@@ -4388,6 +4420,8 @@
DA9F7E8E1DCC04C000ACAE48 /* SDLUnsubscribeWayPointsResponse.m */,
5D61FC061A84238C00846EE7 /* SDLUpdateTurnListResponse.h */,
5D61FC071A84238C00846EE7 /* SDLUpdateTurnListResponse.m */,
+ 8BA12B1322DCEACB00371E82 /* SDLUnpublishAppServiceResponse.h */,
+ 8BA12B1422DCEACB00371E82 /* SDLUnpublishAppServiceResponse.m */,
);
name = Responses;
sourceTree = "<group>";
@@ -4493,6 +4527,8 @@
88AAD4BB2211B76800F1E6D7 /* SDLMediaServiceManifest.m */,
5D61FB0B1A84238A00846EE7 /* SDLMenuParams.h */,
5D61FB0C1A84238A00846EE7 /* SDLMenuParams.m */,
+ 75FF2E3922E0DD5400D0C13B /* SDLMsgVersion.h */,
+ 75FF2E3A22E0DD5400D0C13B /* SDLMsgVersion.m */,
8B9376D51F3349FC009605C4 /* SDLMetadataTags.h */,
8B9376D61F3349FC009605C4 /* SDLMetadataTags.m */,
1E5AD06E1F209C880029B8AF /* SDLModuleData.h */,
@@ -5665,9 +5701,9 @@
5D82041C1BCD8E6100D0A41B /* SDLConfiguration.h */,
5D82041D1BCD8E6100D0A41B /* SDLConfiguration.m */,
5D2F58071D0717D5001085CE /* SDLManagerDelegate.h */,
+ 5D82042A1BCEA91E00D0A41B /* Files */,
5D1654571D3E79CA00554D93 /* Lifecycle */,
5DBAE0A51D355EE700CE00BF /* Lock Screen */,
- 5D82042A1BCEA91E00D0A41B /* Files */,
5D8204291BCEA91400D0A41B /* Permissions */,
DA8966E71E56937100413EAB /* Streaming */,
5D0A736F203F0C450001595D /* Screen */,
@@ -6102,7 +6138,6 @@
DA1166D71D14601C00438CEA /* Touches */ = {
isa = PBXGroup;
children = (
- DA4353E61D2721680099B8C4 /* DispatchTimerSpec.m */,
DA4353E71D2721680099B8C4 /* SDLTouchManagerSpec.m */,
DA4353E81D2721680099B8C4 /* SDLTouchSpec.m */,
DA4353DE1D271FD10099B8C4 /* CGPointUtilSpec.m */,
@@ -6189,8 +6224,6 @@
DAC572601D10C5020004288B /* SDLPinchGesture.m */,
DAC572651D10C5640004288B /* CGPoint_Util.h */,
DAC572641D10C5640004288B /* CGPoint_Util.m */,
- DAC572691D10D5FC0004288B /* dispatch_timer.h */,
- DAC572681D10D5FC0004288B /* dispatch_timer.m */,
);
name = Touches;
sourceTree = "<group>";
@@ -6235,6 +6268,8 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
+ 8BA12B1122DCCE1F00371E82 /* SDLUnpublishAppService.h in Headers */,
+ 8BA12B1522DCEACB00371E82 /* SDLUnpublishAppServiceResponse.h in Headers */,
1EB59CBF202DA26000343A61 /* SDLSeatControlData.h in Headers */,
1EB59CB3202D9B5F00343A61 /* SDLSeatMemoryActionType.h in Headers */,
88665B73220B80F400D9DA77 /* SDLWeatherAlert.h in Headers */,
@@ -6371,13 +6406,13 @@
5D92938020B70CD600FCC775 /* SDLCheckChoiceVROptionalOperation.h in Headers */,
5D339CEF207C08BA000CC364 /* SDLVoiceCommand.h in Headers */,
5D61FC4B1A84238C00846EE7 /* SDLBeltStatus.h in Headers */,
- DAC5726B1D10D5FC0004288B /* dispatch_timer.h in Headers */,
DA9F7E991DCC052C00ACAE48 /* SDLLocationCoordinate.h in Headers */,
5D0A7382203F23F30001595D /* SDLSoftButtonManager.h in Headers */,
5D61FC351A84238C00846EE7 /* SDLAirbagStatus.h in Headers */,
5D61FC8A1A84238C00846EE7 /* SDLDiagnosticMessageResponse.h in Headers */,
5D61FC2D1A84238C00846EE7 /* SDLAddCommand.h in Headers */,
88B3BF9C20DA8BBC00943565 /* SDLFuelRange.h in Headers */,
+ 7538765322D8D95100FE8484 /* SDLShowAppMenuResponse.h in Headers */,
5D61FD931A84238C00846EE7 /* SDLShowConstantTBTResponse.h in Headers */,
5DBF06391E64ABBE00A5CF03 /* SDLLogConfiguration.h in Headers */,
5D61FCCB1A84238C00846EE7 /* SDLIgnitionStatus.h in Headers */,
@@ -6626,6 +6661,7 @@
88A5E7F7220B5BBC00495E8A /* SDLGetAppServiceData.h in Headers */,
1E5AD0441F1F5A1F0029B8AF /* SDLRadioControlCapabilities.h in Headers */,
88F65136220C74FD00CAF321 /* SDLWeatherData.h in Headers */,
+ 7538764F22D8CEDB00FE8484 /* SDLShowAppMenu.h in Headers */,
1E5AD0841F20B9290029B8AF /* SDLButtonPressResponse.h in Headers */,
1E5AD0681F2080B50029B8AF /* SDLRadioControlData.h in Headers */,
1E5AD0481F1F773E0029B8AF /* SDLModuleType.h in Headers */,
@@ -6718,6 +6754,7 @@
5D92936320B3551600FCC775 /* SDLKeyboardDelegate.h in Headers */,
5D92936820B3601700FCC775 /* SDLChoiceSetManager.h in Headers */,
5DBF06351E64A9FE00A5CF03 /* SDLLogConstants.h in Headers */,
+ 75FF2E3B22E0DD5400D0C13B /* SDLMsgVersion.h in Headers */,
DAC572671D10C5640004288B /* CGPoint_Util.h in Headers */,
5D61FDF91A84238C00846EE7 /* SDLV2ProtocolHeader.h in Headers */,
884E702B21FBB151008D53BA /* SDLAppServiceRecord.h in Headers */,
@@ -7106,6 +7143,7 @@
8881AFBF2225E9BB00EA870B /* SDLGetCloudAppPropertiesResponse.m in Sources */,
1E5AD0691F2080B50029B8AF /* SDLRadioControlData.m in Sources */,
888F86FE221DEE200052FE4C /* SDLAsynchronousRPCOperation.m in Sources */,
+ 7538765422D8D95100FE8484 /* SDLShowAppMenuResponse.m in Sources */,
5D61FCC01A84238C00846EE7 /* SDLHexUtility.m in Sources */,
5DB9964F1F26886C002D8795 /* SDLControlFramePayloadEndService.m in Sources */,
5D61FD821A84238C00846EE7 /* SDLSetAppIconResponse.m in Sources */,
@@ -7133,6 +7171,7 @@
5D61FC8B1A84238C00846EE7 /* SDLDiagnosticMessageResponse.m in Sources */,
5DBF063A1E64ABBE00A5CF03 /* SDLLogConfiguration.m in Sources */,
5D92937120B5E0E500FCC775 /* SDLDeleteChoicesOperation.m in Sources */,
+ 8BA12B1222DCCE1F00371E82 /* SDLUnpublishAppService.m in Sources */,
1EAA475220356CD2000FE74B /* SDLDistanceUnit.m in Sources */,
5D61FD2E1A84238C00846EE7 /* SDLPermissionItem.m in Sources */,
5D61FD041A84238C00846EE7 /* SDLOnButtonEvent.m in Sources */,
@@ -7213,6 +7252,7 @@
5D61FC4E1A84238C00846EE7 /* SDLBitsPerSample.m in Sources */,
5D00AC701F1511B9004000D9 /* SDLGetSystemCapability.m in Sources */,
5D61FDEA1A84238C00846EE7 /* SDLUnsubscribeButtonResponse.m in Sources */,
+ 7538765022D8CEDB00FE8484 /* SDLShowAppMenu.m in Sources */,
1E5AD05D1F2064A80029B8AF /* SDLRDSData.m in Sources */,
5D61FCA61A84238C00846EE7 /* SDLEndAudioPassThruResponse.m in Sources */,
5D61FD281A84238C00846EE7 /* SDLPerformAudioPassThruResponse.m in Sources */,
@@ -7369,6 +7409,7 @@
5D61FCB21A84238C00846EE7 /* SDLGetDTCs.m in Sources */,
8881AFB92225E5EE00EA870B /* SDLGetCloudAppProperties.m in Sources */,
5D61FD441A84238C00846EE7 /* SDLProtocol.m in Sources */,
+ 75FF2E3C22E0DD5400D0C13B /* SDLMsgVersion.m in Sources */,
5DF40B23208E761A00DD6FDA /* SDLVoiceCommandManager.m in Sources */,
5D61FC341A84238C00846EE7 /* SDLAddSubMenuResponse.m in Sources */,
5DA240011F325621009C0313 /* SDLStreamingMediaConfiguration.m in Sources */,
@@ -7463,7 +7504,6 @@
5D61FDC21A84238C00846EE7 /* SDLSystemRequestResponse.m in Sources */,
5D9FDA911F2A7D3400A495C8 /* bson_object.c in Sources */,
5D61FD001A84238C00846EE7 /* SDLOnAppInterfaceUnregistered.m in Sources */,
- DAC5726A1D10D5FC0004288B /* dispatch_timer.m in Sources */,
5D61FC6C1A84238C00846EE7 /* SDLCreateInteractionChoiceSet.m in Sources */,
5DCD7AF71FCCA8E400A0FC7F /* SDLScreenshotViewController.m in Sources */,
1EB59CA4202D92F600343A61 /* SDLMassageMode.m in Sources */,
@@ -7493,6 +7533,7 @@
5D61FCB41A84238C00846EE7 /* SDLGetDTCsResponse.m in Sources */,
5D61FDFC1A84238C00846EE7 /* SDLV2ProtocolMessage.m in Sources */,
1EAA4726203416D3000FE74B /* SDLEqualizerSettings.m in Sources */,
+ 8BA12B1622DCEACB00371E82 /* SDLUnpublishAppServiceResponse.m in Sources */,
5D61FD361A84238C00846EE7 /* SDLPowerModeStatus.m in Sources */,
5D61FD621A84238C00846EE7 /* SDLRequestType.m in Sources */,
1EAA473E203554B5000FE74B /* SDLLightState.m in Sources */,
@@ -7656,7 +7697,6 @@
88B848C91F462E3600DED768 /* TestFileProgressResponse.m in Sources */,
162E83231A9BDE8B00906325 /* SDLAddSubMenuSpec.m in Sources */,
5DCC458D221C9F6600036C2F /* SDLVersionSpec.m in Sources */,
- DA4353E91D2721680099B8C4 /* DispatchTimerSpec.m in Sources */,
1EE8C45D1F387D1C00FDC2CF /* SDLGetInteriorVehicleDataResponseSpec.m in Sources */,
162E82F21A9BDE8B00906325 /* SDLPredefinedLayoutSpec.m in Sources */,
162E83521A9BDE8B00906325 /* SDLDeleteSubMenuResponseSpec.m in Sources */,
@@ -7773,6 +7813,7 @@
5D43466F1E6F55BD00B639C6 /* SDLLogManagerSpec.m in Sources */,
162E83451A9BDE8B00906325 /* SDLUnregisterAppInterfaceSpec.m in Sources */,
162E82EF1A9BDE8B00906325 /* SDLPermissionStatusSpec.m in Sources */,
+ 8BA12B1822DCF59700371E82 /* SDLUnpublishAppServiceResponseSpec.m in Sources */,
DA9F7EA61DCC05F500ACAE48 /* SDLUnsubscribeWaypointsSpec.m in Sources */,
1E89B0E2203196B800A47992 /* SDLSeatControlCapabilitiesSpec.m in Sources */,
162E82F01A9BDE8B00906325 /* SDLPowerModeQualificationStatusSpec.m in Sources */,
@@ -7789,6 +7830,7 @@
162E834C1A9BDE8B00906325 /* SDLAlertResponseSpec.m in Sources */,
1680B11B1A9CD7AD00DBD79E /* SDLFunctionIDSpec.m in Sources */,
5DB1BCDA1D243D85002FFC37 /* SDLStateMachineSpec.m in Sources */,
+ 7538765622DCAF5400FE8484 /* SDLShowAppMenuSpec.m in Sources */,
8831FA4B2202402B00B8FFB7 /* SDLAppServicesCapabilitiesSpec.m in Sources */,
5D4346731E6F617D00B639C6 /* TestLogTarget.m in Sources */,
1EE8C43C1F347EAE00FDC2CF /* SDLTemperatureUnitSpec.m in Sources */,
@@ -7873,6 +7915,7 @@
88D2AAE41F682BB20078D5B2 /* SDLLogConstantsSpec.m in Sources */,
162E836B1A9BDE8B00906325 /* SDLSyncPDataResponseSpec.m in Sources */,
8B7B31AF1F2FBA0200BDC38D /* SDLVideoStreamingCapabilitySpec.m in Sources */,
+ 8B05F88922DD011300666CD8 /* SDLUnpublishAppServiceSpec.m in Sources */,
162E839B1A9BDE8B00906325 /* SDLRPCNotificationSpec.m in Sources */,
162E83581A9BDE8B00906325 /* SDLGetVehicleDataResponseSpec.m in Sources */,
88E6F1B0220E25B2006156F9 /* SDLMediaServiceDataSpec.m in Sources */,
@@ -7968,6 +8011,7 @@
162E82EC1A9BDE8B00906325 /* SDLLockScreenStatusSpec.m in Sources */,
DA96C0661D4D4F730022F520 /* SDLAppInfoSpec.m in Sources */,
162E832F1A9BDE8B00906325 /* SDLGetDTCsSpec.m in Sources */,
+ 75FF2E3822DF9D5900D0C13B /* SDLShowAppMenuResponseSpec.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/SmartDeviceLink-iOS.xcodeproj/xcshareddata/xcschemes/SmartDeviceLink.xcscheme b/SmartDeviceLink-iOS.xcodeproj/xcshareddata/xcschemes/SmartDeviceLink.xcscheme
index 4570e5a1a..6f8818b13 100644
--- a/SmartDeviceLink-iOS.xcodeproj/xcshareddata/xcschemes/SmartDeviceLink.xcscheme
+++ b/SmartDeviceLink-iOS.xcodeproj/xcshareddata/xcschemes/SmartDeviceLink.xcscheme
@@ -92,7 +92,7 @@
</AdditionalOptions>
</LaunchAction>
<ProfileAction
- buildConfiguration = "Release"
+ buildConfiguration = "Debug"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
diff --git a/SmartDeviceLink.podspec b/SmartDeviceLink.podspec
index 6bfec845f..ee10df832 100644
--- a/SmartDeviceLink.podspec
+++ b/SmartDeviceLink.podspec
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "SmartDeviceLink"
-s.version = "6.3.0"
+s.version = "6.3.1"
s.summary = "Connect your app with cars!"
s.homepage = "https://github.com/smartdevicelink/SmartDeviceLink-iOS"
s.license = { :type => "New BSD", :file => "LICENSE" }
@@ -328,6 +328,8 @@ sdefault.public_header_files = [
'SmartDeviceLink/SDLSetMediaClockTimer.h',
'SmartDeviceLink/SDLSetMediaClockTimerResponse.h',
'SmartDeviceLink/SDLShow.h',
+'SmartDeviceLink/SDLShowAppMenu.h',
+'SmartDeviceLink/SDLShowAppMenuResponse.h',
'SmartDeviceLink/SDLShowConstantTBT.h',
'SmartDeviceLink/SDLShowConstantTBTResponse.h',
'SmartDeviceLink/SDLShowResponse.h',
@@ -357,6 +359,7 @@ sdefault.public_header_files = [
'SmartDeviceLink/SDLSubscribeWaypoints.h',
'SmartDeviceLink/SDLSubscribeWaypointsResponse.h',
'SmartDeviceLink/SDLSyncMsgVersion.h',
+'SmartDeviceLink/SDLMsgVersion.h',
'SmartDeviceLink/SDLSyncPData.h',
'SmartDeviceLink/SDLSyncPDataResponse.h',
'SmartDeviceLink/SDLSystemAction.h',
@@ -386,6 +389,8 @@ sdefault.public_header_files = [
'SmartDeviceLink/SDLTTSChunk.h',
'SmartDeviceLink/SDLTurn.h',
'SmartDeviceLink/SDLTurnSignal.h',
+'SmartDeviceLink/SDLUnpublishAppService.h',
+'SmartDeviceLink/SDLUnpublishAppServiceResponse.h',
'SmartDeviceLink/SDLUnregisterAppInterface.h',
'SmartDeviceLink/SDLUnregisterAppInterfaceResponse.h',
'SmartDeviceLink/SDLUnsubscribeButton.h',
diff --git a/SmartDeviceLink/CVPixelBufferRef+SDLUtil.m b/SmartDeviceLink/CVPixelBufferRef+SDLUtil.m
index 4234f76f1..1a62ece10 100644
--- a/SmartDeviceLink/CVPixelBufferRef+SDLUtil.m
+++ b/SmartDeviceLink/CVPixelBufferRef+SDLUtil.m
@@ -28,7 +28,7 @@ UIFont * _Nullable sdl_findFontSizeToFitText(CGSize size, NSString *text) {
break;
}
- fontSize -= 1.0;
+ fontSize -= (CGFloat)1.0;
} while (fontSize > 0.0);
return (fontSize > 0) ? [UIFont systemFontOfSize:fontSize] : nil;
diff --git a/SmartDeviceLink/Info.plist b/SmartDeviceLink/Info.plist
index 8761e930d..0e0ef8021 100644
--- a/SmartDeviceLink/Info.plist
+++ b/SmartDeviceLink/Info.plist
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
- <string>6.3.0</string>
+ <string>6.3.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
diff --git a/SmartDeviceLink/NSMutableDictionary+Store.h b/SmartDeviceLink/NSMutableDictionary+Store.h
index 0c20aa1c8..26493a1b8 100644
--- a/SmartDeviceLink/NSMutableDictionary+Store.h
+++ b/SmartDeviceLink/NSMutableDictionary+Store.h
@@ -17,7 +17,7 @@ typedef NSString* SDLEnum SDL_SWIFT_ENUM;
@interface NSDictionary (Store)
-- (void)sdl_setObject:(NSObject *)object forName:(SDLRPCParameterName)name;
+- (void)sdl_setObject:(nullable NSObject *)object forName:(SDLRPCParameterName)name;
- (nullable SDLEnum)sdl_enumForName:(SDLRPCParameterName)name error:(NSError * _Nullable *)error;
- (nullable NSArray<SDLEnum> *)sdl_enumsForName:(SDLRPCParameterName)name error:(NSError * _Nullable *)error;
diff --git a/SmartDeviceLink/NSMutableDictionary+Store.m b/SmartDeviceLink/NSMutableDictionary+Store.m
index 90bb6c9f1..33e4b974f 100644
--- a/SmartDeviceLink/NSMutableDictionary+Store.m
+++ b/SmartDeviceLink/NSMutableDictionary+Store.m
@@ -14,7 +14,7 @@ NS_ASSUME_NONNULL_BEGIN
@implementation NSMutableDictionary (Store)
-- (void)sdl_setObject:(NSObject *)object forName:(SDLRPCParameterName)name {
+- (void)sdl_setObject:(nullable NSObject *)object forName:(SDLRPCParameterName)name {
if (object != nil) {
self[name] = object;
} else {
diff --git a/SmartDeviceLink/SDLAlert.h b/SmartDeviceLink/SDLAlert.h
index b888deb6a..a0a8329c5 100644
--- a/SmartDeviceLink/SDLAlert.h
+++ b/SmartDeviceLink/SDLAlert.h
@@ -4,6 +4,7 @@
#import "SDLRPCRequest.h"
+@class SDLImage;
@class SDLSoftButton;
@class SDLTTSChunk;
@@ -39,27 +40,29 @@ NS_ASSUME_NONNULL_BEGIN
@interface SDLAlert : SDLRPCRequest
+- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 duration:(UInt16)duration __deprecated_msg("Use initWithAlertText1:alertText2: instead");
-- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 duration:(UInt16)duration;
+- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 __deprecated_msg("Use initWithAlertText1:alertText2: instead");
-- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3;
+- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 duration:(UInt16)duration __deprecated_msg("Use initWithAlertText1:alertText2: instead");
-- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 duration:(UInt16)duration;
+- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 duration:(UInt16)duration softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons __deprecated_msg("Use initWithAlertText1:alertText2: instead");
-- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 duration:(UInt16)duration softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons;
+- (instancetype)initWithTTS:(nullable NSString *)ttsText alertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 playTone:(BOOL)playTone duration:(UInt16)duration __deprecated_msg("Use initWithAlertText1:alertText2: instead");
-- (instancetype)initWithTTS:(nullable NSString *)ttsText playTone:(BOOL)playTone;
+- (instancetype)initWithTTS:(nullable NSString *)ttsText alertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 playTone:(BOOL)playTone duration:(UInt16)duration __deprecated_msg("Use initWithAlertText1:alertText2: instead");
-- (instancetype)initWithTTS:(nullable NSString *)ttsText alertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 playTone:(BOOL)playTone duration:(UInt16)duration;
+- (instancetype)initWithTTS:(nullable NSString *)ttsText playTone:(BOOL)playTone __deprecated_msg("Use initWithTTSChunks:playTone: instead");
-- (instancetype)initWithTTS:(nullable NSString *)ttsText alertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 playTone:(BOOL)playTone duration:(UInt16)duration;
+- (instancetype)initWithTTSChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks alertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 playTone:(BOOL)playTone softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons __deprecated_msg("Use initWithAlertText1:alertText2:alertText3:ttsChunks:playTone:progressIndicator:duration:softButtons:alertIcon: instead");
-- (instancetype)initWithTTSChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks playTone:(BOOL)playTone;
+- (instancetype)initWithTTSChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks alertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 playTone:(BOOL)playTone duration:(UInt16)duration softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons __deprecated_msg("Use initWithAlertText1:alertText2:alertText3:ttsChunks:playTone:progressIndicator:duration:softButtons:alertIcon: instead");;
-- (instancetype)initWithTTSChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks alertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 playTone:(BOOL)playTone softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons;
+- (instancetype)initWithAlertText1:(NSString *)alertText1 alertText2:(nullable NSString *)alertText2;
-- (instancetype)initWithTTSChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks alertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 playTone:(BOOL)playTone duration:(UInt16)duration softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons;
+- (instancetype)initWithTTSChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks playTone:(BOOL)playTone;
+- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 ttsChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks playTone:(BOOL)playTone progressIndicator:(BOOL)showProgressIndicator duration:(UInt16)duration softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons alertIcon:(nullable SDLImage *)icon;
/**
* The String to be displayed in the first field of the display during the Alert
@@ -154,6 +157,12 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (nullable, strong, nonatomic) NSArray<SDLSoftButton *> *softButtons;
+/**
+ Image struct determining whether static or dynamic icon.
+ If omitted on supported displays, no (or the default if applicable) icon should be displayed.
+ */
+@property (nullable, strong, nonatomic) SDLImage *alertIcon;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLAlert.m b/SmartDeviceLink/SDLAlert.m
index 120ed6fe7..31cb2cbac 100644
--- a/SmartDeviceLink/SDLAlert.m
+++ b/SmartDeviceLink/SDLAlert.m
@@ -3,12 +3,13 @@
#import "SDLAlert.h"
#import "NSMutableDictionary+Store.h"
+#import "SDLImage.h"
#import "SDLRPCParameterNames.h"
#import "SDLRPCFunctionNames.h"
#import "SDLSoftButton.h"
#import "SDLTTSChunk.h"
-static UInt16 const SDLDefaultDuration = 5000;
+static UInt16 const DefaultAlertDuration = 5000;
NS_ASSUME_NONNULL_BEGIN
@@ -24,55 +25,65 @@ NS_ASSUME_NONNULL_BEGIN
#pragma clang diagnostic pop
- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 {
- return [self initWithAlertText1:alertText1 alertText2:alertText2 alertText3:alertText3 duration:SDLDefaultDuration];
+ return [self initWithAlertText1:alertText1 alertText2:alertText2 alertText3:alertText3 ttsChunks:nil playTone:NO progressIndicator:NO duration:DefaultAlertDuration softButtons:nil alertIcon:nil];
}
- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 duration:(UInt16)duration {
- return [self initWithAlertText1:alertText1 alertText2:alertText2 alertText3:nil duration:duration];
+ return [self initWithAlertText1:alertText1 alertText2:alertText2 alertText3:nil ttsChunks:nil playTone:NO progressIndicator:NO duration:duration softButtons:nil alertIcon:nil];
+
}
- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 duration:(UInt16)duration {
- return [self initWithAlertText1:alertText1 alertText2:alertText2 alertText3:alertText3 duration:duration softButtons:nil];
+ return [self initWithAlertText1:alertText1 alertText2:alertText2 alertText3:alertText3 ttsChunks:nil playTone:NO progressIndicator:NO duration:duration softButtons:nil alertIcon:nil];
}
- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 duration:(UInt16)duration softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons {
- return [self initWithTTSChunks:nil alertText1:alertText1 alertText2:alertText2 alertText3:alertText3 playTone:NO duration:duration softButtons:softButtons];
+ return [self initWithAlertText1:alertText1 alertText2:alertText2 alertText3:alertText3 ttsChunks:nil playTone:NO progressIndicator:NO duration:duration softButtons:softButtons alertIcon:nil];
}
- (instancetype)initWithTTS:(nullable NSString *)ttsText playTone:(BOOL)playTone {
- return [self initWithTTS:ttsText alertText1:nil alertText2:nil playTone:playTone duration:SDLDefaultDuration];
+ return [self initWithAlertText1:nil alertText2:nil alertText3:nil ttsChunks:[SDLTTSChunk textChunksFromString:ttsText] playTone:playTone progressIndicator:NO duration:DefaultAlertDuration softButtons:nil alertIcon:nil];
}
- (instancetype)initWithTTS:(nullable NSString *)ttsText alertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 playTone:(BOOL)playTone duration:(UInt16)duration {
- return [self initWithTTS:ttsText alertText1:alertText1 alertText2:alertText2 alertText3:nil playTone:playTone duration:duration];
+ return [self initWithAlertText1:alertText1 alertText2:alertText2 alertText3:nil ttsChunks:[SDLTTSChunk textChunksFromString:ttsText] playTone:playTone progressIndicator:NO duration:duration softButtons:nil alertIcon:nil];
}
- (instancetype)initWithTTS:(nullable NSString *)ttsText alertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 playTone:(BOOL)playTone duration:(UInt16)duration {
- NSArray *ttsChunks = [SDLTTSChunk textChunksFromString:ttsText];
- return [self initWithTTSChunks:ttsChunks alertText1:alertText1 alertText2:alertText2 alertText3:alertText3 playTone:playTone duration:duration softButtons:nil];
-}
-
-- (instancetype)initWithTTSChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks playTone:(BOOL)playTone {
- return [self initWithTTSChunks:ttsChunks alertText1:nil alertText2:nil alertText3:nil playTone:playTone duration:SDLDefaultDuration softButtons:nil];
+ return [self initWithAlertText1:alertText1 alertText2:alertText2 alertText3:alertText3 ttsChunks:[SDLTTSChunk textChunksFromString:ttsText] playTone:playTone progressIndicator:NO duration:duration softButtons:nil alertIcon:nil];
}
- (instancetype)initWithTTSChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks alertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 playTone:(BOOL)playTone softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons {
- return [self initWithTTSChunks:ttsChunks alertText1:alertText1 alertText2:alertText2 alertText3:alertText3 playTone:playTone duration:SDLDefaultDuration softButtons:softButtons];
+ return [self initWithAlertText1:alertText1 alertText2:alertText2 alertText3:alertText3 ttsChunks:ttsChunks playTone:playTone progressIndicator:NO duration:DefaultAlertDuration softButtons:softButtons alertIcon:nil];
}
- (instancetype)initWithTTSChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks alertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 playTone:(BOOL)playTone duration:(UInt16)duration softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons {
+ return [self initWithAlertText1:alertText1 alertText2:alertText2 alertText3:alertText3 ttsChunks:ttsChunks playTone:playTone progressIndicator:NO duration:duration softButtons:softButtons alertIcon:nil];
+}
+
+- (instancetype)initWithAlertText1:(NSString *)alertText1 alertText2:(nullable NSString *)alertText2 {
+ return [self initWithAlertText1:alertText1 alertText2:alertText2 alertText3:nil ttsChunks:nil playTone:NO progressIndicator:NO duration:DefaultAlertDuration softButtons:nil alertIcon:nil];
+}
+
+- (instancetype)initWithTTSChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks playTone:(BOOL)playTone {
+ return [self initWithAlertText1:nil alertText2:nil alertText3:nil ttsChunks:ttsChunks playTone:playTone progressIndicator:NO duration:DefaultAlertDuration softButtons:nil alertIcon:nil];
+}
+
+- (instancetype)initWithAlertText1:(nullable NSString *)alertText1 alertText2:(nullable NSString *)alertText2 alertText3:(nullable NSString *)alertText3 ttsChunks:(nullable NSArray<SDLTTSChunk *> *)ttsChunks playTone:(BOOL)playTone progressIndicator:(BOOL)showProgressIndicator duration:(UInt16)duration softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons alertIcon:(nullable SDLImage *)icon {
self = [self init];
if (!self) {
return nil;
}
- self.ttsChunks = [ttsChunks mutableCopy];
+ self.ttsChunks = [ttsChunks copy];
self.alertText1 = alertText1;
self.alertText2 = alertText2;
self.alertText3 = alertText3;
self.playTone = @(playTone);
+ self.progressIndicator = @(showProgressIndicator);
self.duration = @(duration);
- self.softButtons = [softButtons mutableCopy];
+ self.softButtons = [softButtons copy];
+ self.alertIcon = icon;
return self;
}
@@ -141,6 +152,14 @@ NS_ASSUME_NONNULL_BEGIN
return [self.parameters sdl_objectsForName:SDLRPCParameterNameSoftButtons ofClass:SDLSoftButton.class error:nil];
}
+- (void)setAlertIcon:(nullable SDLImage *)alertIcon {
+ [self.parameters sdl_setObject:alertIcon forName:SDLRPCParameterNameAlertIcon];
+}
+
+- (nullable SDLImage *)alertIcon {
+ return [self.parameters sdl_objectForName:SDLRPCParameterNameAlertIcon ofClass:SDLImage.class error:nil];
+}
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLAppServiceManifest.h b/SmartDeviceLink/SDLAppServiceManifest.h
index 4622418e1..94069d104 100644
--- a/SmartDeviceLink/SDLAppServiceManifest.h
+++ b/SmartDeviceLink/SDLAppServiceManifest.h
@@ -15,6 +15,7 @@
@class SDLMediaServiceManifest;
@class SDLNavigationServiceManifest;
@class SDLSyncMsgVersion;
+@class SDLMsgVersion;
@class SDLWeatherServiceManifest;
@@ -44,7 +45,20 @@ NS_ASSUME_NONNULL_BEGIN
* @param mediaServiceManifest A media service manifest
* @return A SDLAppServiceManifest object
*/
-- (instancetype)initWithMediaServiceName:(nullable NSString *)serviceName serviceIcon:(nullable SDLImage *)serviceIcon allowAppConsumers:(BOOL)allowAppConsumers rpcSpecVersion:(nullable SDLSyncMsgVersion *)rpcSpecVersion handledRPCs:(nullable NSArray<NSNumber<SDLInt> *> *)handledRPCs mediaServiceManifest:(nullable SDLMediaServiceManifest *)mediaServiceManifest;
+- (instancetype)initWithMediaServiceName:(nullable NSString *)serviceName serviceIcon:(nullable SDLImage *)serviceIcon allowAppConsumers:(BOOL)allowAppConsumers rpcSpecVersion:(nullable SDLSyncMsgVersion *)rpcSpecVersion handledRPCs:(nullable NSArray<NSNumber<SDLInt> *> *)handledRPCs mediaServiceManifest:(nullable SDLMediaServiceManifest *)mediaServiceManifest __deprecated_msg(("Use initWithMediaServiceName:serviceIcon:allowAppConsumers:maxRPCSpecVersion:handledRPCs:mediaServiceManifest instead"));
+
+/**
+ * Convenience init for a media service manifest.
+ *
+ * @param serviceName Unique name of this service
+ * @param serviceIcon The file name of the icon to be associated with this service
+ * @param allowAppConsumers If true, app service consumers beyond the IVI system will be able to access this service. If false, only the IVI system will be able consume the service. If not provided, it is assumed to be false
+ * @param maxRPCSpecVersion This is the max RPC Spec version the app service understands
+ * @param handledRPCs This field contains the Function IDs for the RPCs that this service intends to handle correctly
+ * @param mediaServiceManifest A media service manifest
+ * @return A SDLAppServiceManifest object
+ */
+- (instancetype)initWithMediaServiceName:(nullable NSString *)serviceName serviceIcon:(nullable SDLImage *)serviceIcon allowAppConsumers:(BOOL)allowAppConsumers maxRPCSpecVersion:(nullable SDLMsgVersion *)maxRPCSpecVersion handledRPCs:(nullable NSArray<NSNumber<SDLInt> *> *)handledRPCs mediaServiceManifest:(nullable SDLMediaServiceManifest *)mediaServiceManifest;
/**
* Convenience init for a weather service manifest.
@@ -57,7 +71,20 @@ NS_ASSUME_NONNULL_BEGIN
* @param weatherServiceManifest A weather service manifest
* @return A SDLAppServiceManifest object
*/
-- (instancetype)initWithWeatherServiceName:(nullable NSString *)serviceName serviceIcon:(nullable SDLImage *)serviceIcon allowAppConsumers:(BOOL)allowAppConsumers rpcSpecVersion:(nullable SDLSyncMsgVersion *)rpcSpecVersion handledRPCs:(nullable NSArray<NSNumber<SDLInt> *> *)handledRPCs weatherServiceManifest:(nullable SDLWeatherServiceManifest *)weatherServiceManifest;
+- (instancetype)initWithWeatherServiceName:(nullable NSString *)serviceName serviceIcon:(nullable SDLImage *)serviceIcon allowAppConsumers:(BOOL)allowAppConsumers rpcSpecVersion:(nullable SDLSyncMsgVersion *)rpcSpecVersion handledRPCs:(nullable NSArray<NSNumber<SDLInt> *> *)handledRPCs weatherServiceManifest:(nullable SDLWeatherServiceManifest *)weatherServiceManifest __deprecated_msg(("Use initWithWeatherServiceName:serviceIcon:allowAppConsumers::maxRPCSpecVersion:handledRPCs:weatherServiceManifest instead"));
+
+/**
+ * Convenience init for a weather service manifest.
+ *
+ * @param serviceName Unique name of this service
+ * @param serviceIcon The file name of the icon to be associated with this service
+ * @param allowAppConsumers If true, app service consumers beyond the IVI system will be able to access this service. If false, only the IVI system will be able consume the service. If not provided, it is assumed to be false
+ * @param maxRPCSpecVersion This is the max RPC Spec version the app service understands
+ * @param handledRPCs This field contains the Function IDs for the RPCs that this service intends to handle correctly
+ * @param weatherServiceManifest A weather service manifest
+ * @return A SDLAppServiceManifest object
+ */
+- (instancetype)initWithWeatherServiceName:(nullable NSString *)serviceName serviceIcon:(nullable SDLImage *)serviceIcon allowAppConsumers:(BOOL)allowAppConsumers maxRPCSpecVersion:(nullable SDLMsgVersion *)maxRPCSpecVersion handledRPCs:(nullable NSArray<NSNumber<SDLInt> *> *)handledRPCs weatherServiceManifest:(nullable SDLWeatherServiceManifest *)weatherServiceManifest;
/**
* Convenience init for a navigation service manifest.
@@ -70,7 +97,20 @@ NS_ASSUME_NONNULL_BEGIN
* @param navigationServiceManifest A navigation service manifest
* @return A SDLAppServiceManifest object
*/
-- (instancetype)initWithNavigationServiceName:(nullable NSString *)serviceName serviceIcon:(nullable SDLImage *)serviceIcon allowAppConsumers:(BOOL)allowAppConsumers rpcSpecVersion:(nullable SDLSyncMsgVersion *)rpcSpecVersion handledRPCs:(nullable NSArray<NSNumber<SDLInt> *> *)handledRPCs navigationServiceManifest:(nullable SDLNavigationServiceManifest *)navigationServiceManifest;
+- (instancetype)initWithNavigationServiceName:(nullable NSString *)serviceName serviceIcon:(nullable SDLImage *)serviceIcon allowAppConsumers:(BOOL)allowAppConsumers rpcSpecVersion:(nullable SDLSyncMsgVersion *)rpcSpecVersion handledRPCs:(nullable NSArray<NSNumber<SDLInt> *> *)handledRPCs navigationServiceManifest:(nullable SDLNavigationServiceManifest *)navigationServiceManifest __deprecated_msg(("Use initWithNavigationServiceName:serviceIcon:allowAppConsumers:macRPCSpecVersion:handledRPCs:navigationServiceManifest instead"));
+
+/**
+ * Convenience init for a navigation service manifest.
+ *
+ * @param serviceName Unique name of this service
+ * @param serviceIcon The file name of the icon to be associated with this service
+ * @param allowAppConsumers If true, app service consumers beyond the IVI system will be able to access this service. If false, only the IVI system will be able consume the service. If not provided, it is assumed to be false
+ * @param maxRPCSpecVersion This is the max RPC Spec version the app service understands
+ * @param handledRPCs This field contains the Function IDs for the RPCs that this service intends to handle correctly
+ * @param navigationServiceManifest A navigation service manifest
+ * @return A SDLAppServiceManifest object
+ */
+- (instancetype)initWithNavigationServiceName:(nullable NSString *)serviceName serviceIcon:(nullable SDLImage *)serviceIcon allowAppConsumers:(BOOL)allowAppConsumers maxRPCSpecVersion:(nullable SDLMsgVersion *)maxRPCSpecVersion handledRPCs:(nullable NSArray<NSNumber<SDLInt> *> *)handledRPCs navigationServiceManifest:(nullable SDLNavigationServiceManifest *)navigationServiceManifest;
/**
* Convenience init for all parameters.
@@ -86,7 +126,23 @@ NS_ASSUME_NONNULL_BEGIN
* @param navigationServiceManifest A navigation service manifest
* @return A SDLAppServiceManifest object
*/
-- (instancetype)initWithServiceName:(nullable NSString *)serviceName serviceType:(SDLAppServiceType)serviceType serviceIcon:(nullable SDLImage *)serviceIcon allowAppConsumers:(BOOL)allowAppConsumers rpcSpecVersion:(nullable SDLSyncMsgVersion *)rpcSpecVersion handledRPCs:(nullable NSArray<NSNumber<SDLInt> *> *)handledRPCs mediaServiceManifest:(nullable SDLMediaServiceManifest *)mediaServiceManifest weatherServiceManifest:(nullable SDLWeatherServiceManifest *)weatherServiceManifest navigationServiceManifest:(nullable SDLNavigationServiceManifest *)navigationServiceManifest;
+- (instancetype)initWithServiceName:(nullable NSString *)serviceName serviceType:(SDLAppServiceType)serviceType serviceIcon:(nullable SDLImage *)serviceIcon allowAppConsumers:(BOOL)allowAppConsumers rpcSpecVersion:(nullable SDLSyncMsgVersion *)rpcSpecVersion handledRPCs:(nullable NSArray<NSNumber<SDLInt> *> *)handledRPCs mediaServiceManifest:(nullable SDLMediaServiceManifest *)mediaServiceManifest weatherServiceManifest:(nullable SDLWeatherServiceManifest *)weatherServiceManifest navigationServiceManifest:(nullable SDLNavigationServiceManifest *)navigationServiceManifest __deprecated_msg(("Use initWithServiceName:serviceType:serviceIcon:allowAppConsumers:maxRPCSpecVersion:handledRPCs:mediaServiceManifest:weatherServiceManifest:navigationServiceManifest instead"));
+
+/**
+ * Convenience init for all parameters.
+ *
+ * @param serviceName Unique name of this service
+ * @param serviceType The type of service that is to be offered by this app
+ * @param serviceIcon The file name of the icon to be associated with this service
+ * @param allowAppConsumers If true, app service consumers beyond the IVI system will be able to access this service. If false, only the IVI system will be able consume the service. If not provided, it is assumed to be false
+ * @param maxRPCSpecVersion This is the max RPC Spec version the app service understands
+ * @param handledRPCs This field contains the Function IDs for the RPCs that this service intends to handle correctly
+ * @param mediaServiceManifest A media service manifest
+ * @param weatherServiceManifest A weather service manifest
+ * @param navigationServiceManifest A navigation service manifest
+ * @return A SDLAppServiceManifest object
+ */
+- (instancetype)initWithServiceName:(nullable NSString *)serviceName serviceType:(SDLAppServiceType)serviceType serviceIcon:(nullable SDLImage *)serviceIcon allowAppConsumers:(BOOL)allowAppConsumers maxRPCSpecVersion:(nullable SDLMsgVersion *)maxRPCSpecVersion handledRPCs:(nullable NSArray<NSNumber<SDLInt> *> *)handledRPCs mediaServiceManifest:(nullable SDLMediaServiceManifest *)mediaServiceManifest weatherServiceManifest:(nullable SDLWeatherServiceManifest *)weatherServiceManifest navigationServiceManifest:(nullable SDLNavigationServiceManifest *)navigationServiceManifest;
/**
* Unique name of this service.
@@ -121,7 +177,14 @@ NS_ASSUME_NONNULL_BEGIN
*
* SyncMsgVersion, Optional
*/
-@property (nullable, strong, nonatomic) SDLSyncMsgVersion *rpcSpecVersion;
+@property (nullable, strong, nonatomic) SDLSyncMsgVersion *rpcSpecVersion __deprecated_msg(("Use maxRPCSpecVersion instead"));
+
+/**
+ * This is the max RPC Spec version the app service understands. This is important during the RPC passthrough functionality. If not included, it is assumed the max version of the module is acceptable.
+ *
+ * SDLMsgVersion, Optional
+ */
+@property (nullable, strong, nonatomic) SDLMsgVersion *maxRPCSpecVersion;
/**
* This field contains the Function IDs for the RPCs that this service intends to handle correctly. This means the service will provide meaningful responses. See FunctionID for enum equivalent values. This parameter is an integer to allow for new function IDs to be used by apps on older versions of SDL Core.
diff --git a/SmartDeviceLink/SDLAppServiceManifest.m b/SmartDeviceLink/SDLAppServiceManifest.m
index 97afc2e77..3a40c9cd0 100644
--- a/SmartDeviceLink/SDLAppServiceManifest.m
+++ b/SmartDeviceLink/SDLAppServiceManifest.m
@@ -15,6 +15,7 @@
#import "SDLMediaServiceManifest.h"
#import "SDLNavigationServiceManifest.h"
#import "SDLSyncMsgVersion.h"
+#import "SDLMsgVersion.h"
#import "SDLWeatherServiceManifest.h"
NS_ASSUME_NONNULL_BEGIN
@@ -32,18 +33,29 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- (instancetype)initWithMediaServiceName:(nullable NSString *)serviceName serviceIcon:(nullable SDLImage *)serviceIcon allowAppConsumers:(BOOL)allowAppConsumers rpcSpecVersion:(nullable SDLSyncMsgVersion *)rpcSpecVersion handledRPCs:(nullable NSArray<NSNumber<SDLInt> *> *)handledRPCs mediaServiceManifest:(nullable SDLMediaServiceManifest *)mediaServiceManifest {
return [self initWithServiceName:serviceName serviceType:SDLAppServiceTypeMedia serviceIcon:serviceIcon allowAppConsumers:allowAppConsumers rpcSpecVersion:rpcSpecVersion handledRPCs:handledRPCs mediaServiceManifest:mediaServiceManifest weatherServiceManifest:nil navigationServiceManifest:nil];
}
+#pragma clang diagnostic pop
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- (instancetype)initWithWeatherServiceName:(nullable NSString *)serviceName serviceIcon:(nullable SDLImage *)serviceIcon allowAppConsumers:(BOOL)allowAppConsumers rpcSpecVersion:(nullable SDLSyncMsgVersion *)rpcSpecVersion handledRPCs:(nullable NSArray<NSNumber<SDLInt> *> *)handledRPCs weatherServiceManifest:(nullable SDLWeatherServiceManifest *)weatherServiceManifest {
return [self initWithServiceName:serviceName serviceType:SDLAppServiceTypeWeather serviceIcon:serviceIcon allowAppConsumers:allowAppConsumers rpcSpecVersion:rpcSpecVersion handledRPCs:handledRPCs mediaServiceManifest:nil weatherServiceManifest:weatherServiceManifest navigationServiceManifest:nil];
}
+#pragma clang diagnostic pop
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- (instancetype)initWithNavigationServiceName:(nullable NSString *)serviceName serviceIcon:(nullable SDLImage *)serviceIcon allowAppConsumers:(BOOL)allowAppConsumers rpcSpecVersion:(nullable SDLSyncMsgVersion *)rpcSpecVersion handledRPCs:(nullable NSArray<NSNumber<SDLInt> *> *)handledRPCs navigationServiceManifest:(nullable SDLNavigationServiceManifest *)navigationServiceManifest {
return [self initWithServiceName:serviceName serviceType:SDLAppServiceTypeNavigation serviceIcon:serviceIcon allowAppConsumers:allowAppConsumers rpcSpecVersion:rpcSpecVersion handledRPCs:handledRPCs mediaServiceManifest:nil weatherServiceManifest:nil navigationServiceManifest:navigationServiceManifest];
}
+#pragma clang diagnostic pop
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- (instancetype)initWithServiceName:(nullable NSString *)serviceName serviceType:(SDLAppServiceType)serviceType serviceIcon:(nullable SDLImage *)serviceIcon allowAppConsumers:(BOOL)allowAppConsumers rpcSpecVersion:(nullable SDLSyncMsgVersion *)rpcSpecVersion handledRPCs:(nullable NSArray<NSNumber<SDLInt> *> *)handledRPCs mediaServiceManifest:(nullable SDLMediaServiceManifest *)mediaServiceManifest weatherServiceManifest:(nullable SDLWeatherServiceManifest *)weatherServiceManifest navigationServiceManifest:(nullable SDLNavigationServiceManifest *)navigationServiceManifest {
self = [self initWithAppServiceType:serviceType];
if (!self) {
@@ -61,6 +73,37 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
+#pragma clang diagnostic pop
+
+- (instancetype)initWithMediaServiceName:(nullable NSString *)serviceName serviceIcon:(nullable SDLImage *)serviceIcon allowAppConsumers:(BOOL)allowAppConsumers maxRPCSpecVersion:(nullable SDLMsgVersion *)maxRPCSpecVersion handledRPCs:(nullable NSArray<NSNumber<SDLInt> *> *)handledRPCs mediaServiceManifest:(nullable SDLMediaServiceManifest *)mediaServiceManifest {
+ return [self initWithServiceName:serviceName serviceType:SDLAppServiceTypeMedia serviceIcon:serviceIcon allowAppConsumers:allowAppConsumers maxRPCSpecVersion:maxRPCSpecVersion handledRPCs:handledRPCs mediaServiceManifest:mediaServiceManifest weatherServiceManifest:nil navigationServiceManifest:nil];
+}
+
+- (instancetype)initWithWeatherServiceName:(nullable NSString *)serviceName serviceIcon:(nullable SDLImage *)serviceIcon allowAppConsumers:(BOOL)allowAppConsumers maxRPCSpecVersion:(nullable SDLMsgVersion *)maxRPCSpecVersion handledRPCs:(nullable NSArray<NSNumber<SDLInt> *> *)handledRPCs weatherServiceManifest:(nullable SDLWeatherServiceManifest *)weatherServiceManifest {
+ return [self initWithServiceName:serviceName serviceType:SDLAppServiceTypeWeather serviceIcon:serviceIcon allowAppConsumers:allowAppConsumers maxRPCSpecVersion:maxRPCSpecVersion handledRPCs:handledRPCs mediaServiceManifest:nil weatherServiceManifest:weatherServiceManifest navigationServiceManifest:nil];
+}
+
+- (instancetype)initWithNavigationServiceName:(nullable NSString *)serviceName serviceIcon:(nullable SDLImage *)serviceIcon allowAppConsumers:(BOOL)allowAppConsumers maxRPCSpecVersion:(nullable SDLMsgVersion *)maxRPCSpecVersion handledRPCs:(nullable NSArray<NSNumber<SDLInt> *> *)handledRPCs navigationServiceManifest:(nullable SDLNavigationServiceManifest *)navigationServiceManifest {
+ return [self initWithServiceName:serviceName serviceType:SDLAppServiceTypeNavigation serviceIcon:serviceIcon allowAppConsumers:allowAppConsumers maxRPCSpecVersion:maxRPCSpecVersion handledRPCs:handledRPCs mediaServiceManifest:nil weatherServiceManifest:nil navigationServiceManifest:navigationServiceManifest];
+}
+
+- (instancetype)initWithServiceName:(nullable NSString *)serviceName serviceType:(SDLAppServiceType)serviceType serviceIcon:(nullable SDLImage *)serviceIcon allowAppConsumers:(BOOL)allowAppConsumers maxRPCSpecVersion:(nullable SDLMsgVersion *)maxRPCSpecVersion handledRPCs:(nullable NSArray<NSNumber<SDLInt> *> *)handledRPCs mediaServiceManifest:(nullable SDLMediaServiceManifest *)mediaServiceManifest weatherServiceManifest:(nullable SDLWeatherServiceManifest *)weatherServiceManifest navigationServiceManifest:(nullable SDLNavigationServiceManifest *)navigationServiceManifest {
+ self = [self initWithAppServiceType:serviceType];
+ if (!self) {
+ return self;
+ }
+
+ self.serviceName = serviceName;
+ self.serviceIcon = serviceIcon;
+ self.allowAppConsumers = @(allowAppConsumers);
+ self.maxRPCSpecVersion = maxRPCSpecVersion;
+ self.handledRPCs = handledRPCs;
+ self.mediaServiceManifest = mediaServiceManifest;
+ self.weatherServiceManifest = weatherServiceManifest;
+ self.navigationServiceManifest = navigationServiceManifest;
+
+ return self;
+}
- (void)setServiceName:(nullable NSString *)serviceName {
[self.store sdl_setObject:serviceName forName:SDLRPCParameterNameServiceName];
@@ -95,12 +138,34 @@ NS_ASSUME_NONNULL_BEGIN
return [self.store sdl_objectForName:SDLRPCParameterNameAllowAppConsumers ofClass:NSNumber.class error:nil];
}
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- (void)setRpcSpecVersion:(nullable SDLSyncMsgVersion *)rpcSpecVersion {
- [self.store sdl_setObject:rpcSpecVersion forName:SDLRPCParameterNameRPCSpecVersion];
+ if (rpcSpecVersion == nil) {
+ [self.store sdl_setObject:nil forName:SDLRPCParameterNameRPCSpecVersion];
+ return;
+ }
+ SDLMsgVersion *maxRPCSpecVersion = [[SDLMsgVersion alloc] initWithMajorVersion:(uint8_t)rpcSpecVersion.majorVersion.unsignedIntValue minorVersion:(uint8_t)rpcSpecVersion.minorVersion.unsignedIntValue patchVersion:(uint8_t)rpcSpecVersion.patchVersion.unsignedIntValue];
+ [self.store sdl_setObject:maxRPCSpecVersion forName:SDLRPCParameterNameRPCSpecVersion];
}
- (nullable SDLSyncMsgVersion *)rpcSpecVersion {
- return [self.store sdl_objectForName:SDLRPCParameterNameRPCSpecVersion ofClass:SDLSyncMsgVersion.class error:nil];
+ SDLMsgVersion *maxRPCSpecVersion = [self.store sdl_objectForName:SDLRPCParameterNameRPCSpecVersion ofClass:SDLMsgVersion.class error:nil];
+
+ if(maxRPCSpecVersion == nil) {
+ return [self.store sdl_objectForName:SDLRPCParameterNameRPCSpecVersion ofClass:SDLSyncMsgVersion.class error:nil];
+ }
+
+ return [[SDLSyncMsgVersion alloc] initWithMajorVersion:(uint8_t)maxRPCSpecVersion.majorVersion.unsignedIntValue minorVersion:(uint8_t)maxRPCSpecVersion.minorVersion.unsignedIntValue patchVersion:(uint8_t)maxRPCSpecVersion.patchVersion.unsignedIntValue];
+}
+#pragma clang diagnostic pop
+
+- (void)setMaxRPCSpecVersion:(nullable SDLMsgVersion *)maxRPCSpecVersion {
+ [self.store sdl_setObject:maxRPCSpecVersion forName:SDLRPCParameterNameRPCSpecVersion];
+}
+
+- (nullable SDLMsgVersion *)maxRPCSpecVersion {
+ return [self.store sdl_objectForName:SDLRPCParameterNameRPCSpecVersion ofClass:SDLMsgVersion.class error:nil];
}
- (void)setHandledRPCs:(nullable NSArray<NSNumber<SDLInt> *> *)handledRPCs {
diff --git a/SmartDeviceLink/SDLAsynchronousOperation.m b/SmartDeviceLink/SDLAsynchronousOperation.m
index 49450f49b..d2e12384d 100644
--- a/SmartDeviceLink/SDLAsynchronousOperation.m
+++ b/SmartDeviceLink/SDLAsynchronousOperation.m
@@ -8,16 +8,21 @@
#import "SDLAsynchronousOperation.h"
+#import "SDLLogMacros.h"
+
@implementation SDLAsynchronousOperation {
BOOL executing;
BOOL finished;
}
- (void)start {
+ SDLLogV(@"Starting operation: %@", self);
+
if (self.isCancelled) {
[self willChangeValueForKey:@"isFinished"];
finished = YES;
[self didChangeValueForKey:@"isFinished"];
+ SDLLogV(@"Operation was cancelled: %@", self);
return;
}
@@ -28,6 +33,7 @@
}
- (void)finishOperation {
+ SDLLogV(@"Finishing Operation: %@", self);
[self willChangeValueForKey:@"isExecuting"];
executing = NO;
[self didChangeValueForKey:@"isExecuting"];
diff --git a/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m b/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m
index 5c67e3e8a..c77c80d52 100644
--- a/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m
+++ b/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m
@@ -91,29 +91,30 @@ NS_ASSUME_NONNULL_BEGIN
- (void)sdl_sendRequest:(SDLRPCRequest *)request {
__weak typeof(self) weakSelf = self;
[self.connectionManager sendConnectionRequest:request withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) {
- __strong typeof(self) strongSelf = weakSelf;
+ if (weakSelf == nil) { return; }
- if (strongSelf.isCancelled) {
- [self sdl_abortOperationWithRequest:request];
+ if (weakSelf.isCancelled) {
+ [weakSelf sdl_abortOperationWithRequest:request];
BLOCK_RETURN;
}
- strongSelf.requestsComplete++;
+ weakSelf.requestsComplete++;
// If this request failed set our internal request failed to YES
if (error != nil) {
- strongSelf.requestFailed = YES;
+ weakSelf.requestFailed = YES;
}
- if (strongSelf.progressHandler != NULL) {
- strongSelf.progressHandler(request, response, error, strongSelf.percentComplete);
- } else if (strongSelf.responseHandler != NULL) {
- strongSelf.responseHandler(request, response, error);
+ if (weakSelf.progressHandler != NULL) {
+ float percentComplete = weakSelf.percentComplete;
+ weakSelf.progressHandler(request, response, error, percentComplete);
+ } else if (weakSelf.responseHandler != NULL) {
+ weakSelf.responseHandler(request, response, error);
}
// If we've received responses for all requests, call the completion handler.
- if (strongSelf.requestsComplete >= strongSelf.requests.count) {
- [strongSelf finishOperation];
+ if (weakSelf.requestsComplete >= weakSelf.requests.count) {
+ [weakSelf finishOperation];
}
}];
}
diff --git a/SmartDeviceLink/SDLAudioStreamManager.m b/SmartDeviceLink/SDLAudioStreamManager.m
index ff16f2b16..11d39812a 100755
--- a/SmartDeviceLink/SDLAudioStreamManager.m
+++ b/SmartDeviceLink/SDLAudioStreamManager.m
@@ -10,6 +10,7 @@
#import "SDLAudioFile.h"
#import "SDLFile.h"
+#import "SDLGlobals.h"
#import "SDLLogMacros.h"
#import "SDLManager.h"
#import "SDLPCMAudioConverter.h"
@@ -38,9 +39,14 @@ NSString *const SDLErrorDomainAudioStreamManager = @"com.sdl.extension.pcmAudioS
if (!self) { return nil; }
_mutableQueue = [NSMutableArray array];
- _audioQueue = dispatch_queue_create("com.sdl.audiomanager.transcode", DISPATCH_QUEUE_SERIAL);
_shouldPlayWhenReady = NO;
+ if (@available(iOS 10.0, *)) {
+ _audioQueue = dispatch_queue_create_with_target("com.sdl.audiomanager.transcode", DISPATCH_QUEUE_SERIAL, [SDLGlobals sharedGlobals].sdlProcessingQueue);
+ } else {
+ _audioQueue = [SDLGlobals sharedGlobals].sdlProcessingQueue;
+ }
+
_streamManager = streamManager;
return self;
@@ -146,7 +152,7 @@ NSString *const SDLErrorDomainAudioStreamManager = @"com.sdl.extension.pcmAudioS
// Determine the length of the audio PCM data and perform a few items once the audio has finished playing
float audioLengthSecs = (float)audioData.length / (float)32000.0;
__weak typeof(self) weakself = self;
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(audioLengthSecs * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(audioLengthSecs * NSEC_PER_SEC)), [SDLGlobals sharedGlobals].sdlProcessingQueue, ^{
__strong typeof(weakself) strongSelf = weakself;
strongSelf.playing = NO;
diff --git a/SmartDeviceLink/SDLButtonName.h b/SmartDeviceLink/SDLButtonName.h
index cb767ef35..2badd1635 100644
--- a/SmartDeviceLink/SDLButtonName.h
+++ b/SmartDeviceLink/SDLButtonName.h
@@ -208,3 +208,79 @@ extern SDLButtonName const SDLButtonNameShuffle;
* Represents a Repeat button.
*/
extern SDLButtonName const SDLButtonNameRepeat;
+
+#pragma mark - Navigation Buttons
+/**
+ * Represents a Navigate to center button.
+ */
+extern SDLButtonName const SDLButtonNameNavCenterLocation;
+
+/**
+ * Represents a Zoom in button.
+ */
+extern SDLButtonName const SDLButtonNameNavZoomIn;
+
+/**
+ * Represents a Zoom out button.
+ */
+extern SDLButtonName const SDLButtonNameNavZoomOut;
+
+/**
+ * Represents a Pan up button
+ */
+extern SDLButtonName const SDLButtonNameNavPanUp;
+
+/**
+ * Represents a Pan up/right button
+ */
+extern SDLButtonName const SDLButtonNameNavPanUpRight;
+
+/**
+ * Represents a Pan right button
+ */
+extern SDLButtonName const SDLButtonNameNavPanRight;
+
+/**
+ * Represents a Pan down/right button
+ */
+extern SDLButtonName const SDLButtonNameNavPanDownRight;
+
+/**
+ * Represents a Pan down button
+ */
+extern SDLButtonName const SDLButtonNameNavPanDown;
+
+/**
+ * Represents a Pan down left button
+ */
+extern SDLButtonName const SDLButtonNameNavPanDownLeft;
+
+/*
+ * Represents a Pan left button
+ */
+extern SDLButtonName const SDLButtonNameNavPanLeft;
+
+/*
+ * Represents a Pan up left button
+ */
+extern SDLButtonName const SDLButtonNameNavPanUpLeft;
+
+/*
+ * Represents a Tilt button. If supported, this toggles between a top-down view and an angled/3D view. If your app supports different, but substantially similar options, then you may implement those. If you don't implement these or similar options, do not subscribe to this button.
+ */
+extern SDLButtonName const SDLButtonNameNavTiltToggle;
+
+/*
+ * Represents a Rotate clockwise button
+ */
+extern SDLButtonName const SDLButtonNameNavRotateClockwise;
+
+/*
+ * Represents a Rotate counterclockwise button
+ */
+extern SDLButtonName const SDLButtonNameNavRotateCounterClockwise;
+
+/*
+ * Represents a Heading toggle button. If supported, this toggles between locking the orientation to north or to the vehicle's heading. If your app supports different, but substantially similar options, then you may implement those. If you don't implement these or similar options, do not subscribe to this button.
+ */
+extern SDLButtonName const SDLButtonNameNavHeadingToggle;
diff --git a/SmartDeviceLink/SDLButtonName.m b/SmartDeviceLink/SDLButtonName.m
index fe8e1ac33..c0979df8b 100644
--- a/SmartDeviceLink/SDLButtonName.m
+++ b/SmartDeviceLink/SDLButtonName.m
@@ -40,3 +40,18 @@ SDLButtonName const SDLButtonNameEject = @"EJECT";
SDLButtonName const SDLButtonNameSource = @"SOURCE";
SDLButtonName const SDLButtonNameShuffle = @"SHUFFLE";
SDLButtonName const SDLButtonNameRepeat = @"REPEAT";
+SDLButtonName const SDLButtonNameNavCenterLocation = @"NAV_CENTER_LOCATION";
+SDLButtonName const SDLButtonNameNavZoomIn = @"NAV_ZOOM_IN";
+SDLButtonName const SDLButtonNameNavZoomOut = @"NAV_ZOOM_OUT";
+SDLButtonName const SDLButtonNameNavPanUp = @"NAV_PAN_UP";
+SDLButtonName const SDLButtonNameNavPanUpRight = @"NAV_PAN_UP_RIGHT";
+SDLButtonName const SDLButtonNameNavPanRight = @"NAV_PAN_RIGHT";
+SDLButtonName const SDLButtonNameNavPanDownRight = @"NAV_PAN_DOWN_RIGHT";
+SDLButtonName const SDLButtonNameNavPanDown = @"NAV_PAN_DOWN";
+SDLButtonName const SDLButtonNameNavPanDownLeft = @"NAV_PAN_DOWN_LEFT";
+SDLButtonName const SDLButtonNameNavPanLeft = @"NAV_PAN_LEFT";
+SDLButtonName const SDLButtonNameNavPanUpLeft = @"NAV_PAN_UP_LEFT";
+SDLButtonName const SDLButtonNameNavTiltToggle = @"NAV_TILT_TOGGLE";
+SDLButtonName const SDLButtonNameNavRotateClockwise = @"NAV_ROTATE_CLOCKWISE";
+SDLButtonName const SDLButtonNameNavRotateCounterClockwise = @"NAV_ROTATE_COUNTERCLOCKWISE";
+SDLButtonName const SDLButtonNameNavHeadingToggle = @"NAV_HEADING_TOGGLE";
diff --git a/SmartDeviceLink/SDLCheckChoiceVROptionalOperation.m b/SmartDeviceLink/SDLCheckChoiceVROptionalOperation.m
index f42144e67..abe323689 100644
--- a/SmartDeviceLink/SDLCheckChoiceVROptionalOperation.m
+++ b/SmartDeviceLink/SDLCheckChoiceVROptionalOperation.m
@@ -18,6 +18,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface SDLCheckChoiceVROptionalOperation()
+@property (strong, nonatomic) NSUUID *operationId;
@property (weak, nonatomic) id<SDLConnectionManagerType> connectionManager;
@property (copy, nonatomic, nullable) NSError *internalError;
@@ -30,6 +31,7 @@ NS_ASSUME_NONNULL_BEGIN
if (!self) { return nil; }
_connectionManager = connectionManager;
+ _operationId = [NSUUID UUID];
return self;
}
@@ -94,7 +96,7 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Property Overrides
- (nullable NSString *)name {
- return @"com.sdl.choicesetmanager.checkVROptional";
+ return [NSString stringWithFormat:@"%@ - %@", self.class, self.operationId];
}
- (NSOperationQueuePriority)queuePriority {
diff --git a/SmartDeviceLink/SDLChoiceSetManager.m b/SmartDeviceLink/SDLChoiceSetManager.m
index 037878fc5..7818dac24 100644
--- a/SmartDeviceLink/SDLChoiceSetManager.m
+++ b/SmartDeviceLink/SDLChoiceSetManager.m
@@ -21,6 +21,7 @@
#import "SDLDisplayCapabilities+ShowManagerExtensions.h"
#import "SDLError.h"
#import "SDLFileManager.h"
+#import "SDLGlobals.h"
#import "SDLHMILevel.h"
#import "SDLKeyboardProperties.h"
#import "SDLLogMacros.h"
@@ -127,9 +128,9 @@ UInt16 const ChoiceCellIdMin = 1;
- (NSOperationQueue *)sdl_newTransactionQueue {
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
- queue.name = @"SDLChoiceSetManager Transaction Queue";
+ queue.name = @"com.sdl.screenManager.choiceSetManager.transactionQueue";
queue.maxConcurrentOperationCount = 1;
- queue.qualityOfService = NSQualityOfServiceUserInitiated;
+ queue.underlyingQueue = [SDLGlobals sharedGlobals].sdlConcurrentQueue;
queue.suspended = YES;
return queue;
diff --git a/SmartDeviceLink/SDLDeleteChoicesOperation.m b/SmartDeviceLink/SDLDeleteChoicesOperation.m
index 46b7c0d6d..7fd42a491 100644
--- a/SmartDeviceLink/SDLDeleteChoicesOperation.m
+++ b/SmartDeviceLink/SDLDeleteChoicesOperation.m
@@ -23,6 +23,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface SDLDeleteChoicesOperation()
+@property (strong, nonatomic) NSUUID *operationId;
@property (strong, nonatomic) NSSet<SDLChoiceCell *> *cellsToDelete;
@property (weak, nonatomic) id<SDLConnectionManagerType> connectionManager;
@property (copy, nonatomic, nullable) NSError *internalError;
@@ -37,6 +38,7 @@ NS_ASSUME_NONNULL_BEGIN
_connectionManager = connectionManager;
_cellsToDelete = cells;
+ _operationId = [NSUUID UUID];
return self;
}
@@ -71,7 +73,7 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Property Overrides
- (nullable NSString *)name {
- return @"com.sdl.choicesetmanager.deleteChoices";
+ return [NSString stringWithFormat:@"%@ - %@", self.class, self.operationId];
}
- (NSOperationQueuePriority)queuePriority {
diff --git a/SmartDeviceLink/SDLDeleteFileOperation.h b/SmartDeviceLink/SDLDeleteFileOperation.h
index 78563c58f..9252ae725 100644
--- a/SmartDeviceLink/SDLDeleteFileOperation.h
+++ b/SmartDeviceLink/SDLDeleteFileOperation.h
@@ -29,6 +29,21 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (instancetype)initWithFileName:(NSString *)fileName connectionManager:(id<SDLConnectionManagerType>)connectionManager completionHandler:(nullable SDLFileManagerDeleteCompletionHandler)completionHandler;
+/**
+ The name of the file to be deleted on the remote system.
+ */
+@property (copy, nonatomic, readonly) NSString *fileName;
+
+/**
+ The connection manager which will handle transporting the request to the remote system.
+ */
+@property (weak, nonatomic, readonly) id<SDLConnectionManagerType> connectionManager;
+
+/**
+ A completion handler to be called when the delete finishes.
+ */
+@property (copy, nonatomic, nullable, readonly) SDLFileManagerDeleteCompletionHandler completionHandler;
+
@end
-NS_ASSUME_NONNULL_END \ No newline at end of file
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLDeleteFileOperation.m b/SmartDeviceLink/SDLDeleteFileOperation.m
index 4d974a2ad..fa1de55f6 100644
--- a/SmartDeviceLink/SDLDeleteFileOperation.m
+++ b/SmartDeviceLink/SDLDeleteFileOperation.m
@@ -69,7 +69,7 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark Property Overrides
- (nullable NSString *)name {
- return self.fileName;
+ return [NSString stringWithFormat:@"%@ - %@", self.class, self.fileName];
}
- (NSOperationQueuePriority)queuePriority {
diff --git a/SmartDeviceLink/SDLDisplayCapabilities.h b/SmartDeviceLink/SDLDisplayCapabilities.h
index c9cbe1598..ed856ccdf 100644
--- a/SmartDeviceLink/SDLDisplayCapabilities.h
+++ b/SmartDeviceLink/SDLDisplayCapabilities.h
@@ -76,11 +76,11 @@ NS_ASSUME_NONNULL_BEGIN
@property (strong, nonatomic) NSNumber<SDLBool> *graphicSupported;
/**
- * Number of presets the screen supports
+ * An array of all predefined persistent display templates available on the head unit.
*
- * @discussion The number of on-screen custom presets available (if any)
+ * Optional, Array of String, max string size 100, 0 - 100 objects, since SDL 3.0
*
- * Optional, Array of String, max string size 100, 0 - 100 objects
+ * See SDLPredefinedLayout
*/
@property (nullable, strong, nonatomic) NSArray<NSString *> *templatesAvailable;
diff --git a/SmartDeviceLink/SDLFile.m b/SmartDeviceLink/SDLFile.m
index 3e69a943c..1efe7454b 100644
--- a/SmartDeviceLink/SDLFile.m
+++ b/SmartDeviceLink/SDLFile.m
@@ -166,6 +166,10 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - NSObject overrides
+- (NSString *)description {
+ return [NSString stringWithFormat:@"SDLFile: %@", self.name];
+}
+
- (NSUInteger)hash {
return self.name.hash ^ self.data.hash;
}
diff --git a/SmartDeviceLink/SDLFileManager.m b/SmartDeviceLink/SDLFileManager.m
index eef7e92ac..215c098d2 100644
--- a/SmartDeviceLink/SDLFileManager.m
+++ b/SmartDeviceLink/SDLFileManager.m
@@ -45,14 +45,13 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
// Local state
@property (strong, nonatomic) NSOperationQueue *transactionQueue;
-@property (strong, nonatomic) NSMutableDictionary<SDLFileName *, NSOperation *> *uploadsInProgress;
@property (strong, nonatomic) NSMutableSet<SDLFileName *> *uploadedEphemeralFileNames;
@property (strong, nonatomic) SDLStateMachine *stateMachine;
@property (copy, nonatomic, nullable) SDLFileManagerStartupCompletionHandler startupCompletionHandler;
@property (strong, nonatomic) NSMutableDictionary<SDLFileName *, NSNumber<SDLUInt> *> *failedFileUploadsCount;
-@property (assign, nonatomic) UInt8 maxFileUploadAttempts;
-@property (assign, nonatomic) UInt8 maxArtworkUploadAttempts;
+@property (assign, nonatomic) NSUInteger maxFileUploadAttempts;
+@property (assign, nonatomic) NSUInteger maxArtworkUploadAttempts;
@end
@@ -77,9 +76,9 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
_mutableRemoteFileNames = [NSMutableSet set];
_transactionQueue = [[NSOperationQueue alloc] init];
- _transactionQueue.name = @"SDLFileManager Transaction Queue";
+ _transactionQueue.name = @"com.sdl.fileManager.transactionQueue";
+ _transactionQueue.underlyingQueue = [SDLGlobals sharedGlobals].sdlProcessingQueue;
_transactionQueue.maxConcurrentOperationCount = 1;
- _uploadsInProgress = [[NSMutableDictionary alloc] init];
_uploadedEphemeralFileNames = [[NSMutableSet<SDLFileName *> alloc] init];
_stateMachine = [[SDLStateMachine alloc] initWithTarget:self initialState:SDLFileManagerStateShutdown states:[self.class sdl_stateTransitionDictionary]];
@@ -105,11 +104,13 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
- (void)stop {
[self.stateMachine transitionToState:SDLFileManagerStateShutdown];
-
- // Clear the failed uploads tracking so failed files can be uploaded again when a new connection has been established with Core
- _failedFileUploadsCount = [NSMutableDictionary dictionary];
}
+- (void)dealloc {
+ if (self.currentState != SDLFileManagerStateShutdown) {
+ [self.stateMachine transitionToState:SDLFileManagerStateShutdown];
+ }
+}
#pragma mark - Getters
@@ -161,6 +162,9 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
[self.class sdl_clearTemporaryFileDirectory];
self.bytesAvailable = 0;
+ // Clear the failed uploads tracking so failed files can be uploaded again when a new connection has been established with Core
+ _failedFileUploadsCount = [NSMutableDictionary dictionary];
+
if (self.startupCompletionHandler != nil) {
self.startupCompletionHandler(NO, [NSError sdl_fileManager_unableToStartError]);
self.startupCompletionHandler = nil;
@@ -262,7 +266,7 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
dispatch_group_leave(deleteFilesTask);
// Wait for all files to be deleted
- dispatch_group_notify(deleteFilesTask, dispatch_get_main_queue(), ^{
+ dispatch_group_notify(deleteFilesTask, [SDLGlobals sharedGlobals].sdlProcessingQueue, ^{
if (completionHandler == nil) { return; }
if (failedDeletes.count > 0) {
return completionHandler([NSError sdl_fileManager_unableToDelete_ErrorWithUserInfo:failedDeletes]);
@@ -302,9 +306,20 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
dispatch_group_t uploadFilesTask = dispatch_group_create();
dispatch_group_enter(uploadFilesTask);
- for(SDLFile *file in files) {
- dispatch_group_enter(uploadFilesTask);
+ // Wait for all files to be uploaded
+ dispatch_group_notify(uploadFilesTask, [SDLGlobals sharedGlobals].sdlProcessingQueue, ^{
+ if (completionHandler == nil) { return; }
+ if (failedUploads.count > 0) {
+ return completionHandler([NSError sdl_fileManager_unableToUpload_ErrorWithUserInfo:failedUploads]);
+ }
+ return completionHandler(nil);
+ });
+
+ for(NSUInteger i = 0; i < files.count; i++) {
+ SDLFile *file = files[i];
+ dispatch_group_enter(uploadFilesTask);
+ __weak typeof(self) weakself = self;
[self uploadFile:file completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
if(!success) {
failedUploads[file.name] = error;
@@ -313,14 +328,17 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
// Send an update for each file sent to the remote
if (progressHandler != nil) {
totalBytesUploaded += file.fileSize;
- float uploadPercentage = [self sdl_uploadPercentage:totalBytesToUpload uploadedBytes:totalBytesUploaded];
+ float uploadPercentage = [weakself sdl_uploadPercentage:totalBytesToUpload uploadedBytes:totalBytesUploaded];
BOOL continueWithRemainingUploads = progressHandler(file.name, uploadPercentage, error);
if (!continueWithRemainingUploads) {
// Cancel any remaining files waiting to be uploaded
- for(SDLFile *file in files) {
- NSOperation *fileUploadOperation = self.uploadsInProgress[file.name];
- if (fileUploadOperation) {
- [fileUploadOperation cancel];
+ for(NSUInteger j = i + 1; j < files.count; j++) {
+ SDLFile *cancelFile = files[j];
+ for (SDLUploadFileOperation *op in weakself.transactionQueue.operations) {
+ if ([op.fileWrapper.file isEqual:cancelFile]) {
+ [op cancel];
+ break;
+ }
}
}
@@ -332,15 +350,6 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
}];
}
dispatch_group_leave(uploadFilesTask);
-
- // Wait for all files to be uploaded
- dispatch_group_notify(uploadFilesTask, dispatch_get_main_queue(), ^{
- if (completionHandler == nil) { return; }
- if (failedUploads.count > 0) {
- return completionHandler([NSError sdl_fileManager_unableToUpload_ErrorWithUserInfo:failedUploads]);
- }
- return completionHandler(nil);
- });
}
- (void)uploadFile:(SDLFile *)file completionHandler:(nullable SDLFileManagerUploadCompletionHandler)handler {
@@ -372,7 +381,7 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
}
// Check our overwrite settings and error out if it would overwrite
- if (file.overwrite == NO && [self.remoteFileNames containsObject:file.name]) {
+ if (!file.overwrite && [self.remoteFileNames containsObject:file.name]) {
if (handler != nil) {
handler(NO, self.bytesAvailable, [NSError sdl_fileManager_cannotOverwriteError]);
}
@@ -389,21 +398,17 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
__weak typeof(self) weakSelf = self;
SDLFileWrapper *fileWrapper = [SDLFileWrapper wrapperWithFile:file completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError *_Nullable error) {
- if (self.uploadsInProgress[file.name]) {
- [self.uploadsInProgress removeObjectForKey:file.name];
- }
-
if (success) {
weakSelf.bytesAvailable = bytesAvailable;
[weakSelf.mutableRemoteFileNames addObject:fileName];
[weakSelf.uploadedEphemeralFileNames addObject:fileName];
} else {
- self.failedFileUploadsCount = [self.class sdl_incrementFailedUploadCountForFileName:file.name failedFileUploadsCount:self.failedFileUploadsCount];
+ weakSelf.failedFileUploadsCount = [weakSelf.class sdl_incrementFailedUploadCountForFileName:file.name failedFileUploadsCount:weakSelf.failedFileUploadsCount];
- UInt8 maxUploadCount = [file isKindOfClass:[SDLArtwork class]] ? self.maxArtworkUploadAttempts : self.maxFileUploadAttempts;
- if ([self sdl_canFileBeUploadedAgain:file maxUploadCount:maxUploadCount failedFileUploadsCount:self.failedFileUploadsCount]) {
+ NSUInteger maxUploadCount = [file isMemberOfClass:[SDLArtwork class]] ? weakSelf.maxArtworkUploadAttempts : self.maxFileUploadAttempts;
+ if ([weakSelf sdl_canFileBeUploadedAgain:file maxUploadCount:maxUploadCount failedFileUploadsCount:weakSelf.failedFileUploadsCount]) {
SDLLogD(@"Attempting to resend file with name %@ after a failed upload attempt", file.name);
- return [self sdl_uploadFile:file completionHandler:handler];
+ return [weakSelf sdl_uploadFile:file completionHandler:handler];
}
}
@@ -414,18 +419,18 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
SDLUploadFileOperation *uploadOperation = [[SDLUploadFileOperation alloc] initWithFile:fileWrapper connectionManager:self.connectionManager];
- self.uploadsInProgress[file.name] = uploadOperation;
[self.transactionQueue addOperation:uploadOperation];
}
#pragma mark Artworks
- (void)uploadArtwork:(SDLArtwork *)artwork completionHandler:(nullable SDLFileManagerUploadArtworkCompletionHandler)completion {
+ __weak typeof(self) weakself = self;
[self uploadFile:artwork completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
if (completion == nil) { return; }
- if ([self sdl_isErrorCannotOverwriteError:error]) {
+ if ([weakself sdl_isErrorCannotOverwriteError:error]) {
// Artwork with same name already uploaded to remote
- return completion(true, artwork.name, bytesAvailable, nil);
+ return completion(YES, artwork.name, bytesAvailable, nil);
}
completion(success, artwork.name, bytesAvailable, error);
}];
@@ -440,9 +445,10 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
@throw [NSException sdl_missingFilesException];
}
+ __weak typeof(self) weakself = self;
[self uploadFiles:artworks progressHandler:^BOOL(SDLFileName * _Nonnull fileName, float uploadPercentage, NSError * _Nullable error) {
if (progressHandler == nil) { return YES; }
- if ([self sdl_isErrorCannotOverwriteError:error]) {
+ if ([weakself sdl_isErrorCannotOverwriteError:error]) {
return progressHandler(fileName, uploadPercentage, nil);
}
return progressHandler(fileName, uploadPercentage, error);
@@ -457,7 +463,7 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
if (error != nil) {
for (NSString *erroredArtworkName in error.userInfo) {
- if (![self sdl_isErrorCannotOverwriteError:[error.userInfo objectForKey:erroredArtworkName]]) {
+ if (![weakself sdl_isErrorCannotOverwriteError:error.userInfo[erroredArtworkName]]) {
[successfulArtworkUploadNames removeObject:erroredArtworkName];
} else {
// An overwrite error means that an artwork with the same name is already uploaded to the remote
@@ -523,7 +529,7 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
* @param maxUploadCount The max number of times the file is allowed to be uploaded to Core
* @return True if the file still needs to be (re)sent to Core; false if not.
*/
-- (BOOL)sdl_canFileBeUploadedAgain:(nullable SDLFile *)file maxUploadCount:(UInt8)maxUploadCount failedFileUploadsCount:(NSMutableDictionary<SDLFileName *, NSNumber<SDLUInt> *> *)failedFileUploadsCount {
+- (BOOL)sdl_canFileBeUploadedAgain:(nullable SDLFile *)file maxUploadCount:(NSUInteger)maxUploadCount failedFileUploadsCount:(NSMutableDictionary<SDLFileName *, NSNumber<SDLUInt> *> *)failedFileUploadsCount {
if (![self.currentState isEqualToString:SDLFileManagerStateReady]) {
SDLLogW(@"File named %@ failed to upload. The file manager has shutdown so the file upload will not retry.", file.name);
return NO;
@@ -540,7 +546,7 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
}
NSNumber *failedUploadCount = failedFileUploadsCount[file.name];
- BOOL canFileBeUploadedAgain = (failedUploadCount == nil) ? YES : (failedUploadCount.integerValue < maxUploadCount);
+ BOOL canFileBeUploadedAgain = (failedUploadCount == nil) ? YES : (failedUploadCount.unsignedIntegerValue < maxUploadCount);
if (!canFileBeUploadedAgain) {
SDLLogE(@"File named %@ failed to upload. Max number of upload attempts reached.", file.name);
}
diff --git a/SmartDeviceLink/SDLFocusableItemLocator.m b/SmartDeviceLink/SDLFocusableItemLocator.m
index e3fb4d451..9ab7da07a 100644
--- a/SmartDeviceLink/SDLFocusableItemLocator.m
+++ b/SmartDeviceLink/SDLFocusableItemLocator.m
@@ -148,7 +148,13 @@ NS_ASSUME_NONNULL_BEGIN
@param notification object with notification data
*/
- (void)sdl_projectionViewUpdated:(NSNotification *)notification {
- [self updateInterfaceLayout];
+ if ([NSThread isMainThread]) {
+ [self updateInterfaceLayout];
+ } else {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [self updateInterfaceLayout];
+ });
+ }
}
@end
diff --git a/SmartDeviceLink/SDLFunctionID.m b/SmartDeviceLink/SDLFunctionID.m
index e8e86991a..80cc2437d 100644
--- a/SmartDeviceLink/SDLFunctionID.m
+++ b/SmartDeviceLink/SDLFunctionID.m
@@ -88,7 +88,9 @@ NS_ASSUME_NONNULL_BEGIN
@53: SDLRPCFunctionNameGetAppServiceData,
@54: SDLRPCFunctionNameGetFile,
@55: SDLRPCFunctionNamePerformAppServiceInteraction,
+ @56: SDLRPCFunctionNameUnpublishAppService,
@58: SDLRPCFunctionNameCloseApplication,
+ @59: SDLRPCFunctionNameShowAppMenu,
@32768: SDLRPCFunctionNameOnHMIStatus,
@32769: SDLRPCFunctionNameOnAppInterfaceUnregistered,
@32770: SDLRPCFunctionNameOnButtonEvent,
diff --git a/SmartDeviceLink/SDLGlobals.h b/SmartDeviceLink/SDLGlobals.h
index 99ed61bf6..2d4edf017 100644
--- a/SmartDeviceLink/SDLGlobals.h
+++ b/SmartDeviceLink/SDLGlobals.h
@@ -11,7 +11,6 @@
#import "SDLProtocolConstants.h"
@class SDLProtocolHeader;
-@class SDLSyncMsgVersion;
@class SDLVersion;
NS_ASSUME_NONNULL_BEGIN
@@ -33,6 +32,9 @@ extern NSUInteger const SDLV3MTUSize;
@property (strong, nonatomic) SDLVersion *rpcVersion;
@property (copy, nonatomic) SDLVersion *maxHeadUnitProtocolVersion;
+@property (copy, nonatomic) dispatch_queue_t sdlProcessingQueue;
+@property (copy, nonatomic) dispatch_queue_t sdlConcurrentQueue;
+
+ (instancetype)sharedGlobals;
- (void)setDynamicMTUSize:(NSUInteger)maxMTUSize forServiceType:(SDLServiceType)serviceType;
diff --git a/SmartDeviceLink/SDLGlobals.m b/SmartDeviceLink/SDLGlobals.m
index 735139b22..dfff3ca50 100644
--- a/SmartDeviceLink/SDLGlobals.m
+++ b/SmartDeviceLink/SDLGlobals.m
@@ -10,14 +10,13 @@
#import "SDLLogMacros.h"
#import "SDLProtocolHeader.h"
-#import "SDLSyncMsgVersion.h"
#import "SDLVersion.h"
NS_ASSUME_NONNULL_BEGIN
// VERSION DEPENDENT CODE
NSString *const SDLMaxProxyProtocolVersion = @"5.2.0";
-NSString *const SDLMaxProxyRPCVersion = @"5.1.0";
+NSString *const SDLMaxProxyRPCVersion = @"6.0.0";
NSUInteger const SDLDefaultMTUSize = UINT32_MAX;
NSUInteger const SDLV1MTUSize = 1024;
@@ -59,6 +58,12 @@ typedef NSNumber *MTUBox;
_rpcVersion = [[SDLVersion alloc] initWithString:@"1.0.0"];
_dynamicMTUDict = [NSMutableDictionary dictionary];
+ dispatch_queue_attr_t qosSerial = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_USER_INITIATED, 0);
+ dispatch_queue_attr_t qosConcurrent = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_CONCURRENT, QOS_CLASS_USER_INITIATED, 0);
+
+ _sdlProcessingQueue = dispatch_queue_create("com.sdl.serialProcessing", qosSerial);
+ _sdlConcurrentQueue = dispatch_queue_create("com.sdl.concurrentProcessing", qosConcurrent);
+
return self;
}
diff --git a/SmartDeviceLink/SDLIAPTransport.m b/SmartDeviceLink/SDLIAPTransport.m
index d67b2f11e..e83e5aa3d 100644
--- a/SmartDeviceLink/SDLIAPTransport.m
+++ b/SmartDeviceLink/SDLIAPTransport.m
@@ -80,7 +80,7 @@ int const CreateSessionRetries = 3;
*/
- (void)sdl_stopEventListening {
SDLLogV(@"SDLIAPTransport stopped listening for events");
- [[EAAccessoryManager sharedAccessoryManager] unregisterForLocalNotifications];
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
}
#pragma mark EAAccessory Notifications
diff --git a/SmartDeviceLink/SDLImageFieldName.h b/SmartDeviceLink/SDLImageFieldName.h
index 34e50c3b3..cd3e101c9 100644
--- a/SmartDeviceLink/SDLImageFieldName.h
+++ b/SmartDeviceLink/SDLImageFieldName.h
@@ -12,6 +12,11 @@
typedef SDLEnum SDLImageFieldName SDL_SWIFT_ENUM;
/**
+ The image field for Alert
+ */
+extern SDLImageFieldName const SDLImageFieldNameAlertIcon;
+
+/**
The image field for SoftButton
*/
extern SDLImageFieldName const SDLImageFieldNameSoftButtonImage;
diff --git a/SmartDeviceLink/SDLImageFieldName.m b/SmartDeviceLink/SDLImageFieldName.m
index 63397b089..0282f25b6 100644
--- a/SmartDeviceLink/SDLImageFieldName.m
+++ b/SmartDeviceLink/SDLImageFieldName.m
@@ -4,6 +4,7 @@
#import "SDLImageFieldName.h"
+SDLImageFieldName const SDLImageFieldNameAlertIcon = @"alertIcon";
SDLImageFieldName const SDLImageFieldNameSoftButtonImage = @"softButtonImage";
SDLImageFieldName const SDLImageFieldNameChoiceImage = @"choiceImage";
SDLImageFieldName const SDLImageFieldNameChoiceSecondaryImage = @"choiceSecondaryImage";
diff --git a/SmartDeviceLink/SDLKeyboardDelegate.h b/SmartDeviceLink/SDLKeyboardDelegate.h
index 517832748..4af085ab4 100644
--- a/SmartDeviceLink/SDLKeyboardDelegate.h
+++ b/SmartDeviceLink/SDLKeyboardDelegate.h
@@ -17,11 +17,18 @@ NS_ASSUME_NONNULL_BEGIN
/**
This handler is called when you wish to update your autocomplete text in response to the user's input
- @param updatedAutocompleteText The new autocomplete text to use
+ @param updatedAutocompleteText The autocomplete results to use
*/
typedef void(^SDLKeyboardAutocompleteCompletionHandler)(NSString *_Nullable updatedAutocompleteText);
/**
+ This handler is called when you wish to update your autocomplete text in response to the user's input.
+
+ @param updatedAutoCompleteList The list of autocomplete results to use, a max of 100 items are allowed
+ */
+typedef void(^SDLKeyboardAutoCompleteResultsHandler)(NSArray<NSString *> *_Nullable updatedAutoCompleteList);
+
+/**
This handler is called when you wish to update your keyboard's limitedCharacterSet in response to the user's input
@param updatedCharacterSet The new set of characters to use
@@ -65,7 +72,17 @@ typedef void(^SDLKeyboardCharacterSetCompletionHandler)(NSArray<NSString *> *_Nu
@param currentInputText The user's full current input text
@param completionHandler A completion handler to update the autoCompleteText
*/
-- (void)updateAutocompleteWithInput:(NSString *)currentInputText completionHandler:(SDLKeyboardAutocompleteCompletionHandler)completionHandler;
+- (void)updateAutocompleteWithInput:(NSString *)currentInputText completionHandler:(SDLKeyboardAutocompleteCompletionHandler)completionHandler __deprecated_msg("Use updateAutocompleteWithInput:autoCompleteResultsHandler:");
+
+/**
+ Implement this if you wish to updated the KeyboardProperties.autoCompleteList as the user updates their input. This is called upon a KEYPRESS event.
+
+ This allows you to present a list of options that the user can use to fill in the search / text box with suggestions you provide.
+
+ @param currentInputText The user's full current input text
+ @param resultsHandler A completion handler to update the autoCompleteList
+ */
+- (void)updateAutocompleteWithInput:(NSString *)currentInputText autoCompleteResultsHandler:(SDLKeyboardAutoCompleteResultsHandler)resultsHandler;
/**
Implement this if you wish to update the limitedCharacterSet as the user updates their input. This is called upon a KEYPRESS event.
diff --git a/SmartDeviceLink/SDLKeyboardProperties.h b/SmartDeviceLink/SDLKeyboardProperties.h
index a4a0dbf4c..19b494eb2 100644
--- a/SmartDeviceLink/SDLKeyboardProperties.h
+++ b/SmartDeviceLink/SDLKeyboardProperties.h
@@ -14,7 +14,30 @@ NS_ASSUME_NONNULL_BEGIN
*/
@interface SDLKeyboardProperties : SDLRPCStruct
-- (instancetype)initWithLanguage:(nullable SDLLanguage)language layout:(nullable SDLKeyboardLayout)layout keypressMode:(nullable SDLKeypressMode)keypressMode limitedCharacterList:(nullable NSArray<NSString *> *)limitedCharacterList autoCompleteText:(nullable NSString *)autoCompleteText;
+/**
+ Create a Keyboard Properties RPC object
+
+ @param language The language to set the keyboard to
+ @param layout The layout of the keyboard
+ @param keypressMode The mode of keypresses to use
+ @param limitedCharacterList A list of characters restricting what the user is allowed to press
+ @param autoCompleteText A string to show the user to complete what they are typing
+ @return The RPC object
+ */
+- (instancetype)initWithLanguage:(nullable SDLLanguage)language layout:(nullable SDLKeyboardLayout)layout keypressMode:(nullable SDLKeypressMode)keypressMode limitedCharacterList:(nullable NSArray<NSString *> *)limitedCharacterList autoCompleteText:(nullable NSString *)autoCompleteText __deprecated_msg(("use initWithLanguagelayout:keypressMode:limitedCharacterList:autoCompleteText:autoCompleteList: instead"));
+
+/**
+ Create a Keyboard Properties RPC object
+
+ @param language The language to set the keyboard to
+ @param layout The layout of the keyboard
+ @param keypressMode The mode of keypresses to use
+ @param limitedCharacterList A list of characters restricting what the user is allowed to press
+ @param autoCompleteText A string to show to user to complete what they are typing
+ @param autoCompleteList A list of strings to show the user to complete what they are typing.
+ @return The RPC object
+ */
+- (instancetype)initWithLanguage:(nullable SDLLanguage)language layout:(nullable SDLKeyboardLayout)layout keypressMode:(nullable SDLKeypressMode)keypressMode limitedCharacterList:(nullable NSArray<NSString *> *)limitedCharacterList autoCompleteText:(nullable NSString *)autoCompleteText autoCompleteList:(nullable NSArray<NSString *> *)autoCompleteList;
/**
The keyboard language
@@ -53,6 +76,13 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (nullable, strong, nonatomic) NSString *autoCompleteText;
+/**
+ Allows an app to show a list of possible autocomplete suggestions as the user types
+
+ Optional, 1-100 items, max string length 1000 characters (note that these may not all be displayed on the screen)
+ */
+@property (nullable, strong, nonatomic) NSArray<NSString *> *autoCompleteList;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLKeyboardProperties.m b/SmartDeviceLink/SDLKeyboardProperties.m
index 2e90ad4c1..0adb701e2 100644
--- a/SmartDeviceLink/SDLKeyboardProperties.m
+++ b/SmartDeviceLink/SDLKeyboardProperties.m
@@ -11,6 +11,10 @@ NS_ASSUME_NONNULL_BEGIN
@implementation SDLKeyboardProperties
- (instancetype)initWithLanguage:(nullable SDLLanguage)language layout:(nullable SDLKeyboardLayout)layout keypressMode:(nullable SDLKeypressMode)keypressMode limitedCharacterList:(nullable NSArray<NSString *> *)limitedCharacterList autoCompleteText:(nullable NSString *)autoCompleteText {
+ return [self initWithLanguage:language layout:layout keypressMode:keypressMode limitedCharacterList:limitedCharacterList autoCompleteText:autoCompleteText autoCompleteList:nil];
+}
+
+- (instancetype)initWithLanguage:(nullable SDLLanguage)language layout:(nullable SDLKeyboardLayout)layout keypressMode:(nullable SDLKeypressMode)keypressMode limitedCharacterList:(nullable NSArray<NSString *> *)limitedCharacterList autoCompleteText:(nullable NSString *)autoCompleteText autoCompleteList:(nullable NSArray<NSString *> *)autoCompleteList {
self = [self init];
if (!self) {
return nil;
@@ -21,6 +25,7 @@ NS_ASSUME_NONNULL_BEGIN
self.keypressMode = keypressMode;
self.limitedCharacterList = [limitedCharacterList mutableCopy];
self.autoCompleteText = autoCompleteText;
+ self.autoCompleteList = autoCompleteList;
return self;
}
@@ -65,6 +70,14 @@ NS_ASSUME_NONNULL_BEGIN
return [self.store sdl_objectForName:SDLRPCParameterNameAutoCompleteText ofClass:NSString.class error:nil];
}
+- (void)setAutoCompleteList:(nullable NSArray<NSString *> *)autoCompleteList {
+ [self.store sdl_setObject:autoCompleteList forName:SDLRPCParameterNameAutoCompleteList];
+}
+
+- (nullable NSArray<NSString *> *)autoCompleteList {
+ return [self.store sdl_objectsForName:SDLRPCParameterNameAutoCompleteList ofClass:NSString.class error:nil];
+}
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m
index 908f5c43f..d59b1e4eb 100644
--- a/SmartDeviceLink/SDLLifecycleManager.m
+++ b/SmartDeviceLink/SDLLifecycleManager.m
@@ -127,8 +127,13 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask
_rpcOperationQueue = [[NSOperationQueue alloc] init];
_rpcOperationQueue.name = @"com.sdl.lifecycle.rpcOperation.concurrent";
- _rpcOperationQueue.maxConcurrentOperationCount = 3;
- _lifecycleQueue = dispatch_queue_create("com.sdl.lifecycle", DISPATCH_QUEUE_SERIAL);
+ _rpcOperationQueue.underlyingQueue = [SDLGlobals sharedGlobals].sdlConcurrentQueue;
+
+ if (@available(iOS 10.0, *)) {
+ _lifecycleQueue = dispatch_queue_create_with_target("com.sdl.lifecycle", DISPATCH_QUEUE_SERIAL, [SDLGlobals sharedGlobals].sdlProcessingQueue);
+ } else {
+ _lifecycleQueue = [SDLGlobals sharedGlobals].sdlProcessingQueue;
+ }
// Managers
_fileManager = [[SDLFileManager alloc] initWithConnectionManager:self configuration:_configuration.fileManagerConfig];
@@ -273,7 +278,7 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask
// Due to a race condition internally with EAStream, we cannot immediately attempt to restart the proxy, as we will randomly crash.
// Apple Bug ID #30059457
__weak typeof(self) weakSelf = self;
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), self.lifecycleQueue, ^{
__strong typeof(weakSelf) strongSelf = weakSelf;
if (!strongSelf) { return; }
@@ -282,7 +287,7 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask
if (shouldRestart) {
[strongSelf sdl_transitionToState:SDLLifecycleStateStarted];
} else {
- // End any background tasks because a session will not be established
+ // End the background task because a session will not be established
[self.backgroundTaskManager endBackgroundTask];
}
});
@@ -313,25 +318,23 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask
__weak typeof(self) weakSelf = self;
[self sdl_sendRequest:regRequest
withResponseHandler:^(__kindof SDLRPCRequest *_Nullable request, __kindof SDLRPCResponse *_Nullable response, NSError *_Nullable error) {
- dispatch_async(weakSelf.lifecycleQueue, ^{
- // If the success BOOL is NO or we received an error at this point, we failed. Call the ready handler and transition to the DISCONNECTED state.
- if (error != nil || ![response.success boolValue]) {
- SDLLogE(@"Failed to register the app. Error: %@, Response: %@", error, response);
- if (weakSelf.readyHandler) {
- weakSelf.readyHandler(NO, error);
- }
-
- if (weakSelf.lifecycleState != SDLLifecycleStateReconnecting) {
- [weakSelf sdl_transitionToState:SDLLifecycleStateStopped];
- }
-
- return;
+ // If the success BOOL is NO or we received an error at this point, we failed. Call the ready handler and transition to the DISCONNECTED state.
+ if (error != nil || ![response.success boolValue]) {
+ SDLLogE(@"Failed to register the app. Error: %@, Response: %@", error, response);
+ if (weakSelf.readyHandler) {
+ weakSelf.readyHandler(NO, error);
}
- weakSelf.registerResponse = (SDLRegisterAppInterfaceResponse *)response;
- [SDLGlobals sharedGlobals].rpcVersion = [SDLVersion versionWithSyncMsgVersion:weakSelf.registerResponse.syncMsgVersion];
- [weakSelf sdl_transitionToState:SDLLifecycleStateRegistered];
- });
+ if (weakSelf.lifecycleState != SDLLifecycleStateReconnecting) {
+ [weakSelf sdl_transitionToState:SDLLifecycleStateStopped];
+ }
+
+ return;
+ }
+
+ weakSelf.registerResponse = (SDLRegisterAppInterfaceResponse *)response;
+ [SDLGlobals sharedGlobals].rpcVersion = [SDLVersion versionWithSDLMsgVersion:weakSelf.registerResponse.sdlMsgVersion];
+ [weakSelf sdl_transitionToState:SDLLifecycleStateRegistered];
}];
}
@@ -483,21 +486,20 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask
}
// If we got to this point, we succeeded, send the error if there was a warning.
- dispatch_async(dispatch_get_main_queue(), ^{
- self.readyHandler(YES, startError);
- });
+ self.readyHandler(YES, startError);
[self.notificationDispatcher postNotificationName:SDLDidBecomeReady infoObject:nil];
// Send the hmi level going from NONE to whatever we're at now (could still be NONE)
- dispatch_async(dispatch_get_main_queue(), ^{
- [self.delegate hmiLevel:SDLHMILevelNone didChangeToLevel:self.hmiLevel];
+ [self.delegate hmiLevel:SDLHMILevelNone didChangeToLevel:self.hmiLevel];
- // Send the audio streaming state going from NOT_AUDIBLE to whatever we're at now (could still be NOT_AUDIBLE)
- if ([self.delegate respondsToSelector:@selector(audioStreamingState:didChangeToState:)]) {
- [self.delegate audioStreamingState:SDLAudioStreamingStateNotAudible didChangeToState:self.audioStreamingState];
- }
- });
+ // Send the audio streaming state going from NOT_AUDIBLE to whatever we're at now (could still be NOT_AUDIBLE)
+ if ([self.delegate respondsToSelector:@selector(audioStreamingState:didChangeToState:)]) {
+ [self.delegate audioStreamingState:SDLAudioStreamingStateNotAudible didChangeToState:self.audioStreamingState];
+ }
+
+ // Stop the background task now that setup has completed
+ [self.backgroundTaskManager endBackgroundTask];
}
- (void)didEnterStateUnregistering {
@@ -604,33 +606,25 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask
return;
}
- dispatch_async(_lifecycleQueue, ^{
- [self sdl_sendRequest:rpc withResponseHandler:nil];
- });
+ [self sdl_sendRequest:rpc withResponseHandler:nil];
}
- (void)sendConnectionRequest:(__kindof SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler {
if (![self.lifecycleStateMachine isCurrentState:SDLLifecycleStateReady]) {
SDLLogW(@"Manager not ready, request not sent (%@)", request);
if (handler) {
- dispatch_async(dispatch_get_main_queue(), ^{
- handler(request, nil, [NSError sdl_lifecycle_notReadyError]);
- });
+ handler(request, nil, [NSError sdl_lifecycle_notReadyError]);
}
return;
}
- dispatch_async(_lifecycleQueue, ^{
- [self sdl_sendRequest:request withResponseHandler:handler];
- });
+ [self sdl_sendRequest:request withResponseHandler:handler];
}
// Managers need to avoid state checking. Part of <SDLConnectionManagerType>.
- (void)sendConnectionManagerRequest:(__kindof SDLRPCMessage *)request withResponseHandler:(nullable SDLResponseHandler)handler {
- dispatch_async(_lifecycleQueue, ^{
- [self sdl_sendRequest:request withResponseHandler:handler];
- });
+ [self sdl_sendRequest:request withResponseHandler:handler];
}
- (void)sdl_sendRequest:(__kindof SDLRPCMessage *)request withResponseHandler:(nullable SDLResponseHandler)handler {
@@ -642,9 +636,7 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask
NSError *error = [NSError sdl_lifecycle_rpcErrorWithDescription:@"Nil Request Sent" andReason:@"A nil RPC request was passed and cannot be sent."];
SDLLogW(@"%@", error);
if (handler) {
- dispatch_async(dispatch_get_main_queue(), ^{
- handler(nil, nil, error);
- });
+ handler(nil, nil, error);
}
return;
}
@@ -683,8 +675,18 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask
}
// this is to make sure that the transition happens on the dedicated queue
+- (void)sdl_runOnProcessingQueue:(void (^)(void))block {
+ if (strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label(self.lifecycleQueue)) == 0
+ || strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label([SDLGlobals sharedGlobals].sdlProcessingQueue)) == 0) {
+ block();
+ } else {
+ dispatch_sync(self.lifecycleQueue, block);
+ }
+}
+
- (void)sdl_transitionToState:(SDLState *)state {
- if (strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label(self.lifecycleQueue)) == 0) {
+ if (strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label(self.lifecycleQueue)) == 0
+ || strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label([SDLGlobals sharedGlobals].sdlProcessingQueue)) == 0) {
[self.lifecycleStateMachine transitionToState:state];
} else {
// once this method returns, the transition is completed
@@ -708,9 +710,6 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask
- (void)transportDidConnect {
SDLLogD(@"Transport connected");
- // End any background tasks since the transport connected successfully
- [self.backgroundTaskManager endBackgroundTask];
-
dispatch_async(self.lifecycleQueue, ^{
[self sdl_transitionToState:SDLLifecycleStateConnected];
});
@@ -769,24 +768,22 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask
return;
}
- dispatch_async(dispatch_get_main_queue(), ^{
- if (![oldHMILevel isEqualToEnum:self.hmiLevel]
- && !(oldHMILevel == nil && self.hmiLevel == nil)) {
- [self.delegate hmiLevel:oldHMILevel didChangeToLevel:self.hmiLevel];
- }
+ if (![oldHMILevel isEqualToEnum:self.hmiLevel]
+ && !(oldHMILevel == nil && self.hmiLevel == nil)) {
+ [self.delegate hmiLevel:oldHMILevel didChangeToLevel:self.hmiLevel];
+ }
- if (![oldStreamingState isEqualToEnum:self.audioStreamingState]
- && !(oldStreamingState == nil && self.audioStreamingState == nil)
- && [self.delegate respondsToSelector:@selector(audioStreamingState:didChangeToState:)]) {
- [self.delegate audioStreamingState:oldStreamingState didChangeToState:self.audioStreamingState];
- }
+ if (![oldStreamingState isEqualToEnum:self.audioStreamingState]
+ && !(oldStreamingState == nil && self.audioStreamingState == nil)
+ && [self.delegate respondsToSelector:@selector(audioStreamingState:didChangeToState:)]) {
+ [self.delegate audioStreamingState:oldStreamingState didChangeToState:self.audioStreamingState];
+ }
- if (![oldSystemContext isEqualToEnum:self.systemContext]
- && !(oldSystemContext == nil && self.systemContext == nil)
- && [self.delegate respondsToSelector:@selector(systemContext:didChangeToContext:)]) {
- [self.delegate systemContext:oldSystemContext didChangeToContext:self.systemContext];
- }
- });
+ if (![oldSystemContext isEqualToEnum:self.systemContext]
+ && !(oldSystemContext == nil && self.systemContext == nil)
+ && [self.delegate respondsToSelector:@selector(systemContext:didChangeToContext:)]) {
+ [self.delegate systemContext:oldSystemContext didChangeToContext:self.systemContext];
+ }
}
- (void)remoteHardwareDidUnregister:(SDLRPCNotificationNotification *)notification {
diff --git a/SmartDeviceLink/SDLListFilesOperation.h b/SmartDeviceLink/SDLListFilesOperation.h
index 9107ef758..fc8453820 100644
--- a/SmartDeviceLink/SDLListFilesOperation.h
+++ b/SmartDeviceLink/SDLListFilesOperation.h
@@ -28,6 +28,16 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (instancetype)initWithConnectionManager:(id<SDLConnectionManagerType>)connectionManager completionHandler:(nullable SDLFileManagerListFilesCompletionHandler)completionHandler;
+/**
+ The connection manager which will handle transporting the request to the remote system.
+ */
+@property (weak, nonatomic, readonly) id<SDLConnectionManagerType> connectionManager;
+
+/**
+ A completion handler for when the response returns.
+ */
+@property (copy, nonatomic, nullable, readonly) SDLFileManagerListFilesCompletionHandler completionHandler;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLListFilesOperation.m b/SmartDeviceLink/SDLListFilesOperation.m
index ca45ac928..5e6ace166 100644
--- a/SmartDeviceLink/SDLListFilesOperation.m
+++ b/SmartDeviceLink/SDLListFilesOperation.m
@@ -17,6 +17,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface SDLListFilesOperation ()
+@property (strong, nonatomic) NSUUID *operationId;
@property (weak, nonatomic) id<SDLConnectionManagerType> connectionManager;
@property (copy, nonatomic, nullable) SDLFileManagerListFilesCompletionHandler completionHandler;
@@ -31,6 +32,7 @@ NS_ASSUME_NONNULL_BEGIN
return nil;
}
+ _operationId = [NSUUID UUID];
_connectionManager = connectionManager;
_completionHandler = completionHandler;
@@ -67,7 +69,7 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark Property Overrides
- (nullable NSString *)name {
- return @"List Files";
+ return [NSString stringWithFormat:@"%@ - %@", self.class, self.operationId];
}
- (NSOperationQueuePriority)queuePriority {
diff --git a/SmartDeviceLink/SDLLockScreenConfiguration.h b/SmartDeviceLink/SDLLockScreenConfiguration.h
index 80575567a..ba0bd2d5a 100644
--- a/SmartDeviceLink/SDLLockScreenConfiguration.h
+++ b/SmartDeviceLink/SDLLockScreenConfiguration.h
@@ -14,9 +14,9 @@ NS_ASSUME_NONNULL_BEGIN
@interface SDLLockScreenConfiguration : NSObject <NSCopying>
/**
- * Whether or not the lock screen should be shown in the "lock screen optional" state. Defaults to false.
+ * Whether or not the lock screen should be shown in the "lock screen optional" state. Defaults to NO.
*
- * @discussion In order for the "lock screen optional" state to occur, the following must be true:
+ * In order for the "lock screen optional" state to occur, the following must be true:
* 1. The app should have received at least 1 driver distraction notification (i.e. a `OnDriverDistraction` notification) from SDL Core. Older versions of Core did not send a notification immediately on connection.
* 2. The driver is not distracted (i.e. the last `OnDriverDistraction` notification received was for a driver distraction state off).
* 3. The `hmiLevel` can not be `NONE`.
@@ -25,7 +25,18 @@ NS_ASSUME_NONNULL_BEGIN
@property (assign, nonatomic) BOOL showInOptionalState;
/**
- * If YES, the lock screen should be managed by SDL and automatically engage when necessary. If NO, then the lock screen will never be engaged.
+ If YES, then the lock screen can be dismissed with a downward swipe on compatible head units. Requires a connection of SDL 6.0+ and the head unit to enable the feature. Defaults to YES.
+ */
+@property (assign, nonatomic) BOOL enableDismissGesture;
+
+/**
+* If YES, then the lockscreen will show the vehicle's logo if the vehicle has made it available. If NO, then the lockscreen will not show the vehicle logo.
+ Defaults to YES.
+*/
+@property (assign, nonatomic) BOOL showDeviceLogo;
+
+/**
+ * If YES, the lock screen should be managed by SDL and automatically engage when necessary. If NO, then the lock screen will never be engaged. Defaults to YES.
*/
@property (assign, nonatomic, readonly) BOOL enableAutomaticLockScreen;
diff --git a/SmartDeviceLink/SDLLockScreenConfiguration.m b/SmartDeviceLink/SDLLockScreenConfiguration.m
index 4f82c287a..f2cf71f9f 100644
--- a/SmartDeviceLink/SDLLockScreenConfiguration.m
+++ b/SmartDeviceLink/SDLLockScreenConfiguration.m
@@ -20,7 +20,7 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Lifecycle
-- (instancetype)initWithAutoLockScreen:(BOOL)enableAutomatic enableInOptional:(BOOL)enableOptional backgroundColor:(UIColor *)backgroundColor appIcon:(nullable UIImage *)appIcon viewController:(nullable UIViewController *)customViewController {
+- (instancetype)initWithAutoLockScreen:(BOOL)enableAutomatic enableInOptional:(BOOL)enableOptional enableDismissGesture:(BOOL)enableDismissGesture showDeviceLogo:(BOOL)showDeviceLogo backgroundColor:(UIColor *)backgroundColor appIcon:(nullable UIImage *)appIcon viewController:(nullable UIViewController *)customViewController {
self = [super init];
if (!self) {
return nil;
@@ -28,19 +28,21 @@ NS_ASSUME_NONNULL_BEGIN
_enableAutomaticLockScreen = enableAutomatic;
_showInOptionalState = enableOptional;
+ _enableDismissGesture = enableDismissGesture;
_backgroundColor = backgroundColor;
_appIcon = appIcon;
_customViewController = customViewController;
+ _showDeviceLogo = showDeviceLogo;
return self;
}
+ (instancetype)disabledConfiguration {
- return [[self alloc] initWithAutoLockScreen:NO enableInOptional:NO backgroundColor:[self sdl_defaultBackgroundColor] appIcon:nil viewController:nil];
+ return [[self alloc] initWithAutoLockScreen:NO enableInOptional:NO enableDismissGesture:NO showDeviceLogo:NO backgroundColor:[self sdl_defaultBackgroundColor] appIcon:nil viewController:nil];
}
+ (instancetype)enabledConfiguration {
- return [[self alloc] initWithAutoLockScreen:YES enableInOptional:NO backgroundColor:[self sdl_defaultBackgroundColor] appIcon:nil viewController:nil];
+ return [[self alloc] initWithAutoLockScreen:YES enableInOptional:NO enableDismissGesture:YES showDeviceLogo:YES backgroundColor:[self sdl_defaultBackgroundColor] appIcon:nil viewController:nil];
}
+ (instancetype)enabledConfigurationWithAppIcon:(UIImage *)lockScreenAppIcon backgroundColor:(nullable UIColor *)lockScreenBackgroundColor {
@@ -48,11 +50,11 @@ NS_ASSUME_NONNULL_BEGIN
lockScreenBackgroundColor = [self.class sdl_defaultBackgroundColor];
}
- return [[self alloc] initWithAutoLockScreen:YES enableInOptional:NO backgroundColor:lockScreenBackgroundColor appIcon:lockScreenAppIcon viewController:nil];
+ return [[self alloc] initWithAutoLockScreen:YES enableInOptional:NO enableDismissGesture:YES showDeviceLogo:YES backgroundColor:lockScreenBackgroundColor appIcon:lockScreenAppIcon viewController:nil];
}
+ (instancetype)enabledConfigurationWithViewController:(UIViewController *)viewController {
- return [[self alloc] initWithAutoLockScreen:YES enableInOptional:NO backgroundColor:[self.class sdl_defaultBackgroundColor] appIcon:nil viewController:viewController];
+ return [[self alloc] initWithAutoLockScreen:YES enableInOptional:NO enableDismissGesture:YES showDeviceLogo:YES backgroundColor:[self.class sdl_defaultBackgroundColor] appIcon:nil viewController:viewController];
}
@@ -66,11 +68,7 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - NSCopying
- (id)copyWithZone:(nullable NSZone *)zone {
- SDLLockScreenConfiguration *new = [[SDLLockScreenConfiguration allocWithZone:zone] initWithAutoLockScreen : _enableAutomaticLockScreen
- enableInOptional : _showInOptionalState
- backgroundColor : _backgroundColor
- appIcon : _appIcon
- viewController : _customViewController];
+ SDLLockScreenConfiguration *new = [[SDLLockScreenConfiguration allocWithZone:zone] initWithAutoLockScreen:_enableAutomaticLockScreen enableInOptional:_showInOptionalState enableDismissGesture:_enableDismissGesture showDeviceLogo:_showDeviceLogo backgroundColor:_backgroundColor appIcon:_appIcon viewController:_customViewController];
return new;
}
diff --git a/SmartDeviceLink/SDLLockScreenManager.h b/SmartDeviceLink/SDLLockScreenManager.h
index f709c53ee..a63e42234 100644
--- a/SmartDeviceLink/SDLLockScreenManager.h
+++ b/SmartDeviceLink/SDLLockScreenManager.h
@@ -23,6 +23,11 @@ NS_ASSUME_NONNULL_BEGIN
@property (assign, nonatomic, readonly) BOOL lockScreenPresented;
/**
+ * Whether or not the lock screen is currently dismissable
+ */
+@property (assign, nonatomic, readonly, getter=isLockScreenDismissable) BOOL lockScreenDismissable;
+
+/**
* The lock screen configuration used to set up the manager
*/
@property (strong, nonatomic, readonly) SDLLockScreenConfiguration *config;
diff --git a/SmartDeviceLink/SDLLockScreenManager.m b/SmartDeviceLink/SDLLockScreenManager.m
index a8c8c3758..3cea501b6 100644
--- a/SmartDeviceLink/SDLLockScreenManager.m
+++ b/SmartDeviceLink/SDLLockScreenManager.m
@@ -15,6 +15,7 @@
#import "SDLLockScreenViewController.h"
#import "SDLNotificationConstants.h"
#import "SDLOnLockScreenStatus.h"
+#import "SDLOnDriverDistraction.h"
#import "SDLRPCNotificationNotification.h"
#import "SDLScreenshotViewController.h"
#import "SDLViewControllerPresentable.h"
@@ -27,7 +28,15 @@ NS_ASSUME_NONNULL_BEGIN
@property (assign, nonatomic) BOOL canPresent;
@property (strong, nonatomic, readwrite) SDLLockScreenConfiguration *config;
@property (strong, nonatomic) id<SDLViewControllerPresentable> presenter;
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
@property (strong, nonatomic, nullable) SDLOnLockScreenStatus *lastLockNotification;
+#pragma clang diagnostic pop
+
+@property (strong, nonatomic, nullable) SDLOnDriverDistraction *lastDriverDistractionNotification;
+@property (assign, nonatomic, readwrite, getter=isLockScreenDismissable) BOOL lockScreenDismissable;
+@property (assign, nonatomic) BOOL lockScreenDismissedByUser;
@end
@@ -41,12 +50,15 @@ NS_ASSUME_NONNULL_BEGIN
}
_canPresent = NO;
+ _lockScreenDismissable = NO;
_config = config;
_presenter = presenter;
-
+ _lockScreenDismissedByUser = NO;
+
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_lockScreenStatusDidChange:) name:SDLDidChangeLockScreenStatusNotification object:dispatcher];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_lockScreenIconReceived:) name:SDLDidReceiveLockScreenIcon object:dispatcher];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_appDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_driverDistractionStateDidChange:) name:SDLDidChangeDriverDistractionStateNotification object:dispatcher];
return self;
}
@@ -91,11 +103,13 @@ NS_ASSUME_NONNULL_BEGIN
return self.presenter.lockViewController;
}
-
#pragma mark - Notification Selectors
- (void)sdl_lockScreenStatusDidChange:(SDLRPCNotificationNotification *)notification {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
if (![notification isNotificationMemberOfClass:[SDLOnLockScreenStatus class]]) {
+#pragma clang diagnostic pop
return;
}
@@ -112,7 +126,7 @@ NS_ASSUME_NONNULL_BEGIN
UIImage *icon = notification.userInfo[SDLNotificationUserInfoObject];
// If the VC is our special type, then add the vehicle icon. If they passed in a custom VC, there's no current way to show the vehicle icon. If they're managing it themselves, they can grab the notification themselves.
- if ([self.lockScreenViewController isKindOfClass:[SDLLockScreenViewController class]]) {
+ if ([self.lockScreenViewController isKindOfClass:[SDLLockScreenViewController class]] && self.config.showDeviceLogo) {
((SDLLockScreenViewController *)self.lockScreenViewController).vehicleIcon = icon;
}
}
@@ -121,6 +135,14 @@ NS_ASSUME_NONNULL_BEGIN
[self sdl_checkLockScreen];
}
+- (void)sdl_driverDistractionStateDidChange:(SDLRPCNotificationNotification *)notification {
+ if (![notification isNotificationMemberOfClass:[SDLOnDriverDistraction class]]) {
+ return;
+ }
+
+ self.lastDriverDistractionNotification = notification.notification;
+ [self sdl_updateLockScreenDismissable];
+}
#pragma mark - Private Helpers
@@ -131,11 +153,11 @@ NS_ASSUME_NONNULL_BEGIN
// Present the VC depending on the lock screen status
if ([self.lastLockNotification.lockScreenStatus isEqualToEnum:SDLLockScreenStatusRequired]) {
- if (!self.presenter.presented && self.canPresent) {
+ if (!self.presenter.presented && self.canPresent && !self.lockScreenDismissedByUser) {
[self.presenter present];
}
} else if ([self.lastLockNotification.lockScreenStatus isEqualToEnum:SDLLockScreenStatusOptional]) {
- if (self.config.showInOptionalState && !self.presenter.presented && self.canPresent) {
+ if (self.config.showInOptionalState && !self.presenter.presented && self.canPresent && !self.lockScreenDismissedByUser) {
[self.presenter present];
} else if (!self.config.showInOptionalState && self.presenter.presented) {
[self.presenter dismiss];
@@ -147,6 +169,49 @@ NS_ASSUME_NONNULL_BEGIN
}
}
+- (void)sdl_updateLockScreenDismissable {
+ if (self.lastDriverDistractionNotification == nil ||
+ self.lastDriverDistractionNotification.lockScreenDismissalEnabled == nil ||
+ !self.lastDriverDistractionNotification.lockScreenDismissalEnabled.boolValue ||
+ !self.config.enableDismissGesture) {
+ self.lockScreenDismissable = NO;
+ } else {
+ self.lockScreenDismissable = YES;
+ }
+
+ if (self.lockScreenDismissedByUser &&
+ [self.lastDriverDistractionNotification.state isEqualToEnum:SDLDriverDistractionStateOn] &&
+ !self.lockScreenDismissable) {
+ self.lockScreenDismissedByUser = NO;
+ }
+
+ if (!self.lockScreenDismissedByUser) {
+ [self sdl_updateLockscreenViewControllerWithDismissableState:self.lockScreenDismissable];
+ }
+}
+
+- (void)sdl_updateLockscreenViewControllerWithDismissableState:(BOOL)enabled {
+ if (![self.lockScreenViewController isKindOfClass:[SDLLockScreenViewController class]]) {
+ return;
+ }
+
+ __weak typeof(self) weakself = self;
+ dispatch_async(dispatch_get_main_queue(), ^{
+ __strong typeof(self) strongSelf = weakself;
+ SDLLockScreenViewController *lockscreenViewController = (SDLLockScreenViewController *)strongSelf.lockScreenViewController;
+ if (enabled) {
+ [lockscreenViewController addDismissGestureWithCallback:^{
+ [strongSelf.presenter dismiss];
+ strongSelf.lockScreenDismissedByUser = YES;
+ }];
+ lockscreenViewController.lockedLabelText = strongSelf.lastDriverDistractionNotification.lockScreenDismissalWarning;
+ } else {
+ [lockscreenViewController removeDismissGesture];
+ lockscreenViewController.lockedLabelText = nil;
+ }
+ });
+}
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLLockScreenStatus.h b/SmartDeviceLink/SDLLockScreenStatus.h
index 9926852c9..62f48ba05 100644
--- a/SmartDeviceLink/SDLLockScreenStatus.h
+++ b/SmartDeviceLink/SDLLockScreenStatus.h
@@ -24,6 +24,6 @@ extern SDLLockScreenStatus const SDLLockScreenStatusOff;
extern SDLLockScreenStatus const SDLLockScreenStatusOptional;
/**
- * LockScreen is Not Required
+ * LockScreen is Required
*/
extern SDLLockScreenStatus const SDLLockScreenStatusRequired;
diff --git a/SmartDeviceLink/SDLLockScreenStatusManager.h b/SmartDeviceLink/SDLLockScreenStatusManager.h
index 2a37b9d83..90b3d85a3 100644
--- a/SmartDeviceLink/SDLLockScreenStatusManager.h
+++ b/SmartDeviceLink/SDLLockScreenStatusManager.h
@@ -18,7 +18,10 @@ NS_ASSUME_NONNULL_BEGIN
@property (assign, nonatomic) BOOL driverDistracted;
@property (nullable, strong, nonatomic) SDLHMILevel hmiLevel;
@property (strong, nonatomic, readonly) SDLLockScreenStatus lockScreenStatus;
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
@property (strong, nonatomic, readonly) SDLOnLockScreenStatus *lockScreenStatusNotification;
+#pragma clang diagnostic pop
@end
diff --git a/SmartDeviceLink/SDLLockScreenStatusManager.m b/SmartDeviceLink/SDLLockScreenStatusManager.m
index 82724eb6f..4ab22faa4 100644
--- a/SmartDeviceLink/SDLLockScreenStatusManager.m
+++ b/SmartDeviceLink/SDLLockScreenStatusManager.m
@@ -55,8 +55,11 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark Custom Getters
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- (SDLOnLockScreenStatus *)lockScreenStatusNotification {
SDLOnLockScreenStatus *notification = [[SDLOnLockScreenStatus alloc] init];
+#pragma clang diagnostic pop
notification.driverDistractionStatus = @(self.driverDistracted);
notification.hmiLevel = self.hmiLevel;
notification.userSelected = @(self.userSelected);
diff --git a/SmartDeviceLink/SDLLockScreenViewController.h b/SmartDeviceLink/SDLLockScreenViewController.h
index d340db61a..2b19537b5 100644
--- a/SmartDeviceLink/SDLLockScreenViewController.h
+++ b/SmartDeviceLink/SDLLockScreenViewController.h
@@ -12,6 +12,8 @@ NS_ASSUME_NONNULL_BEGIN
@interface SDLLockScreenViewController : UIViewController
+typedef void (^SwipeGestureCallbackBlock)(void);
+
/**
* The app's icon. This will be set by the lock screen configuration.
*/
@@ -27,6 +29,21 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (copy, nonatomic, nullable) UIColor *backgroundColor;
+/**
+ * The locked label string. This will be set by the lock screen manager to inform the user about the dismissable state.
+ */
+@property (copy, nonatomic, nullable) NSString *lockedLabelText;
+
+/**
+ * Adds a swipe gesture to the lock screen view controller.
+ */
+- (void)addDismissGestureWithCallback:(SwipeGestureCallbackBlock)swipeGestureCallback;
+
+/**
+ * Remove swipe gesture to the lock screen view controller.
+ */
+- (void)removeDismissGesture;
+
@end
-NS_ASSUME_NONNULL_END \ No newline at end of file
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLLockScreenViewController.m b/SmartDeviceLink/SDLLockScreenViewController.m
index 291913aaa..9c5a14c99 100644
--- a/SmartDeviceLink/SDLLockScreenViewController.m
+++ b/SmartDeviceLink/SDLLockScreenViewController.m
@@ -23,6 +23,8 @@ NS_ASSUME_NONNULL_BEGIN
@property (weak, nonatomic) IBOutlet UILabel *lockedLabel;
@property (weak, nonatomic) IBOutlet UIImageView *arrowUpImageView;
@property (weak, nonatomic) IBOutlet UIImageView *arrowDownImageView;
+@property (strong, nonatomic) SwipeGestureCallbackBlock dismissGestureCallback;
+@property (strong, nonatomic, nullable) UISwipeGestureRecognizer *swipeGesture;
@end
@@ -49,7 +51,6 @@ NS_ASSUME_NONNULL_BEGIN
return useWhiteIcon ? UIStatusBarStyleLightContent : UIStatusBarStyleDefault;
}
-
#pragma mark - Setters
- (void)setAppIcon:(UIImage *_Nullable)appIcon {
@@ -70,6 +71,31 @@ NS_ASSUME_NONNULL_BEGIN
[self sdl_layoutViews];
}
+- (void)setLockedLabelText:(NSString *_Nullable)lockedLabelText {
+ _lockedLabelText = lockedLabelText;
+
+ [self sdl_layoutViews];
+}
+
+#pragma mark - Swipe Gesture
+
+- (void)addDismissGestureWithCallback:(SwipeGestureCallbackBlock)swipeGestureCallback {
+ if (!self.swipeGesture) {
+ self.dismissGestureCallback = swipeGestureCallback;
+ self.swipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(sdl_didSwipeToDismiss:)];
+ [self.swipeGesture setDirection: UISwipeGestureRecognizerDirectionDown];
+ [self.view addGestureRecognizer:self.swipeGesture];
+ }
+}
+
+- (void)removeDismissGesture {
+ [self.view removeGestureRecognizer:self.swipeGesture];
+ self.swipeGesture = nil;
+}
+
+- (void)sdl_didSwipeToDismiss:(UISwipeGestureRecognizer *)gesture {
+ self.dismissGestureCallback();
+}
#pragma mark - Layout
@@ -87,7 +113,14 @@ NS_ASSUME_NONNULL_BEGIN
self.arrowDownImageView.tintColor = iconColor;
self.lockedLabel.textColor = iconColor;
-
+ self.lockedLabel.numberOfLines = 0;
+
+ if (self.lockedLabelText != nil) {
+ self.lockedLabel.text = self.lockedLabelText;
+ } else {
+ self.lockedLabel.text = NSLocalizedString(@"Locked for your safety", nil);
+ }
+
self.view.backgroundColor = self.backgroundColor;
if (self.vehicleIcon != nil && self.appIcon != nil) {
diff --git a/SmartDeviceLink/SDLLogFileModuleMap.m b/SmartDeviceLink/SDLLogFileModuleMap.m
index 11e7466e7..e9e2a56ba 100644
--- a/SmartDeviceLink/SDLLogFileModuleMap.m
+++ b/SmartDeviceLink/SDLLogFileModuleMap.m
@@ -60,7 +60,7 @@
}
+ (SDLLogFileModule *)sdl_lifecycleManagerModule {
- return [SDLLogFileModule moduleWithName:@"Lifecycle" files:[NSSet setWithArray:@[@"SDLLifecycleManager", @"SDLManager"]]];
+ return [SDLLogFileModule moduleWithName:@"Lifecycle" files:[NSSet setWithArray:@[@"SDLLifecycleManager", @"SDLManager", @"SDLAsynchronousOperation"]]];
}
+ (SDLLogFileModule *)sdl_systemCapabilityModule {
diff --git a/SmartDeviceLink/SDLLogManager.m b/SmartDeviceLink/SDLLogManager.m
index 22918ed9c..ae0fa317f 100644
--- a/SmartDeviceLink/SDLLogManager.m
+++ b/SmartDeviceLink/SDLLogManager.m
@@ -8,6 +8,7 @@
#import "SDLLogManager.h"
+#import "SDLGlobals.h"
#import "SDLHexUtility.h"
#import "SDLLogConfiguration.h"
#import "SDLLogFileModule.h"
@@ -189,9 +190,7 @@ static dispatch_queue_t _logQueue = NULL;
}
- (void)sdl_syncLog:(SDLLogModel *)log {
- dispatch_sync(self.class.logQueue, ^{
- [self sdl_log:log];
- });
+ [self sdl_log:log];
}
- (void)sdl_log:(SDLLogModel *)log {
@@ -341,7 +340,11 @@ static dispatch_queue_t _logQueue = NULL;
+ (dispatch_queue_t)logQueue {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
- _logQueue = dispatch_queue_create("com.sdl.log", DISPATCH_QUEUE_SERIAL);
+ if (@available(iOS 10.0, *)) {
+ _logQueue = dispatch_queue_create_with_target("com.sdl.log", DISPATCH_QUEUE_SERIAL, [SDLGlobals sharedGlobals].sdlProcessingQueue);
+ } else {
+ _logQueue = [SDLGlobals sharedGlobals].sdlProcessingQueue;
+ }
});
return _logQueue;
diff --git a/SmartDeviceLink/SDLMediaServiceData.h b/SmartDeviceLink/SDLMediaServiceData.h
index ba61d05a3..7d4d6180b 100644
--- a/SmartDeviceLink/SDLMediaServiceData.h
+++ b/SmartDeviceLink/SDLMediaServiceData.h
@@ -7,9 +7,10 @@
//
#import "SDLRPCRequest.h"
-
#import "SDLMediaType.h"
+@class SDLImage;
+
NS_ASSUME_NONNULL_BEGIN
@@ -35,7 +36,37 @@ NS_ASSUME_NONNULL_BEGIN
* @param queueTotalTrackCount The total number of tracks in the playback queue
* @return A SDLMediaServiceData object
*/
-- (instancetype)initWithMediaType:(nullable SDLMediaType)mediaType mediaTitle:(nullable NSString *)mediaTitle mediaArtist:(nullable NSString *)mediaArtist mediaAlbum:(nullable NSString *)mediaAlbum playlistName:(nullable NSString *)playlistName isExplicit:(BOOL)isExplicit trackPlaybackProgress:(UInt32)trackPlaybackProgress trackPlaybackDuration:(UInt32)trackPlaybackDuration queuePlaybackProgress:(UInt32)queuePlaybackProgress queuePlaybackDuration:(UInt32)queuePlaybackDuration queueCurrentTrackNumber:(UInt32)queueCurrentTrackNumber queueTotalTrackCount:(UInt32)queueTotalTrackCount;
+- (instancetype)initWithMediaType:(nullable SDLMediaType)mediaType mediaTitle:(nullable NSString *)mediaTitle mediaArtist:(nullable NSString *)mediaArtist mediaAlbum:(nullable NSString *)mediaAlbum playlistName:(nullable NSString *)playlistName isExplicit:(BOOL)isExplicit trackPlaybackProgress:(UInt32)trackPlaybackProgress trackPlaybackDuration:(UInt32)trackPlaybackDuration queuePlaybackProgress:(UInt32)queuePlaybackProgress queuePlaybackDuration:(UInt32)queuePlaybackDuration queueCurrentTrackNumber:(UInt32)queueCurrentTrackNumber queueTotalTrackCount:(UInt32)queueTotalTrackCount __deprecated_msg("Use initWithMediaType:mediaImage:mediaTitle:mediaArtist:mediaAlbum:playlistName:isExplicit:trackPlaybackProgress:trackPlaybackDuration:queuePlaybackProgress:queuePlaybackDuration:queueCurrentTrackNumber:queueTotalTrackCount: instead");
+
+/**
+ * Convenience init
+ *
+ * @param mediaType The type of the currently playing or paused track
+ * @param mediaImage The current artwork for the playing media.
+ * @param mediaTitle The name of the current playing media
+ * @param mediaArtist The name of the current media artist
+ * @param mediaAlbum The name of the current media album
+ * @param playlistName The name of the playlist
+ * @param isExplicit Whether or not the content currently playing contains explicit content
+ * @param trackPlaybackProgress The current progress of the track
+ * @param trackPlaybackDuration The total duration of the track
+ * @param queuePlaybackProgress The current progress of the playback queue in seconds
+ * @param queuePlaybackDuration The total duration of the playback queue in seconds
+ * @param queueCurrentTrackNumber The current number (1 based) of the track in the playback queue
+ * @param queueTotalTrackCount The total number of tracks in the playback queue
+ * @return A SDLMediaServiceData object
+ */
+- (instancetype)initWithMediaType:(nullable SDLMediaType)mediaType mediaImage:(nullable SDLImage *)mediaImage mediaTitle:(nullable NSString *)mediaTitle mediaArtist:(nullable NSString *)mediaArtist mediaAlbum:(nullable NSString *)mediaAlbum playlistName:(nullable NSString *)playlistName isExplicit:(BOOL)isExplicit trackPlaybackProgress:(UInt32)trackPlaybackProgress trackPlaybackDuration:(UInt32)trackPlaybackDuration queuePlaybackProgress:(UInt32)queuePlaybackProgress queuePlaybackDuration:(UInt32)queuePlaybackDuration queueCurrentTrackNumber:(UInt32)queueCurrentTrackNumber queueTotalTrackCount:(UInt32)queueTotalTrackCount;
+
+/**
+ * Sets the media image associated with the currently playing media
+ * Music: The album art of the current track
+ * Podcast: The podcast or chapter artwork of the current podcast episode
+ * Audiobook: The book or chapter artwork of the current audiobook
+ *
+ * SDLImage, Optional
+ */
+@property (nullable, strong, nonatomic) SDLImage *mediaImage;
/**
* The type of the currently playing or paused track.
diff --git a/SmartDeviceLink/SDLMediaServiceData.m b/SmartDeviceLink/SDLMediaServiceData.m
index a605e9bf6..911ec7572 100644
--- a/SmartDeviceLink/SDLMediaServiceData.m
+++ b/SmartDeviceLink/SDLMediaServiceData.m
@@ -10,18 +10,25 @@
#import "NSMutableDictionary+Store.h"
#import "SDLRPCParameterNames.h"
+#import "SDLImage.h"
NS_ASSUME_NONNULL_BEGIN
@implementation SDLMediaServiceData
- (instancetype)initWithMediaType:(nullable SDLMediaType)mediaType mediaTitle:(nullable NSString *)mediaTitle mediaArtist:(nullable NSString *)mediaArtist mediaAlbum:(nullable NSString *)mediaAlbum playlistName:(nullable NSString *)playlistName isExplicit:(BOOL)isExplicit trackPlaybackProgress:(UInt32)trackPlaybackProgress trackPlaybackDuration:(UInt32)trackPlaybackDuration queuePlaybackProgress:(UInt32)queuePlaybackProgress queuePlaybackDuration:(UInt32)queuePlaybackDuration queueCurrentTrackNumber:(UInt32)queueCurrentTrackNumber queueTotalTrackCount:(UInt32)queueTotalTrackCount {
+
+ return [self initWithMediaType:mediaType mediaImage:nil mediaTitle:mediaTitle mediaArtist:mediaArtist mediaAlbum:mediaAlbum playlistName:playlistName isExplicit:isExplicit trackPlaybackProgress:trackPlaybackProgress trackPlaybackDuration:trackPlaybackDuration queuePlaybackProgress:queuePlaybackProgress queuePlaybackDuration:queuePlaybackDuration queueCurrentTrackNumber:queueCurrentTrackNumber queueTotalTrackCount:queueTotalTrackCount];
+}
+
+- (instancetype)initWithMediaType:(nullable SDLMediaType)mediaType mediaImage:(nullable SDLImage *)mediaImage mediaTitle:(nullable NSString *)mediaTitle mediaArtist:(nullable NSString *)mediaArtist mediaAlbum:(nullable NSString *)mediaAlbum playlistName:(nullable NSString *)playlistName isExplicit:(BOOL)isExplicit trackPlaybackProgress:(UInt32)trackPlaybackProgress trackPlaybackDuration:(UInt32)trackPlaybackDuration queuePlaybackProgress:(UInt32)queuePlaybackProgress queuePlaybackDuration:(UInt32)queuePlaybackDuration queueCurrentTrackNumber:(UInt32)queueCurrentTrackNumber queueTotalTrackCount:(UInt32)queueTotalTrackCount {
self = [self init];
if (!self) {
return nil;
}
self.mediaType = mediaType;
+ self.mediaImage = mediaImage;
self.mediaTitle = mediaTitle;
self.mediaArtist = mediaArtist;
self.mediaAlbum = mediaAlbum;
@@ -33,10 +40,18 @@ NS_ASSUME_NONNULL_BEGIN
self.queuePlaybackDuration = @(queuePlaybackDuration);
self.queueCurrentTrackNumber = @(queueCurrentTrackNumber);
self.queueTotalTrackCount = @(queueTotalTrackCount);
-
+
return self;
}
+- (void)setMediaImage:(nullable SDLImage *)mediaImage {
+ [self.store sdl_setObject:mediaImage forName:SDLRPCParameterNameMediaImage];
+}
+
+- (nullable SDLImage *)mediaImage {
+ return [self.store sdl_objectForName:SDLRPCParameterNameMediaImage ofClass:SDLImage.class error:nil];
+}
+
- (void)setMediaType:(nullable SDLMediaType)mediaType {
[self.store sdl_setObject:mediaType forName:SDLRPCParameterNameMediaType];
}
diff --git a/SmartDeviceLink/SDLMenuManager.h b/SmartDeviceLink/SDLMenuManager.h
index a9b253559..a2d076197 100644
--- a/SmartDeviceLink/SDLMenuManager.h
+++ b/SmartDeviceLink/SDLMenuManager.h
@@ -40,6 +40,10 @@ typedef void(^SDLMenuUpdateCompletionHandler)(NSError *__nullable error);
@property (assign, nonatomic) SDLDynamicMenuUpdatesMode dynamicMenuUpdatesMode;
+- (BOOL)openMenu;
+
+- (BOOL)openSubmenu:(SDLMenuCell *)cell;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLMenuManager.m b/SmartDeviceLink/SDLMenuManager.m
index ee8ecf725..8103d88ef 100644
--- a/SmartDeviceLink/SDLMenuManager.m
+++ b/SmartDeviceLink/SDLMenuManager.m
@@ -34,6 +34,7 @@
#import "SDLSetDisplayLayoutResponse.h"
#import "SDLSetGlobalProperties.h"
#import "SDLScreenManager.h"
+#import "SDLShowAppMenu.h"
#import "SDLVersion.h"
#import "SDLVoiceCommand.h"
@@ -415,10 +416,10 @@ UInt32 const MenuCellIdMin = 1;
}
self.inProgressUpdate = [mainMenuCommands arrayByAddingObjectsFromArray:subMenuCommands];
-
+
__block NSMutableDictionary<SDLRPCRequest *, NSError *> *errors = [NSMutableDictionary dictionary];
__weak typeof(self) weakSelf = self;
- [self.connectionManager sendRequests:mainMenuCommands progressHandler:^(__kindof SDLRPCRequest * _Nonnull request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error, float percentComplete) {
+ [self.connectionManager sendRequests:mainMenuCommands progressHandler:^void(__kindof SDLRPCRequest * _Nonnull request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error, float percentComplete) {
if (error != nil) {
errors[request] = error;
}
@@ -672,6 +673,46 @@ UInt32 const MenuCellIdMin = 1;
}
}
+- (BOOL)openMenu {
+ if ([SDLGlobals.sharedGlobals.rpcVersion isLessThanVersion:[[SDLVersion alloc] initWithMajor:6 minor:0 patch:0]]) {
+ SDLLogE(@"The openMenu method is not supported on this head unit.");
+ return NO;
+ }
+
+ SDLShowAppMenu *openMenu = [[SDLShowAppMenu alloc] init];
+
+ [self.connectionManager sendConnectionRequest:openMenu withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) {
+ if (error != nil) {
+ SDLLogE(@"Error opening application menu: %@", error);
+ }
+ }];
+
+ return YES;
+}
+
+- (BOOL)openSubmenu:(SDLMenuCell *)cell {
+ if (cell.subCells.count == 0) {
+ SDLLogE(@"The cell %@ does not contain any sub cells, so no submenu can be opened", cell);
+ return NO;
+ } else if ([SDLGlobals.sharedGlobals.rpcVersion isLessThanVersion:[[SDLVersion alloc] initWithMajor:6 minor:0 patch:0]]) {
+ SDLLogE(@"The openSubmenu method is not supported on this head unit.");
+ return NO;
+ } else if (![self.menuCells containsObject:cell]) {
+ SDLLogE(@"This cell has not been sent to the head unit, so no submenu can be opened. Make sure that the cell exists in the SDLManager.menu array");
+ return NO;
+ }
+
+ SDLShowAppMenu *subMenu = [[SDLShowAppMenu alloc] initWithMenuID:cell.cellId];
+
+ [self.connectionManager sendConnectionRequest:subMenu withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) {
+ if (error != nil) {
+ SDLLogE(@"Error opening application to submenu cell: %@, with error: %@", cell, error);
+ }
+ }];
+
+ return YES;
+}
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLMsgVersion.h b/SmartDeviceLink/SDLMsgVersion.h
new file mode 100644
index 000000000..03b033a08
--- /dev/null
+++ b/SmartDeviceLink/SDLMsgVersion.h
@@ -0,0 +1,52 @@
+//
+// SDLMsgVersion.h
+// SmartDeviceLink
+//
+// Created by Justin Gluck on 7/18/19.
+// Copyright © 2019 smartdevicelink. All rights reserved.
+//
+
+#import "SDLRPCStruct.h"
+
+NS_ASSUME_NONNULL_BEGIN
+/**
+ * Specifies the version number of the SDL V4 interface. This is used by both the application and SDL to declare what interface version each is using.
+ *
+ * @since SDL 1.0
+ */
+@interface SDLMsgVersion : SDLRPCStruct
+
+/**
+ * Convenience init for all parameters.
+ *
+ * @param majorVersion Major version
+ * @param minorVersion Minor version
+ * @param patchVersion Patch version
+ * @return A SDLMsgVersion object
+ */
+- (instancetype)initWithMajorVersion:(UInt8)majorVersion minorVersion:(UInt8)minorVersion patchVersion:(UInt8)patchVersion;
+
+/**
+ * The major version indicates versions that is not-compatible to previous versions
+ *
+ * Required, Integer, 1 - 10
+ */
+@property (strong, nonatomic) NSNumber<SDLInt> *majorVersion;
+
+/**
+ * The minor version indicates a change to a previous version that should still allow to be run on an older version (with limited functionality)
+ *
+ * Required, Integer, 0 - 1000
+ */
+@property (strong, nonatomic) NSNumber<SDLInt> *minorVersion;
+
+/**
+ * Allows backward-compatible fixes to the API without increasing the minor version of the interface
+ *
+ * Optional, Integer, 0 - 1000
+ */
+@property (strong, nonatomic, nullable) NSNumber<SDLInt> *patchVersion;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLMsgVersion.m b/SmartDeviceLink/SDLMsgVersion.m
new file mode 100644
index 000000000..dce291b1b
--- /dev/null
+++ b/SmartDeviceLink/SDLMsgVersion.m
@@ -0,0 +1,58 @@
+//
+// SDLMsgVersion.m
+// SmartDeviceLink
+//
+// Created by Justin Gluck on 7/18/19.
+// Copyright © 2019 smartdevicelink. All rights reserved.
+//
+
+#import "SDLMsgVersion.h"
+#import "NSMutableDictionary+Store.h"
+#import "SDLRPCParameterNames.h"
+
+@implementation SDLMsgVersion
+
+- (instancetype)initWithMajorVersion:(UInt8)majorVersion minorVersion:(UInt8)minorVersion patchVersion:(UInt8)patchVersion {
+ self = [self init];
+ if (!self) {
+ return nil;
+ }
+
+ self.majorVersion = @(majorVersion);
+ self.minorVersion = @(minorVersion);
+ self.patchVersion = @(patchVersion);
+
+ return self;
+}
+
+- (void)setMajorVersion:(NSNumber<SDLInt> *)majorVersion {
+ [self.store sdl_setObject:majorVersion forName:SDLRPCParameterNameMajorVersion];
+}
+
+- (NSNumber<SDLInt> *)majorVersion {
+ NSError *error = nil;
+ return [self.store sdl_objectForName:SDLRPCParameterNameMajorVersion ofClass:NSNumber.class error:&error];
+}
+
+- (void)setMinorVersion:(NSNumber<SDLInt> *)minorVersion {
+ [self.store sdl_setObject:minorVersion forName:SDLRPCParameterNameMinorVersion];
+}
+
+- (NSNumber<SDLInt> *)minorVersion {
+ NSError *error = nil;
+ return [self.store sdl_objectForName:SDLRPCParameterNameMinorVersion ofClass:NSNumber.class error:&error];
+}
+
+- (void)setPatchVersion:(nullable NSNumber<SDLInt> *)patchVersion {
+ [self.store sdl_setObject:patchVersion forName:SDLRPCParameterNamePatchVersion];
+}
+
+- (nullable NSNumber<SDLInt> *)patchVersion {
+ return [self.store sdl_objectForName:SDLRPCParameterNamePatchVersion ofClass:NSNumber.class error:nil];
+}
+
+- (NSString *)description {
+ return [NSString stringWithFormat:@"%@.%@.%@", self.majorVersion, self.minorVersion, self.patchVersion];
+}
+
+@end
diff --git a/SmartDeviceLink/SDLNotificationConstants.h b/SmartDeviceLink/SDLNotificationConstants.h
index 2430e1473..995923606 100644
--- a/SmartDeviceLink/SDLNotificationConstants.h
+++ b/SmartDeviceLink/SDLNotificationConstants.h
@@ -161,6 +161,7 @@ extern SDLNotificationName const SDLDidReceiveSetInteriorVehicleDataResponse;
extern SDLNotificationName const SDLDidReceiveSetMediaClockTimerResponse;
extern SDLNotificationName const SDLDidReceiveShowConstantTBTResponse;
extern SDLNotificationName const SDLDidReceiveShowResponse;
+extern SDLNotificationName const SDLDidReceiveShowAppMenuResponse;
extern SDLNotificationName const SDLDidReceiveSliderResponse;
extern SDLNotificationName const SDLDidReceiveSpeakResponse;
extern SDLNotificationName const SDLDidReceiveSubscribeButtonResponse;
@@ -168,6 +169,7 @@ extern SDLNotificationName const SDLDidReceiveSubscribeVehicleDataResponse;
extern SDLNotificationName const SDLDidReceiveSubscribeWaypointsResponse;
extern SDLNotificationName const SDLDidReceiveSyncPDataResponse;
extern SDLNotificationName const SDLDidReceiveUpdateTurnListResponse;
+extern SDLNotificationName const SDLDidReceiveUnpublishAppServiceResponse;
extern SDLNotificationName const SDLDidReceiveUnregisterAppInterfaceResponse;
extern SDLNotificationName const SDLDidReceiveUnsubscribeButtonResponse;
extern SDLNotificationName const SDLDidReceiveUnsubscribeVehicleDataResponse;
@@ -220,6 +222,7 @@ extern SDLNotificationName const SDLDidReceiveSetGlobalPropertiesRequest;
extern SDLNotificationName const SDLDidReceiveSetInteriorVehicleDataRequest;
extern SDLNotificationName const SDLDidReceiveSetMediaClockTimerRequest;
extern SDLNotificationName const SDLDidReceiveShowRequest;
+extern SDLNotificationName const SDLDidReceiveShowAppMenuRequest;
extern SDLNotificationName const SDLDidReceiveShowConstantTBTRequest;
extern SDLNotificationName const SDLDidReceiveSliderRequest;
extern SDLNotificationName const SDLDidReceiveSpeakRequest;
@@ -228,6 +231,7 @@ extern SDLNotificationName const SDLDidReceiveSubscribeVehicleDataRequest;
extern SDLNotificationName const SDLDidReceiveSubscribeWayPointsRequest;
extern SDLNotificationName const SDLDidReceiveSyncPDataRequest;
extern SDLNotificationName const SDLDidReceiveSystemRequestRequest;
+extern SDLNotificationName const SDLDidReceiveUnpublishAppServiceRequest;
extern SDLNotificationName const SDLDidReceiveUnregisterAppInterfaceRequest;
extern SDLNotificationName const SDLDidReceiveUnsubscribeButtonRequest;
extern SDLNotificationName const SDLDidReceiveUnsubscribeVehicleDataRequest;
diff --git a/SmartDeviceLink/SDLNotificationConstants.m b/SmartDeviceLink/SDLNotificationConstants.m
index 9519555a4..7e0083a51 100644
--- a/SmartDeviceLink/SDLNotificationConstants.m
+++ b/SmartDeviceLink/SDLNotificationConstants.m
@@ -69,6 +69,7 @@ SDLNotificationName const SDLDidReceiveSetInteriorVehicleDataResponse = @"com.sd
SDLNotificationName const SDLDidReceiveSetMediaClockTimerResponse = @"com.sdl.response.setMediaClockTimer";
SDLNotificationName const SDLDidReceiveShowConstantTBTResponse = @"com.sdl.response.showConstantTBT";
SDLNotificationName const SDLDidReceiveShowResponse = @"com.sdl.response.show";
+SDLNotificationName const SDLDidReceiveShowAppMenuResponse = @"com.sdl.response.showAppMenu";
SDLNotificationName const SDLDidReceiveSliderResponse = @"com.sdl.response.slider";
SDLNotificationName const SDLDidReceiveSpeakResponse = @"com.sdl.response.speak";
SDLNotificationName const SDLDidReceiveSubscribeButtonResponse = @"com.sdl.response.subscribeButton";
@@ -76,6 +77,7 @@ SDLNotificationName const SDLDidReceiveSubscribeVehicleDataResponse = @"com.sdl.
SDLNotificationName const SDLDidReceiveSubscribeWaypointsResponse = @"com.sdl.response.subscribeWaypoints";
SDLNotificationName const SDLDidReceiveSyncPDataResponse = @"com.sdl.response.syncPData";
SDLNotificationName const SDLDidReceiveUpdateTurnListResponse = @"com.sdl.response.updateTurnList";
+SDLNotificationName const SDLDidReceiveUnpublishAppServiceResponse = @"com.sdl.response.unpublishAppService";
SDLNotificationName const SDLDidReceiveUnregisterAppInterfaceResponse = @"com.sdl.response.unregisterAppInterface";
SDLNotificationName const SDLDidReceiveUnsubscribeButtonResponse = @"com.sdl.response.unsubscribeButton";
SDLNotificationName const SDLDidReceiveUnsubscribeVehicleDataResponse = @"com.sdl.response.unsubscribeVehicleData";
@@ -125,6 +127,7 @@ SDLNotificationName const SDLDidReceiveSetGlobalPropertiesRequest = @"com.sdl.re
SDLNotificationName const SDLDidReceiveSetInteriorVehicleDataRequest = @"com.sdl.request.setInteriorVehicleData";
SDLNotificationName const SDLDidReceiveSetMediaClockTimerRequest = @"com.sdl.request.setMediaClockTimer";
SDLNotificationName const SDLDidReceiveShowRequest = @"com.sdl.request.show";
+SDLNotificationName const SDLDidReceiveShowAppMenuRequest = @"com.sdl.request.showAppMenu";
SDLNotificationName const SDLDidReceiveShowConstantTBTRequest = @"com.sdl.request.showConstantTBT";
SDLNotificationName const SDLDidReceiveSliderRequest = @"com.sdl.request.slider";
SDLNotificationName const SDLDidReceiveSpeakRequest = @"com.sdl.request.speak";
@@ -133,6 +136,7 @@ SDLNotificationName const SDLDidReceiveSubscribeVehicleDataRequest = @"com.sdl.r
SDLNotificationName const SDLDidReceiveSubscribeWayPointsRequest = @"com.sdl.request.subscribeWayPoints";
SDLNotificationName const SDLDidReceiveSyncPDataRequest = @"com.sdl.request.syncPData";
SDLNotificationName const SDLDidReceiveSystemRequestRequest = @"com.sdl.request.systemRequest";
+SDLNotificationName const SDLDidReceiveUnpublishAppServiceRequest = @"com.sdl.request.unpublishAppService";
SDLNotificationName const SDLDidReceiveUnregisterAppInterfaceRequest = @"com.sdl.request.unregisterAppInterface";
SDLNotificationName const SDLDidReceiveUnsubscribeButtonRequest = @"com.sdl.request.unsubscribeButton";
SDLNotificationName const SDLDidReceiveUnsubscribeVehicleDataRequest = @"com.sdl.request.unsubscribeVehicleData";
@@ -212,6 +216,7 @@ SDLNotificationName const SDLDidReceiveWaypointNotification = @"com.sdl.notifica
SDLDidReceiveSetMediaClockTimerResponse,
SDLDidReceiveShowConstantTBTResponse,
SDLDidReceiveShowResponse,
+ SDLDidReceiveShowAppMenuResponse,
SDLDidReceiveSliderResponse,
SDLDidReceiveSpeakResponse,
SDLDidReceiveSubscribeButtonResponse,
@@ -219,6 +224,7 @@ SDLNotificationName const SDLDidReceiveWaypointNotification = @"com.sdl.notifica
SDLDidReceiveSubscribeWaypointsResponse,
SDLDidReceiveSyncPDataResponse,
SDLDidReceiveUpdateTurnListResponse,
+ SDLDidReceiveUnpublishAppServiceResponse,
SDLDidReceiveUnregisterAppInterfaceResponse,
SDLDidReceiveUnsubscribeButtonResponse,
SDLDidReceiveUnsubscribeVehicleDataResponse,
diff --git a/SmartDeviceLink/SDLNotificationDispatcher.m b/SmartDeviceLink/SDLNotificationDispatcher.m
index f5232a194..c45aa658a 100644
--- a/SmartDeviceLink/SDLNotificationDispatcher.m
+++ b/SmartDeviceLink/SDLNotificationDispatcher.m
@@ -275,6 +275,10 @@ NS_ASSUME_NONNULL_BEGIN
[self postRPCResponseNotification:SDLDidReceiveShowResponse response:response];
}
+- (void)onShowAppMenuResponse:(SDLShowAppMenuResponse *)response {
+ [self postRPCResponseNotification:SDLDidReceiveShowAppMenuResponse response:response];
+}
+
- (void)onSliderResponse:(SDLSliderResponse *)response {
[self postRPCResponseNotification:SDLDidReceiveSliderResponse response:response];
}
@@ -303,6 +307,10 @@ NS_ASSUME_NONNULL_BEGIN
[self postRPCResponseNotification:SDLDidReceiveUpdateTurnListResponse response:response];
}
+- (void)onUnpublishAppServiceResponse:(SDLUnpublishAppServiceResponse *)response {
+ [self postRPCResponseNotification:SDLDidReceiveUnpublishAppServiceResponse response:response];
+}
+
- (void)onUnregisterAppInterfaceResponse:(SDLUnregisterAppInterfaceResponse *)response {
[self postRPCResponseNotification:SDLDidReceiveUnregisterAppInterfaceResponse response:response];
}
@@ -493,6 +501,10 @@ NS_ASSUME_NONNULL_BEGIN
[self postRPCRequestNotification:SDLDidReceiveShowRequest request:request];
}
+- (void)onShowAppMenu:(SDLShowAppMenu *)request {
+ [self postRPCRequestNotification:SDLDidReceiveShowAppMenuRequest request:request];
+}
+
- (void)onShowConstantTBT:(SDLShowConstantTBT *)request {
[self postRPCRequestNotification:SDLDidReceiveShowConstantTBTRequest request:request];
}
@@ -525,6 +537,10 @@ NS_ASSUME_NONNULL_BEGIN
[self postRPCRequestNotification:SDLDidReceiveSystemRequestRequest request:request];
}
+- (void)onUnpublishAppService:(SDLUnpublishAppService *)request {
+ [self postRPCRequestNotification:SDLDidReceiveUnpublishAppServiceRequest request:request];
+}
+
- (void)onUnregisterAppInterface:(SDLUnregisterAppInterface *)request {
[self postRPCRequestNotification:SDLDidReceiveUnregisterAppInterfaceRequest request:request];
}
diff --git a/SmartDeviceLink/SDLOnDriverDistraction.h b/SmartDeviceLink/SDLOnDriverDistraction.h
index d7f369348..f7df06bd8 100644
--- a/SmartDeviceLink/SDLOnDriverDistraction.h
+++ b/SmartDeviceLink/SDLOnDriverDistraction.h
@@ -28,6 +28,20 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (strong, nonatomic) SDLDriverDistractionState state;
+/**
+ If enabled, the lock screen will be able to be dismissed while connected to SDL, allowing users the ability to interact with the app.
+
+ Optional, Boolean
+ */
+@property (strong, nonatomic) NSNumber<SDLBool> *lockScreenDismissalEnabled;
+
+/**
+ Warning message to be displayed on the lock screen when dismissal is enabled. This warning should be used to ensure that the user is not the driver of the vehicle, ex. `Swipe up to dismiss, acknowledging that you are not the driver.`. This parameter must be present if "lockScreenDismissalEnabled" is set to true.
+
+ Optional, String
+ */
+@property (strong, nonatomic) NSString *lockScreenDismissalWarning;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLOnDriverDistraction.m b/SmartDeviceLink/SDLOnDriverDistraction.m
index e65ef63d5..40fb3afa2 100644
--- a/SmartDeviceLink/SDLOnDriverDistraction.m
+++ b/SmartDeviceLink/SDLOnDriverDistraction.m
@@ -30,6 +30,24 @@ NS_ASSUME_NONNULL_BEGIN
return [self.parameters sdl_enumForName:SDLRPCParameterNameState error:&error];
}
+- (void)setLockScreenDismissalEnabled:(NSNumber<SDLBool> *)lockScreenDismissalEnabled {
+ [self.parameters sdl_setObject:lockScreenDismissalEnabled forName:SDLRPCParameterNameLockScreenDismissalEnabled];
+}
+
+- (NSNumber<SDLBool> *)lockScreenDismissalEnabled {
+ NSError *error = nil;
+ return [self.parameters sdl_objectForName:SDLRPCParameterNameLockScreenDismissalEnabled ofClass:NSNumber.class error:&error];
+}
+
+- (void)setLockScreenDismissalWarning:(NSString *)lockScreenDismissalWarning {
+ [self.parameters sdl_setObject:lockScreenDismissalWarning forName:SDLRPCParameterNameLockScreenDismissalWarning];
+}
+
+- (NSString *)lockScreenDismissalWarning {
+ NSError *error = nil;
+ return [self.parameters sdl_objectForName:SDLRPCParameterNameLockScreenDismissalWarning ofClass:NSString.class error:&error];
+}
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLOnLockScreenStatus.h b/SmartDeviceLink/SDLOnLockScreenStatus.h
index 255c0d71f..ce1b2cd62 100644
--- a/SmartDeviceLink/SDLOnLockScreenStatus.h
+++ b/SmartDeviceLink/SDLOnLockScreenStatus.h
@@ -23,6 +23,7 @@
NS_ASSUME_NONNULL_BEGIN
+__deprecated
@interface SDLOnLockScreenStatus : SDLRPCNotification
/**
diff --git a/SmartDeviceLink/SDLOnLockScreenStatus.m b/SmartDeviceLink/SDLOnLockScreenStatus.m
index 563b593bb..6264ea5fd 100644
--- a/SmartDeviceLink/SDLOnLockScreenStatus.m
+++ b/SmartDeviceLink/SDLOnLockScreenStatus.m
@@ -13,7 +13,10 @@
NS_ASSUME_NONNULL_BEGIN
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-implementations"
@implementation SDLOnLockScreenStatus
+#pragma clang diagnostic pop
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
diff --git a/SmartDeviceLink/SDLPermissionManager.m b/SmartDeviceLink/SDLPermissionManager.m
index 6904190e2..ada837ba7 100644
--- a/SmartDeviceLink/SDLPermissionManager.m
+++ b/SmartDeviceLink/SDLPermissionManager.m
@@ -185,7 +185,7 @@ NS_ASSUME_NONNULL_BEGIN
NSArray<SDLPermissionFilter *> *currentFilters = [self.filters copy];
// We can eliminate calling those filters who had no permission changes, so we'll filter down and see which had permissions that changed
- NSArray<SDLPermissionFilter *> *modifiedFilters = [self.class sdl_filterPermissionChangesForFilters:currentFilters updatedPermissions:newPermissionItems];
+ NSArray<SDLPermissionFilter *> *modifiedFilters = [self.class sdl_filterPermissionChangesForFilters:currentFilters currentPermissions:self.permissions updatedPermissions:newPermissionItems];
// We need the old group status and new group status for all allowed filters so we know if they should be called
NSDictionary<SDLPermissionObserverIdentifier, NSNumber<SDLInt> *> *allAllowedFiltersWithOldStatus = [self sdl_currentStatusForFilters:modifiedFilters];
@@ -312,19 +312,20 @@ NS_ASSUME_NONNULL_BEGIN
}
/**
- * Takes a set of filters and a set of updated permission items. Loops through each permission for each filter and determines if the filter contains a permission that was updated. Returns the set of filters that contain an updated permission.
- *
- * @param filters The set of filters to check
- * @param permissionItems The set of updated permissions to test each filter against
- *
- * @return An array of filters that contained one of the passed permissions
+ Takes a set of filters and a set of updated permission items. Loops through each permission for each filter and determines if the filter contains a permission that was updated. Returns the set of filters that contain an updated permission.
+
+ @param filters The set of filters to check
+ @param currentPermissions The current set of permissions to check the updated permissions and make sure they were modified
+ @param updatedPermissions The set of updated permissions to test each filter against
+ @return An array of filters that contained one of the passed permissions
*/
-+ (NSArray<SDLPermissionFilter *> *)sdl_filterPermissionChangesForFilters:(NSArray<SDLPermissionFilter *> *)filters updatedPermissions:(NSArray<SDLPermissionItem *> *)permissionItems {
++ (NSArray<SDLPermissionFilter *> *)sdl_filterPermissionChangesForFilters:(NSArray<SDLPermissionFilter *> *)filters currentPermissions:(NSMutableDictionary<SDLPermissionRPCName, SDLPermissionItem *> *)currentPermissions updatedPermissions:(NSArray<SDLPermissionItem *> *)updatedPermissions {
NSMutableArray<SDLPermissionFilter *> *modifiedFilters = [NSMutableArray arrayWithCapacity:filters.count];
// Loop through each updated permission item for each filter, if the filter had something modified, store it and go to the next filter
for (SDLPermissionFilter *filter in filters) {
- for (SDLPermissionItem *item in permissionItems) {
+ NSArray<SDLPermissionItem *> *modifiedPermissionItems = [self sdl_modifiedUpdatedPermissions:updatedPermissions comparedToCurrentPermissions:currentPermissions];
+ for (SDLPermissionItem *item in modifiedPermissionItems) {
if ([filter.rpcNames containsObject:item.rpcName]) {
[modifiedFilters addObject:filter];
break;
@@ -335,6 +336,19 @@ NS_ASSUME_NONNULL_BEGIN
return [modifiedFilters copy];
}
++ (NSArray<SDLPermissionItem *> *)sdl_modifiedUpdatedPermissions:(NSArray<SDLPermissionItem *> *)permissionItems comparedToCurrentPermissions:(NSMutableDictionary<SDLPermissionRPCName, SDLPermissionItem *> *)currentPermissions {
+ NSMutableArray<SDLPermissionItem *> *modifiedPermissions = [NSMutableArray arrayWithCapacity:permissionItems.count];
+
+ for (SDLPermissionItem *item in permissionItems) {
+ SDLPermissionItem *currentItem = currentPermissions[item.rpcName];
+ if (![item isEqual:currentItem]) {
+ [modifiedPermissions addObject:item];
+ }
+ }
+
+ return [modifiedPermissions copy];
+}
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLPreloadChoicesOperation.m b/SmartDeviceLink/SDLPreloadChoicesOperation.m
index caedc168b..a2f83b5b7 100644
--- a/SmartDeviceLink/SDLPreloadChoicesOperation.m
+++ b/SmartDeviceLink/SDLPreloadChoicesOperation.m
@@ -30,6 +30,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface SDLPreloadChoicesOperation()
+@property (strong, nonatomic) NSUUID *operationId;
@property (strong, nonatomic) NSMutableSet<SDLChoiceCell *> *cellsToUpload;
@property (strong, nonatomic) SDLDisplayCapabilities *displayCapabilities;
@property (assign, nonatomic, getter=isVROptional) BOOL vrOptional;
@@ -51,6 +52,7 @@ NS_ASSUME_NONNULL_BEGIN
_displayCapabilities = displayCapabilities;
_vrOptional = isVROptional;
_cellsToUpload = [cells mutableCopy];
+ _operationId = [NSUUID UUID];
_currentState = SDLPreloadChoicesOperationStateWaitingToStart;
@@ -191,7 +193,7 @@ NS_ASSUME_NONNULL_BEGIN
}
- (nullable NSString *)name {
- return @"com.sdl.choicesetmanager.preloadChoices";
+ return [NSString stringWithFormat:@"%@ - %@", self.class, self.operationId];
}
- (NSOperationQueuePriority)queuePriority {
diff --git a/SmartDeviceLink/SDLPresentChoiceSetOperation.m b/SmartDeviceLink/SDLPresentChoiceSetOperation.m
index 4e923b8e1..87caf9d0a 100644
--- a/SmartDeviceLink/SDLPresentChoiceSetOperation.m
+++ b/SmartDeviceLink/SDLPresentChoiceSetOperation.m
@@ -32,6 +32,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface SDLPresentChoiceSetOperation()
+@property (strong, nonatomic) NSUUID *operationId;
@property (weak, nonatomic) id<SDLConnectionManagerType> connectionManager;
@property (strong, nonatomic, readwrite) SDLChoiceSet *choiceSet;
@property (strong, nonatomic) SDLInteractionMode presentationMode;
@@ -60,6 +61,7 @@ NS_ASSUME_NONNULL_BEGIN
_connectionManager = connectionManager;
_choiceSet = choiceSet;
_presentationMode = mode;
+ _operationId = [NSUUID UUID];
_originalKeyboardProperties = originalKeyboardProperties;
_keyboardProperties = originalKeyboardProperties;
@@ -211,11 +213,27 @@ NS_ASSUME_NONNULL_BEGIN
[self.keyboardDelegate userDidSubmitInput:onKeyboard.data withEvent:onKeyboard.event];
} else if ([onKeyboard.event isEqualToEnum:SDLKeyboardEventKeypress]) {
// Notify of keypress
- if ([self.keyboardDelegate respondsToSelector:@selector(updateAutocompleteWithInput:completionHandler:)]) {
- [self.keyboardDelegate updateAutocompleteWithInput:onKeyboard.data completionHandler:^(NSString *updatedAutocompleteText) {
+ if ([self.keyboardDelegate respondsToSelector:@selector(updateAutocompleteWithInput:autoCompleteResultsHandler:)]) {
+ [self.keyboardDelegate updateAutocompleteWithInput:onKeyboard.data autoCompleteResultsHandler:^(NSArray<NSString *> * _Nullable updatedAutoCompleteList) {
+ NSArray<NSString *> *newList = nil;
+ if (updatedAutoCompleteList.count > 100) {
+ newList = [updatedAutoCompleteList subarrayWithRange:NSMakeRange(0, 100)];
+ } else {
+ newList = updatedAutoCompleteList;
+ }
+
+ weakself.keyboardProperties.autoCompleteList = (newList.count > 0) ? newList : @[];
+ weakself.keyboardProperties.autoCompleteText = (newList.count > 0) ? newList.firstObject : nil;
+ [weakself sdl_updateKeyboardPropertiesWithCompletionHandler:nil];
+ }];
+ } else if ([self.keyboardDelegate respondsToSelector:@selector(updateAutocompleteWithInput:completionHandler:)]) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ [self.keyboardDelegate updateAutocompleteWithInput:onKeyboard.data completionHandler:^(NSString * _Nullable updatedAutocompleteText) {
weakself.keyboardProperties.autoCompleteText = updatedAutocompleteText;
[weakself sdl_updateKeyboardPropertiesWithCompletionHandler:nil];
}];
+#pragma clang diagnostic pop
}
if ([self.keyboardDelegate respondsToSelector:@selector(updateCharacterSetWithInput:completionHandler:)]) {
@@ -254,7 +272,7 @@ NS_ASSUME_NONNULL_BEGIN
}
- (nullable NSString *)name {
- return @"com.sdl.choicesetmanager.presentChoiceSet";
+ return [NSString stringWithFormat:@"%@ - %@", self.class, self.operationId];
}
- (NSOperationQueuePriority)queuePriority {
diff --git a/SmartDeviceLink/SDLPresentKeyboardOperation.m b/SmartDeviceLink/SDLPresentKeyboardOperation.m
index b81284ebe..b54f040fe 100644
--- a/SmartDeviceLink/SDLPresentKeyboardOperation.m
+++ b/SmartDeviceLink/SDLPresentKeyboardOperation.m
@@ -23,6 +23,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface SDLPresentKeyboardOperation()
+@property (strong, nonatomic) NSUUID *operationId;
@property (weak, nonatomic) id<SDLConnectionManagerType> connectionManager;
@property (weak, nonatomic) id<SDLKeyboardDelegate> keyboardDelegate;
@property (copy, nonatomic) NSString *initialText;
@@ -46,6 +47,7 @@ NS_ASSUME_NONNULL_BEGIN
_keyboardDelegate = keyboardDelegate;
_originalKeyboardProperties = originalKeyboardProperties;
_keyboardProperties = originalKeyboardProperties;
+ _operationId = [NSUUID UUID];
return self;
}
@@ -141,11 +143,27 @@ NS_ASSUME_NONNULL_BEGIN
[self.keyboardDelegate userDidSubmitInput:onKeyboard.data withEvent:onKeyboard.event];
} else if ([onKeyboard.event isEqualToEnum:SDLKeyboardEventKeypress]) {
// Notify of keypress
- if ([self.keyboardDelegate respondsToSelector:@selector(updateAutocompleteWithInput:completionHandler:)]) {
- [self.keyboardDelegate updateAutocompleteWithInput:onKeyboard.data completionHandler:^(NSString *updatedAutocompleteText) {
+ if ([self.keyboardDelegate respondsToSelector:@selector(updateAutocompleteWithInput:autoCompleteResultsHandler:)]) {
+ [self.keyboardDelegate updateAutocompleteWithInput:onKeyboard.data autoCompleteResultsHandler:^(NSArray<NSString *> * _Nullable updatedAutoCompleteList) {
+ NSArray<NSString *> *newList = nil;
+ if (updatedAutoCompleteList.count > 100) {
+ newList = [updatedAutoCompleteList subarrayWithRange:NSMakeRange(0, 100)];
+ } else {
+ newList = updatedAutoCompleteList;
+ }
+
+ weakself.keyboardProperties.autoCompleteList = (newList.count > 0) ? newList : @[];
+ weakself.keyboardProperties.autoCompleteText = (newList.count > 0) ? newList.firstObject : nil;
+ [weakself sdl_updateKeyboardPropertiesWithCompletionHandler:nil];
+ }];
+ } else if ([self.keyboardDelegate respondsToSelector:@selector(updateAutocompleteWithInput:completionHandler:)]) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ [self.keyboardDelegate updateAutocompleteWithInput:onKeyboard.data completionHandler:^(NSString * _Nullable updatedAutocompleteText) {
weakself.keyboardProperties.autoCompleteText = updatedAutocompleteText;
[weakself sdl_updateKeyboardPropertiesWithCompletionHandler:nil];
}];
+#pragma clang diagnostic pop
}
if ([self.keyboardDelegate respondsToSelector:@selector(updateCharacterSetWithInput:completionHandler:)]) {
@@ -163,7 +181,7 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Property Overrides
- (nullable NSString *)name {
- return @"com.sdl.choicesetmanager.presentKeyboard";
+ return [NSString stringWithFormat:@"%@ - %@", self.class, self.operationId];
}
- (NSOperationQueuePriority)queuePriority {
diff --git a/SmartDeviceLink/SDLProtocol.m b/SmartDeviceLink/SDLProtocol.m
index 3f1996e92..5adfd5b88 100644
--- a/SmartDeviceLink/SDLProtocol.m
+++ b/SmartDeviceLink/SDLProtocol.m
@@ -39,8 +39,6 @@ NS_ASSUME_NONNULL_BEGIN
@interface SDLProtocol () {
UInt32 _messageID;
- dispatch_queue_t _receiveQueue;
- dispatch_queue_t _sendQueue;
SDLPrioritizedObjectCollection *_prioritizedCollection;
}
@@ -65,8 +63,6 @@ NS_ASSUME_NONNULL_BEGIN
if (self = [super init]) {
_messageID = 0;
_hashId = SDLControlFrameInt32NotFound;
- _receiveQueue = dispatch_queue_create("com.sdl.protocol.receive", DISPATCH_QUEUE_SERIAL);
- _sendQueue = dispatch_queue_create("com.sdl.protocol.transmit", DISPATCH_QUEUE_SERIAL);
_prioritizedCollection = [[SDLPrioritizedObjectCollection alloc] init];
_protocolDelegateTable = [NSHashTable weakObjectsHashTable];
_serviceHeaders = [[NSMutableDictionary alloc] init];
@@ -357,13 +353,10 @@ NS_ASSUME_NONNULL_BEGIN
- (void)sdl_sendDataToTransport:(NSData *)data onService:(NSInteger)priority {
[_prioritizedCollection addObject:data withPriority:priority];
- // TODO: (Joel F.)[2016-02-11] Autoreleasepool?
- dispatch_async(_sendQueue, ^{
- NSData *dataToTransmit = nil;
- while (dataToTransmit = (NSData *)[self->_prioritizedCollection nextObject]) {
- [self.transport sendData:dataToTransmit];
- };
- });
+ NSData *dataToTransmit = nil;
+ while (dataToTransmit = (NSData *)[self->_prioritizedCollection nextObject]) {
+ [self.transport sendData:dataToTransmit];
+ }
}
- (void)sendRawData:(NSData *)data withServiceType:(SDLServiceType)serviceType {
@@ -465,9 +458,7 @@ NS_ASSUME_NONNULL_BEGIN
self.receiveBuffer = [[self.receiveBuffer subdataWithRange:NSMakeRange(messageSize, self.receiveBuffer.length - messageSize)] mutableCopy];
// Pass on the message to the message router.
- dispatch_async(_receiveQueue, ^{
- [self.messageRouter handleReceivedMessage:message];
- });
+ [self.messageRouter handleReceivedMessage:message];
// Call recursively until the buffer is empty or incomplete message is encountered
if (self.receiveBuffer.length > 0) {
@@ -475,7 +466,6 @@ NS_ASSUME_NONNULL_BEGIN
}
}
-// TODO: This is a v4 packet (create new delegate methods)
- (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceACK {
// V5 Packet
if (startServiceACK.header.version >= 5) {
diff --git a/SmartDeviceLink/SDLProxy.m b/SmartDeviceLink/SDLProxy.m
index 6ab2006c8..f32b3de94 100644
--- a/SmartDeviceLink/SDLProxy.m
+++ b/SmartDeviceLink/SDLProxy.m
@@ -50,7 +50,7 @@ typedef NSString SDLVehicleMake;
typedef void (^URLSessionTaskCompletionHandler)(NSData *data, NSURLResponse *response, NSError *error);
typedef void (^URLSessionDownloadTaskCompletionHandler)(NSURL *location, NSURLResponse *response, NSError *error);
-NSString *const SDLProxyVersion = @"6.3.0";
+NSString *const SDLProxyVersion = @"6.3.1";
const float StartSessionTime = 10.0;
const float NotifyProxyClosedDelay = (float)0.1;
const int PoliciesCorrelationId = 65535;
@@ -65,7 +65,6 @@ static float DefaultConnectionTimeout = 45.0;
@property (nullable, nonatomic, strong) SDLDisplayCapabilities *displayCapabilities;
@property (nonatomic, strong) NSMutableDictionary<SDLVehicleMake *, Class> *securityManagers;
@property (nonatomic, strong) NSURLSession* urlSession;
-@property (strong, nonatomic) dispatch_queue_t rpcProcessingQueue;
@end
@@ -77,7 +76,6 @@ static float DefaultConnectionTimeout = 45.0;
if (self = [super init]) {
SDLLogD(@"Framework Version: %@", self.proxyVersion);
_lsm = [[SDLLockScreenStatusManager alloc] init];
- _rpcProcessingQueue = dispatch_queue_create("com.sdl.rpcProcessingQueue", DISPATCH_QUEUE_SERIAL);
_mutableProxyListeners = [NSMutableSet setWithObject:delegate];
_securityManagers = [NSMutableDictionary dictionary];
@@ -150,13 +148,15 @@ static float DefaultConnectionTimeout = 45.0;
#pragma mark - Application Lifecycle
- (void)sendMobileHMIState {
- dispatch_async(dispatch_get_main_queue(), ^{
- [self sdl_sendMobileHMIState];
- });
-}
+ __block UIApplicationState appState = UIApplicationStateInactive;
+ if ([NSThread isMainThread]) {
+ appState = [UIApplication sharedApplication].applicationState;
+ } else {
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ appState = [UIApplication sharedApplication].applicationState;
+ });
+ }
-- (void)sdl_sendMobileHMIState {
- UIApplicationState appState = [UIApplication sharedApplication].applicationState;
SDLOnHMIStatus *HMIStatusRPC = [[SDLOnHMIStatus alloc] init];
HMIStatusRPC.audioStreamingState = SDLAudioStreamingStateNotAudible;
@@ -898,15 +898,13 @@ static float DefaultConnectionTimeout = 45.0;
}
- (void)invokeMethodOnDelegates:(SEL)aSelector withObject:(nullable id)object {
- // Occurs on the protocol receive serial queue
- dispatch_async(_rpcProcessingQueue, ^{
- for (id<SDLProxyListener> listener in self.proxyListeners) {
- if ([listener respondsToSelector:aSelector]) {
- // HAX: http://stackoverflow.com/questions/7017281/performselector-may-cause-a-leak-because-its-selector-is-unknown
- ((void (*)(id, SEL, id))[(NSObject *)listener methodForSelector:aSelector])(listener, aSelector, object);
- }
+ // Occurs on the processing serial queue
+ for (id<SDLProxyListener> listener in self.proxyListeners) {
+ if ([listener respondsToSelector:aSelector]) {
+ // HAX: http://stackoverflow.com/questions/7017281/performselector-may-cause-a-leak-because-its-selector-is-unknown
+ ((void (*)(id, SEL, id))[(NSObject *)listener methodForSelector:aSelector])(listener, aSelector, object);
}
- });
+ }
}
diff --git a/SmartDeviceLink/SDLProxyListener.h b/SmartDeviceLink/SDLProxyListener.h
index ea19fde07..c95a64383 100644
--- a/SmartDeviceLink/SDLProxyListener.h
+++ b/SmartDeviceLink/SDLProxyListener.h
@@ -112,6 +112,8 @@
@class SDLSetMediaClockTimer;
@class SDLSetMediaClockTimerResponse;
@class SDLShow;
+@class SDLShowAppMenu;
+@class SDLShowAppMenuResponse;
@class SDLShowConstantTBT;
@class SDLShowConstantTBTResponse;
@class SDLShowResponse;
@@ -128,6 +130,8 @@
@class SDLSyncPData;
@class SDLSyncPDataResponse;
@class SDLSystemRequest;
+@class SDLUnpublishAppService;
+@class SDLUnpublishAppServiceResponse;
@class SDLUnregisterAppInterface;
@class SDLUnregisterAppInterfaceResponse;
@class SDLUnsubscribeButton;
@@ -494,6 +498,13 @@ NS_ASSUME_NONNULL_BEGIN
- (void)onShowResponse:(SDLShowResponse *)response;
/**
+ * Called when a ShowAppMenu Response is received from Core
+ *
+ * @param response A SDLShowAppMenuResponse object
+ */
+- (void)onShowAppMenuResponse:(SDLShowAppMenuResponse *)response;
+
+/**
* Called when a Slider Response is received from Core
*
* @param response A SDLSliderResponse object
@@ -543,6 +554,13 @@ NS_ASSUME_NONNULL_BEGIN
- (void)onUpdateTurnListResponse:(SDLUpdateTurnListResponse *)response;
/**
+ * Called when an Unpublish App Service Response is received from Core
+ *
+ * @param response A SDLUnpublishAppServiceResponse object
+ */
+- (void)onUnpublishAppServiceResponse:(SDLUnpublishAppServiceResponse *)response;
+
+/**
* Called when an Unregister App Interface Response is received from Core
*
* @param response A SDLUnregisterAppInterfaceResponse object
@@ -874,6 +892,13 @@ NS_ASSUME_NONNULL_BEGIN
- (void)onShow:(SDLShow *)request;
/**
+ * Called when a `ShowAppMenu` is received from Core
+ *
+ * @param request A SDLShowAppMenu object
+ */
+- (void)onShowAppMenu:(SDLShowAppMenu *)request;
+
+/**
* Called when a `ShowConstantTBT` request is received from Core
*
* @param request A SDLShowConstantTBT object
@@ -930,6 +955,13 @@ NS_ASSUME_NONNULL_BEGIN
- (void)onSystemRequest:(SDLSystemRequest *)request;
/**
+ * Called when a `SDLUnpublishAppService` request is received from Core
+ *
+ * @param request A SDLUnpublishAppService object
+ */
+- (void)onUnpublishAppService:(SDLUnpublishAppService *)request;
+
+/**
* Called when a `UnregisterAppInterface` request is received from Core
*
* @param request A SDLUnregisterAppInterface object
@@ -1049,7 +1081,10 @@ NS_ASSUME_NONNULL_BEGIN
*
* @param notification A SDLOnLockScreenStatus object
*/
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- (void)onOnLockScreenNotification:(SDLOnLockScreenStatus *)notification;
+#pragma clang diagnostic pop
/**
* Called when an On Permissions Change notification is received from Core
diff --git a/SmartDeviceLink/SDLPublishAppService.h b/SmartDeviceLink/SDLPublishAppService.h
index e9effe25d..d8a07c77d 100644
--- a/SmartDeviceLink/SDLPublishAppService.h
+++ b/SmartDeviceLink/SDLPublishAppService.h
@@ -15,6 +15,7 @@ NS_ASSUME_NONNULL_BEGIN
/**
* Registers a service offered by this app on the module.
+ * Subsequent calls with the same service type will update the manifest for that service.
*/
@interface SDLPublishAppService : SDLRPCRequest
@@ -28,6 +29,7 @@ NS_ASSUME_NONNULL_BEGIN
/**
* The manifest of the service that wishes to be published.
+ * If already published, the updated manifest for this service.
*
* SDLAppServiceManifest, Required
*/
diff --git a/SmartDeviceLink/SDLRPCFunctionNames.h b/SmartDeviceLink/SDLRPCFunctionNames.h
index 1693d773c..fa3cce56d 100644
--- a/SmartDeviceLink/SDLRPCFunctionNames.h
+++ b/SmartDeviceLink/SDLRPCFunctionNames.h
@@ -81,6 +81,7 @@ extern SDLRPCFunctionName const SDLRPCFunctionNameSetGlobalProperties;
extern SDLRPCFunctionName const SDLRPCFunctionNameSetInteriorVehicleData;
extern SDLRPCFunctionName const SDLRPCFunctionNameSetMediaClockTimer;
extern SDLRPCFunctionName const SDLRPCFunctionNameShow;
+extern SDLRPCFunctionName const SDLRPCFunctionNameShowAppMenu;
extern SDLRPCFunctionName const SDLRPCFunctionNameShowConstantTBT;
extern SDLRPCFunctionName const SDLRPCFunctionNameSlider;
extern SDLRPCFunctionName const SDLRPCFunctionNameSpeak;
@@ -89,6 +90,7 @@ extern SDLRPCFunctionName const SDLRPCFunctionNameSubscribeVehicleData;
extern SDLRPCFunctionName const SDLRPCFunctionNameSubscribeWayPoints;
extern SDLRPCFunctionName const SDLRPCFunctionNameSyncPData;
extern SDLRPCFunctionName const SDLRPCFunctionNameSystemRequest;
+extern SDLRPCFunctionName const SDLRPCFunctionNameUnpublishAppService;
extern SDLRPCFunctionName const SDLRPCFunctionNameUnregisterAppInterface;
extern SDLRPCFunctionName const SDLRPCFunctionNameUnsubscribeButton;
extern SDLRPCFunctionName const SDLRPCFunctionNameUnsubscribeVehicleData;
diff --git a/SmartDeviceLink/SDLRPCFunctionNames.m b/SmartDeviceLink/SDLRPCFunctionNames.m
index 879ae943b..4aceed985 100644
--- a/SmartDeviceLink/SDLRPCFunctionNames.m
+++ b/SmartDeviceLink/SDLRPCFunctionNames.m
@@ -76,6 +76,7 @@ SDLRPCFunctionName const SDLRPCFunctionNameSetGlobalProperties = @"SetGlobalProp
SDLRPCFunctionName const SDLRPCFunctionNameSetInteriorVehicleData = @"SetInteriorVehicleData";
SDLRPCFunctionName const SDLRPCFunctionNameSetMediaClockTimer = @"SetMediaClockTimer";
SDLRPCFunctionName const SDLRPCFunctionNameShow = @"Show";
+SDLRPCFunctionName const SDLRPCFunctionNameShowAppMenu = @"ShowAppMenu";
SDLRPCFunctionName const SDLRPCFunctionNameShowConstantTBT = @"ShowConstantTBT";
SDLRPCFunctionName const SDLRPCFunctionNameSlider = @"Slider";
SDLRPCFunctionName const SDLRPCFunctionNameSpeak = @"Speak";
@@ -84,6 +85,7 @@ SDLRPCFunctionName const SDLRPCFunctionNameSubscribeVehicleData = @"SubscribeVeh
SDLRPCFunctionName const SDLRPCFunctionNameSubscribeWayPoints = @"SubscribeWayPoints";
SDLRPCFunctionName const SDLRPCFunctionNameSyncPData = @"SyncPData";
SDLRPCFunctionName const SDLRPCFunctionNameSystemRequest = @"SystemRequest";
+SDLRPCFunctionName const SDLRPCFunctionNameUnpublishAppService = @"UnpublishAppService";
SDLRPCFunctionName const SDLRPCFunctionNameUnregisterAppInterface = @"UnregisterAppInterface";
SDLRPCFunctionName const SDLRPCFunctionNameUnsubscribeButton = @"UnsubscribeButton";
SDLRPCFunctionName const SDLRPCFunctionNameUnsubscribeVehicleData = @"UnsubscribeVehicleData";
diff --git a/SmartDeviceLink/SDLRPCParameterNames.h b/SmartDeviceLink/SDLRPCParameterNames.h
index b6fa2ad45..c3b053652 100644
--- a/SmartDeviceLink/SDLRPCParameterNames.h
+++ b/SmartDeviceLink/SDLRPCParameterNames.h
@@ -20,6 +20,7 @@ extern SDLRPCParameterName const SDLRPCParameterNameAddress;
extern SDLRPCParameterName const SDLRPCParameterNameAddressLines;
extern SDLRPCParameterName const SDLRPCParameterNameAdministrativeArea;
extern SDLRPCParameterName const SDLRPCParameterNameAirbagStatus;
+extern SDLRPCParameterName const SDLRPCParameterNameAlertIcon;
extern SDLRPCParameterName const SDLRPCParameterNameAlerts;
extern SDLRPCParameterName const SDLRPCParameterNameAlertText1;
extern SDLRPCParameterName const SDLRPCParameterNameAlertText2;
@@ -47,6 +48,7 @@ extern SDLRPCParameterName const SDLRPCParameterNameAppServiceRecord;
extern SDLRPCParameterName const SDLRPCParameterNameAppServices;
extern SDLRPCParameterName const SDLRPCParameterNameAppServicesCapabilities;
extern SDLRPCParameterName const SDLRPCParameterNameAppVersion;
+extern SDLRPCParameterName const SDLRPCParameterNameAutoCompleteList;
extern SDLRPCParameterName const SDLRPCParameterNameAudioControlCapabilities;
extern SDLRPCParameterName const SDLRPCParameterNameAudioControlData;
extern SDLRPCParameterName const SDLRPCParameterNameAudioPassThruCapabilities;
@@ -315,6 +317,8 @@ extern SDLRPCParameterName const SDLRPCParameterNameLocationDescription;
extern SDLRPCParameterName const SDLRPCParameterNameLocationDetails;
extern SDLRPCParameterName const SDLRPCParameterNameLocationImage;
extern SDLRPCParameterName const SDLRPCParameterNameLocationName;
+extern SDLRPCParameterName const SDLRPCParameterNameLockScreenDismissalEnabled;
+extern SDLRPCParameterName const SDLRPCParameterNameLockScreenDismissalWarning;
extern SDLRPCParameterName const SDLRPCParameterNameLongitudeDegrees;
extern SDLRPCParameterName const SDLRPCParameterNameLongPress;
extern SDLRPCParameterName const SDLRPCParameterNameLongPressAvailable;
@@ -354,6 +358,7 @@ extern SDLRPCParameterName const SDLRPCParameterNameMediaServiceData;
extern SDLRPCParameterName const SDLRPCParameterNameMediaServiceManifest;
extern SDLRPCParameterName const SDLRPCParameterNameMediaTitle;
extern SDLRPCParameterName const SDLRPCParameterNameMediaTrack;
+extern SDLRPCParameterName const SDLRPCParameterNameMediaImage;
extern SDLRPCParameterName const SDLRPCParameterNameMediaType;
extern SDLRPCParameterName const SDLRPCParameterNameMemory;
extern SDLRPCParameterName const SDLRPCParameterNameMenuIcon;
@@ -598,6 +603,7 @@ extern SDLRPCParameterName const SDLRPCParameterNameTemperatureLow;
extern SDLRPCParameterName const SDLRPCParameterNameTemperatureUnit;
extern SDLRPCParameterName const SDLRPCParameterNameTemperatureUnitAvailable;
extern SDLRPCParameterName const SDLRPCParameterNameTemplatesAvailable;
+extern SDLRPCParameterName const SDLRPCParameterNameTemplateTitle;
extern SDLRPCParameterName const SDLRPCParameterNameTertiaryText;
extern SDLRPCParameterName const SDLRPCParameterNameText;
extern SDLRPCParameterName const SDLRPCParameterNameTextFields;
diff --git a/SmartDeviceLink/SDLRPCParameterNames.m b/SmartDeviceLink/SDLRPCParameterNames.m
index 939424a62..9eaface64 100644
--- a/SmartDeviceLink/SDLRPCParameterNames.m
+++ b/SmartDeviceLink/SDLRPCParameterNames.m
@@ -18,6 +18,7 @@ SDLRPCParameterName const SDLRPCParameterNameAddress = @"address";
SDLRPCParameterName const SDLRPCParameterNameAddressLines = @"addressLines";
SDLRPCParameterName const SDLRPCParameterNameAdministrativeArea = @"administrativeArea";
SDLRPCParameterName const SDLRPCParameterNameAirbagStatus = @"airbagStatus";
+SDLRPCParameterName const SDLRPCParameterNameAlertIcon = @"alertIcon";
SDLRPCParameterName const SDLRPCParameterNameAlerts = @"alerts";
SDLRPCParameterName const SDLRPCParameterNameAlertText1 = @"alertText1";
SDLRPCParameterName const SDLRPCParameterNameAlertText2 = @"alertText2";
@@ -54,6 +55,7 @@ SDLRPCParameterName const SDLRPCParameterNameAudioStreamingIndicator = @"audioSt
SDLRPCParameterName const SDLRPCParameterNameAudioStreamingState = @"audioStreamingState";
SDLRPCParameterName const SDLRPCParameterNameAudioType = @"audioType";
SDLRPCParameterName const SDLRPCParameterNameAuthToken = @"authToken";
+SDLRPCParameterName const SDLRPCParameterNameAutoCompleteList = @"autoCompleteList";
SDLRPCParameterName const SDLRPCParameterNameAutoCompleteText = @"autoCompleteText";
SDLRPCParameterName const SDLRPCParameterNameAutoModeEnable = @"autoModeEnable";
SDLRPCParameterName const SDLRPCParameterNameAutoModeEnableAvailable = @"autoModeEnableAvailable";
@@ -313,6 +315,8 @@ SDLRPCParameterName const SDLRPCParameterNameLocationDescription = @"locationDes
SDLRPCParameterName const SDLRPCParameterNameLocationDetails = @"locationDetails";
SDLRPCParameterName const SDLRPCParameterNameLocationImage = @"locationImage";
SDLRPCParameterName const SDLRPCParameterNameLocationName = @"locationName";
+SDLRPCParameterName const SDLRPCParameterNameLockScreenDismissalEnabled = @"lockScreenDismissalEnabled";
+SDLRPCParameterName const SDLRPCParameterNameLockScreenDismissalWarning = @"lockScreenDismissalWarning";
SDLRPCParameterName const SDLRPCParameterNameLongitudeDegrees = @"longitudeDegrees";
SDLRPCParameterName const SDLRPCParameterNameLongPress = @"longPress";
SDLRPCParameterName const SDLRPCParameterNameLongPressAvailable = @"longPressAvailable";
@@ -345,6 +349,7 @@ SDLRPCParameterName const SDLRPCParameterNameMediaClock = @"mediaClock";
SDLRPCParameterName const SDLRPCParameterNameMediaClockFormats = @"mediaClockFormats";
SDLRPCParameterName const SDLRPCParameterNameMediaServiceData = @"mediaServiceData";
SDLRPCParameterName const SDLRPCParameterNameMediaServiceManifest = @"mediaServiceManifest";
+SDLRPCParameterName const SDLRPCParameterNameMediaImage = @"mediaImage";
SDLRPCParameterName const SDLRPCParameterNameMediaTitle = @"mediaTitle";
SDLRPCParameterName const SDLRPCParameterNameMediaTrack = @"mediaTrack";
SDLRPCParameterName const SDLRPCParameterNameMediaType = @"mediaType";
@@ -593,6 +598,7 @@ SDLRPCParameterName const SDLRPCParameterNameTemperatureLow = @"temperatureLow";
SDLRPCParameterName const SDLRPCParameterNameTemperatureUnit = @"temperatureUnit";
SDLRPCParameterName const SDLRPCParameterNameTemperatureUnitAvailable = @"temperatureUnitAvailable";
SDLRPCParameterName const SDLRPCParameterNameTemplatesAvailable = @"templatesAvailable";
+SDLRPCParameterName const SDLRPCParameterNameTemplateTitle = @"templateTitle";
SDLRPCParameterName const SDLRPCParameterNameTertiaryText = @"tertiaryText";
SDLRPCParameterName const SDLRPCParameterNameText = @"text";
SDLRPCParameterName const SDLRPCParameterNameTextFields = @"textFields";
diff --git a/SmartDeviceLink/SDLRPCRequest.m b/SmartDeviceLink/SDLRPCRequest.m
index 1ce2186c1..445bace56 100644
--- a/SmartDeviceLink/SDLRPCRequest.m
+++ b/SmartDeviceLink/SDLRPCRequest.m
@@ -26,6 +26,10 @@ NS_ASSUME_NONNULL_BEGIN
[self.function sdl_setObject:corrID forName:SDLRPCParameterNameCorrelationId];
}
+- (NSString *)description {
+ return [NSString stringWithFormat:@"%@ (%@), id: %@\n%@", self.name, self.messageType, self.correlationID, self.parameters];
+}
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLRPCResponse.m b/SmartDeviceLink/SDLRPCResponse.m
index c996473e9..c0ad88b74 100644
--- a/SmartDeviceLink/SDLRPCResponse.m
+++ b/SmartDeviceLink/SDLRPCResponse.m
@@ -44,8 +44,13 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
+
#pragma clang diagnostic pop
+- (NSString *)description {
+ return [NSString stringWithFormat:@"%@ (%@), id: %@\n%@", self.name, self.messageType, self.correlationID, self.parameters];
+}
+
- (NSNumber<SDLInt> *)correlationID {
NSError *error = nil;
return [self.function sdl_objectForName:SDLRPCParameterNameCorrelationId ofClass:NSNumber.class error:&error];
diff --git a/SmartDeviceLink/SDLRegisterAppInterface.h b/SmartDeviceLink/SDLRegisterAppInterface.h
index 1ffd4892a..d1b8298e7 100644
--- a/SmartDeviceLink/SDLRegisterAppInterface.h
+++ b/SmartDeviceLink/SDLRegisterAppInterface.h
@@ -10,6 +10,7 @@
@class SDLDeviceInfo;
@class SDLLifecycleConfiguration;
@class SDLSyncMsgVersion;
+@class SDLMsgVersion;
@class SDLTemplateColorScheme;
@class SDLTTSChunk;
@@ -105,7 +106,16 @@ NS_ASSUME_NONNULL_BEGIN
*
* @since SDL 1.0
*/
-@property (strong, nonatomic) SDLSyncMsgVersion *syncMsgVersion;
+@property (strong, nonatomic) SDLSyncMsgVersion *syncMsgVersion __deprecated_msg(("Use sdlMsgVersion instead"));
+
+/**
+ * Specifies the version number of the SmartDeviceLink protocol that is supported by the mobile application.
+ *
+ * SDLMsgVersion, Required
+ *
+ * @since SDL 1.0
+ */
+@property (strong, nonatomic) SDLMsgVersion *sdlMsgVersion;
/**
* The mobile application's name. This name is displayed in the SDL Mobile Applications menu. It also serves as the unique identifier of the application for SmartDeviceLink. Applications with the same name will be rejected.
diff --git a/SmartDeviceLink/SDLRegisterAppInterface.m b/SmartDeviceLink/SDLRegisterAppInterface.m
index 6a752b641..6fa2ed638 100644
--- a/SmartDeviceLink/SDLRegisterAppInterface.m
+++ b/SmartDeviceLink/SDLRegisterAppInterface.m
@@ -14,6 +14,7 @@
#import "SDLRPCParameterNames.h"
#import "SDLRPCFunctionNames.h"
#import "SDLSyncMsgVersion.h"
+#import "SDLMsgVersion.h"
#import "SDLTemplateColorScheme.h"
#import "SDLTTSChunk.h"
@@ -66,7 +67,7 @@ NS_ASSUME_NONNULL_BEGIN
UInt8 majorVersion = (UInt8)[SDLMaxProxyRPCVersion substringWithRange:NSMakeRange(0, 1)].intValue;
UInt8 minorVersion = (UInt8)[SDLMaxProxyRPCVersion substringWithRange:NSMakeRange(2, 1)].intValue;
UInt8 patchVersion = (UInt8)[SDLMaxProxyRPCVersion substringWithRange:NSMakeRange(4, 1)].intValue;
- self.syncMsgVersion = [[SDLSyncMsgVersion alloc] initWithMajorVersion:majorVersion minorVersion:minorVersion patchVersion:patchVersion];
+ self.sdlMsgVersion = [[SDLMsgVersion alloc] initWithMajorVersion:majorVersion minorVersion:minorVersion patchVersion:patchVersion];
self.appInfo = [SDLAppInfo currentAppInfo];
self.deviceInfo = [SDLDeviceInfo currentDevice];
self.correlationID = @1;
@@ -119,12 +120,25 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Getters and Setters
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- (void)setSyncMsgVersion:(SDLSyncMsgVersion *)syncMsgVersion {
- [self.parameters sdl_setObject:syncMsgVersion forName:SDLRPCParameterNameSyncMessageVersion];
+ SDLMsgVersion * sdlMsgVersion = [[SDLMsgVersion alloc] initWithMajorVersion:(uint8_t)syncMsgVersion.majorVersion.unsignedIntValue minorVersion:(uint8_t)syncMsgVersion.minorVersion.unsignedIntValue patchVersion:(uint8_t)syncMsgVersion.patchVersion.unsignedIntValue];
+ [self.parameters sdl_setObject:sdlMsgVersion forName:SDLRPCParameterNameSyncMessageVersion];
}
- (SDLSyncMsgVersion *)syncMsgVersion {
- return [self.parameters sdl_objectForName:SDLRPCParameterNameSyncMessageVersion ofClass:SDLSyncMsgVersion.class error:nil];
+ SDLMsgVersion * sdlMsgVersion = [self.parameters sdl_objectForName:SDLRPCParameterNameSyncMessageVersion ofClass:SDLMsgVersion.class error:nil];
+ return [[SDLSyncMsgVersion alloc] initWithMajorVersion:(uint8_t)sdlMsgVersion.majorVersion.unsignedIntValue minorVersion:(uint8_t)sdlMsgVersion.minorVersion.unsignedIntValue patchVersion:(uint8_t)sdlMsgVersion.patchVersion.unsignedIntValue];
+}
+#pragma clang diagnostic pop
+
+- (void)setSdlMsgVersion:(SDLMsgVersion *)sdlMsgVersion {
+ [self.parameters sdl_setObject:sdlMsgVersion forName:SDLRPCParameterNameSyncMessageVersion];
+}
+
+- (SDLMsgVersion *)sdlMsgVersion {
+ return [self.parameters sdl_objectForName:SDLRPCParameterNameSyncMessageVersion ofClass:SDLMsgVersion.class error:nil];
}
- (void)setAppName:(NSString *)appName {
diff --git a/SmartDeviceLink/SDLRegisterAppInterfaceResponse.h b/SmartDeviceLink/SDLRegisterAppInterfaceResponse.h
index 38b61f1a1..331588fa6 100644
--- a/SmartDeviceLink/SDLRegisterAppInterfaceResponse.h
+++ b/SmartDeviceLink/SDLRegisterAppInterfaceResponse.h
@@ -17,6 +17,7 @@
@class SDLPresetBankCapabilities;
@class SDLSoftButtonCapabilities;
@class SDLSyncMsgVersion;
+@class SDLMsgVersion;
@class SDLVehicleType;
@@ -36,7 +37,16 @@ NS_ASSUME_NONNULL_BEGIN
*
* @since SDL 1.0
*/
-@property (nullable, strong, nonatomic) SDLSyncMsgVersion *syncMsgVersion;
+@property (nullable, strong, nonatomic) SDLSyncMsgVersion *syncMsgVersion __deprecated_msg(("Use sdlMsgVersion Instead"));
+
+/**
+ * Specifies the negotiated version number of the SmartDeviceLink protocol that is to be supported by the mobile application.
+ *
+ * SDLMsgVersion, Optional
+ *
+ * @since SDL 1.0
+ */
+@property(nullable, strong, nonatomic) SDLMsgVersion *sdlMsgVersion;
/**
* The currently active VR+TTS language on the module. See "Language" for options.
diff --git a/SmartDeviceLink/SDLRegisterAppInterfaceResponse.m b/SmartDeviceLink/SDLRegisterAppInterfaceResponse.m
index 146491185..e1d174ecf 100644
--- a/SmartDeviceLink/SDLRegisterAppInterfaceResponse.m
+++ b/SmartDeviceLink/SDLRegisterAppInterfaceResponse.m
@@ -14,6 +14,7 @@
#import "SDLPresetBankCapabilities.h"
#import "SDLSoftButtonCapabilities.h"
#import "SDLSyncMsgVersion.h"
+#import "SDLMsgVersion.h"
#import "SDLVehicleType.h"
#import "SDLVrCapabilities.h"
@@ -31,11 +32,31 @@ NS_ASSUME_NONNULL_BEGIN
#pragma clang diagnostic pop
- (void)setSyncMsgVersion:(nullable SDLSyncMsgVersion *)syncMsgVersion {
- [self.parameters sdl_setObject:syncMsgVersion forName:SDLRPCParameterNameSyncMessageVersion];
+ if (syncMsgVersion == nil) {
+ [self.parameters sdl_setObject:nil forName:SDLRPCParameterNameSyncMessageVersion];
+ return;
+ }
+
+ SDLMsgVersion *sdlMsgVersion = [[SDLMsgVersion alloc] initWithMajorVersion:(uint8_t)syncMsgVersion.majorVersion.unsignedIntValue minorVersion:(uint8_t)syncMsgVersion.minorVersion.unsignedIntValue patchVersion:(uint8_t)syncMsgVersion.patchVersion.unsignedIntValue];
+ [self.parameters sdl_setObject:sdlMsgVersion forName:SDLRPCParameterNameSyncMessageVersion];
}
- (nullable SDLSyncMsgVersion *)syncMsgVersion {
- return [self.parameters sdl_objectForName:SDLRPCParameterNameSyncMessageVersion ofClass:SDLSyncMsgVersion.class error:nil];
+ SDLMsgVersion *sdlMsgVersion = [self.parameters sdl_objectForName:SDLRPCParameterNameSyncMessageVersion ofClass:SDLMsgVersion.class error:nil];
+
+ if(sdlMsgVersion == nil) {
+ return [self.parameters sdl_objectForName:SDLRPCParameterNameSyncMessageVersion ofClass:SDLSyncMsgVersion.class error:nil];
+ }
+
+ return [[SDLSyncMsgVersion alloc] initWithMajorVersion:(uint8_t)sdlMsgVersion.majorVersion.unsignedIntValue minorVersion:(uint8_t)sdlMsgVersion.minorVersion.unsignedIntValue patchVersion:(uint8_t)sdlMsgVersion.patchVersion.unsignedIntValue];
+}
+
+- (void)setSdlMsgVersion:(nullable SDLMsgVersion *)sdlMsgVersion {
+ [self.parameters sdl_setObject:sdlMsgVersion forName:SDLRPCParameterNameSyncMessageVersion];
+}
+
+- (nullable SDLMsgVersion *)sdlMsgVersion {
+ return [self.parameters sdl_objectForName:SDLRPCParameterNameSyncMessageVersion ofClass:SDLMsgVersion.class error:nil];
}
- (void)setLanguage:(nullable SDLLanguage)language {
diff --git a/SmartDeviceLink/SDLResponseDispatcher.m b/SmartDeviceLink/SDLResponseDispatcher.m
index 6851a1575..4ac79c8bf 100644
--- a/SmartDeviceLink/SDLResponseDispatcher.m
+++ b/SmartDeviceLink/SDLResponseDispatcher.m
@@ -132,8 +132,12 @@ NS_ASSUME_NONNULL_BEGIN
// When we get disconnected we have to delete all existing responseHandlers as they are not valid anymore
for (SDLRPCCorrelationId *correlationID in self.rpcResponseHandlerMap.dictionaryRepresentation) {
SDLResponseHandler responseHandler = self.rpcResponseHandlerMap[correlationID];
- responseHandler(self.rpcRequestDictionary[correlationID], nil, [NSError sdl_lifecycle_notConnectedError]);
+
+ if (responseHandler != NULL) {
+ responseHandler(self.rpcRequestDictionary[correlationID], nil, [NSError sdl_lifecycle_notConnectedError]);
+ }
}
+
[self.rpcRequestDictionary removeAllObjects];
[self.rpcResponseHandlerMap removeAllObjects];
[self.commandHandlerMap removeAllObjects];
diff --git a/SmartDeviceLink/SDLScreenManager.h b/SmartDeviceLink/SDLScreenManager.h
index 5c1bcaf2f..ec5729d8e 100644
--- a/SmartDeviceLink/SDLScreenManager.h
+++ b/SmartDeviceLink/SDLScreenManager.h
@@ -107,6 +107,11 @@ typedef void(^SDLPreloadChoiceCompletionHandler)(NSError *__nullable error);
*/
@property (copy, nonatomic, nullable) SDLMetadataType textField4Type;
+/**
+ The title of the current template layout.
+ */
+@property (copy, nonatomic, nullable) NSString *title;
+
#pragma mark Soft Buttons
/**
@@ -287,6 +292,19 @@ If set to `SDLDynamicMenuUpdatesModeForceOff`, menu updates will work the legacy
*/
- (void)presentKeyboardWithInitialText:(NSString *)initialText delegate:(id<SDLKeyboardDelegate>)delegate;
+#pragma mark Menu
+/**
+ Present the top-level of your application menu. This method should be called if the menu needs to be opened programmatically because the built in menu button is hidden.
+ */
+- (BOOL)openMenu;
+
+/**
+ Present the application menu. This method should be called if the menu needs to be opened programmatically because the built in menu button is hidden. You must update the menu with the proper cells before calling this method. This RPC will fail if the cell does not contain a sub menu, or is not in the menu array.
+
+@param cell The submenu cell that should be opened as a sub menu, with its sub cells as the options.
+ */
+- (BOOL)openSubmenu:(SDLMenuCell *)cell;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLScreenManager.m b/SmartDeviceLink/SDLScreenManager.m
index c6533a588..282aa122c 100644
--- a/SmartDeviceLink/SDLScreenManager.m
+++ b/SmartDeviceLink/SDLScreenManager.m
@@ -13,7 +13,6 @@
#import "SDLSoftButtonManager.h"
#import "SDLTextAndGraphicManager.h"
#import "SDLVoiceCommandManager.h"
-
NS_ASSUME_NONNULL_BEGIN
@interface SDLScreenManager()
@@ -126,6 +125,10 @@ NS_ASSUME_NONNULL_BEGIN
self.textAndGraphicManager.textField4Type = textField4Type;
}
+- (void)setTitle:(nullable NSString *)title {
+ self.textAndGraphicManager.title = title;
+}
+
- (void)setSoftButtonObjects:(NSArray<SDLSoftButtonObject *> *)softButtonObjects {
self.softButtonManager.softButtonObjects = softButtonObjects;
}
@@ -272,6 +275,17 @@ NS_ASSUME_NONNULL_BEGIN
[self.choiceSetManager presentKeyboardWithInitialText:initialText delegate:delegate];
}
+#pragma mark - Menu
+
+- (BOOL)openMenu {
+ return [self.menuManager openMenu];
+}
+
+- (BOOL)openSubmenu:(SDLMenuCell *)cell {
+ return [self.menuManager openSubmenu:cell];
+}
+
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLShow.h b/SmartDeviceLink/SDLShow.h
index 833a3dea1..e1e360912 100644
--- a/SmartDeviceLink/SDLShow.h
+++ b/SmartDeviceLink/SDLShow.h
@@ -246,6 +246,15 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (strong, nonatomic, nullable) SDLMetadataTags *metadataTags;
+/**
+ The title of the current template.
+
+ How this will be displayed is dependent on the OEM design and implementation of the template.
+
+ Optional, since SmartDeviceLink 6.0
+ */
+@property (strong, nonatomic, nullable) NSString *templateTitle;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLShow.m b/SmartDeviceLink/SDLShow.m
index cb67f1b69..a90949e4f 100644
--- a/SmartDeviceLink/SDLShow.m
+++ b/SmartDeviceLink/SDLShow.m
@@ -204,6 +204,14 @@ NS_ASSUME_NONNULL_BEGIN
return [self.parameters sdl_objectForName:SDLRPCParameterNameMetadataTags ofClass:SDLMetadataTags.class error:nil];
}
+- (void)setTemplateTitle:(nullable NSString *)templateTitle {
+ [self.parameters sdl_setObject:templateTitle forName:SDLRPCParameterNameTemplateTitle];
+}
+
+- (nullable NSString *)templateTitle {
+ return [self.parameters sdl_objectForName:SDLRPCParameterNameTemplateTitle ofClass:NSString.class error:nil];
+}
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLShowAppMenu.h b/SmartDeviceLink/SDLShowAppMenu.h
new file mode 100644
index 000000000..a7ca2cf0f
--- /dev/null
+++ b/SmartDeviceLink/SDLShowAppMenu.h
@@ -0,0 +1,35 @@
+//
+// SDLOpenMenu.h
+// SmartDeviceLink
+//
+// Created by Justin Gluck on 7/12/19.
+// Copyright © 2019 smartdevicelink. All rights reserved.
+//
+
+#import "SDLRPCRequest.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ Used by an app to show the app's menu, typically this is used by a navigation app if the menu button is hidden.
+
+ Added in SmartDeviceLink 6.0
+ */
+@interface SDLShowAppMenu : SDLRPCRequest
+
+/**
+ Creates a ShowAppMenu RPC to open the app menu directly to a AddSubMenu RPC's submenu.
+
+ @param menuID The ID of the AddSubMenu to open
+ @return SDLShowAppMenu RPCRequest
+ */
+- (instancetype)initWithMenuID:(UInt32)menuID;
+
+/**
+ A Menu ID that identifies the AddSubMenu to open if it correlates with the AddSubMenu menuID parameter. If not set the top level menu will be opened.
+ */
+@property (nullable, strong, nonatomic) NSNumber<SDLInt> *menuID;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLShowAppMenu.m b/SmartDeviceLink/SDLShowAppMenu.m
new file mode 100644
index 000000000..d93b8480d
--- /dev/null
+++ b/SmartDeviceLink/SDLShowAppMenu.m
@@ -0,0 +1,48 @@
+//
+// SDLOpenMenu.m
+// SmartDeviceLink
+//
+// Created by Justin Gluck on 7/12/19.
+// Copyright © 2019 smartdevicelink. All rights reserved.
+//
+
+#import "SDLShowAppMenu.h"
+#import "NSMutableDictionary+Store.h"
+#import "SDLRPCParameterNames.h"
+#import "SDLRPCFunctionNames.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@implementation SDLShowAppMenu
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+- (instancetype)init {
+ if (self = [super initWithName:SDLRPCFunctionNameShowAppMenu]) {
+ }
+ return self;
+}
+#pragma clang diagnostic pop
+
+- (instancetype)initWithMenuID:(UInt32)menuID {
+ self = [self init];
+ if (!self) {
+ return nil;
+ }
+
+ self.menuID = @(menuID);
+ return self;
+}
+
+- (void)setMenuID:(nullable NSNumber<SDLInt> *)menuID {
+ [self.parameters sdl_setObject:menuID forName:SDLRPCParameterNameMenuId];
+}
+
+- (nullable NSNumber<SDLInt> *)menuID {
+ NSError *error = nil;
+ return [self.parameters sdl_objectForName:SDLRPCParameterNameMenuId ofClass:NSNumber.class error:&error];
+}
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLShowAppMenuResponse.h b/SmartDeviceLink/SDLShowAppMenuResponse.h
new file mode 100644
index 000000000..d5acd4c34
--- /dev/null
+++ b/SmartDeviceLink/SDLShowAppMenuResponse.h
@@ -0,0 +1,20 @@
+//
+// SDLOpenMenuResponse.h
+// SmartDeviceLink
+//
+// Created by Justin Gluck on 7/12/19.
+// Copyright © 2019 smartdevicelink. All rights reserved.
+//
+
+#import "SDLRPCResponse.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ * Response to the request to show the app menu.
+ */
+@interface SDLShowAppMenuResponse : SDLRPCResponse
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLShowAppMenuResponse.m b/SmartDeviceLink/SDLShowAppMenuResponse.m
new file mode 100644
index 000000000..281079e7b
--- /dev/null
+++ b/SmartDeviceLink/SDLShowAppMenuResponse.m
@@ -0,0 +1,23 @@
+//
+// SDLOpenMenuResponse.m
+// SmartDeviceLink
+//
+// Created by Justin Gluck on 7/12/19.
+// Copyright © 2019 smartdevicelink. All rights reserved.
+//
+
+#import "SDLShowAppMenuResponse.h"
+#import "SDLRPCFunctionNames.h"
+
+@implementation SDLShowAppMenuResponse
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+- (instancetype)init {
+ if (self = [super initWithName:SDLRPCFunctionNameShowAppMenu]) {
+ }
+ return self;
+}
+#pragma clang diagnostic pop
+
+@end
diff --git a/SmartDeviceLink/SDLStreamingMediaManager.h b/SmartDeviceLink/SDLStreamingMediaManager.h
index 8e96e7ebb..989611e80 100644
--- a/SmartDeviceLink/SDLStreamingMediaManager.h
+++ b/SmartDeviceLink/SDLStreamingMediaManager.h
@@ -109,6 +109,11 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (assign, nonatomic) SDLStreamingEncryptionFlag requestedEncryptionType;
+/**
+ When YES, the StreamingMediaManager will send a black screen with "Video Backgrounded String". Defaults to YES.
+ */
+@property (assign, nonatomic) BOOL showVideoBackgroundDisplay;
+
- (instancetype)init NS_UNAVAILABLE;
/**
diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m
index d666a6254..f6eef1c32 100644
--- a/SmartDeviceLink/SDLStreamingMediaManager.m
+++ b/SmartDeviceLink/SDLStreamingMediaManager.m
@@ -163,6 +163,11 @@ NS_ASSUME_NONNULL_BEGIN
return self.videoLifecycleManager.requestedEncryptionType;
}
+- (BOOL)showVideoBackgroundDisplay {
+ // both audio and video managers should have same type
+ return self.videoLifecycleManager.showVideoBackgroundDisplay;
+}
+
#pragma mark - Setters
- (void)setRootViewController:(nullable UIViewController *)rootViewController {
self.videoLifecycleManager.rootViewController = rootViewController;
@@ -173,6 +178,10 @@ NS_ASSUME_NONNULL_BEGIN
self.audioLifecycleManager.requestedEncryptionType = requestedEncryptionType;
}
+- (void)setShowVideoBackgroundDisplay:(BOOL)showVideoBackgroundDisplay {
+ self.videoLifecycleManager.showVideoBackgroundDisplay = showVideoBackgroundDisplay;
+}
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h
index 1d1350469..ca6188904 100644
--- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h
+++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h
@@ -130,6 +130,12 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (assign, nonatomic) SDLStreamingEncryptionFlag requestedEncryptionType;
+/**
+ When YES, the StreamingMediaManager will send a black screen with "Video Backgrounded String". Defaults to YES.
+ */
+@property (assign, nonatomic) BOOL showVideoBackgroundDisplay;
+
+
- (instancetype)init NS_UNAVAILABLE;
/**
diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m
index f483866ec..c0d92c30d 100644
--- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m
+++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m
@@ -122,6 +122,7 @@ typedef void(^SDLVideoCapabilityResponseHandler)(SDLVideoStreamingCapability *_N
_useDisplayLink = configuration.streamingMediaConfig.enableForcedFramerateSync;
_screenSize = SDLDefaultScreenSize;
_backgroundingPixelBuffer = NULL;
+ _showVideoBackgroundDisplay = YES;
_preferredFormatIndex = 0;
_preferredResolutionIndex = 0;
@@ -272,7 +273,9 @@ typedef void(^SDLVideoCapabilityResponseHandler)(SDLVideoStreamingCapability *_N
SDLLogD(@"App became inactive");
if (!self.protocol) { return; }
- [self sdl_sendBackgroundFrames];
+ if (_showVideoBackgroundDisplay) {
+ [self sdl_sendBackgroundFrames];
+ }
[self.touchManager cancelPendingTouches];
if (self.isVideoConnected) {
diff --git a/SmartDeviceLink/SDLSyncMsgVersion.h b/SmartDeviceLink/SDLSyncMsgVersion.h
index 6a920e638..5efcfde38 100644
--- a/SmartDeviceLink/SDLSyncMsgVersion.h
+++ b/SmartDeviceLink/SDLSyncMsgVersion.h
@@ -11,6 +11,7 @@ NS_ASSUME_NONNULL_BEGIN
*
* @since SDL 1.0
*/
+__deprecated_msg("Use SDLMsgVersion instead")
@interface SDLSyncMsgVersion : SDLRPCStruct
- (instancetype)initWithMajorVersion:(UInt8)majorVersion minorVersion:(UInt8)minorVersion patchVersion:(UInt8)patchVersion;
diff --git a/SmartDeviceLink/SDLSyncMsgVersion.m b/SmartDeviceLink/SDLSyncMsgVersion.m
index f7db832c2..b922672ed 100644
--- a/SmartDeviceLink/SDLSyncMsgVersion.m
+++ b/SmartDeviceLink/SDLSyncMsgVersion.m
@@ -9,7 +9,10 @@
NS_ASSUME_NONNULL_BEGIN
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-implementations"
@implementation SDLSyncMsgVersion
+#pragma clang diagnostic pop
- (instancetype)initWithMajorVersion:(UInt8)majorVersion minorVersion:(UInt8)minorVersion patchVersion:(UInt8)patchVersion {
self = [self init];
diff --git a/SmartDeviceLink/SDLTextAndGraphicManager.h b/SmartDeviceLink/SDLTextAndGraphicManager.h
index a3a9c23be..48c9c7332 100644
--- a/SmartDeviceLink/SDLTextAndGraphicManager.h
+++ b/SmartDeviceLink/SDLTextAndGraphicManager.h
@@ -36,6 +36,7 @@ typedef void(^SDLTextAndGraphicUpdateCompletionHandler)(NSError *__nullable erro
@property (copy, nonatomic, nullable) NSString *textField3;
@property (copy, nonatomic, nullable) NSString *textField4;
@property (copy, nonatomic, nullable) NSString *mediaTrackTextField;
+@property (copy, nonatomic, nullable) NSString *title;
@property (strong, nonatomic, nullable) SDLArtwork *primaryGraphic;
@property (strong, nonatomic, nullable) SDLArtwork *secondaryGraphic;
diff --git a/SmartDeviceLink/SDLTextAndGraphicManager.m b/SmartDeviceLink/SDLTextAndGraphicManager.m
index 3c3395f14..5692ddaf3 100644
--- a/SmartDeviceLink/SDLTextAndGraphicManager.m
+++ b/SmartDeviceLink/SDLTextAndGraphicManager.m
@@ -282,6 +282,12 @@ NS_ASSUME_NONNULL_BEGIN
} else {
show.mediaTrack = @"";
}
+
+ if (self.title != nil) {
+ show.templateTitle = self.title;
+ } else {
+ show.templateTitle = @"";
+ }
NSArray *nonNilFields = [self sdl_findNonNilTextFields];
if (nonNilFields.count == 0) { return show; }
@@ -435,6 +441,7 @@ NS_ASSUME_NONNULL_BEGIN
show.mainField3 = @"";
show.mainField4 = @"";
show.mediaTrack = @"";
+ show.templateTitle = @"";
return show;
}
@@ -448,6 +455,7 @@ NS_ASSUME_NONNULL_BEGIN
newShow.mainField3 = show.mainField3;
newShow.mainField4 = show.mainField4;
newShow.mediaTrack = show.mediaTrack;
+ newShow.templateTitle = show.templateTitle;
newShow.metadataTags = show.metadataTags;
return newShow;
@@ -481,6 +489,7 @@ NS_ASSUME_NONNULL_BEGIN
self.currentScreenData.mainField3 = show.mainField3 ?: self.currentScreenData.mainField3;
self.currentScreenData.mainField4 = show.mainField4 ?: self.currentScreenData.mainField4;
self.currentScreenData.mediaTrack = show.mediaTrack ?: self.currentScreenData.mediaTrack;
+ self.currentScreenData.templateTitle = show.templateTitle ?: self.currentScreenData.templateTitle;
self.currentScreenData.metadataTags = show.metadataTags ?: self.currentScreenData.metadataTags;
self.currentScreenData.alignment = show.alignment ?: self.currentScreenData.alignment;
self.currentScreenData.graphic = show.graphic ?: self.currentScreenData.graphic;
@@ -596,6 +605,14 @@ NS_ASSUME_NONNULL_BEGIN
}
}
+- (void)setTitle:(nullable NSString *)title {
+ _title = title;
+ _isDirty = YES;
+ if (!self.isBatchingUpdates) {
+ [self updateWithCompletionHandler:nil];
+ }
+}
+
- (void)setPrimaryGraphic:(nullable SDLArtwork *)primaryGraphic {
_primaryGraphic = primaryGraphic;
_isDirty = YES;
diff --git a/SmartDeviceLink/SDLTextFieldName.h b/SmartDeviceLink/SDLTextFieldName.h
index 74c471657..7827e4e2a 100644
--- a/SmartDeviceLink/SDLTextFieldName.h
+++ b/SmartDeviceLink/SDLTextFieldName.h
@@ -38,6 +38,13 @@ extern SDLTextFieldName const SDLTextFieldNameMainField3;
extern SDLTextFieldName const SDLTextFieldNameMainField4;
/**
+ The title line of the persistent display. Applies to SDLShow.
+
+ @since SDL 6.0
+ */
+extern SDLTextFieldName const SDLTextFieldNameTemplateTitle;
+
+/**
* The status bar on the NGN display. Applies to SDLShow.
*/
extern SDLTextFieldName const SDLTextFieldNameStatusBar;
diff --git a/SmartDeviceLink/SDLTextFieldName.m b/SmartDeviceLink/SDLTextFieldName.m
index 8c597e532..3bb04fd4b 100644
--- a/SmartDeviceLink/SDLTextFieldName.m
+++ b/SmartDeviceLink/SDLTextFieldName.m
@@ -8,6 +8,7 @@ SDLTextFieldName const SDLTextFieldNameMainField1 = @"mainField1";
SDLTextFieldName const SDLTextFieldNameMainField2 = @"mainField2";
SDLTextFieldName const SDLTextFieldNameMainField3 = @"mainField3";
SDLTextFieldName const SDLTextFieldNameMainField4 = @"mainField4";
+SDLTextFieldName const SDLTextFieldNameTemplateTitle = @"templateTitle";
SDLTextFieldName const SDLTextFieldNameStatusBar = @"statusBar";
SDLTextFieldName const SDLTextFieldNameMediaClock = @"mediaClock";
SDLTextFieldName const SDLTextFieldNameMediaTrack = @"mediaTrack";
diff --git a/SmartDeviceLink/SDLTouch.m b/SmartDeviceLink/SDLTouch.m
index e4007471f..d9fa83c7a 100644
--- a/SmartDeviceLink/SDLTouch.m
+++ b/SmartDeviceLink/SDLTouch.m
@@ -58,6 +58,10 @@ NS_ASSUME_NONNULL_BEGIN
return self.identifier == SDLTouchIdentifierSecondFinger;
}
+- (NSString *)description {
+ return [NSString stringWithFormat:@"SDLTouch: ID: %ld, Location: %@, Timestamp: %lu, firstFinger? %@, secondFinger? %@", (long)_identifier, NSStringFromCGPoint(_location), (unsigned long)_timeStamp, (self.isFirstFinger ? @"YES" : @"NO"), (self.isSecondFinger ? @"YES" : @"NO")];
+}
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLTouchManager.m b/SmartDeviceLink/SDLTouchManager.m
index 9a66d81e4..1f4f4adea 100644
--- a/SmartDeviceLink/SDLTouchManager.m
+++ b/SmartDeviceLink/SDLTouchManager.m
@@ -9,8 +9,8 @@
#import "SDLTouchManager.h"
#import "CGPoint_Util.h"
-#import "dispatch_timer.h"
+#import "SDLGlobals.h"
#import "SDLFocusableItemHitTester.h"
#import "SDLLogMacros.h"
#import "SDLNotificationConstants.h"
@@ -75,7 +75,7 @@ static NSUInteger const MaximumNumberOfTouches = 2;
* @abstract
* Timer used for distinguishing between single & double taps.
*/
-@property (nonatomic, strong, nullable) dispatch_source_t singleTapTimer;
+@property (nonatomic, strong, nullable) NSTimer *singleTapTimer;
/*!
* @abstract
@@ -131,39 +131,43 @@ static NSUInteger const MaximumNumberOfTouches = 2;
return;
}
- dispatch_async(dispatch_get_main_queue(), ^{
- if (self.performingTouchType == SDLPerformingTouchTypePanningTouch) {
- CGPoint storedTouchLocation = self.lastStoredTouchLocation;
- CGPoint notifiedTouchLocation = self.lastNotifiedTouchLocation;
+ if (self.performingTouchType == SDLPerformingTouchTypePanningTouch) {
+ CGPoint storedTouchLocation = self.lastStoredTouchLocation;
+ CGPoint notifiedTouchLocation = self.lastNotifiedTouchLocation;
- if (CGPointEqualToPoint(storedTouchLocation, CGPointZero) ||
- CGPointEqualToPoint(notifiedTouchLocation, CGPointZero) ||
- CGPointEqualToPoint(storedTouchLocation, notifiedTouchLocation)) {
- return;
- }
+ if (CGPointEqualToPoint(storedTouchLocation, CGPointZero) ||
+ CGPointEqualToPoint(notifiedTouchLocation, CGPointZero) ||
+ CGPointEqualToPoint(storedTouchLocation, notifiedTouchLocation)) {
+ return;
+ }
- if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:didReceivePanningFromPoint:toPoint:)]) {
+ if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:didReceivePanningFromPoint:toPoint:)]) {
+ dispatch_async(dispatch_get_main_queue(), ^{
[self.touchEventDelegate touchManager:self
didReceivePanningFromPoint:notifiedTouchLocation
toPoint:storedTouchLocation];
self.lastNotifiedTouchLocation = storedTouchLocation;
- }
- } else if (self.performingTouchType == SDLPerformingTouchTypeMultiTouch) {
- if (self.previousPinchDistance == self.currentPinchGesture.distance) {
- return;
- }
+ });
+ }
+ } else if (self.performingTouchType == SDLPerformingTouchTypeMultiTouch) {
+ if (self.previousPinchDistance == self.currentPinchGesture.distance) {
+ return;
+ }
- if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:didReceivePinchAtCenterPoint:withScale:)]) {
- CGFloat scale = self.currentPinchGesture.distance / self.previousPinchDistance;
+ if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:didReceivePinchAtCenterPoint:withScale:)]) {
+
+ CGFloat scale = self.currentPinchGesture.distance / self.previousPinchDistance;
+ CGPoint center = self.currentPinchGesture.center;
+ dispatch_async(dispatch_get_main_queue(), ^{
[self.touchEventDelegate touchManager:self
- didReceivePinchAtCenterPoint:self.currentPinchGesture.center
+ didReceivePinchAtCenterPoint:center
withScale:scale];
- }
-
- self.previousPinchDistance = self.currentPinchGesture.distance;
+ });
}
- });
+
+ self.previousPinchDistance = self.currentPinchGesture.distance;
+ }
}
#pragma mark - SDLDidReceiveTouchEventNotification
@@ -186,25 +190,25 @@ static NSUInteger const MaximumNumberOfTouches = 2;
[onTouchEvent.event enumerateObjectsUsingBlock:^(SDLTouchEvent *touchEvent, NSUInteger idx, BOOL *stop) {
SDLTouch *touch = [[SDLTouch alloc] initWithTouchEvent:touchEvent];
- if (self.touchEventHandler) {
- self.touchEventHandler(touch, touchType);
+ if (self.touchEventHandler != NULL) {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ self.touchEventHandler(touch, touchType);
+ });
}
if (!self.touchEventDelegate || (touch.identifier > MaximumNumberOfTouches)) {
return;
}
- dispatch_async(dispatch_get_main_queue(), ^{
- if ([onTouchEvent.type isEqualToEnum:SDLTouchTypeBegin]) {
- [self sdl_handleTouchBegan:touch];
- } else if ([onTouchEvent.type isEqualToEnum:SDLTouchTypeMove]) {
- [self sdl_handleTouchMoved:touch];
- } else if ([onTouchEvent.type isEqualToEnum:SDLTouchTypeEnd]) {
- [self sdl_handleTouchEnded:touch];
- } else if ([onTouchEvent.type isEqualToEnum:SDLTouchTypeCancel]) {
- [self sdl_handleTouchCanceled:touch];
- }
- });
+ if ([onTouchEvent.type isEqualToEnum:SDLTouchTypeBegin]) {
+ [self sdl_handleTouchBegan:touch];
+ } else if ([onTouchEvent.type isEqualToEnum:SDLTouchTypeMove]) {
+ [self sdl_handleTouchMoved:touch];
+ } else if ([onTouchEvent.type isEqualToEnum:SDLTouchTypeEnd]) {
+ [self sdl_handleTouchEnded:touch];
+ } else if ([onTouchEvent.type isEqualToEnum:SDLTouchTypeCancel]) {
+ [self sdl_handleTouchCanceled:touch];
+ }
}];
}
@@ -227,8 +231,11 @@ static NSUInteger const MaximumNumberOfTouches = 2;
self.currentPinchGesture = [[SDLPinchGesture alloc] initWithFirstTouch:self.previousTouch secondTouch:touch];
self.previousPinchDistance = self.currentPinchGesture.distance;
if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:pinchDidStartInView:atCenterPoint:)]) {
- UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:self.currentPinchGesture.center] : nil;
- [self.touchEventDelegate touchManager:self pinchDidStartInView:hitView atCenterPoint:self.currentPinchGesture.center];
+ CGPoint center = self.currentPinchGesture.center;
+ dispatch_async(dispatch_get_main_queue(), ^{
+ UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:center] : nil;
+ [self.touchEventDelegate touchManager:self pinchDidStartInView:hitView atCenterPoint:center];
+ });
}
} break;
}
@@ -275,8 +282,10 @@ static NSUInteger const MaximumNumberOfTouches = 2;
_performingTouchType = SDLPerformingTouchTypePanningTouch;
if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:panningDidStartInView:atPoint:)]) {
- UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:touch.location] : nil;
- [self.touchEventDelegate touchManager:self panningDidStartInView:hitView atPoint:touch.location];
+ dispatch_async(dispatch_get_main_queue(), ^{
+ UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:touch.location] : nil;
+ [self.touchEventDelegate touchManager:self panningDidStartInView:hitView atPoint:touch.location];
+ });
}
} break;
case SDLPerformingTouchTypePanningTouch: {
@@ -302,9 +311,11 @@ static NSUInteger const MaximumNumberOfTouches = 2;
[self sdl_setMultiTouchFingerTouchForTouch:touch];
if (self.currentPinchGesture.isValid) {
if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:pinchDidEndInView:atCenterPoint:)]) {
- UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:self.currentPinchGesture.center] : nil;
- [self.touchEventDelegate touchManager:self pinchDidEndInView:hitView atCenterPoint:self.currentPinchGesture.center];
- self.currentPinchGesture = nil;
+ dispatch_async(dispatch_get_main_queue(), ^{
+ UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:self.currentPinchGesture.center] : nil;
+ [self.touchEventDelegate touchManager:self pinchDidEndInView:hitView atCenterPoint:self.currentPinchGesture.center];
+ self.currentPinchGesture = nil;
+ });
} else {
self.currentPinchGesture = nil;
}
@@ -312,8 +323,10 @@ static NSUInteger const MaximumNumberOfTouches = 2;
} break;
case SDLPerformingTouchTypePanningTouch: {
if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:panningDidEndInView:atPoint:)]) {
- UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:touch.location] : nil;
- [self.touchEventDelegate touchManager:self panningDidEndInView:hitView atPoint:touch.location];
+ dispatch_async(dispatch_get_main_queue(), ^{
+ UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:touch.location] : nil;
+ [self.touchEventDelegate touchManager:self panningDidEndInView:hitView atPoint:touch.location];
+ });
}
} break;
case SDLPerformingTouchTypeSingleTouch: {
@@ -333,8 +346,10 @@ static NSUInteger const MaximumNumberOfTouches = 2;
CGPoint centerPoint = CGPointCenterOfPoints(touch.location,
self.singleTapTouch.location);
if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:didReceiveDoubleTapForView:atPoint:)]) {
- UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:centerPoint] : nil;
- [self.touchEventDelegate touchManager:self didReceiveDoubleTapForView:hitView atPoint:centerPoint];
+ dispatch_async(dispatch_get_main_queue(), ^{
+ UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:centerPoint] : nil;
+ [self.touchEventDelegate touchManager:self didReceiveDoubleTapForView:hitView atPoint:centerPoint];
+ });
}
}
@@ -368,16 +383,21 @@ static NSUInteger const MaximumNumberOfTouches = 2;
[self sdl_setMultiTouchFingerTouchForTouch:touch];
if (self.currentPinchGesture.isValid) {
if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:pinchCanceledAtCenterPoint:)]) {
- [self.touchEventDelegate touchManager:self
- pinchCanceledAtCenterPoint:self.currentPinchGesture.center];
+ CGPoint center = self.currentPinchGesture.center;
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [self.touchEventDelegate touchManager:self
+ pinchCanceledAtCenterPoint:center];
+ });
}
self.currentPinchGesture = nil;
}
} break;
case SDLPerformingTouchTypePanningTouch: {
if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:panningCanceledAtPoint:)]) {
- [self.touchEventDelegate touchManager:self
- panningCanceledAtPoint:touch.location];
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [self.touchEventDelegate touchManager:self
+ panningCanceledAtPoint:touch.location];
+ });
}
} break;
case SDLPerformingTouchTypeSingleTouch: // fallthrough
@@ -413,18 +433,32 @@ static NSUInteger const MaximumNumberOfTouches = 2;
* @param point Screen coordinates of the tap gesture
*/
- (void)sdl_initializeSingleTapTimerAtPoint:(CGPoint)point {
- __weak typeof(self) weakSelf = self;
- self.singleTapTimer = dispatch_create_timer(self.tapTimeThreshold, NO, ^{
- // If timer was not canceled by a second tap then only one tap detected
- typeof(weakSelf) strongSelf = weakSelf;
- strongSelf.singleTapTouch = nil;
- [strongSelf sdl_cancelSingleTapTimer];
- if ([strongSelf.touchEventDelegate respondsToSelector:@selector(touchManager:didReceiveSingleTapForView:atPoint:)]) {
+ if (self.singleTapTimer != nil) {
+ [self sdl_cancelSingleTapTimer];
+ }
+
+ self.singleTapTimer = [NSTimer timerWithTimeInterval:self.tapTimeThreshold target:self selector:@selector(sdl_singleTapTimerCallback:) userInfo:@{@"point": [NSValue valueWithCGPoint:point]} repeats:NO];
+ [[NSRunLoop mainRunLoop] addTimer:self.singleTapTimer forMode:NSRunLoopCommonModes];
+}
+
+/**
+ The method that will be called when the timer fires that was started in `sdl_initializeSingleTapTimerAtPoint:`.
+
+ This is called on the main thread based on `sdl_initializeSingleTapTimerAtPoint:`
+
+ @param timer The timer that was fired
+ */
+- (void)sdl_singleTapTimerCallback:(NSTimer *)timer {
+ CGPoint point = ((NSValue *)timer.userInfo[@"point"]).CGPointValue;
+ self.singleTapTouch = nil;
+ [self sdl_cancelSingleTapTimer];
+ if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:didReceiveSingleTapForView:atPoint:)]) {
+ dispatch_async(dispatch_get_main_queue(), ^{
[self sdl_getSingleTapHitView:point hitViewHandler:^(UIView * _Nullable selectedView) {
- [strongSelf.touchEventDelegate touchManager:strongSelf didReceiveSingleTapForView:selectedView atPoint:point];
+ [self.touchEventDelegate touchManager:self didReceiveSingleTapForView:selectedView atPoint:point];
}];
- }
- });
+ });
+ }
}
/**
@@ -441,24 +475,22 @@ static NSUInteger const MaximumNumberOfTouches = 2;
return hitViewHandler(nil);
}
- dispatch_async(dispatch_get_main_queue(), ^{
- UIView *hitView = [self.hitTester viewForPoint:point];
- dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
- if (!hitViewHandler) { return; }
- return hitViewHandler(hitView);
- });
- });
+ UIView *hitView = [self.hitTester viewForPoint:point];
+ if (!hitViewHandler) { return; }
+
+ return hitViewHandler(hitView);
}
/**
* Cancels a tap gesture timer
*/
- (void)sdl_cancelSingleTapTimer {
- if (self.singleTapTimer == NULL) {
+ if (self.singleTapTimer == nil) {
return;
}
- dispatch_stop_timer(self.singleTapTimer);
- self.singleTapTimer = NULL;
+
+ [self.singleTapTimer invalidate];
+ self.singleTapTimer = nil;
}
@end
diff --git a/SmartDeviceLink/SDLUnpublishAppService.h b/SmartDeviceLink/SDLUnpublishAppService.h
new file mode 100644
index 000000000..56e1f12b7
--- /dev/null
+++ b/SmartDeviceLink/SDLUnpublishAppService.h
@@ -0,0 +1,34 @@
+//
+// SDLUnpublishAppService.h
+// SmartDeviceLink
+//
+// Created by Bretty White on 7/15/19.
+// Copyright © 2019 smartdevicelink. All rights reserved.
+//
+
+#import "SDLRPCRequest.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ * Unpublish an existing service published by this application.
+ */
+@interface SDLUnpublishAppService : SDLRPCRequest
+
+/**
+ * Create an instance of UnpublishAppService with the serviceID that corresponds with the service to be unpublished
+ *
+ * @param serviceID The ID of the service to be unpublished.
+ */
+- (instancetype)initWithServiceID:(NSString*)serviceID;
+
+/**
+ * The ID of the service to be unpublished.
+ *
+ * Required, String
+ */
+@property (strong, nonatomic) NSString *serviceID;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLUnpublishAppService.m b/SmartDeviceLink/SDLUnpublishAppService.m
new file mode 100644
index 000000000..3da728501
--- /dev/null
+++ b/SmartDeviceLink/SDLUnpublishAppService.m
@@ -0,0 +1,49 @@
+//
+// SDLUnpublishAppService.m
+// SmartDeviceLink
+//
+// Created by Bretty White on 7/15/19.
+// Copyright © 2019 smartdevicelink. All rights reserved.
+//
+
+#import "NSMutableDictionary+Store.h"
+#import "SDLUnpublishAppService.h"
+#import "SDLRPCFunctionNames.h"
+#import "SDLRPCParameterNames.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@implementation SDLUnpublishAppService
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+- (instancetype)init {
+ if (self = [super initWithName:SDLRPCFunctionNameUnpublishAppService]) {
+ }
+ return self;
+}
+#pragma clang diagnostic pop
+
+- (instancetype)initWithServiceID:(NSString *)serviceID {
+ self = [self init];
+ if (!self) {
+ return nil;
+ }
+
+ self.serviceID = serviceID;
+
+ return self;
+}
+
+- (void)setServiceID:(NSString *)serviceID {
+ [self.parameters sdl_setObject:serviceID forName:SDLRPCParameterNameServiceID];
+}
+
+- (NSString *)serviceID {
+ NSError *error = nil;
+ return [self.parameters sdl_objectForName:SDLRPCParameterNameServiceID ofClass:NSString.class error:&error];
+}
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLUnpublishAppServiceResponse.h b/SmartDeviceLink/SDLUnpublishAppServiceResponse.h
new file mode 100644
index 000000000..fb048ca4b
--- /dev/null
+++ b/SmartDeviceLink/SDLUnpublishAppServiceResponse.h
@@ -0,0 +1,20 @@
+//
+// SDLUnpublishAppServiceResponse.h
+// SmartDeviceLink
+//
+// Created by Bretty White on 7/15/19.
+// Copyright © 2019 smartdevicelink. All rights reserved.
+//
+
+#import "SDLRPCResponse.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ * The response to UnpublishAppService
+ */
+@interface SDLUnpublishAppServiceResponse : SDLRPCResponse
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLUnpublishAppServiceResponse.m b/SmartDeviceLink/SDLUnpublishAppServiceResponse.m
new file mode 100644
index 000000000..db26d0610
--- /dev/null
+++ b/SmartDeviceLink/SDLUnpublishAppServiceResponse.m
@@ -0,0 +1,27 @@
+//
+// SDLUnpublishAppServiceResponse.m
+// SmartDeviceLink
+//
+// Created by Bretty White on 7/15/19.
+// Copyright © 2019 smartdevicelink. All rights reserved.
+//
+
+#import "SDLUnpublishAppServiceResponse.h"
+#import "SDLRPCFunctionNames.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@implementation SDLUnpublishAppServiceResponse
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+- (instancetype)init {
+ if (self = [super initWithName:SDLRPCFunctionNameUnpublishAppService]) {
+ }
+ return self;
+}
+#pragma clang diagnostic pop
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLUploadFileOperation.h b/SmartDeviceLink/SDLUploadFileOperation.h
index 40c4b36c4..cd3eaa4af 100644
--- a/SmartDeviceLink/SDLUploadFileOperation.h
+++ b/SmartDeviceLink/SDLUploadFileOperation.h
@@ -31,6 +31,8 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (instancetype)initWithFile:(SDLFileWrapper *)file connectionManager:(id<SDLConnectionManagerType>)connectionManager;
+@property (nonatomic, strong, readonly) SDLFileWrapper *fileWrapper;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLUploadFileOperation.m b/SmartDeviceLink/SDLUploadFileOperation.m
index 620d0f833..f9edfe2f5 100644
--- a/SmartDeviceLink/SDLUploadFileOperation.m
+++ b/SmartDeviceLink/SDLUploadFileOperation.m
@@ -24,7 +24,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface SDLUploadFileOperation ()
-@property (strong, nonatomic) SDLFileWrapper *fileWrapper;
+@property (strong, nonatomic, readwrite) SDLFileWrapper *fileWrapper;
@property (weak, nonatomic) id<SDLConnectionManagerType> connectionManager;
@property (strong, nonatomic) NSInputStream *inputStream;
@@ -70,21 +70,25 @@ NS_ASSUME_NONNULL_BEGIN
__block NSInteger highestCorrelationIDReceived = -1;
if (self.isCancelled) {
+ completion(NO, bytesAvailable, [NSError sdl_fileManager_fileUploadCanceled]);
[self finishOperation];
- return completion(NO, bytesAvailable, [NSError sdl_fileManager_fileUploadCanceled]);
+ return;
}
if (file == nil) {
+ completion(NO, bytesAvailable, [NSError sdl_fileManager_fileDoesNotExistError]);
[self finishOperation];
- return completion(NO, bytesAvailable, [NSError sdl_fileManager_fileDoesNotExistError]);
+ return;
}
self.inputStream = [self sdl_openInputStreamWithFile:file];
if (self.inputStream == nil || ![self.inputStream hasBytesAvailable]) {
// If the file does not exist or the passed data is nil, return an error
[self sdl_closeInputStream];
+
+ completion(NO, bytesAvailable, [NSError sdl_fileManager_fileDoesNotExistError]);
[self finishOperation];
- return completion(NO, bytesAvailable, [NSError sdl_fileManager_fileDoesNotExistError]);
+ return;
}
dispatch_group_t putFileGroup = dispatch_group_create();
@@ -92,7 +96,7 @@ NS_ASSUME_NONNULL_BEGIN
// Wait for all packets be sent before returning whether or not the upload was a success
__weak typeof(self) weakself = self;
- dispatch_group_notify(putFileGroup, dispatch_get_main_queue(), ^{
+ dispatch_group_notify(putFileGroup, [SDLGlobals sharedGlobals].sdlProcessingQueue, ^{
typeof(weakself) strongself = weakself;
[weakself sdl_closeInputStream];
@@ -101,6 +105,7 @@ NS_ASSUME_NONNULL_BEGIN
} else {
completion(YES, bytesAvailable, nil);
}
+
[weakself finishOperation];
});
@@ -259,7 +264,7 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Property Overrides
- (nullable NSString *)name {
- return self.fileWrapper.file.name;
+ return [NSString stringWithFormat:@"%@ - %@", self.class, self.fileWrapper.file.name];
}
- (NSOperationQueuePriority)queuePriority {
diff --git a/SmartDeviceLink/SDLVersion.h b/SmartDeviceLink/SDLVersion.h
index 02a4feb68..54d1ac776 100644
--- a/SmartDeviceLink/SDLVersion.h
+++ b/SmartDeviceLink/SDLVersion.h
@@ -9,6 +9,7 @@
#import <Foundation/Foundation.h>
@class SDLSyncMsgVersion;
+@class SDLMsgVersion;
NS_ASSUME_NONNULL_BEGIN
@@ -24,8 +25,13 @@ NS_ASSUME_NONNULL_BEGIN
+ (instancetype)versionWithMajor:(NSUInteger)major minor:(NSUInteger)minor patch:(NSUInteger)patch;
- (nullable instancetype)initWithString:(NSString *)versionString;
+ (nullable instancetype)versionWithString:(NSString *)versionString;
-- (instancetype)initWithSyncMsgVersion:(SDLSyncMsgVersion *)syncMsgVersion;
-+ (instancetype)versionWithSyncMsgVersion:(SDLSyncMsgVersion *)syncMsgVersion;
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-implementations"
+- (instancetype)initWithSyncMsgVersion:(SDLSyncMsgVersion *)syncMsgVersion __deprecated_msg(("Use initWithSDLMsgVersion:sdlMsgVersion: instead"));
++ (instancetype)versionWithSyncMsgVersion:(SDLSyncMsgVersion *)syncMsgVersion __deprecated_msg(("Use versionWithSDLMsgVersion:sdlMsgVersion instead"));
+#pragma clang diagnostic pop
+- (instancetype)initWithSDLMsgVersion:(SDLMsgVersion *)sdlMsgVersion;
++ (instancetype)versionWithSDLMsgVersion:(SDLMsgVersion *)sdlMsgVersion;
- (NSComparisonResult)compare:(SDLVersion *)otherVersion;
- (BOOL)isLessThanVersion:(SDLVersion *)otherVersion;
diff --git a/SmartDeviceLink/SDLVersion.m b/SmartDeviceLink/SDLVersion.m
index 0dd4173cb..9ec3e4824 100644
--- a/SmartDeviceLink/SDLVersion.m
+++ b/SmartDeviceLink/SDLVersion.m
@@ -9,6 +9,8 @@
#import "SDLVersion.h"
#import "SDLSyncMsgVersion.h"
+#import "SDLMsgVersion.h"
+
NS_ASSUME_NONNULL_BEGIN
@@ -76,6 +78,21 @@ NS_ASSUME_NONNULL_BEGIN
return [[self alloc] initWithSyncMsgVersion:syncMsgVersion];
}
+- (instancetype)initWithSDLMsgVersion:(SDLMsgVersion *)sdlMsgVersion {
+ self = [super init];
+ if (!self) { return nil; }
+
+ _major = sdlMsgVersion.majorVersion.unsignedIntegerValue;
+ _minor = sdlMsgVersion.minorVersion.unsignedIntegerValue;
+ _patch = sdlMsgVersion.patchVersion.unsignedIntegerValue;
+
+ return self;
+}
+
++ (instancetype)versionWithSDLMsgVersion:(SDLMsgVersion *)sdlMsgVersion {
+ return [[self alloc] initWithSDLMsgVersion:sdlMsgVersion];
+}
+
#pragma mark - Setters / Getters
- (NSString *)stringVersion {
diff --git a/SmartDeviceLink/SmartDeviceLink.h b/SmartDeviceLink/SmartDeviceLink.h
index 2c0e8778e..97d91a6a6 100644
--- a/SmartDeviceLink/SmartDeviceLink.h
+++ b/SmartDeviceLink/SmartDeviceLink.h
@@ -62,6 +62,7 @@ FOUNDATION_EXPORT const unsigned char SmartDeviceLinkVersionString[];
#import "SDLSetInteriorVehicleData.h"
#import "SDLSetMediaClockTimer.h"
#import "SDLShow.h"
+#import "SDLShowAppMenu.h"
#import "SDLShowConstantTBT.h"
#import "SDLSlider.h"
#import "SDLSpeak.h"
@@ -70,6 +71,7 @@ FOUNDATION_EXPORT const unsigned char SmartDeviceLinkVersionString[];
#import "SDLSubscribeWayPoints.h"
#import "SDLSyncPData.h"
#import "SDLSystemRequest.h"
+#import "SDLUnpublishAppService.h"
#import "SDLUnregisterAppInterface.h"
#import "SDLUnsubscribeButton.h"
#import "SDLUnsubscribeVehicleData.h"
@@ -122,12 +124,14 @@ FOUNDATION_EXPORT const unsigned char SmartDeviceLinkVersionString[];
#import "SDLSetMediaClockTimerResponse.h"
#import "SDLShowConstantTBTResponse.h"
#import "SDLShowResponse.h"
+#import "SDLShowAppMenuResponse.h"
#import "SDLSliderResponse.h"
#import "SDLSpeakResponse.h"
#import "SDLSubscribeButtonResponse.h"
#import "SDLSubscribeVehicleDataResponse.h"
#import "SDLSubscribeWayPointsResponse.h"
#import "SDLSyncPDataResponse.h"
+#import "SDLUnpublishAppServiceResponse.h"
#import "SDLUnregisterAppInterfaceResponse.h"
#import "SDLUnsubscribeButtonResponse.h"
#import "SDLUnsubscribeVehicleDataResponse.h"
@@ -238,6 +242,7 @@ FOUNDATION_EXPORT const unsigned char SmartDeviceLinkVersionString[];
#import "SDLStartTime.h"
#import "SDLStationIDNumber.h"
#import "SDLSyncMsgVersion.h"
+#import "SDLMsgVersion.h"
#import "SDLSystemCapability.h"
#import "SDLTTSChunk.h"
#import "SDLTemperature.h"
diff --git a/SmartDeviceLink/dispatch_timer.h b/SmartDeviceLink/dispatch_timer.h
deleted file mode 100644
index 1dd8bb9f2..000000000
--- a/SmartDeviceLink/dispatch_timer.h
+++ /dev/null
@@ -1,18 +0,0 @@
-//
-// dispatch_timer.h
-// MobileNav
-//
-// Created by Muller, Alexander (A.) on 5/12/16.
-// Copyright © 2016 Alex Muller. All rights reserved.
-//
-
-#ifndef dispatch_timer_h
-#define dispatch_timer_h
-
-#include <dispatch/dispatch.h>
-#include <stdio.h>
-
-dispatch_source_t dispatch_create_timer(double afterInterval, bool repeating, dispatch_block_t block);
-void dispatch_stop_timer(dispatch_source_t timer);
-
-#endif /* dispatch_timer_h */
diff --git a/SmartDeviceLink/dispatch_timer.m b/SmartDeviceLink/dispatch_timer.m
deleted file mode 100644
index 445095eb6..000000000
--- a/SmartDeviceLink/dispatch_timer.m
+++ /dev/null
@@ -1,38 +0,0 @@
-//
-// dispatch_timer.c
-// MobileNav
-//
-// Created by Muller, Alexander (A.) on 5/12/16.
-// Copyright © 2016 Alex Muller. All rights reserved.
-//
-
-#include "dispatch_timer.h"
-
-dispatch_source_t dispatch_create_timer(double afterInterval, bool repeating, dispatch_block_t block) {
- dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
- 0);
- dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,
- 0,
- 0,
- queue);
- dispatch_source_set_timer(timer,
- dispatch_time(DISPATCH_TIME_NOW, (int64_t)(afterInterval * NSEC_PER_SEC)),
- (uint64_t)(afterInterval * NSEC_PER_SEC),
- (1ull * NSEC_PER_SEC) / 10);
- dispatch_source_set_event_handler(timer, ^{
- if (!repeating) {
- dispatch_stop_timer(timer);
- }
- if (block) {
- block();
- }
- });
- dispatch_resume(timer);
-
- return timer;
-}
-
-void dispatch_stop_timer(dispatch_source_t timer) {
- dispatch_source_set_event_handler(timer, NULL);
- dispatch_source_cancel(timer);
-}
diff --git a/SmartDeviceLinkSwift/Info.plist b/SmartDeviceLinkSwift/Info.plist
index 93c3f315c..5286dd4de 100644
--- a/SmartDeviceLinkSwift/Info.plist
+++ b/SmartDeviceLinkSwift/Info.plist
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
- <string>6.3.0</string>
+ <string>6.3.1</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLAsynchronousRPCRequestOperationSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLAsynchronousRPCRequestOperationSpec.m
index 7cec8f3e5..9a80d5fd4 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLAsynchronousRPCRequestOperationSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLAsynchronousRPCRequestOperationSpec.m
@@ -45,21 +45,21 @@ describe(@"sending asynchronous requests", ^{
});
it(@"should correctly send all requests", ^{
- testOperation = [[SDLAsynchronousRPCRequestOperation alloc] initWithConnectionManager:testConnectionManager requests:sendRequests.copy progressHandler:^(__kindof SDLRPCRequest * _Nonnull request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error, float percentComplete) {
- TestRequestProgressResponse *progressResponse = testProgressResponses[request.correlationID];
-
- expect(progressResponse.percentComplete).to(beCloseTo(percentComplete));
- expect(response).toNot(beNil());
- expect(error).to(beNil());
+ __block NSError *testError = nil;
+ __block BOOL testSuccess = NO;
- [resultResponses addObject:response];
+ testOperation = [[SDLAsynchronousRPCRequestOperation alloc] initWithConnectionManager:testConnectionManager requests:sendRequests.copy progressHandler:^(__kindof SDLRPCRequest * _Nonnull request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error, float percentComplete) {
+ if (testError == nil) { testError = error; }
+ if (response != nil) { [resultResponses addObject:response]; }
} completionHandler:^(BOOL success) {
- expect(resultResponses).to(haveCount(3));
- expect(success).to(beTruthy());
+ testSuccess = success;
}];
[testOperationQueue addOperation:testOperation];
[NSThread sleepForTimeInterval:0.5];
+
+ expect(testSuccess).toEventually(beTruthy());
+ expect(testError).toEventually(beNil());
});
});
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLFileManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLFileManagerSpec.m
index c7dd86483..5cb8377f4 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLFileManagerSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLFileManagerSpec.m
@@ -3,11 +3,13 @@
#import <OCMock/OCMock.h>
#import "SDLDeleteFileResponse.h"
+#import "SDLDeleteFileOperation.h"
#import "SDLError.h"
#import "SDLFile.h"
#import "SDLFileManager.h"
#import "SDLFileManagerConfiguration.h"
#import "SDLFileType.h"
+#import "SDLFileWrapper.h"
#import "SDLListFiles.h"
#import "SDLListFilesOperation.h"
#import "SDLListFilesResponse.h"
@@ -16,6 +18,7 @@
#import "SDLPutFileResponse.h"
#import "SDLRPCResponse.h"
#import "SDLStateMachine.h"
+#import "SDLUploadFileOperation.h"
#import "TestConnectionManager.h"
#import "TestMultipleFilesConnectionManager.h"
#import "TestFileProgressResponse.h"
@@ -28,6 +31,10 @@ SDLFileManagerState *const SDLFileManagerStateReady = @"Ready";
SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
@interface SDLFileManager ()
+
+@property (strong, nonatomic) NSMutableSet<SDLFileName *> *mutableRemoteFileNames;
+@property (assign, nonatomic, readwrite) NSUInteger bytesAvailable;
+
@property (strong, nonatomic) NSOperationQueue *transactionQueue;
@property (strong, nonatomic) NSMutableSet<SDLFileName *> *uploadedEphemeralFileNames;
@property (strong, nonatomic) NSMutableDictionary<SDLFileName *, NSNumber<SDLUInt> *> *failedFileUploadsCount;
@@ -35,44 +42,68 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
@property (assign, nonatomic) UInt8 maxArtworkUploadAttempts;
@property (strong, nonatomic) SDLStateMachine *stateMachine;
+// List files helper
+- (void)sdl_listRemoteFilesWithCompletionHandler:(SDLFileManagerListFilesCompletionHandler)handler;
+
- (BOOL)sdl_canFileBeUploadedAgain:(nullable SDLFile *)file maxUploadCount:(int)maxRetryCount failedFileUploadsCount:(NSMutableDictionary<SDLFileName *, NSNumber<SDLUInt> *> *)failedFileUploadsCount;
+ (NSMutableDictionary<SDLFileName *, NSNumber<SDLUInt> *> *)sdl_incrementFailedUploadCountForFileName:(SDLFileName *)fileName failedFileUploadsCount:(NSMutableDictionary<SDLFileName *, NSNumber<SDLUInt> *> *)failedFileUploadsCount;
@end
+@interface FileManagerSpecHelper : NSObject
+
+@end
+
+@implementation FileManagerSpecHelper
+
++ (NSArray<UIImage *> *)imagesForCount:(NSUInteger)count {
+ NSMutableArray<UIImage *> *images = [NSMutableArray arrayWithCapacity:count];
+ for (NSUInteger i = 0; i < count; i++) {
+ UIGraphicsBeginImageContextWithOptions(CGSizeMake(5, 5), YES, 0);
+ CGContextRef context = UIGraphicsGetCurrentContext();
+ CGFloat grey = (i % 255) / 255.0;
+ [[UIColor colorWithRed:grey green:grey blue:grey alpha:1.0] setFill];
+ CGContextFillRect(context, CGRectMake(0, 0, i + 1, i + 1));
+ UIImage *graySquareImage = UIGraphicsGetImageFromCurrentImageContext();
+ UIGraphicsEndImageContext();
+
+ [images addObject:graySquareImage];
+ }
+
+ return [images copy];
+}
+
+@end
+
QuickSpecBegin(SDLFileManagerSpec)
-describe(@"SDLFileManager", ^{
+describe(@"uploading / deleting single files with the file manager", ^{
__block TestConnectionManager *testConnectionManager = nil;
__block SDLFileManager *testFileManager = nil;
__block SDLFileManagerConfiguration *testFileManagerConfiguration = nil;
- __block NSUInteger initialSpaceAvailable = 250;
+ NSUInteger initialSpaceAvailable = 250;
+ NSUInteger failureSpaceAvailabe = 2000000000;
+ NSUInteger newBytesAvailable = 750;
+ NSArray<NSString *> *testInitialFileNames = @[@"testFile1", @"testFile2", @"testFile3"];
beforeEach(^{
testConnectionManager = [[TestConnectionManager alloc] init];
testFileManagerConfiguration = [[SDLFileManagerConfiguration alloc] initWithArtworkRetryCount:0 fileRetryCount:0];
testFileManager = [[SDLFileManager alloc] initWithConnectionManager:testConnectionManager configuration:testFileManagerConfiguration];
testFileManager.suspended = YES;
+ testFileManager.bytesAvailable = initialSpaceAvailable;
+ });
+
+ afterEach(^{
+ [testFileManager stop];
});
describe(@"before starting", ^{
it(@"should be in the shutdown state", ^{
expect(testFileManager.currentState).to(match(SDLFileManagerStateShutdown));
- });
-
- it(@"bytesAvailable should be 0", ^{
- expect(@(testFileManager.bytesAvailable)).to(equal(@0));
- });
-
- it(@"remoteFileNames should be empty", ^{
+ expect(testFileManager.bytesAvailable).to(equal(initialSpaceAvailable));
expect(testFileManager.remoteFileNames).to(beEmpty());
- });
-
- it(@"should have no pending operations", ^{
expect(testFileManager.pendingTransactions).to(beEmpty());
- });
-
- it(@"should set the maximum number of upload attempts to 1", ^{
expect(testFileManager.maxFileUploadAttempts).to(equal(1));
expect(testFileManager.maxArtworkUploadAttempts).to(equal(1));
});
@@ -91,718 +122,421 @@ describe(@"SDLFileManager", ^{
completionHandlerCalled = YES;
}];
- testFileManager.suspended = NO;
-
[NSThread sleepForTimeInterval:0.1];
});
it(@"should have queued a ListFiles request", ^{
+ expect(testFileManager.currentState).to(match(SDLFileManagerStateFetchingInitialList));
expect(testFileManager.pendingTransactions).to(haveCount(@1));
expect(testFileManager.pendingTransactions.firstObject).to(beAnInstanceOf([SDLListFilesOperation class]));
});
- it(@"should be in the fetching initial list state", ^{
- expect(testFileManager.currentState).to(match(SDLFileManagerStateFetchingInitialList));
- });
-
describe(@"after going to the shutdown state and receiving a ListFiles response", ^{
- __block SDLListFilesResponse *testListFilesResponse = nil;
- __block NSSet<NSString *> *testInitialFileNames = nil;
-
beforeEach(^{
- testInitialFileNames = [NSSet setWithArray:@[@"testFile1", @"testFile2", @"testFile3"]];
-
- testListFilesResponse = [[SDLListFilesResponse alloc] init];
- testListFilesResponse.success = @YES;
- testListFilesResponse.spaceAvailable = @(initialSpaceAvailable);
- testListFilesResponse.filenames = [NSArray arrayWithArray:[testInitialFileNames allObjects]];
-
[testFileManager stop];
- [testConnectionManager respondToLastRequestWithResponse:testListFilesResponse];
+ SDLListFilesOperation *operation = testFileManager.pendingTransactions.firstObject;
+ operation.completionHandler(YES, initialSpaceAvailable, testInitialFileNames, nil);
});
it(@"should remain in the stopped state after receiving the response if disconnected", ^{
- expect(testFileManager.currentState).toEventually(match(SDLFileManagerStateShutdown));
- expect(@(completionHandlerCalled)).toEventually(equal(@YES));
+ expect(testFileManager.currentState).to(match(SDLFileManagerStateShutdown));
+ expect(completionHandlerCalled).to(beTrue());
});
});
describe(@"after receiving a ListFiles error", ^{
- __block SDLListFilesResponse *testListFilesResponse = nil;
- __block NSSet<NSString *> *testInitialFileNames = nil;
- __block NSUInteger initialBytesAvailable = 0;
-
beforeEach(^{
- testInitialFileNames = [NSSet setWithArray:@[@"testFile1", @"testFile2", @"testFile3"]];
- initialBytesAvailable = testFileManager.bytesAvailable;
-
- testListFilesResponse = [[SDLListFilesResponse alloc] init];
- testListFilesResponse.success = @NO;
- testListFilesResponse.spaceAvailable = nil;
- testListFilesResponse.filenames = nil;
- [testConnectionManager respondToLastRequestWithResponse:testListFilesResponse];
+ SDLListFilesOperation *operation = testFileManager.pendingTransactions.firstObject;
+ operation.completionHandler(NO, initialSpaceAvailable, testInitialFileNames, [NSError sdl_fileManager_unableToStartError]);
});
it(@"should handle the error properly", ^{
- [testConnectionManager respondToLastRequestWithResponse:testListFilesResponse];
-
- expect(testFileManager.currentState).toEventually(match(SDLFileManagerStateStartupError));
- expect(testFileManager.remoteFileNames).toEventually(beEmpty());
- expect(@(testFileManager.bytesAvailable)).toEventually(equal(initialBytesAvailable));
+ expect(testFileManager.currentState).to(match(SDLFileManagerStateStartupError));
+ expect(testFileManager.remoteFileNames).to(beEmpty());
+ expect(@(testFileManager.bytesAvailable)).to(equal(initialSpaceAvailable));
});
});
describe(@"after receiving a ListFiles response", ^{
- __block SDLListFilesResponse *testListFilesResponse = nil;
- __block NSSet<NSString *> *testInitialFileNames = nil;
-
beforeEach(^{
- testInitialFileNames = [NSSet setWithArray:@[@"testFile1", @"testFile2", @"testFile3"]];
-
- testListFilesResponse = [[SDLListFilesResponse alloc] init];
- testListFilesResponse.success = @YES;
- testListFilesResponse.spaceAvailable = @(initialSpaceAvailable);
- testListFilesResponse.filenames = [NSArray arrayWithArray:[testInitialFileNames allObjects]];
- [testConnectionManager respondToLastRequestWithResponse:testListFilesResponse];
+ SDLListFilesOperation *operation = testFileManager.pendingTransactions.firstObject;
+ operation.completionHandler(YES, initialSpaceAvailable, testInitialFileNames, nil);
});
it(@"the file manager should be in the correct state", ^{
- [testConnectionManager respondToLastRequestWithResponse:testListFilesResponse];
-
- expect(testFileManager.currentState).toEventually(match(SDLFileManagerStateReady));
- expect(testFileManager.remoteFileNames).toEventually(equal(testInitialFileNames));
- expect(@(testFileManager.bytesAvailable)).toEventually(equal(@(initialSpaceAvailable)));
+ expect(testFileManager.currentState).to(match(SDLFileManagerStateReady));
+ expect(testFileManager.remoteFileNames).to(equal([NSSet setWithArray:testInitialFileNames]));
+ expect(@(testFileManager.bytesAvailable)).to(equal(@(initialSpaceAvailable)));
});
+ });
+ });
- describe(@"deleting a file", ^{
- __block BOOL completionSuccess = NO;
- __block NSUInteger completionBytesAvailable = 0;
- __block NSError *completionError = nil;
-
- context(@"when the file is unknown", ^{
- beforeEach(^{
- NSString *someUnknownFileName = @"Some Unknown File Name";
- [testFileManager deleteRemoteFileWithName:someUnknownFileName completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
- completionSuccess = success;
- completionBytesAvailable = bytesAvailable;
- completionError = error;
- }];
-
- [NSThread sleepForTimeInterval:0.1];
- });
-
- it(@"should return the correct data", ^{
- expect(@(completionSuccess)).toEventually(equal(@NO));
- expect(@(completionBytesAvailable)).toEventually(equal(@250));
- expect(completionError).toEventually(equal([NSError sdl_fileManager_noKnownFileError]));
- });
-
- it(@"should not have deleted any files in the file manager", ^{
- expect(testFileManager.remoteFileNames).toEventually(haveCount(@(testInitialFileNames.count)));
- });
- });
-
- context(@"when the file is known", ^{
- __block NSUInteger newSpaceAvailable = 600;
- __block NSString *someKnownFileName = nil;
- __block BOOL completionSuccess = NO;
- __block NSUInteger completionBytesAvailable = 0;
- __block NSError *completionError = nil;
+ describe(@"deleting a file", ^{
+ __block BOOL completionSuccess = NO;
+ __block NSUInteger completionBytesAvailable = 0;
+ __block NSError *completionError = nil;
- beforeEach(^{
- someKnownFileName = [testInitialFileNames anyObject];
- [testFileManager deleteRemoteFileWithName:someKnownFileName completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
- completionSuccess = success;
- completionBytesAvailable = bytesAvailable;
- completionError = error;
- }];
+ beforeEach(^{
+ testFileManager.mutableRemoteFileNames = [NSMutableSet setWithArray:testInitialFileNames];
+ [testFileManager.stateMachine setToState:SDLFileManagerStateReady fromOldState:SDLFileManagerStateShutdown callEnterTransition:NO];
+ });
- SDLDeleteFileResponse *deleteResponse = [[SDLDeleteFileResponse alloc] init];
- deleteResponse.success = @YES;
- deleteResponse.spaceAvailable = @(newSpaceAvailable);
+ context(@"when the file is unknown", ^{
+ beforeEach(^{
+ NSString *someUnknownFileName = @"Some Unknown File Name";
+ [testFileManager deleteRemoteFileWithName:someUnknownFileName completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
+ completionSuccess = success;
+ completionBytesAvailable = bytesAvailable;
+ completionError = error;
+ }];
- [NSThread sleepForTimeInterval:0.1];
+ expect(testFileManager.pendingTransactions).to(beEmpty());
+ });
- [testConnectionManager respondToLastRequestWithResponse:deleteResponse];
- });
+ it(@"should return the correct data", ^{
+ expect(completionSuccess).to(beFalse());
+ expect(completionBytesAvailable).to(equal(initialSpaceAvailable));
+ expect(completionError).to(equal([NSError sdl_fileManager_noKnownFileError]));
+ expect(testFileManager.remoteFileNames).to(haveCount(testInitialFileNames.count));
+ });
+ });
- it(@"should return the correct data", ^{
- expect(@(completionSuccess)).to(equal(@YES));
- expect(@(completionBytesAvailable)).to(equal(@(newSpaceAvailable)));
- expect(@(testFileManager.bytesAvailable)).to(equal(@(newSpaceAvailable)));
- expect(completionError).to(beNil());
- });
+ context(@"when the file is known", ^{
+ __block NSUInteger newSpaceAvailable = 600;
+ __block NSString *someKnownFileName = nil;
+ __block BOOL completionSuccess = NO;
+ __block NSUInteger completionBytesAvailable = 0;
+ __block NSError *completionError = nil;
- it(@"should have removed the file from the file manager", ^{
- expect(testFileManager.remoteFileNames).toNot(contain(someKnownFileName));
- });
- });
+ beforeEach(^{
+ someKnownFileName = [testInitialFileNames lastObject];
+ [testFileManager deleteRemoteFileWithName:someKnownFileName completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
+ completionSuccess = success;
+ completionBytesAvailable = bytesAvailable;
+ completionError = error;
+ }];
- context(@"when the request returns an error", ^{
- __block NSUInteger initialSpaceAvailable = 0;
- __block NSString *someKnownFileName = nil;
- __block BOOL completionSuccess = NO;
- __block NSUInteger completionBytesAvailable = 0;
- __block NSError *completionError = nil;
+ SDLDeleteFileOperation *operation = testFileManager.pendingTransactions.firstObject;
+ operation.completionHandler(YES, newSpaceAvailable, nil);
+ });
- beforeEach(^{
- initialSpaceAvailable = testFileManager.bytesAvailable;
- someKnownFileName = [testInitialFileNames anyObject];
- [testFileManager deleteRemoteFileWithName:someKnownFileName completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
- completionSuccess = success;
- completionBytesAvailable = bytesAvailable;
- completionError = error;
- }];
+ it(@"should return the correct data", ^{
+ expect(@(completionSuccess)).to(equal(@YES));
+ expect(@(completionBytesAvailable)).to(equal(@(newSpaceAvailable)));
+ expect(@(testFileManager.bytesAvailable)).to(equal(@(newSpaceAvailable)));
+ expect(completionError).to(beNil());
+ expect(testFileManager.remoteFileNames).toNot(contain(someKnownFileName));
+ });
+ });
+ });
- SDLDeleteFileResponse *deleteResponse = [[SDLDeleteFileResponse alloc] init];
- deleteResponse.success = @NO;
- deleteResponse.spaceAvailable = nil;
+ describe(@"uploading a new file", ^{
+ __block NSString *testFileName = nil;
+ __block SDLFile *testUploadFile = nil;
+ __block BOOL completionSuccess = NO;
+ __block NSUInteger completionBytesAvailable = 0;
+ __block NSError *completionError = nil;
- [NSThread sleepForTimeInterval:0.1];
+ __block NSData *testFileData = nil;
- [testConnectionManager respondToLastRequestWithResponse:deleteResponse];;
- });
+ beforeEach(^{
+ testFileManager.mutableRemoteFileNames = [NSMutableSet setWithArray:testInitialFileNames];
+ [testFileManager.stateMachine setToState:SDLFileManagerStateReady fromOldState:SDLFileManagerStateShutdown callEnterTransition:NO];
+ });
- it(@"should handle the error properly", ^{
- expect(testFileManager.currentState).toEventually(match(SDLFileManagerStateReady));
- expect(completionSuccess).toEventually(beFalse());
- expect(completionBytesAvailable).toEventually(equal(2000000000));
- expect(completionError).toNot(beNil());
- expect(@(testFileManager.bytesAvailable)).toEventually(equal(@(initialSpaceAvailable)));
- });
- });
+ context(@"when there is a remote file with the same file name", ^{
+ beforeEach(^{
+ testFileName = [testInitialFileNames lastObject];
+ testFileData = [@"someData" dataUsingEncoding:NSUTF8StringEncoding];
+ testUploadFile = [SDLFile fileWithData:testFileData name:testFileName fileExtension:@"bin"];
});
- describe(@"uploading a new file", ^{
- __block NSString *testFileName = nil;
- __block SDLFile *testUploadFile = nil;
- __block BOOL completionSuccess = NO;
- __block NSUInteger completionBytesAvailable = 0;
- __block NSError *completionError = nil;
+ context(@"when the file's overwrite property is YES", ^{
+ beforeEach(^{
+ testUploadFile.overwrite = YES;
- __block SDLPutFile *sentPutFile = nil;
- __block NSData *testFileData = nil;
+ [testFileManager uploadFile:testUploadFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
+ completionSuccess = success;
+ completionBytesAvailable = bytesAvailable;
+ completionError = error;
+ }];
+ });
- context(@"when there is a remote file with the same file name", ^{
+ context(@"when the connection returns a success", ^{
beforeEach(^{
- testFileName = [testInitialFileNames anyObject];
- testFileData = [@"someData" dataUsingEncoding:NSUTF8StringEncoding];
- testUploadFile = [SDLFile fileWithData:testFileData name:testFileName fileExtension:@"bin"];
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.firstObject;
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
});
- context(@"when the file's overwrite property is YES", ^{
- beforeEach(^{
- testUploadFile.overwrite = YES;
-
- [testFileManager uploadFile:testUploadFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
- completionSuccess = success;
- completionBytesAvailable = bytesAvailable;
- completionError = error;
- }];
-
- [NSThread sleepForTimeInterval:0.1];
-
- sentPutFile = testConnectionManager.receivedRequests.lastObject;
- });
-
- it(@"should set the file manager state to be waiting", ^{
- expect(testFileManager.currentState).to(match(SDLFileManagerStateReady));
- expect(testFileManager.uploadedEphemeralFileNames).to(beEmpty());
- });
-
- it(@"should create a putfile with the correct data", ^{
- expect(sentPutFile.length).to(equal(@(testFileData.length)));
- expect(sentPutFile.bulkData).to(equal(testFileData));
- expect(sentPutFile.fileType).to(match(SDLFileTypeBinary));
- });
-
- context(@"when the response returns without error", ^{
- __block SDLPutFileResponse *testResponse = nil;
- __block NSNumber *testResponseSuccess = nil;
- __block NSNumber *testResponseBytesAvailable = nil;
-
- beforeEach(^{
- testResponseBytesAvailable = @750;
- testResponseSuccess = @YES;
-
- testResponse = [[SDLPutFileResponse alloc] init];
- testResponse.success = testResponseSuccess;
- testResponse.spaceAvailable = testResponseBytesAvailable;
-
- [testConnectionManager respondToLastRequestWithResponse:testResponse];
- });
-
- it(@"should set the file manager data correctly", ^{
- expect(@(testFileManager.bytesAvailable)).toEventually(equal(testResponseBytesAvailable));
- expect(testFileManager.currentState).toEventually(match(SDLFileManagerStateReady));
- expect(testFileManager.remoteFileNames).toEventually(contain(testFileName));
- expect(testFileManager.uploadedEphemeralFileNames).toEventually(contain(testFileName));
- });
-
- it(@"should call the completion handler with the correct data", ^{
- expect(@(completionBytesAvailable)).toEventually(equal(testResponseBytesAvailable));
- expect(@(completionSuccess)).toEventually(equal(@YES));
- expect(completionError).to(beNil());
- });
- });
-
- context(@"when the connection returns failure", ^{
- __block SDLPutFileResponse *testResponse = nil;
-
- beforeEach(^{
- testResponse = [[SDLPutFileResponse alloc] init];
- testResponse.spaceAvailable = nil;
- testResponse.success = @NO;
-
- [testConnectionManager respondToLastRequestWithResponse:testResponse];
- });
-
- it(@"should set the file manager data correctly", ^{
- expect(@(testFileManager.bytesAvailable)).toEventually(equal(@(initialSpaceAvailable)));
- expect(testFileManager.remoteFileNames).toEventually(contain(testFileName));
- expect(testFileManager.currentState).toEventually(match(SDLFileManagerStateReady));
- expect(testFileManager.uploadedEphemeralFileNames).to(beEmpty());
- });
-
- it(@"should call the completion handler with the correct data", ^{
- expect(completionBytesAvailable).to(equal(2000000000));
- expect(@(completionSuccess)).to(equal(@NO));
- expect(completionError).toEventuallyNot(beNil());
- });
-
- it(@"should increment the failure count for the artwork", ^{
- expect(testFileManager.failedFileUploadsCount[testFileName]).toEventually(equal(1));
- });
- });
-
- context(@"when the connection errors without a response", ^{
- beforeEach(^{
- [testConnectionManager respondToLastRequestWithResponse:nil error:[NSError sdl_lifecycle_notReadyError]];
- });
-
- it(@"should have the correct file manager state", ^{
- expect(testFileManager.remoteFileNames).to(contain(testFileName));
- expect(testFileManager.currentState).to(match(SDLFileManagerStateReady));
- });
-
- it(@"should call the completion handler with correct data", ^{
- expect(completionError).toEventually(equal([NSError sdl_lifecycle_notReadyError]));
- });
- });
- });
+ it(@"should set the file manager state to be waiting and set correct data", ^{
+ expect(testFileManager.currentState).to(match(SDLFileManagerStateReady));
+ expect(testFileManager.uploadedEphemeralFileNames).toNot(beEmpty());
+
+ expect(completionBytesAvailable).to(equal(newBytesAvailable));
+ expect(completionSuccess).to(equal(YES));
+ expect(completionError).to(beNil());
- context(@"when allow overwrite is NO", ^{
- __block NSString *testUploadFileName = nil;
- __block Boolean testUploadOverwrite = NO;
-
- beforeEach(^{
- testUploadFileName = [testInitialFileNames anyObject];
- });
-
- it(@"should not upload the file if persistance is YES", ^{
- SDLFile *persistantFile = [[SDLFile alloc] initWithData:testFileData name:testUploadFileName fileExtension:@"bin" persistent:YES];
- persistantFile.overwrite = testUploadOverwrite;
-
- waitUntilTimeout(1, ^(void (^done)(void)){
- [testFileManager uploadFile:persistantFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
- expect(testConnectionManager.receivedRequests.lastObject).toNot(beAnInstanceOf([SDLPutFile class]));
- expect(@(success)).to(beFalse());
- expect(@(bytesAvailable)).to(equal(@(testFileManager.bytesAvailable)));
- expect(error).to(equal([NSError sdl_fileManager_cannotOverwriteError]));
- done();
- }];
- });
- });
-
- it(@"should upload the file if persistance is NO", ^{
- SDLFile *unPersistantFile = [[SDLFile alloc] initWithData:testFileData name:testUploadFileName fileExtension:@"bin" persistent:NO];
- unPersistantFile.overwrite = testUploadOverwrite;
-
- waitUntilTimeout(1, ^(void (^done)(void)){
- [testFileManager uploadFile:unPersistantFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
- expect(testConnectionManager.receivedRequests.lastObject).to(beAnInstanceOf([SDLPutFile class]));
- expect(@(success)).to(beTrue());
- expect(@(bytesAvailable)).to(equal(@(testFileManager.bytesAvailable)));
- expect(error).to(beNil());
- done();
- }];
-
- [NSThread sleepForTimeInterval:0.1];
-
- [testConnectionManager respondToLastRequestWithResponse:testListFilesResponse];
- });
- });
+ expect(@(testFileManager.bytesAvailable)).to(equal(newBytesAvailable));
+ expect(testFileManager.currentState).to(match(SDLFileManagerStateReady));
+ expect(testFileManager.remoteFileNames).to(contain(testFileName));
+ expect(testFileManager.uploadedEphemeralFileNames).to(contain(testFileName));
});
});
- context(@"when there is not a remote file named the same thing", ^{
+ context(@"when the connection returns failure", ^{
beforeEach(^{
- testFileName = @"not a test file";
- testFileData = [@"someData" dataUsingEncoding:NSUTF8StringEncoding];
- testUploadFile = [SDLFile fileWithData:testFileData name:testFileName fileExtension:@"bin"];
-
- [testFileManager uploadFile:testUploadFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
- completionSuccess = success;
- completionBytesAvailable = bytesAvailable;
- completionError = error;
- }];
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.firstObject;
+ sentOperation.fileWrapper.completionHandler(NO, failureSpaceAvailabe, [NSError sdl_fileManager_fileUploadCanceled]);
+ });
- [NSThread sleepForTimeInterval:0.1];
+ it(@"should set the file manager data correctly", ^{
+ expect(testFileManager.bytesAvailable).to(equal(initialSpaceAvailable));
+ expect(testFileManager.remoteFileNames).to(contain(testFileName));
+ expect(testFileManager.currentState).to(match(SDLFileManagerStateReady));
+ expect(testFileManager.uploadedEphemeralFileNames).to(beEmpty());
- sentPutFile = (SDLPutFile *)testConnectionManager.receivedRequests.lastObject;
- });
+ expect(completionBytesAvailable).to(equal(failureSpaceAvailabe));
+ expect(completionSuccess).to(equal(@NO));
+ expect(completionError).toNot(beNil());
- it(@"should not have testFileName in the files set", ^{
- expect(testInitialFileNames).toNot(contain(testFileName));
+ expect(testFileManager.failedFileUploadsCount[testFileName]).to(equal(1));
});
+ });
+ });
- context(@"when the connection returns without error", ^{
- __block SDLPutFileResponse *testResponse = nil;
- __block NSNumber *testResponseSuccess = nil;
- __block NSNumber *testResponseBytesAvailable = nil;
-
- beforeEach(^{
- testResponseBytesAvailable = @750;
- testResponseSuccess = @YES;
-
- testResponse = [[SDLPutFileResponse alloc] init];
- testResponse.success = testResponseSuccess;
- testResponse.spaceAvailable = testResponseBytesAvailable;
-
- [testConnectionManager respondToLastRequestWithResponse:testResponse];
- });
-
- it(@"should set the file manager state correctly", ^{
- expect(@(testFileManager.bytesAvailable)).toEventually(equal(testResponseBytesAvailable));
- expect(testFileManager.remoteFileNames).toEventually(contain(testFileName));
- expect(testFileManager.uploadedEphemeralFileNames).toEventually(contain(testUploadFile.name));
- expect(testFileManager.currentState).toEventually(match(SDLFileManagerStateReady));
- });
-
- it(@"should call the completion handler with the correct data", ^{
- expect(@(completionBytesAvailable)).toEventually(equal(testResponseBytesAvailable));
- expect(@(completionSuccess)).toEventually(equal(@YES));
- expect(completionError).to(beNil());
- });
- });
+ context(@"when allow overwrite is NO", ^{
+ __block NSString *testUploadFileName = nil;
+ __block Boolean testUploadOverwrite = NO;
- context(@"when the connection returns failure", ^{
- __block SDLPutFileResponse *testResponse = nil;
- __block NSNumber *testResponseBytesAvailable = nil;
- __block NSNumber *testResponseSuccess = nil;
+ beforeEach(^{
+ testUploadFileName = [testInitialFileNames lastObject];
+ });
- beforeEach(^{
- testResponseBytesAvailable = @750;
- testResponseSuccess = @NO;
+ it(@"should not upload the file if persistance is YES", ^{
+ SDLFile *persistantFile = [[SDLFile alloc] initWithData:testFileData name:testUploadFileName fileExtension:@"bin" persistent:YES];
+ persistantFile.overwrite = testUploadOverwrite;
- testResponse = [[SDLPutFileResponse alloc] init];
- testResponse.spaceAvailable = testResponseBytesAvailable;
- testResponse.success = testResponseSuccess;
+ [testFileManager uploadFile:persistantFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
+ expect(@(success)).to(beFalse());
+ expect(@(bytesAvailable)).to(equal(@(testFileManager.bytesAvailable)));
+ expect(error).to(equal([NSError sdl_fileManager_cannotOverwriteError]));
+ }];
- testFileManager.accessibilityHint = @"This doesn't matter";
+ expect(testFileManager.pendingTransactions.count).to(equal(0));
+ });
- [testConnectionManager respondToLastRequestWithResponse:testResponse];
- });
+ it(@"should upload the file if persistance is NO", ^{
+ SDLFile *unPersistantFile = [[SDLFile alloc] initWithData:testFileData name:testUploadFileName fileExtension:@"bin" persistent:NO];
+ unPersistantFile.overwrite = testUploadOverwrite;
- it(@"should set the file manager state correctly", ^{
- expect(@(testFileManager.bytesAvailable)).toEventually(equal(@(initialSpaceAvailable)));
- expect(testFileManager.remoteFileNames).toEventuallyNot(contain(testFileName));
- expect(testFileManager.uploadedEphemeralFileNames).toEventuallyNot(contain(testUploadFile.name));
- expect(testFileManager.currentState).toEventually(match(SDLFileManagerStateReady));
- });
+ [testFileManager uploadFile:unPersistantFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
+ expect(success).to(beTrue());
+ expect(bytesAvailable).to(equal(newBytesAvailable));
+ expect(error).to(beNil());
+ }];
- it(@"should call the completion handler with the correct data", ^{
- expect(@(completionBytesAvailable)).to(equal(@2000000000));
- expect(@(completionSuccess)).to(equal(testResponseSuccess));
- expect(completionError).toEventuallyNot(beNil());
- });
- });
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.firstObject;
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
+ expect(testFileManager.pendingTransactions.count).to(equal(1));
+ });
+ });
+ });
- context(@"when the connection errors without a response", ^{
- beforeEach(^{
- [testConnectionManager respondToLastRequestWithResponse:nil error:[NSError sdl_lifecycle_notReadyError]];
- });
+ context(@"when there is not a remote file named the same thing", ^{
+ beforeEach(^{
+ testFileName = @"not a test file";
+ testFileData = [@"someData" dataUsingEncoding:NSUTF8StringEncoding];
+ testUploadFile = [SDLFile fileWithData:testFileData name:testFileName fileExtension:@"bin"];
+
+ [testFileManager uploadFile:testUploadFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
+ completionSuccess = success;
+ completionBytesAvailable = bytesAvailable;
+ completionError = error;
+ }];
+ });
- it(@"should set the file manager state correctly", ^{
- expect(testFileManager.remoteFileNames).toNot(contain(testFileName));
- expect(testFileManager.currentState).to(match(SDLFileManagerStateReady));
- });
+ it(@"should not have testFileName in the files set", ^{
+ expect(testInitialFileNames).toNot(contain(testFileName));
+ });
- it(@"should call the completion handler with nil error", ^{
- expect(completionError).toEventually(equal([NSError sdl_lifecycle_notReadyError]));
- });
- });
+ context(@"when the connection returns without error", ^{\
+ beforeEach(^{
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.firstObject;
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
});
- context(@"When the file data is nil", ^{
- it(@"should call the completion handler with an error", ^{
- SDLFile *emptyFile = [[SDLFile alloc] initWithData:[[NSData alloc] init] name:@"testFile" fileExtension:@"bin" persistent:YES];
-
- waitUntilTimeout(1, ^(void (^done)(void)){
- [testFileManager uploadFile:emptyFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
- expect(testConnectionManager.receivedRequests.lastObject).toNot(beAnInstanceOf([SDLPutFile class]));
- expect(@(success)).to(beFalse());
- expect(@(bytesAvailable)).to(equal(@(testFileManager.bytesAvailable)));
- expect(error).to(equal([NSError sdl_fileManager_dataMissingError]));
- done();
- }];
- });
- });
+ it(@"should set the file manager state correctly", ^{
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
+ expect(testFileManager.remoteFileNames).to(contain(testFileName));
+ expect(testFileManager.uploadedEphemeralFileNames).to(contain(testUploadFile.name));
+ expect(testFileManager.currentState).to(equal(SDLFileManagerStateReady));
+
+ expect(@(completionBytesAvailable)).to(equal(newBytesAvailable));
+ expect(@(completionSuccess)).to(equal(@YES));
+ expect(completionError).to(beNil());
});
});
- describe(@"uploading artwork", ^{
- __block UIImage *testUIImage = nil;
- __block SDLArtwork *testArtwork = nil;
-
- __block NSString *expectedArtworkName = nil;
- __block Boolean expectedOverwrite = false;
- __block NSUInteger expectedRemoteFilesCount = 0;
- __block NSUInteger expectedBytesAvailable = 0;
-
- __block Boolean expectedToUploadArtwork = true;
- __block NSUInteger expectedRPCsSentCount = 1;
-
+ context(@"when the connection returns failure", ^{
beforeEach(^{
- UIGraphicsBeginImageContextWithOptions(CGSizeMake(5, 5), YES, 0);
- CGContextRef context = UIGraphicsGetCurrentContext();
- [[UIColor blackColor] setFill];
- CGContextFillRect(context, CGRectMake(0, 0, 5, 5));
- UIImage *blackSquareImage = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
- testUIImage = blackSquareImage;
-
- expectedRemoteFilesCount = testInitialFileNames.count;
- expect(testFileManager.remoteFileNames.count).to(equal(expectedRemoteFilesCount));
-
- expectedBytesAvailable = initialSpaceAvailable;
- expect(testFileManager.bytesAvailable).to(equal(expectedBytesAvailable));
-
- expectedRPCsSentCount = 1; // ListFiles RPC
- expect(testConnectionManager.receivedRequests.count).to(equal(expectedRPCsSentCount));
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.firstObject;
+ sentOperation.fileWrapper.completionHandler(NO, failureSpaceAvailabe, [NSError sdl_fileManager_fileUploadCanceled]);
});
- it(@"should not upload the artwork again and simply return the artwork name when sending artwork that has already been uploaded", ^{
- expectedArtworkName = [testListFilesResponse.filenames firstObject];
- expectedOverwrite = false;
- expectedRemoteFilesCount = testInitialFileNames.count;
- expectedBytesAvailable = initialSpaceAvailable;
- expectedToUploadArtwork = false;
- });
+ it(@"should set the file manager state correctly", ^{
+ expect(testFileManager.bytesAvailable).toEventually(equal(initialSpaceAvailable));
+ expect(testFileManager.remoteFileNames).toEventuallyNot(contain(testFileName));
+ expect(testFileManager.uploadedEphemeralFileNames).toEventuallyNot(contain(testUploadFile.name));
+ expect(testFileManager.currentState).toEventually(match(SDLFileManagerStateReady));
- it(@"should upload the artwork and return the artwork name when done when sending artwork that has not yet been uploaded", ^{
- expectedArtworkName = @"uniqueArtworkName";
- expectedOverwrite = false;
- expectedRemoteFilesCount = testInitialFileNames.count + 1;
- expectedBytesAvailable = 22;
- expectedToUploadArtwork = true;
- expectedRPCsSentCount += 1;
+ expect(completionBytesAvailable).to(equal(failureSpaceAvailabe));
+ expect(completionSuccess).to(beFalse());
+ expect(completionError).toEventuallyNot(beNil());
});
+ });
+ });
+ });
- it(@"should upload the artwork and return the artwork name when done when sending arwork that is already been uploaded but overwrite is enabled", ^{
- expectedArtworkName = [testListFilesResponse.filenames firstObject];
- expectedOverwrite = true;
- expectedRemoteFilesCount = testInitialFileNames.count;
- expectedBytesAvailable = initialSpaceAvailable;
- expectedToUploadArtwork = true;
- expectedRPCsSentCount += 1;
- });
+ describe(@"uploading artwork", ^{
+ __block UIImage *testUIImage = nil;
+ __block NSString *expectedArtworkName = nil;
- afterEach(^{
- testArtwork = [[SDLArtwork alloc] initWithImage:testUIImage name:expectedArtworkName persistent:true asImageFormat:SDLArtworkImageFormatPNG];
- testArtwork.overwrite = expectedOverwrite;
+ beforeEach(^{
+ testUIImage = [FileManagerSpecHelper imagesForCount:1].firstObject;
- waitUntilTimeout(1, ^(void (^done)(void)){
- [testFileManager uploadArtwork:testArtwork completionHandler:^(BOOL success, NSString * _Nonnull artworkName, NSUInteger bytesAvailable, NSError * _Nullable error) {
- expect(artworkName).to(equal(expectedArtworkName));
- expect(success).to(beTrue());
- expect(bytesAvailable).to(equal(expectedBytesAvailable));
- expect(error).to(beNil());
+ testFileManager.uploadedEphemeralFileNames = [NSMutableSet setWithArray:testInitialFileNames];
+ testFileManager.mutableRemoteFileNames = [NSMutableSet setWithArray:testInitialFileNames];
+ [testFileManager.stateMachine setToState:SDLFileManagerStateReady fromOldState:SDLFileManagerStateShutdown callEnterTransition:NO];
+ });
- expect(testFileManager.remoteFileNames.count).to(equal(expectedRemoteFilesCount));
+ it(@"should not upload the artwork again and simply return the artwork name when sending artwork that has already been uploaded", ^{
+ expectedArtworkName = testInitialFileNames.firstObject;
- done();
- }];
+ SDLArtwork *art = [SDLArtwork artworkWithImage:testUIImage name:expectedArtworkName asImageFormat:SDLArtworkImageFormatPNG];
+ [testFileManager uploadArtwork:art completionHandler:^(BOOL success, NSString * _Nonnull artworkName, NSUInteger bytesAvailable, NSError * _Nullable error) {
+ expect(success).to(beTrue());
+ expect(bytesAvailable).to(equal(initialSpaceAvailable));
+ expect(error).to(beNil());
+ }];
- if (expectedToUploadArtwork) {
- [NSThread sleepForTimeInterval:0.1];
+ expect(testFileManager.pendingTransactions.count).to(equal(0));
+ });
- SDLPutFileResponse *successfulPutFileResponse = [[SDLPutFileResponse alloc] init];
- successfulPutFileResponse.success = @YES;
- successfulPutFileResponse.spaceAvailable = @(expectedBytesAvailable);
- [testConnectionManager respondToLastRequestWithResponse:successfulPutFileResponse];
- }
- });
+ it(@"should upload the artwork and return the artwork name when done when sending artwork that has not yet been uploaded", ^{
+ expectedArtworkName = @"uniqueArtworkName";
+ [testFileManager uploadArtwork:[SDLArtwork artworkWithImage:testUIImage name:expectedArtworkName asImageFormat:SDLArtworkImageFormatPNG] completionHandler:^(BOOL success, NSString * _Nonnull artworkName, NSUInteger bytesAvailable, NSError * _Nullable error) {
+ expect(success).to(beTrue());
+ expect(bytesAvailable).to(equal(newBytesAvailable));
+ expect(error).to(beNil());
+ }];
- expect(testConnectionManager.receivedRequests.count).to(equal(expectedRPCsSentCount));
- });
- });
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.firstObject;
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
+ expect(testFileManager.pendingTransactions.count).to(equal(1));
});
- afterEach(^{
- expect(testFileManager.transactionQueue.maxConcurrentOperationCount).to(equal(@(1)));
+ it(@"should upload the artwork and return the artwork name when done when sending arwork that is already been uploaded but overwrite is enabled", ^{
+ expectedArtworkName = testInitialFileNames.firstObject;
+ SDLArtwork *testArt = [SDLArtwork artworkWithImage:testUIImage name:expectedArtworkName asImageFormat:SDLArtworkImageFormatPNG];
+ testArt.overwrite = YES;
+ [testFileManager uploadArtwork:testArt completionHandler:^(BOOL success, NSString * _Nonnull artworkName, NSUInteger bytesAvailable, NSError * _Nullable error) {
+ expect(success).to(beTrue());
+ expect(bytesAvailable).to(equal(newBytesAvailable));
+ expect(error).to(beNil());
+ }];
+
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.firstObject;
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
+ expect(testFileManager.pendingTransactions.count).to(equal(1));
});
});
});
-describe(@"SDLFileManager uploading/deleting multiple files", ^{
+describe(@"uploading/deleting multiple files in the file manager", ^{
__block TestMultipleFilesConnectionManager *testConnectionManager;
__block SDLFileManager *testFileManager;
- __block NSUInteger initialSpaceAvailable;
+ __block NSUInteger initialSpaceAvailable = 123;
+ NSUInteger newBytesAvailable = 750;
+ NSUInteger failureBytesAvailable = 2000000000;
beforeEach(^{
testConnectionManager = [[TestMultipleFilesConnectionManager alloc] init];
SDLFileManagerConfiguration *testFileManagerConfiguration = [[SDLFileManagerConfiguration alloc] initWithArtworkRetryCount:0 fileRetryCount:0];
testFileManager = [[SDLFileManager alloc] initWithConnectionManager:testConnectionManager configuration:testFileManagerConfiguration];
- initialSpaceAvailable = 66666;
+ testFileManager.suspended = YES;
+ testFileManager.bytesAvailable = initialSpaceAvailable;
+ });
+
+ afterEach(^{
+ [testFileManager stop];
});
context(@"When the file manager is passed multiple files to upload", ^{
- __block SDLListFilesResponse *testListFilesResponse;
__block NSMutableArray<SDLFile *> *testSDLFiles;
- __block NSMutableArray *expectedSuccessfulFileNames;
- __block NSNumber *expectedSpaceLeft;
- __block SDLPutFileResponse *failedResponse;
- __block SDLPutFileResponse *successfulResponse;
beforeEach(^{
testSDLFiles = [NSMutableArray array];
- expectedSuccessfulFileNames = [NSMutableArray array];
- expectedSpaceLeft = @(initialSpaceAvailable);
-
- testListFilesResponse = [[SDLListFilesResponse alloc] init];
- testListFilesResponse.success = @YES;
- testListFilesResponse.spaceAvailable = @(initialSpaceAvailable);
- testListFilesResponse.filenames = [[NSArray alloc] initWithObjects:@"A", @"B", @"C", nil];
-
- failedResponse = [[SDLPutFileResponse alloc] init];
- failedResponse.success = @NO;
- failedResponse.spaceAvailable = @(initialSpaceAvailable);
-
- successfulResponse = [[SDLPutFileResponse alloc] init];
- successfulResponse.success = @YES;
- successfulResponse.spaceAvailable = @(initialSpaceAvailable);
-
- waitUntilTimeout(10, ^(void (^done)(void)){
- [testFileManager startWithCompletionHandler:^(BOOL success, NSError * _Nullable error) {
- done();
- }];
-
- // Need to wait state machine transitions to complete before sending testListFilesResponse
- [NSThread sleepForTimeInterval:0.3];
-
- [testConnectionManager respondToLastRequestWithResponse:testListFilesResponse];
- });
+ [testFileManager.stateMachine setToState:SDLFileManagerStateReady fromOldState:SDLFileManagerStateShutdown callEnterTransition:NO];
});
context(@"and all files are uploaded successfully", ^{
- __block NSError *successfulResponseError = nil;
- __block NSMutableDictionary *testConnectionManagerResponses = [[NSMutableDictionary alloc] init];
-
- it(@"should not return an error when one small file is uploaded from memory", ^{
+ it(@"should upload 1 file successfully", ^{
NSString *testFileName = [NSString stringWithFormat:@"TestSmallFileMemory%d", 0];
SDLFile *testSDLFile = [SDLFile fileWithData:[@"someTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
testSDLFile.overwrite = true;
[testSDLFiles addObject:testSDLFile];
- [expectedSuccessfulFileNames addObject:testFileName];
- testConnectionManagerResponses[testFileName] = [[TestResponse alloc] initWithResponse:successfulResponse error:successfulResponseError];
- testConnectionManager.responses = testConnectionManagerResponses;
- });
+ [testFileManager uploadFiles:testSDLFiles completionHandler:^(NSError * _Nullable error) {
+ expect(error).to(beNil());
+ }];
- it(@"should not return an error when one large file is uploaded from disk", ^{
- NSString *testFileName = [NSString stringWithFormat:@"TestLargeFileDisk%d", 0];
- SDLFile *testSDLFile = [SDLFile fileAtFileURL: [[NSURL alloc] initFileURLWithPath:[[NSBundle bundleForClass:[self class]] pathForResource:@"testImagePNG" ofType:@"png"]] name:testFileName];
- testSDLFile.overwrite = true;
- [testSDLFiles addObject:testSDLFile];
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.firstObject;
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
- [expectedSuccessfulFileNames addObject:testFileName];
- testConnectionManagerResponses[testFileName] = [[TestResponse alloc] initWithResponse:successfulResponse error:successfulResponseError];
- testConnectionManager.responses = testConnectionManagerResponses;
+ expect(testFileManager.pendingTransactions.count).to(equal(1));
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
});
- it(@"should not return an error when multiple small files are uploaded from memory", ^{
- NSInteger testSpaceAvailable = initialSpaceAvailable;
+ it(@"should upload 5 files successfully", ^{
for(int i = 0; i < 5; i += 1) {
NSString *testFileName = [NSString stringWithFormat:@"TestSmallFilesMemory%d", i];
SDLFile *testSDLFile = [SDLFile fileWithData:[@"someTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
testSDLFile.overwrite = true;
[testSDLFiles addObject:testSDLFile];
+ }
- successfulResponse.spaceAvailable = @(testSpaceAvailable -= 5);
+ [testFileManager uploadFiles:testSDLFiles completionHandler:^(NSError * _Nullable error) {
+ expect(error).to(beNil());
+ }];
- [expectedSuccessfulFileNames addObject:testFileName];
- testConnectionManagerResponses[testFileName] = [[TestResponse alloc] initWithResponse:successfulResponse error:successfulResponseError];
+ expect(testFileManager.pendingTransactions.count).to(equal(5));
+ for (int i = 0; i < 5; i += 1) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable - i, nil);
}
- expectedSpaceLeft = @(testSpaceAvailable);
- testConnectionManager.responses = testConnectionManagerResponses;
+
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable - 4));
});
- it(@"should not return an error when a large number of small files are uploaded from memory", ^{
- NSInteger testSpaceAvailable = initialSpaceAvailable;
+ it(@"should upload 500 files successfully", ^{
for(int i = 0; i < 500; i += 1) {
- NSString *testFileName = [NSString stringWithFormat:@"Test500FilesMemory%d", i];
+ NSString *testFileName = [NSString stringWithFormat:@"TestSmallFilesMemory%d", i];
SDLFile *testSDLFile = [SDLFile fileWithData:[@"someTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
testSDLFile.overwrite = true;
[testSDLFiles addObject:testSDLFile];
-
- successfulResponse.spaceAvailable = @(testSpaceAvailable -= 4);
-
- [expectedSuccessfulFileNames addObject:testFileName];
- testConnectionManagerResponses[testFileName] = [[TestResponse alloc] initWithResponse:successfulResponse error:successfulResponseError];
- }
- expectedSpaceLeft = @(testSpaceAvailable);
- testConnectionManager.responses = testConnectionManagerResponses;
- });
-
- it(@"should not return an error when multiple small files are uploaded from disk", ^{
- NSInteger testSpaceAvailable = initialSpaceAvailable;
- for(int i = 0; i < 5; i += 1) {
- NSString *testFileName = [NSString stringWithFormat:@"TestMultipleSmallFilesDisk%d", i];
- SDLFile *testSDLFile = [SDLFile fileAtFileURL:[[NSURL alloc] initFileURLWithPath:[[NSBundle bundleForClass:[self class]] pathForResource:@"testImagePNG" ofType:@"png"]] name:testFileName];
- testSDLFile.overwrite = true;
- [testSDLFiles addObject:testSDLFile];
-
- successfulResponse.spaceAvailable = @(testSpaceAvailable -= 3);
-
- [expectedSuccessfulFileNames addObject:testFileName];
- testConnectionManagerResponses[testFileName] = [[TestResponse alloc] initWithResponse:successfulResponse error:successfulResponseError];
}
- expectedSpaceLeft = @(testSpaceAvailable);
- testConnectionManager.responses = testConnectionManagerResponses;
- });
-
- it(@"should not return an error when multiple files are uploaded from both memory and disk", ^{
- NSInteger testSpaceAvailable = initialSpaceAvailable;
- for(int i = 0; i < 10; i += 1) {
- NSString *testFileName = [NSString stringWithFormat:@"TestMultipleFilesDiskAndMemory%d", i];
- SDLFile *testSDLFile;
- if (i < 5) {
- testSDLFile = [SDLFile fileAtFileURL:[[NSURL alloc] initFileURLWithPath:[[NSBundle bundleForClass:[self class]] pathForResource:@"testImagePNG" ofType:@"png"]] name:testFileName];
- } else {
- testSDLFile = [SDLFile fileWithData:[@"someTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
- }
- testSDLFile.overwrite = true;
- [testSDLFiles addObject:testSDLFile];
- successfulResponse.spaceAvailable = @(testSpaceAvailable -= 2);
+ [testFileManager uploadFiles:testSDLFiles completionHandler:^(NSError * _Nullable error) {
+ expect(error).to(beNil());
+ }];
- [expectedSuccessfulFileNames addObject:testFileName];
- testConnectionManagerResponses[testFileName] = [[TestResponse alloc] initWithResponse:successfulResponse error:successfulResponseError];
+ expect(testFileManager.pendingTransactions.count).to(equal(500));
+ for (int i = 0; i < 500; i += 1) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable - i, nil);
}
- expectedSpaceLeft = @(testSpaceAvailable);
- testConnectionManager.responses = testConnectionManagerResponses;
- });
- // TODO: This should use itBehavesLike
- afterEach(^{
- waitUntilTimeout(10, ^(void (^done)(void)){
- [testFileManager uploadFiles:testSDLFiles completionHandler:^(NSError * _Nullable error) {
- expect(error).to(beNil());
- expect(testFileManager.bytesAvailable).to(equal(expectedSpaceLeft));
- done();
- }];
- });
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable - 499));
});
});
@@ -818,336 +552,280 @@ describe(@"SDLFileManager uploading/deleting multiple files", ^{
});
it(@"should upload one artwork successfully", ^{
- UIGraphicsBeginImageContextWithOptions(CGSizeMake(5, 5), YES, 0);
- CGContextRef context = UIGraphicsGetCurrentContext();
- [[UIColor blackColor] setFill];
- CGContextFillRect(context, CGRectMake(0, 0, 5, 5));
- UIImage *blackSquareImage = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
-
- SDLArtwork *testArtwork = [SDLArtwork artworkWithImage:blackSquareImage asImageFormat:SDLArtworkImageFormatPNG];
+ NSArray<UIImage *> *images = [FileManagerSpecHelper imagesForCount:1];
+
+ SDLArtwork *testArtwork = [SDLArtwork artworkWithImage:images.firstObject asImageFormat:SDLArtworkImageFormatPNG];
[testArtworks addObject:testArtwork];
[expectedArtworkNames addObject:testArtwork.name];
- successfulResponse.spaceAvailable = @22;
- testConnectionManagerResponses[testArtwork.name] = [[TestResponse alloc] initWithResponse:successfulResponse error:nil];
- expectedSpaceLeft = @22;
- testConnectionManager.responses = testConnectionManagerResponses;
+ [testFileManager uploadArtworks:testArtworks completionHandler:^(NSArray<NSString *> * _Nonnull artworkNames, NSError * _Nullable error) {
+ expect(error).to(beNil());
+ }];
+
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.firstObject;
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
+
+ expect(testFileManager.pendingTransactions.count).to(equal(1));
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
});
it(@"should upload multiple artworks successfully", ^{
- NSInteger spaceAvailable = 6000;
- for (NSUInteger i = 0; i < 200; i += 1) {
- UIGraphicsBeginImageContextWithOptions(CGSizeMake(5, 5), YES, 0);
- CGContextRef context = UIGraphicsGetCurrentContext();
- CGFloat grey = (i % 255) / 255.0;
- [[UIColor colorWithRed:grey green:grey blue:grey alpha:1.0] setFill];
- CGContextFillRect(context, CGRectMake(0, 0, 10, 10));
- UIImage *greySquareImage = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
-
- SDLArtwork *testArtwork = [SDLArtwork artworkWithImage:greySquareImage asImageFormat:SDLArtworkImageFormatPNG];
+ NSArray<UIImage *> *images = [FileManagerSpecHelper imagesForCount:200];
+
+ for (UIImage *image in images) {
+ SDLArtwork *testArtwork = [SDLArtwork artworkWithImage:image asImageFormat:SDLArtworkImageFormatPNG];
[testArtworks addObject:testArtwork];
[expectedArtworkNames addObject:testArtwork.name];
+ }
+
+ [testFileManager uploadArtworks:testArtworks completionHandler:^(NSArray<NSString *> * _Nonnull artworkNames, NSError * _Nullable error) {
+ expect(error).to(beNil());
+ }];
- successfulResponse.spaceAvailable = @(spaceAvailable -= 1);
- [expectedSuccessfulFileNames addObject:testArtwork.name];
- testConnectionManagerResponses[testArtwork.name] = [[TestResponse alloc] initWithResponse:successfulResponse error:nil];
+ expect(testFileManager.pendingTransactions.count).to(equal(200));
+ for (int i = 0; i < 200; i += 1) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable - i, nil);
}
- expectedSpaceLeft = @(spaceAvailable);
- testConnectionManager.responses = testConnectionManagerResponses;
- });
- afterEach(^{
- waitUntilTimeout(10, ^(void (^done)(void)){
- [testFileManager uploadArtworks:testArtworks completionHandler:^(NSArray<NSString *> * _Nonnull artworkNames, NSError * _Nullable error) {
- for (NSString *artworkName in expectedArtworkNames) {
- expect(artworkNames).to(contain(artworkName));
- }
- expect(expectedArtworkNames.count).to(equal(artworkNames.count));
- expect(error).to(beNil());
- expect(testFileManager.bytesAvailable).to(equal(expectedSpaceLeft));
- done();
- }];
- });
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable - 199));
});
});
- context(@"and all files are not uploaded successfully", ^{
- __block NSMutableDictionary *testConnectionManagerResponses;
- __block NSMutableDictionary *expectedFailedUploads;
- __block NSError *expectedError;
- __block int testTotalFileCount;
- __block NSString *testFileNameBase;
- __block int testFailureIndexStart;
- __block int testFailureIndexEnd;
+ context(@"and file uploads fail", ^{
+ context(@"file upload failure", ^{
+ it(@"should return an error when all files fail", ^{
+ for(int i = 0; i < 5; i++) {
+ NSString *testFileName = [NSString stringWithFormat:@"TestSmallFilesMemory%d", i];
+ SDLFile *testSDLFile = [SDLFile fileWithData:[@"someTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
+ testSDLFile.overwrite = true;
+ [testSDLFiles addObject:testSDLFile];
+ }
- beforeEach(^{
- testConnectionManagerResponses = [[NSMutableDictionary alloc] init];
- expectedFailedUploads = [[NSMutableDictionary alloc] init];
- expectedError = nil;
- });
+ [testFileManager uploadFiles:testSDLFiles completionHandler:^(NSError * _Nullable error) {
+ expect(error).toNot(beNil());
+ }];
- context(@"When the file manager receives a notification from the remote that a file upload failed", ^{
- describe(@"The correct errors should be returned", ^{
- beforeEach(^{
- testFailureIndexStart = -1;
- testFailureIndexEnd = INT8_MAX;
- });
+ expect(testFileManager.pendingTransactions.count).to(equal(5));
+ for (int i = 0; i < 5; i++) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ sentOperation.fileWrapper.completionHandler(NO, failureBytesAvailable, [NSError sdl_fileManager_dataMissingError]);
+ }
+
+ expect(testFileManager.bytesAvailable).to(equal(initialSpaceAvailable));
+ });
- it(@"should return an error when all files fail", ^{
- testTotalFileCount = 5;
- testFileNameBase = @"TestAllFilesUnsuccessful";
- testFailureIndexStart = testTotalFileCount;
- });
+ it(@"should return an error when the first file fails to upload", ^{
+ for(int i = 0; i < 5; i += 1) {
+ NSString *testFileName = [NSString stringWithFormat:@"TestSmallFilesMemory%d", i];
+ SDLFile *testSDLFile = [SDLFile fileWithData:[@"someTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
+ testSDLFile.overwrite = true;
+ [testSDLFiles addObject:testSDLFile];
+ }
- it(@"should return an error when the first file fails to upload", ^{
- testTotalFileCount = 5;
- testFileNameBase = @"TestFirstFileUnsuccessful";
- testFailureIndexStart = 0;
- });
+ [testFileManager uploadFiles:testSDLFiles completionHandler:^(NSError * _Nullable error) {
+ expect(error).toNot(beNil());
+ }];
- it(@"should return an error when the last file fails to upload", ^{
- testTotalFileCount = 100;
- testFileNameBase = @"TestLastFileUnsuccessful";
- testFailureIndexEnd = (testTotalFileCount - 1);
- });
+ expect(testFileManager.pendingTransactions.count).to(equal(5));
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.firstObject;
+ sentOperation.fileWrapper.completionHandler(NO, failureBytesAvailable, [NSError sdl_fileManager_dataMissingError]);
- afterEach(^{
- NSInteger testSpaceAvailable = initialSpaceAvailable;
- for(int i = 0; i < testTotalFileCount; i += 1) {
- NSString *testFileName = [NSString stringWithFormat:@"%@%d", testFileNameBase, i];
- SDLFile *testSDLFile = [SDLFile fileWithData:[@"someTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
- testSDLFile.overwrite = true;
- [testSDLFiles addObject:testSDLFile];
-
- SDLPutFileResponse *response = [[SDLPutFileResponse alloc] init];
- NSError *responseError = nil;
- if (i <= testFailureIndexStart || i >= testFailureIndexEnd) {
- // Failed response
- response = failedResponse;
- response.spaceAvailable = @(testSpaceAvailable);
- responseError = [NSError sdl_lifecycle_unknownRemoteErrorWithDescription:[NSString stringWithFormat:@"file upload failed: %d", i] andReason:[NSString stringWithFormat:@"some error reason: %d", i]];
- expectedFailedUploads[testFileName] = responseError;
- } else {
- // Successful response
- response = successfulResponse;
- response.spaceAvailable = @(testSpaceAvailable -= 1);
- responseError = nil;
- [expectedSuccessfulFileNames addObject:testFileName];
- }
-
- testConnectionManagerResponses[testFileName] = [[TestResponse alloc] initWithResponse:response error:responseError];
- }
-
- testConnectionManager.responses = testConnectionManagerResponses;
- expectedError = [NSError sdl_fileManager_unableToUpload_ErrorWithUserInfo:expectedFailedUploads];
- expectedSpaceLeft = @(testSpaceAvailable);
- });
+ for (int i = 1; i < 5; i += 1) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
+ }
+
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
});
- afterEach(^{
- waitUntilTimeout(10, ^(void (^done)(void)){
- [testFileManager uploadFiles:testSDLFiles completionHandler:^(NSError * _Nullable error) {
- expect(error).to(equal(expectedError));
- expect(testFileManager.bytesAvailable).to(equal(expectedSpaceLeft));
- done();
- }];
- });
+ it(@"should return an error when the last file fails to upload", ^{
+ for(int i = 0; i < 5; i += 1) {
+ NSString *testFileName = [NSString stringWithFormat:@"TestSmallFilesMemory%d", i];
+ SDLFile *testSDLFile = [SDLFile fileWithData:[@"someTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
+ testSDLFile.overwrite = true;
+ [testSDLFiles addObject:testSDLFile];
+ }
+
+ [testFileManager uploadFiles:testSDLFiles completionHandler:^(NSError * _Nullable error) {
+ expect(error).toNot(beNil());
+ }];
+
+ expect(testFileManager.pendingTransactions.count).to(equal(5));
+ for (int i = 0; i < 4; i += 1) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
+ }
+
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.lastObject;
+ sentOperation.fileWrapper.completionHandler(NO, failureBytesAvailable, [NSError sdl_fileManager_dataMissingError]);
+
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
});
});
- context(@"When the file manager receives a notification from the remote that an artwork upload failed", ^{
+ context(@"artwork upload failure", ^{
__block NSMutableArray<SDLArtwork *> *testArtworks = nil;
- __block NSSet<NSNumber *> *testOverwriteErrorIndices = nil;
- __block NSMutableArray<NSString *> *expectedSuccessfulArtworkNames = nil;
- __block NSInteger expectedSuccessfulArtworkNameCount = 0;
- __block NSInteger expectedErrorMessagesCount = 0;
beforeEach(^{
testArtworks = [NSMutableArray array];
- testOverwriteErrorIndices = [NSSet set];
- expectedSuccessfulArtworkNameCount = 0;
- expectedSuccessfulArtworkNames = [NSMutableArray array];
- expectedErrorMessagesCount = 0;
+ });
+
+ it(@"should return an empty artwork name array if all artwork uploads failed", ^{
+ NSArray<UIImage *> *images = [FileManagerSpecHelper imagesForCount:5];
+ for(int i = 0; i < images.count; i += 1) {
+ SDLArtwork *artwork = [SDLArtwork artworkWithImage:images[i] asImageFormat:SDLArtworkImageFormatPNG];
+ [testArtworks addObject:artwork];
+ }
+
+ [testFileManager uploadArtworks:testArtworks completionHandler:^(NSArray<NSString *> * _Nonnull artworkNames, NSError * _Nullable error) {
+ expect(artworkNames).to(beEmpty());
+ expect(error).toNot(beNil());
+ }];
+
+ expect(testFileManager.pendingTransactions.count).to(equal(5));
+ for (int i = 0; i < images.count; i += 1) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ sentOperation.fileWrapper.completionHandler(NO, failureBytesAvailable, [NSError sdl_fileManager_dataMissingError]);
+ }
- testFailureIndexStart = -1;
- testFailureIndexEnd = INT8_MAX;
+ expect(testFileManager.bytesAvailable).to(equal(initialSpaceAvailable));
});
- describe(@"The correct errors should be returned", ^{
- it(@"should return an empty artwork name array if all artwork uploads failed", ^{
- testTotalFileCount = 20;
- testFailureIndexStart = testTotalFileCount;
- expectedSuccessfulArtworkNameCount = 0;
- expectedErrorMessagesCount = 20;
- });
+ it(@"should not include a single failed upload in the artwork names", ^{
+ NSArray<UIImage *> *images = [FileManagerSpecHelper imagesForCount:5];
+ for(int i = 0; i < images.count; i += 1) {
+ SDLArtwork *artwork = [SDLArtwork artworkWithImage:images[i] asImageFormat:SDLArtworkImageFormatPNG];
+ [testArtworks addObject:artwork];
+ }
- it(@"should not include the failed upload in the artwork names", ^{
- testTotalFileCount = 5;
- testFailureIndexStart = 1;
- testFailureIndexEnd = 3;
- expectedSuccessfulArtworkNameCount = 1;
- expectedErrorMessagesCount = 4;
- });
+ [testFileManager uploadArtworks:testArtworks completionHandler:^(NSArray<NSString *> * _Nonnull artworkNames, NSError * _Nullable error) {
+ expect(artworkNames).to(haveCount(images.count - 1));
+ expect(error).toNot(beNil());
+ }];
- it(@"should not return any errors that are overwrite errors", ^{
- testTotalFileCount = 12;
- testFailureIndexEnd = 5;
- testOverwriteErrorIndices = [[NSSet alloc] initWithArray:@[@6, @7]];
- expectedSuccessfulArtworkNameCount = 7;
- expectedErrorMessagesCount = 5;
- });
+ expect(testFileManager.pendingTransactions.count).to(equal(5));
+ for (int i = 0; i < images.count - 1; i += 1) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
+ }
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.lastObject;
+ sentOperation.fileWrapper.completionHandler(NO, failureBytesAvailable, [NSError sdl_fileManager_dataMissingError]);
- it(@"should not return an error if all the errors are overwrite errors", ^{
- testTotalFileCount = 10;
- testFailureIndexEnd = 5;
- testOverwriteErrorIndices = [[NSSet alloc] initWithArray:@[@5, @6, @7, @8, @9]];
- expectedSuccessfulArtworkNameCount = 10;
- expectedErrorMessagesCount = 0;
- });
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
+ });
- afterEach(^{
- NSInteger testSpaceAvailable = initialSpaceAvailable;
- for(int i = 0; i < testTotalFileCount; i += 1) {
- UIGraphicsBeginImageContextWithOptions(CGSizeMake(5, 5), YES, 0);
- CGContextRef context = UIGraphicsGetCurrentContext();
- CGFloat grey = (i % 255) / 255.0;
- [[UIColor colorWithRed:grey green:grey blue:grey alpha:1.0] setFill];
- CGContextFillRect(context, CGRectMake(0, 0, i + 1, i + 1));
- UIImage *greySquareImage = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
-
- SDLArtwork *testArtwork = [SDLArtwork artworkWithImage:greySquareImage asImageFormat:SDLArtworkImageFormatPNG];
- [testArtworks addObject:testArtwork];
-
- SDLPutFileResponse *response = [[SDLPutFileResponse alloc] init];
- NSError *responseError = nil;
- if (i <= testFailureIndexStart || i >= testFailureIndexEnd) {
- // Failed response
- response = failedResponse;
- response.spaceAvailable = @(testSpaceAvailable);
- if ([testOverwriteErrorIndices containsObject:@(i)]) {
- // Overwrite error
- responseError = [NSError sdl_fileManager_cannotOverwriteError];
- [expectedSuccessfulArtworkNames addObject:testArtwork.name];
- } else {
- responseError = [NSError sdl_lifecycle_unknownRemoteErrorWithDescription:[NSString stringWithFormat:@"file upload failed: %d", i] andReason:[NSString stringWithFormat:@"some error reason: %d", i]];
- expectedFailedUploads[testArtwork.name] = responseError;
- }
- } else {
- // Successful response
- response = successfulResponse;
- response.spaceAvailable = @(testSpaceAvailable -= 1);
- responseError = nil;
- [expectedSuccessfulFileNames addObject:testArtwork.name];
- [expectedSuccessfulArtworkNames addObject:testArtwork.name];
- }
- testConnectionManagerResponses[testArtwork.name] = [[TestResponse alloc] initWithResponse:response error:responseError];
- }
-
- testConnectionManager.responses = testConnectionManagerResponses;
- expectedError = expectedFailedUploads.count == 0 ? nil : [NSError sdl_fileManager_unableToUpload_ErrorWithUserInfo:expectedFailedUploads];
- expectedSpaceLeft = @(testSpaceAvailable);
- });
+ it(@"should not return any errors that are overwrite errors", ^{
+ NSArray<UIImage *> *images = [FileManagerSpecHelper imagesForCount:5];
+ for(int i = 0; i < images.count; i++) {
+ SDLArtwork *artwork = [SDLArtwork artworkWithImage:images[i] asImageFormat:SDLArtworkImageFormatPNG];
+ [testArtworks addObject:artwork];
+ }
+
+ [testFileManager uploadArtworks:testArtworks completionHandler:^(NSArray<NSString *> * _Nonnull artworkNames, NSError * _Nullable error) {
+ expect(artworkNames).to(haveCount(images.count));
+ expect(error).to(beNil());
+ }];
+
+ expect(testFileManager.pendingTransactions.count).to(equal(5));
+
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.firstObject;
+ sentOperation.fileWrapper.completionHandler(NO, failureBytesAvailable, [NSError sdl_fileManager_cannotOverwriteError]);
+
+ for (int i = 1; i < images.count; i++) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
+ }
+
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
});
- afterEach(^{
- expect(testFileManager.remoteFileNames.count).to(equal(testListFilesResponse.filenames.count));
-
- waitUntilTimeout(1, ^(void (^done)(void)){
- [testFileManager uploadArtworks:testArtworks completionHandler:^(NSArray<NSString *> * _Nonnull artworkNames, NSError * _Nullable error) {
- expect(artworkNames.count).to(equal(expectedSuccessfulArtworkNameCount));
- if (expectedSuccessfulArtworkNames == nil) {
- expect(artworkNames).to(beNil());
- } else {
- for (NSString *artworkName in expectedSuccessfulArtworkNames) {
- expect(artworkNames).to(contain(artworkName));
- }
- }
-
- if (expectedError == nil) {
- expect(error).to(beNil());
- } else {
- for (NSString *artworkName in expectedError.userInfo) {
- expect([error.userInfo objectForKey:artworkName]).toNot(beNil());
- }
- }
-
- expect(error.userInfo.count).to(equal(expectedErrorMessagesCount));
- expect(testFileManager.bytesAvailable).to(equal(expectedSpaceLeft));
- done();
- }];
- });
+ it(@"should not return an error if all the errors are overwrite errors", ^{
+ NSArray<UIImage *> *images = [FileManagerSpecHelper imagesForCount:5];
+ for(int i = 0; i < images.count; i += 1) {
+ SDLArtwork *artwork = [SDLArtwork artworkWithImage:images[i] asImageFormat:SDLArtworkImageFormatPNG];
+ [testArtworks addObject:artwork];
+ }
+
+ [testFileManager uploadArtworks:testArtworks completionHandler:^(NSArray<NSString *> * _Nonnull artworkNames, NSError * _Nullable error) {
+ expect(artworkNames).to(haveCount(images.count));
+ expect(error).to(beNil());
+ }];
+
+ expect(testFileManager.pendingTransactions.count).to(equal(5));
+ for (int i = 0; i < images.count; i += 1) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ sentOperation.fileWrapper.completionHandler(NO, failureBytesAvailable, [NSError sdl_fileManager_cannotOverwriteError]);
+ }
+
+ expect(testFileManager.bytesAvailable).to(equal(initialSpaceAvailable));
});
});
});
- context(@"and all files are uploaded successfully while expecting a progress response for each file", ^{
+ context(@"files succeed with progress block", ^{
__block NSMutableDictionary *testFileManagerResponses;
__block NSMutableDictionary *testFileManagerProgressResponses;
__block int testTotalFileCount;
- __block NSString *testFileNameBase;
beforeEach(^{
testFileManagerResponses = [[NSMutableDictionary alloc] init];
testFileManagerProgressResponses = [[NSMutableDictionary alloc] init];
});
- describe(@"When uploading files", ^{
- context(@"A progress handler should be returned for each file", ^{
- it(@"should upload 1 small file from memory without error", ^{
- testTotalFileCount = 1;
- testFileNameBase = @"TestProgressHandlerOneSmallFileMemory";
- });
-
- it(@"should upload a large number of small files from memory without error", ^{
- testTotalFileCount = 200;
- testFileNameBase = @"TestProgressHandlerMultipleSmallFileMemory";
- });
+ context(@"when uploading files", ^{
+ it(@"should upload 1 small file from memory without error", ^{
+ NSString *testFileName = [NSString stringWithFormat:@"TestSmallFileMemory%d", 0];
+ SDLFile *testSDLFile = [SDLFile fileWithData:[@"someTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
+ testSDLFile.overwrite = true;
+ [testSDLFiles addObject:testSDLFile];
- afterEach(^{
- NSData *testFileData = [@"someTextData" dataUsingEncoding:NSUTF8StringEncoding];
- float testTotalBytesToUpload = testTotalFileCount * testFileData.length;
- float testTotalBytesUploaded = 0.0;
+ [testFileManager uploadFiles:testSDLFiles progressHandler:^BOOL(SDLFileName * _Nonnull fileName, float uploadPercentage, NSError * _Nullable error) {
+ expect(fileName).to(equal(testFileName));
+ expect(uploadPercentage).to(beCloseTo(1.0));
+ expect(error).to(beNil());
+ return YES;
+ } completionHandler:^(NSError * _Nullable error) {
+ expect(error).to(beNil());
+ }];
- NSInteger testSpaceAvailable = initialSpaceAvailable;
- for(int i = 0; i < testTotalFileCount; i += 1) {
- NSString *testFileName = [NSString stringWithFormat:@"%@%d", testFileNameBase, i];
- SDLFile *testSDLFile = [SDLFile fileWithData:testFileData name:testFileName fileExtension:@"bin"];
- testSDLFile.overwrite = true;
- [testSDLFiles addObject:testSDLFile];
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.firstObject;
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
- successfulResponse.spaceAvailable = @(testSpaceAvailable -= 10);
- [expectedSuccessfulFileNames addObject:testFileName];
- testFileManagerResponses[testFileName] = [[TestResponse alloc] initWithResponse:successfulResponse error:nil];
+ expect(testFileManager.pendingTransactions.count).to(equal(1));
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
+ });
- testTotalBytesUploaded += testSDLFile.fileSize;
- testFileManagerProgressResponses[testFileName] = [[TestFileProgressResponse alloc] initWithFileName:testFileName testUploadPercentage:testTotalBytesUploaded / testTotalBytesToUpload error:nil];
+ it(@"should upload a 5 small files from memory without error", ^{
+ for(int i = 0; i < 5; i += 1) {
+ NSString *testFileName = [NSString stringWithFormat:@"TestSmallFilesMemory%d", i];
+ SDLFile *testSDLFile = [SDLFile fileWithData:[@"someTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
+ testSDLFile.overwrite = true;
+ [testSDLFiles addObject:testSDLFile];
}
- expectedSpaceLeft = @(testSpaceAvailable);
- testConnectionManager.responses = testFileManagerResponses;
- });
- });
- afterEach(^{
- waitUntilTimeout(10, ^(void (^done)(void)){
+ __block NSUInteger numberOfFilesDone = 0;
[testFileManager uploadFiles:testSDLFiles progressHandler:^BOOL(SDLFileName * _Nonnull fileName, float uploadPercentage, NSError * _Nullable error) {
- TestFileProgressResponse *testProgressResponse = testFileManagerProgressResponses[fileName];
- expect(fileName).to(equal(testProgressResponse.testFileName));
- expect(uploadPercentage).to(equal(testProgressResponse.testUploadPercentage));
- expect(error).to(testProgressResponse.testError == nil ? beNil() : equal(testProgressResponse.testError));
+ numberOfFilesDone++;
+ expect(fileName).to(equal([NSString stringWithFormat:@"TestSmallFilesMemory%ld", numberOfFilesDone-1]));
+ expect(uploadPercentage).to(beCloseTo((float)numberOfFilesDone / 5.0));
+ expect(error).to(beNil());
return YES;
} completionHandler:^(NSError * _Nullable error) {
expect(error).to(beNil());
- expect(testFileManager.bytesAvailable).to(equal(expectedSpaceLeft));
- done();
}];
+
+ expect(testFileManager.pendingTransactions.count).to(equal(5));
+ for (int i = 0; i < 5; i += 1) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable - i, nil);
+ }
+
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable - 4));
});
});
- });
- describe(@"When uploading artworks", ^{
+ context(@"when uploading artworks", ^{
__block NSMutableArray<SDLArtwork *> *testArtworks = nil;
__block NSMutableDictionary *testConnectionManagerResponses;
__block NSMutableArray<NSString*> *expectedArtworkNames = nil;
@@ -1159,76 +837,66 @@ describe(@"SDLFileManager uploading/deleting multiple files", ^{
testTotalFileCount = 0;
});
- context(@"A progress handler should be returned for each artwork", ^{
- it(@"should upload 1 artwork without error", ^{
- testTotalFileCount = 1;
- });
+ it(@"should upload 1 artwork without error", ^{
+ NSArray<UIImage *> *images = [FileManagerSpecHelper imagesForCount:1];
- it(@"should upload multiple artworks without error", ^{
- testTotalFileCount = 100;
- });
+ SDLArtwork *testArtwork = [SDLArtwork artworkWithImage:images.firstObject asImageFormat:SDLArtworkImageFormatPNG];
+ [testArtworks addObject:testArtwork];
+ [expectedArtworkNames addObject:testArtwork.name];
- afterEach(^{
- NSInteger spaceAvailable = initialSpaceAvailable;
- float testTotalBytesToUpload = 0; // testTotalFileCount * testFileData.length;
- for (NSUInteger i = 0; i < testTotalFileCount; i += 1) {
- UIGraphicsBeginImageContextWithOptions(CGSizeMake(5, 5), YES, 0);
- CGContextRef context = UIGraphicsGetCurrentContext();
- CGFloat grey = (i % 255) / 255.0;
- [[UIColor colorWithRed:grey green:grey blue:grey alpha:1.0] setFill];
- CGContextFillRect(context, CGRectMake(0, 0, 10, 10));
- UIImage *greySquareImage = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
-
- SDLArtwork *testArtwork = [SDLArtwork artworkWithImage:greySquareImage asImageFormat:SDLArtworkImageFormatPNG];
- [testArtworks addObject:testArtwork];
- [expectedArtworkNames addObject:testArtwork.name];
- testTotalBytesToUpload += testArtwork.fileSize;
-
- successfulResponse.spaceAvailable = @(spaceAvailable -= 1);
- [expectedSuccessfulFileNames addObject:testArtwork.name];
- testFileManagerResponses[testArtwork.name] = [[TestResponse alloc] initWithResponse:successfulResponse error:nil];
-
- testFileManagerProgressResponses[testArtwork.name] = [[TestFileProgressResponse alloc] initWithFileName:testArtwork.name testUploadPercentage:0 error:nil];
- }
-
- float testTotalBytesUploaded = 0.0;
- for (SDLArtwork *artwork in testArtworks) {
- testTotalBytesUploaded += artwork.fileSize;
- TestFileProgressResponse *response = testFileManagerProgressResponses[artwork.name];
- response.testUploadPercentage = testTotalBytesUploaded / testTotalBytesToUpload;
- }
-
- expectedSpaceLeft = @(spaceAvailable);
- testConnectionManager.responses = testFileManagerResponses;
- });
+ [testFileManager uploadArtworks:testArtworks progressHandler:^BOOL(NSString * _Nonnull artworkName, float uploadPercentage, NSError * _Nullable error) {
+ expect(artworkName).to(equal(testArtwork.name));
+ expect(uploadPercentage).to(beCloseTo(1.0));
+ expect(error).to(beNil());
+ return YES;
+ } completionHandler:^(NSArray<NSString *> * _Nonnull artworkNames, NSError * _Nullable error) {
+ expect(artworkNames).to(haveCount(1));
+ expect(artworkNames).to(contain(testArtwork.name));
+ expect(error).to(beNil());
+ }];
+
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.firstObject;
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
+
+ expect(testFileManager.pendingTransactions.count).to(equal(1));
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
});
- afterEach(^{
- waitUntilTimeout(10, ^(void (^done)(void)){
- [testFileManager uploadArtworks:testArtworks progressHandler:^BOOL(NSString * _Nonnull artworkName, float uploadPercentage, NSError * _Nullable error) {
- TestFileProgressResponse *testProgressResponse = testFileManagerProgressResponses[artworkName];
- expect(artworkName).to(equal(testProgressResponse.testFileName));
- expect(uploadPercentage).to(equal(testProgressResponse.testUploadPercentage));
- expect(error).to(testProgressResponse.testError == nil ? beNil() : equal(testProgressResponse.testError));
- return YES;
- } completionHandler:^(NSArray<NSString *> * _Nonnull artworkNames, NSError * _Nullable error) {
- expect(error).to(beNil());
- expect(testFileManager.bytesAvailable).to(equal(expectedSpaceLeft));
- done();
- }];
- });
+ it(@"should upload multiple artworks without error", ^{
+ NSArray<UIImage *> *images = [FileManagerSpecHelper imagesForCount:200];
+
+ for (UIImage *image in images) {
+ SDLArtwork *testArtwork = [SDLArtwork artworkWithImage:image asImageFormat:SDLArtworkImageFormatPNG];
+ [testArtworks addObject:testArtwork];
+ [expectedArtworkNames addObject:testArtwork.name];
+ }
+
+ __block NSUInteger artworksDone = 0;
+ [testFileManager uploadArtworks:testArtworks progressHandler:^BOOL(NSString * _Nonnull artworkName, float uploadPercentage, NSError * _Nullable error) {
+ artworksDone++;
+ expect(artworkName).to(equal(expectedArtworkNames[artworksDone - 1]));
+ expect(uploadPercentage).to(beCloseTo((float)artworksDone / 200.0));
+ expect(error).to(beNil());
+ return YES;
+ } completionHandler:^(NSArray<NSString *> * _Nonnull artworkNames, NSError * _Nullable error) {
+ expect(artworkNames).to(haveCount(200));
+ expect(error).to(beNil());
+ }];
+
+ expect(testFileManager.pendingTransactions.count).to(equal(200));
+ for (int i = 0; i < 200; i += 1) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable - i, nil);
+ }
+
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable - 199));
});
});
});
- context(@"When an upload is canceled while in progress by the cancel parameter of the progress handler", ^{
+ context(@"when an upload is canceled while in progress by the cancel parameter of the progress handler", ^{
__block NSMutableDictionary *testResponses;
__block NSMutableDictionary *testProgressResponses;
- __block NSString *testFileNameBase;
- __block int testFileCount = 0;
- __block int testCancelIndex = 0;
- __block NSError *expectedError;
beforeEach(^{
testResponses = [[NSMutableDictionary alloc] init];
@@ -1236,339 +904,277 @@ describe(@"SDLFileManager uploading/deleting multiple files", ^{
});
it(@"should cancel the remaining files if cancel is triggered after first upload", ^{
- testFileCount = 11;
- testCancelIndex = 0;
- testFileNameBase = @"TestUploadFilesCancelAfterFirst";
- expectedError = [NSError sdl_fileManager_unableToUpload_ErrorWithUserInfo:testResponses];
+ for(int i = 0; i < 5; i += 1) {
+ NSString *testFileName = [NSString stringWithFormat:@"TestSmallFilesMemory%d", i];
+ SDLFile *testSDLFile = [SDLFile fileWithData:[@"someTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
+ testSDLFile.overwrite = true;
+ [testSDLFiles addObject:testSDLFile];
+ }
+
+ __block NSUInteger numberOfFilesDone = 0;
+ [testFileManager uploadFiles:testSDLFiles progressHandler:^BOOL(SDLFileName * _Nonnull fileName, float uploadPercentage, NSError * _Nullable error) {
+ numberOfFilesDone++;
+ expect(fileName).to(equal([NSString stringWithFormat:@"TestSmallFilesMemory%ld", numberOfFilesDone-1]));
+ expect(uploadPercentage).to(beCloseTo((float)numberOfFilesDone / 5.0));
+
+ if (numberOfFilesDone == 1) {
+ expect(error).to(beNil());
+ return NO;
+ } else {
+ expect(error).toNot(beNil());
+ return YES;
+ }
+ } completionHandler:^(NSError * _Nullable error) {
+ expect(error).toNot(beNil());
+ }];
+
+ expect(testFileManager.pendingTransactions.count).to(equal(5));
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.firstObject;
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
+
+ for (int i = 1; i < 5; i++) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ expect(sentOperation.cancelled).to(beTrue());
+ sentOperation.fileWrapper.completionHandler(NO, failureBytesAvailable, [NSError sdl_fileManager_fileUploadCanceled]);
+ }
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
});
it(@"should cancel the remaining files if cancel is triggered after half of the files are uploaded", ^{
- testFileCount = 30;
- testCancelIndex = testFileCount / 2;
- testFileNameBase = @"TestUploadFilesCancelInMiddle";
- expectedError = [NSError sdl_fileManager_unableToUpload_ErrorWithUserInfo:testResponses];
- });
+ for(int i = 0; i < 5; i += 1) {
+ NSString *testFileName = [NSString stringWithFormat:@"TestSmallFilesMemory%d", i];
+ SDLFile *testSDLFile = [SDLFile fileWithData:[@"someTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
+ testSDLFile.overwrite = true;
+ [testSDLFiles addObject:testSDLFile];
+ }
- it(@"should not fail if there are no more files to cancel", ^{
- testFileCount = 20;
- testCancelIndex = (testFileCount - 1);
- testFileNameBase = @"TestUploadFilesCancelAtEnd";
- expectedError = nil;
+ __block NSUInteger numberOfFilesDone = 0;
+ [testFileManager uploadFiles:testSDLFiles progressHandler:^BOOL(SDLFileName * _Nonnull fileName, float uploadPercentage, NSError * _Nullable error) {
+ numberOfFilesDone++;
+ expect(fileName).to(equal([NSString stringWithFormat:@"TestSmallFilesMemory%ld", numberOfFilesDone-1]));
+ expect(uploadPercentage).to(beCloseTo((float)numberOfFilesDone / 5.0));
+
+ if (numberOfFilesDone <= 3) {
+ expect(error).to(beNil());
+ } else {
+ expect(error).toNot(beNil());
+ }
+
+ if (numberOfFilesDone == 3) {
+ return NO;
+ } else {
+ return YES;
+ }
+ } completionHandler:^(NSError * _Nullable error) {
+ expect(error).toNot(beNil());
+ }];
+
+ expect(testFileManager.pendingTransactions.count).to(equal(5));
+ for (int i = 0; i < 3; i++) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
+ }
+
+ for (int i = 3; i < 5; i++) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ expect(sentOperation.cancelled).to(beTrue());
+ sentOperation.fileWrapper.completionHandler(NO, failureBytesAvailable, [NSError sdl_fileManager_fileUploadCanceled]);
+ }
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
});
- afterEach(^{
- for(int i = 0; i < testFileCount; i += 1) {
- NSString *testFileName = [NSString stringWithFormat:@"%@%d", testFileNameBase, i];
+ it(@"should not fail if there are no more files to cancel", ^{
+ for(int i = 0; i < 5; i += 1) {
+ NSString *testFileName = [NSString stringWithFormat:@"TestSmallFilesMemory%d", i];
SDLFile *testSDLFile = [SDLFile fileWithData:[@"someTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
testSDLFile.overwrite = true;
[testSDLFiles addObject:testSDLFile];
+ }
- if (i <= testCancelIndex) {
- [expectedSuccessfulFileNames addObject:testFileName];
- }
+ __block NSUInteger numberOfFilesDone = 0;
+ [testFileManager uploadFiles:testSDLFiles progressHandler:^BOOL(SDLFileName * _Nonnull fileName, float uploadPercentage, NSError * _Nullable error) {
+ numberOfFilesDone++;
+ expect(fileName).to(equal([NSString stringWithFormat:@"TestSmallFilesMemory%ld", numberOfFilesDone-1]));
+ expect(uploadPercentage).to(beCloseTo((float)numberOfFilesDone / 5));
+ expect(error).to(beNil());
+ return numberOfFilesDone == 5 ? NO : YES;
+ } completionHandler:^(NSError * _Nullable error) {
+ expect(error).to(beNil());
+ }];
- testResponses[testFileName] = [[TestResponse alloc] initWithResponse:successfulResponse error:nil];
- testProgressResponses[testFileName] = [[TestFileProgressResponse alloc] initWithFileName:testFileName testUploadPercentage:0.0 error:nil];
+ expect(testFileManager.pendingTransactions.count).to(equal(5));
+ for (int i = 0; i < 5; i++) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
}
- testConnectionManager.responses = testResponses;
-
- waitUntilTimeout(10, ^(void (^done)(void)){
- [testFileManager uploadFiles:testSDLFiles progressHandler:^(NSString * _Nonnull fileName, float uploadPercentage, NSError * _Nullable error) {
- // Once operations are canceled, the order in which the operations complete is random, so the upload percentage and the error message can vary. This means we can not test the error message or upload percentage it will be different every test run.
- TestFileProgressResponse *testProgressResponse = testProgressResponses[fileName];
- expect(fileName).to(equal(testProgressResponse.testFileName));
-
- NSString *cancelFileName = [NSString stringWithFormat:@"%@%d", testFileNameBase, testCancelIndex];
- if ([fileName isEqual:cancelFileName]) {
- return NO;
- }
- return YES;
- } completionHandler:^(NSError * _Nullable error) {
- if (expectedError != nil) {
- expect(error.code).to(equal(SDLFileManagerMultipleFileUploadTasksFailed));
- } else {
- expect(error).to(beNil());
- }
- done();
- }];
- });
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
});
});
context(@"When an upload is canceled it should only cancel files that were passed with the same file array", ^{
- // When canceled is called in this test group, the rest of the files should be canceled
- __block NSMutableDictionary *testResponses;
- __block NSMutableDictionary *testProgressResponses;
- __block NSString *testFileNameBase;
- __block int testFileCount = 0;
- __block int testCancelIndex = 0;
- __block NSError *expectedError;
-
- // Another group of uploads. These uploads should not be canceled when the other files are canceled
+ // Another group of uploads. These uploads should not be canceled when the other files are canceled.
__block NSMutableArray<SDLFile *> *testOtherSDLFiles;
- __block NSString *testOtherFileNameBase;
- __block int testOtherFileCount = 0;
- __block NSError *expectedOtherError;
beforeEach(^{
- testResponses = [[NSMutableDictionary alloc] init];
- testProgressResponses = [[NSMutableDictionary alloc] init];
-
testOtherSDLFiles = [[NSMutableArray alloc] init];
});
it(@"should only cancel the remaining files that were passed with the same file. Other files in the queue that were not passed in the same array should not be canceled", ^{
- testFileCount = 11;
- testCancelIndex = 0;
- testFileNameBase = @"TestUploadFilesCancelGroupOnly";
- expectedError = [NSError sdl_fileManager_unableToUpload_ErrorWithUserInfo:testResponses];
-
- testOtherFileNameBase = @"TestOtherUploadFilesCancelGroupOnly";
- testOtherFileCount = 22;
- expectedOtherError = nil;
- });
-
- it(@"should not fail if no files are canceled", ^{
- testFileCount = 1;
- testCancelIndex = 0;
- testFileNameBase = @"TestUploadFilesCancelGroupOnlyOneFile";
- expectedError = nil;
-
- testOtherFileNameBase = @"TestOtherUploadFilesCancelGroupOnlyOneFile";
- testOtherFileCount = 2;
- expectedOtherError = nil;
- });
-
- afterEach(^{
- for(int i = 0; i < testFileCount; i += 1) {
- NSString *testFileName = [NSString stringWithFormat:@"%@%d", testFileNameBase, i];
+ // Files to be cancelled
+ for(int i = 0; i < 5; i += 1) {
+ NSString *testFileName = [NSString stringWithFormat:@"TestSmallFilesMemory%d", i];
SDLFile *testSDLFile = [SDLFile fileWithData:[@"someTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
- testSDLFile.overwrite = true;
[testSDLFiles addObject:testSDLFile];
-
- if (i <= testCancelIndex) {
- [expectedSuccessfulFileNames addObject:testFileName];
- }
-
- testResponses[testFileName] = [[TestResponse alloc] initWithResponse:successfulResponse error:nil];
- testProgressResponses[testFileName] = [[TestFileProgressResponse alloc] initWithFileName:testFileName testUploadPercentage:0.0 error:nil];
}
- for(int i = 0; i < testOtherFileCount; i += 1) {
- NSString *testFileName = [NSString stringWithFormat:@"%@%d", testOtherFileNameBase, i];
- SDLFile *testSDLFile = [SDLFile fileWithData:[@"someOtherTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
- testSDLFile.overwrite = true;
+ // Files not to be cancelled
+ for(int i = 0; i < 5; i += 1) {
+ NSString *testFileName = [NSString stringWithFormat:@"TestOtherFilesMemory%d", i];
+ SDLFile *testSDLFile = [SDLFile fileWithData:[@"someTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
[testOtherSDLFiles addObject:testSDLFile];
+ }
- [expectedSuccessfulFileNames addObject:testFileName];
+ __block NSUInteger numberOfFilesDone = 0;
+ [testFileManager uploadFiles:testSDLFiles progressHandler:^BOOL(SDLFileName * _Nonnull fileName, float uploadPercentage, NSError * _Nullable error) {
+ numberOfFilesDone++;
+ expect(fileName).to(equal([NSString stringWithFormat:@"TestSmallFilesMemory%ld", numberOfFilesDone-1]));
+ expect(uploadPercentage).to(beCloseTo((float)numberOfFilesDone / 5));
- testResponses[testFileName] = [[TestResponse alloc] initWithResponse:successfulResponse error:nil];
- }
+ if (numberOfFilesDone == 1) {
+ expect(error).to(beNil());
+ } else {
+ expect(error).toNot(beNil());
+ }
- testConnectionManager.responses = testResponses;
+ return NO;
+ } completionHandler:^(NSError * _Nullable error) {
+ expect(error).toNot(beNil());
+ }];
- waitUntilTimeout(10, ^(void (^done)(void)){
- [testFileManager uploadFiles:testSDLFiles progressHandler:^(NSString * _Nonnull fileName, float uploadPercentage, NSError * _Nullable error) {
- // Once operations are canceled, the order in which the operations complete is random, so the upload percentage and the error message can vary. This means we can not test the error message or upload percentage it will be different every test run.
- TestFileProgressResponse *testProgressResponse = testProgressResponses[fileName];
- expect(fileName).to(equal(testProgressResponse.testFileName));
+ [testFileManager uploadFiles:testOtherSDLFiles completionHandler:^(NSError * _Nullable error) {
+ expect(error).to(beNil());
+ }];
- NSString *cancelFileName = [NSString stringWithFormat:@"%@%d", testFileNameBase, testCancelIndex];
- if ([fileName isEqual:cancelFileName]) {
- return NO;
- }
- return YES;
- } completionHandler:^(NSError * _Nullable error) {
- if (expectedError != nil) {
- expect(error.code).to(equal(SDLFileManagerMultipleFileUploadTasksFailed));
- } else {
- expect(error).to(beNil());
- }
- }];
+ expect(testFileManager.pendingTransactions.count).to(equal(10));
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.firstObject;
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
- [testFileManager uploadFiles:testOtherSDLFiles completionHandler:^(NSError * _Nullable error) {
- expect(error).to(beNil());
- // Since the queue is serial, we know that these files will finish after the first uploadFiles() batch.
- done();
- }];
- });
- });
- });
+ for (int i = 1; i < 5; i++) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ expect(sentOperation.cancelled).to(beTrue());
+ sentOperation.fileWrapper.completionHandler(NO, failureBytesAvailable, [NSError sdl_fileManager_fileUploadCanceled]);
+ }
- afterEach(^{
- for(int i = 0; i < expectedSuccessfulFileNames.count; i += 1) {
- expect(testFileManager.remoteFileNames).to(contain(expectedSuccessfulFileNames[i]));
- }
+ for (int i = 5; i < 10; i++) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ expect(sentOperation.cancelled).to(beFalse());
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
+ }
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
+ });
});
});
context(@"When the file manager is passed multiple files to delete", ^{
- __block SDLListFilesResponse *testListFilesResponse;
- __block NSArray<NSString *> *testRemoteFileNames;
- __block NSMutableArray<NSString *> *expectedRemoteFileNames;
- __block NSNumber *expectedSpaceLeft;
- __block NSMutableArray *testDeleteFileNames;
- __block SDLDeleteFileResponse *failedDeleteResponse;
- __block SDLDeleteFileResponse *successfulDeleteResponse;
- __block NSError *expectedError = nil;
-
beforeEach(^{
- testRemoteFileNames = [[NSArray alloc] initWithObjects:@"AA", @"BB", @"CC", @"DD", @"EE", @"FF", nil];
- expectedRemoteFileNames = [[NSMutableArray alloc] init];
-
- testListFilesResponse = [[SDLListFilesResponse alloc] init];
- testListFilesResponse.success = @YES;
- testListFilesResponse.spaceAvailable = @(initialSpaceAvailable);
- testListFilesResponse.filenames = testRemoteFileNames;
-
- // Failed delete response
- failedDeleteResponse = [[SDLDeleteFileResponse alloc] init];
- failedDeleteResponse.spaceAvailable = @10;
- failedDeleteResponse.success = @NO;
-
- // Successful delete response
- successfulDeleteResponse = [[SDLDeleteFileResponse alloc] init];
- successfulDeleteResponse.spaceAvailable = @9;
- successfulDeleteResponse.success = @YES;
-
- waitUntilTimeout(10, ^(void (^done)(void)){
- [testFileManager startWithCompletionHandler:^(BOOL success, NSError * _Nullable error) {
- done();
- }];
-
- // Need to wait state machine transitions to complete before sending testListFilesResponse
- [NSThread sleepForTimeInterval:0.3];
-
- [testConnectionManager respondToLastRequestWithResponse:testListFilesResponse];
- });
+ testFileManager.mutableRemoteFileNames = [NSMutableSet setWithObjects:@"AA", @"BB", @"CC", @"DD", @"EE", @"FF", nil];
+ testFileManager.bytesAvailable = initialSpaceAvailable;
});
context(@"and all files are deleted successfully", ^{
- __block NSMutableDictionary *testResponses;
- __block int testFileCount = 0;
+ it(@"should not return an error when one remote file is deleted", ^{
+ [testFileManager deleteRemoteFilesWithNames:@[@"AA"] completionHandler:^(NSError * _Nullable error) {
+ expect(error).to(beNil());
+ }];
- beforeEach(^{
- testResponses = [[NSMutableDictionary alloc] init];
- testDeleteFileNames = [[NSMutableArray alloc] init];
+ expect(testFileManager.pendingTransactions.count).to(equal(1));
+ SDLDeleteFileOperation *deleteOp = testFileManager.pendingTransactions.firstObject;
+ deleteOp.completionHandler(YES, newBytesAvailable, nil);
+
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
+ expect(testFileManager.remoteFileNames).toNot(contain(@"AA"));
});
- context(@"When the file manager receives a successful notification for each deleted file", ^{
- it(@"should not return an error when one remote file is deleted", ^{
- testFileCount = 1;
- });
+ it(@"should not return an error when all remote files are deleted", ^{
+ [testFileManager deleteRemoteFilesWithNames:@[@"AA", @"BB", @"CC", @"DD", @"EE", @"FF"] completionHandler:^(NSError * _Nullable error) {
+ expect(error).to(beNil());
+ }];
- it(@"should not return an error when all remote files are deleted", ^{
- testFileCount = (int)testRemoteFileNames.count;
- });
+ expect(testFileManager.pendingTransactions.count).to(equal(6));
+ for (int i = 0; i < 6; i++) {
+ SDLDeleteFileOperation *deleteOp = testFileManager.pendingTransactions[i];
+ deleteOp.completionHandler(YES, newBytesAvailable, nil);
+ }
- afterEach(^{
- NSInteger testSpaceAvailable = initialSpaceAvailable;
- for(int i = 0; i < testFileCount; i += 1) {
- NSString *testFileName = [testRemoteFileNames objectAtIndex:i];
- successfulDeleteResponse.spaceAvailable = @(testSpaceAvailable += 91);
- testResponses[testFileName] = [[TestResponse alloc] initWithResponse:successfulDeleteResponse error:nil];
- [testDeleteFileNames addObject:testFileName];
- }
- expectedSpaceLeft = @(testSpaceAvailable);
- [expectedRemoteFileNames removeAllObjects];
- testConnectionManager.responses = testResponses;
- });
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
+ expect(testFileManager.remoteFileNames).to(haveCount(0));
});
});
context(@"and all files are not deleted successfully", ^{
- __block NSMutableDictionary *testConnectionManagerResponses;
- __block NSMutableDictionary *expectedFailedDeletes;
+ __block int testFailureIndexStart;
+ __block int testFailureIndexEnd;
beforeEach(^{
- testConnectionManagerResponses = [[NSMutableDictionary alloc] init];
- testDeleteFileNames = [[NSMutableArray alloc] init];
- expectedFailedDeletes = [[NSMutableDictionary alloc] init];
+ testFailureIndexStart = -1;
+ testFailureIndexEnd = INT8_MAX;
});
- context(@"When the file manager receives a unsuccessful notification for a deleted file", ^{
- __block int testFailureIndexStart;
- __block int testFailureIndexEnd;
+ it(@"should return an error if the first remote file fails to delete", ^{
+ [testFileManager deleteRemoteFilesWithNames:@[@"AA", @"BB", @"CC", @"DD", @"EE", @"FF"] completionHandler:^(NSError * _Nullable error) {
+ expect(error).toNot(beNil());
+ }];
- beforeEach(^{
- testFailureIndexStart = -1;
- testFailureIndexEnd = INT8_MAX;
- });
+ expect(testFileManager.pendingTransactions.count).to(equal(6));
+ SDLDeleteFileOperation *deleteOp = testFileManager.pendingTransactions.firstObject;
+ deleteOp.completionHandler(NO, newBytesAvailable, [NSError sdl_fileManager_unableToDelete_ErrorWithUserInfo:@{}]);
- it(@"should return an error if the first remote file fails to delete", ^{
- testFailureIndexStart = 0;
- });
+ for (int i = 1; i < 6; i++) {
+ SDLDeleteFileOperation *deleteOp = testFileManager.pendingTransactions[i];
+ deleteOp.completionHandler(YES, newBytesAvailable, nil);
+ }
- it(@"should return an error if the last remote file fails to delete", ^{
- testFailureIndexEnd = (int)testRemoteFileNames.count - 1;
- });
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
+ expect(testFileManager.remoteFileNames).to(haveCount(1));
+ });
- it(@"should return an error if all files fail to delete", ^{
- testFailureIndexStart = (int)testRemoteFileNames.count;
- });
+ it(@"should return an error if the last remote file fails to delete", ^{
+ [testFileManager deleteRemoteFilesWithNames:@[@"AA", @"BB", @"CC", @"DD", @"EE", @"FF"] completionHandler:^(NSError * _Nullable error) {
+ expect(error).toNot(beNil());
+ }];
- afterEach(^{
- NSInteger testSpaceAvailable = initialSpaceAvailable;
- for(int i = 0; i < testRemoteFileNames.count; i += 1) {
- NSString *testFileName = [testRemoteFileNames objectAtIndex:i];
-
- SDLDeleteFileResponse *response;
- NSError *responseError;
- if (i <= testFailureIndexStart || i >= testFailureIndexEnd) {
- failedDeleteResponse.spaceAvailable = @(testSpaceAvailable);
- response = failedDeleteResponse;
- responseError = [NSError sdl_lifecycle_unknownRemoteErrorWithDescription:[NSString stringWithFormat:@"file upload failed: %d", i] andReason: [NSString stringWithFormat:@"some error reason: %d", i]];
- expectedFailedDeletes[testFileName] = responseError;
- [expectedRemoteFileNames addObject:testFileName];
- } else {
- successfulDeleteResponse.spaceAvailable = @(testSpaceAvailable += 891);
- response = successfulDeleteResponse;
- responseError = nil;
- }
-
- testConnectionManagerResponses[testFileName] = [[TestResponse alloc] initWithResponse:response error:responseError];
- [testDeleteFileNames addObject:testFileName];
- }
+ expect(testFileManager.pendingTransactions.count).to(equal(6));
+ for (int i = 0; i < 5; i++) {
+ SDLDeleteFileOperation *deleteOp = testFileManager.pendingTransactions[i];
+ deleteOp.completionHandler(YES, newBytesAvailable, nil);
+ }
+ SDLDeleteFileOperation *deleteOp = testFileManager.pendingTransactions.lastObject;
+ deleteOp.completionHandler(NO, newBytesAvailable, [NSError sdl_fileManager_unableToDelete_ErrorWithUserInfo:@{}]);
- testConnectionManager.responses = testConnectionManagerResponses;
- expectedError = [NSError sdl_fileManager_unableToDelete_ErrorWithUserInfo:expectedFailedDeletes];
- expectedSpaceLeft = @(testSpaceAvailable);
- });
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
+ expect(testFileManager.remoteFileNames).to(haveCount(1));
});
- });
- afterEach(^{
- waitUntilTimeout(10, ^(void (^done)(void)){
- [testFileManager deleteRemoteFilesWithNames:testDeleteFileNames completionHandler:^(NSError * _Nullable error) {
- expect(error).to(expectedError == nil ? beNil() : equal(expectedError));
- expect(testFileManager.bytesAvailable).to(equal(expectedSpaceLeft));
- done();
+ it(@"should return an error if all files fail to delete", ^{
+ [testFileManager deleteRemoteFilesWithNames:@[@"AA", @"BB", @"CC", @"DD", @"EE", @"FF"] completionHandler:^(NSError * _Nullable error) {
+ expect(error).toNot(beNil());
}];
- });
- for(int i = 0; i < expectedRemoteFileNames.count; i += 1) {
- expect(testFileManager.remoteFileNames).to(contain(expectedRemoteFileNames[i]));
- }
+ expect(testFileManager.pendingTransactions.count).to(equal(6));
+ for (int i = 0; i < 6; i++) {
+ SDLDeleteFileOperation *deleteOp = testFileManager.pendingTransactions[i];
+ deleteOp.completionHandler(NO, newBytesAvailable, [NSError sdl_fileManager_unableToDelete_ErrorWithUserInfo:@{}]);
+ }
+
+ expect(testFileManager.bytesAvailable).to(equal(initialSpaceAvailable));
+ expect(testFileManager.remoteFileNames).to(haveCount(6));
+ });
});
});
context(@"The file manager should handle exceptions correctly", ^{
beforeEach(^{
- SDLListFilesResponse *testListFilesResponse = [[SDLListFilesResponse alloc] init];
- testListFilesResponse.success = @YES;
- testListFilesResponse.spaceAvailable = @(initialSpaceAvailable);
- testListFilesResponse.filenames = [[NSArray alloc] initWithObjects:@"AA", nil];
-
- waitUntilTimeout(10, ^(void (^done)(void)){
- [testFileManager startWithCompletionHandler:^(BOOL success, NSError * _Nullable error) {
- done();
- }];
-
- // Need to wait state machine transitions to complete before sending testListFilesResponse
- [NSThread sleepForTimeInterval:0.3];
-
- [testConnectionManager respondToLastRequestWithResponse:testListFilesResponse];
- });
+ testFileManager.mutableRemoteFileNames = [NSMutableSet setWithObjects:@"AA", nil];
});
it(@"should throw an exception when the upload function is passed an empty array", ^{
@@ -1609,6 +1215,10 @@ describe(@"SDLFileManager reupload failed files", ^{
__block TestConnectionManager *testConnectionManager = nil;
__block SDLFileManagerConfiguration *testFileManagerConfiguration = nil;
+ afterEach(^{
+ [testFileManager stop];
+ });
+
it(@"should set the max upload attempts to 2 if the configuration properties are not set", ^{
testFileManagerConfiguration = [SDLFileManagerConfiguration defaultConfiguration];
testFileManager = [[SDLFileManager alloc] initWithConnectionManager:testConnectionManager configuration:testFileManagerConfiguration];
@@ -1672,10 +1282,15 @@ describe(@"SDLFileManager reupload failed files", ^{
testConnectionManager = [[TestConnectionManager alloc] init];
testFileManagerConfiguration = [[SDLFileManagerConfiguration alloc] initWithArtworkRetryCount:0 fileRetryCount:0];
testFileManager = [[SDLFileManager alloc] initWithConnectionManager:testConnectionManager configuration:testFileManagerConfiguration];
+ testFileManager.suspended = YES;
testFailedFileUploadsCount = [NSMutableDictionary dictionary];
testFile = [[SDLFile alloc] initWithData:[@"someData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin" persistent:false];
});
+ afterEach(^{
+ [testFileManager stop];
+ });
+
describe(@"the file cannot be uploaded again", ^{
it(@"should not upload a file that is nil", ^{
// Make sure we are in the ready state
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m
index 83805292a..6d2fd0c79 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m
@@ -136,7 +136,6 @@ describe(@"a lifecycle manager", ^{
expect(testManager.streamManager).toNot(beNil());
expect(testManager.systemCapabilityManager).toNot(beNil());
expect(testManager.rpcOperationQueue).toNot(beNil());
- expect(testManager.rpcOperationQueue.maxConcurrentOperationCount).to(equal(3));
expect(@([testManager conformsToProtocol:@protocol(SDLConnectionManagerType)])).to(equal(@YES));
expect(testManager.authToken).to(beNil());
});
@@ -255,12 +254,10 @@ describe(@"a lifecycle manager", ^{
});
describe(@"stopping the manager", ^{
- beforeEach(^{
- [testManager stop];
- });
-
it(@"should simply stop", ^{
- expect(testManager.lifecycleState).to(match(SDLLifecycleStateStopped));
+ [testManager stop];
+
+ expect(testManager.lifecycleState).toEventually(match(SDLLifecycleStateStopped));
});
});
});
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLLockScreenConfigurationSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLLockScreenConfigurationSpec.m
index 59c3974df..d35717658 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLLockScreenConfigurationSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLLockScreenConfigurationSpec.m
@@ -14,8 +14,10 @@ describe(@"a lock screen configuration", ^{
});
it(@"should properly set properties", ^{
- expect(@(testConfig.enableAutomaticLockScreen)).to(beFalsy());
- expect(@(testConfig.showInOptionalState)).to(beFalsy());
+ expect(testConfig.enableAutomaticLockScreen).to(beFalse());
+ expect(testConfig.showInOptionalState).to(beFalse());
+ expect(testConfig.enableDismissGesture).to(beFalse());
+ expect(testConfig.showDeviceLogo).to(beFalse());
expect(testConfig.backgroundColor).to(equal([UIColor colorWithRed:(57.0/255.0) green:(78.0/255.0) blue:(96.0/255.0) alpha:1.0]));
expect(testConfig.appIcon).to(beNil());
expect(testConfig.customViewController).to(beNil());
@@ -28,8 +30,10 @@ describe(@"a lock screen configuration", ^{
});
it(@"should properly set properties", ^{
- expect(@(testConfig.enableAutomaticLockScreen)).to(beTruthy());
- expect(@(testConfig.showInOptionalState)).to(beFalsy());
+ expect(testConfig.enableAutomaticLockScreen).to(beTrue());
+ expect(testConfig.showInOptionalState).to(beFalse());
+ expect(testConfig.enableDismissGesture).to(beTrue());
+ expect(testConfig.showDeviceLogo).to(beTrue());
expect(testConfig.backgroundColor).to(equal([UIColor colorWithRed:(57.0/255.0) green:(78.0/255.0) blue:(96.0/255.0) alpha:1.0]));
expect(testConfig.appIcon).to(beNil());
expect(testConfig.customViewController).to(beNil());
@@ -48,8 +52,10 @@ describe(@"a lock screen configuration", ^{
});
it(@"should properly set properties", ^{
- expect(@(testConfig.enableAutomaticLockScreen)).to(beTruthy());
- expect(@(testConfig.showInOptionalState)).to(beFalsy());
+ expect(testConfig.enableAutomaticLockScreen).to(beTrue());
+ expect(testConfig.showInOptionalState).to(beFalse());
+ expect(testConfig.enableDismissGesture).to(beTrue());
+ expect(testConfig.showDeviceLogo).to(beTrue());
expect(testConfig.backgroundColor).to(equal([UIColor blueColor]));
expect(testConfig.appIcon).to(equal(testImage));
expect(testConfig.customViewController).to(beNil());
@@ -66,8 +72,10 @@ describe(@"a lock screen configuration", ^{
});
it(@"should properly set properties", ^{
- expect(@(testConfig.enableAutomaticLockScreen)).to(beTruthy());
- expect(@(testConfig.showInOptionalState)).to(beFalsy());
+ expect(testConfig.enableAutomaticLockScreen).to(beTrue());
+ expect(testConfig.showInOptionalState).to(beFalse());
+ expect(testConfig.enableDismissGesture).to(beTrue());
+ expect(testConfig.showDeviceLogo).to(beTrue());
expect(testConfig.backgroundColor).to(equal([UIColor colorWithRed:(57.0/255.0) green:(78.0/255.0) blue:(96.0/255.0) alpha:1.0]));
expect(testConfig.appIcon).to(beNil());
expect(testConfig.customViewController).to(equal(testVC));
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLLockScreenManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLLockScreenManagerSpec.m
index 489de7fb0..4f808bd3a 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLLockScreenManagerSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLLockScreenManagerSpec.m
@@ -10,8 +10,25 @@
#import "SDLNotificationConstants.h"
#import "SDLNotificationDispatcher.h"
#import "SDLOnLockScreenStatus.h"
+#import "SDLOnDriverDistraction.h"
#import "SDLRPCNotificationNotification.h"
+@interface SDLLockScreenManager ()
+
+@property (assign, nonatomic) BOOL canPresent;
+@property (strong, nonatomic, readwrite) SDLLockScreenConfiguration *config;
+@property (strong, nonatomic) id<SDLViewControllerPresentable> presenter;
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+@property (strong, nonatomic, nullable) SDLOnLockScreenStatus *lastLockNotification;
+#pragma clang diagnostic pop
+
+@property (strong, nonatomic, nullable) SDLOnDriverDistraction *lastDriverDistractionNotification;
+@property (assign, nonatomic, readwrite, getter=isLockScreenDismissable) BOOL lockScreenDismissable;
+@property (assign, nonatomic) BOOL lockScreenDismissedByUser;
+
+@end
QuickSpecBegin(SDLLockScreenManagerSpec)
@@ -31,7 +48,7 @@ describe(@"a lock screen manager", ^{
it(@"should set properties correctly", ^{
// Note: We can't check the "lockScreenPresented" flag on the Lock Screen Manager because it's a computer property checking the window
- expect(@(fakePresenter.presented)).to(beFalsy());
+ expect(fakePresenter.presented).to(beFalse());
expect(testManager.lockScreenViewController).to(beNil());
});
@@ -46,10 +63,17 @@ describe(@"a lock screen manager", ^{
});
describe(@"when the lock screen status becomes REQUIRED", ^{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
__block SDLOnLockScreenStatus *testRequiredStatus = nil;
-
+#pragma clang diagnostic pop
+
beforeEach(^{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
testRequiredStatus = [[SDLOnLockScreenStatus alloc] init];
+#pragma clang diagnostic pop
+
testRequiredStatus.lockScreenStatus = SDLLockScreenStatusRequired;
[testNotificationDispatcher postNotificationName:SDLDidChangeLockScreenStatusNotification infoObject:testRequiredStatus];
@@ -84,10 +108,17 @@ describe(@"a lock screen manager", ^{
});
describe(@"when the lock screen status becomes REQUIRED", ^{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
__block SDLOnLockScreenStatus *testRequiredStatus = nil;
-
+#pragma clang diagnostic pop
+ __block SDLOnDriverDistraction *testDriverDistraction = nil;
+
beforeEach(^{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
testRequiredStatus = [[SDLOnLockScreenStatus alloc] init];
+#pragma clang diagnostic pop
testRequiredStatus.lockScreenStatus = SDLLockScreenStatusRequired;
SDLRPCNotificationNotification *testLockStatusNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidChangeLockScreenStatusNotification object:nil rpcNotification:testRequiredStatus];
@@ -95,7 +126,7 @@ describe(@"a lock screen manager", ^{
});
it(@"should have presented the lock screen", ^{
- expect(@(fakePresenter.presented)).to(beTruthy());
+ expect(fakePresenter.presented).to(beTrue());
});
it(@"should not have a vehicle icon", ^{
@@ -116,6 +147,58 @@ describe(@"a lock screen manager", ^{
});
});
+ describe(@"when a driver distraction notification is posted with lockScreenDismissableEnabled as true", ^{
+ __block SDLRPCNotificationNotification *testDriverDistractionNotification = nil;
+
+ beforeEach(^{
+ testDriverDistraction = [[SDLOnDriverDistraction alloc] init];
+ testDriverDistraction.lockScreenDismissalEnabled = @YES;
+
+ testDriverDistractionNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidChangeDriverDistractionStateNotification object:nil rpcNotification:testDriverDistraction];
+
+ [[NSNotificationCenter defaultCenter] postNotification:testDriverDistractionNotification];
+ });
+
+ it(@"should be able to be dismissed", ^{
+ expect(testManager.isLockScreenDismissable).toEventually(equal(YES));
+ });
+ });
+
+ describe(@"when a driver distraction notification is posted with lockScreenDismissableEnabled as false", ^{
+ __block SDLRPCNotificationNotification *testDriverDistractionNotification = nil;
+
+ beforeEach(^{
+ testDriverDistraction = [[SDLOnDriverDistraction alloc] init];
+ testDriverDistraction.lockScreenDismissalEnabled = @0;
+
+ testDriverDistractionNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidChangeDriverDistractionStateNotification object:nil rpcNotification:testDriverDistraction];
+
+ [[NSNotificationCenter defaultCenter] postNotification:testDriverDistractionNotification];
+ });
+
+ it(@"should not be able to be dismissed", ^{
+ expect(testManager.isLockScreenDismissable).toEventually(equal(NO));
+ });
+
+ });
+
+ describe(@"when a driver distraction notification is posted with lockScreenDismissableEnabled nil bit", ^{
+ __block SDLRPCNotificationNotification *testDriverDistractionNotification = nil;
+
+ beforeEach(^{
+ testDriverDistraction = [[SDLOnDriverDistraction alloc] init];
+
+ testDriverDistractionNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidChangeDriverDistractionStateNotification object:nil rpcNotification:testDriverDistraction];
+
+ [[NSNotificationCenter defaultCenter] postNotification:testDriverDistractionNotification];
+ });
+
+ it(@"should not be able to be dismissed", ^{
+ expect(testManager.isLockScreenDismissable).toEventually(equal(NO));
+ });
+
+ });
+
describe(@"then the manager is stopped", ^{
beforeEach(^{
[testManager stop];
@@ -127,10 +210,16 @@ describe(@"a lock screen manager", ^{
});
describe(@"then the status becomes OFF", ^{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
__block SDLOnLockScreenStatus *testOffStatus = nil;
+#pragma clang diagnostic pop
beforeEach(^{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
testOffStatus = [[SDLOnLockScreenStatus alloc] init];
+#pragma clang diagnostic pop
testOffStatus.lockScreenStatus = SDLLockScreenStatusOff;
SDLRPCNotificationNotification *testLockStatusNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidChangeLockScreenStatusNotification object:nil rpcNotification:testOffStatus];
@@ -144,7 +233,31 @@ describe(@"a lock screen manager", ^{
});
});
});
-
+
+ context(@"with showDeviceLogo as NO", ^{
+ beforeEach(^{
+ SDLLockScreenConfiguration *config = [SDLLockScreenConfiguration enabledConfiguration];
+ config.showDeviceLogo = NO;
+
+ testManager = [[SDLLockScreenManager alloc] initWithConfiguration:config notificationDispatcher:nil presenter:fakePresenter];
+ [testManager start];
+ });
+
+ describe(@"when a vehicle icon is received", ^{
+ __block UIImage *testIcon = nil;
+
+ beforeEach(^{
+ testIcon = [UIImage imageNamed:@"testImagePNG" inBundle:[NSBundle bundleForClass:self.class] compatibleWithTraitCollection:nil];
+ [[NSNotificationCenter defaultCenter] postNotificationName:SDLDidReceiveLockScreenIcon object:nil userInfo:@{ SDLNotificationUserInfoObject: testIcon }];
+ });
+
+ it(@"should not have a vehicle icon if showDeviceLogo is set to NO", ^{
+ expect(((SDLLockScreenViewController *)testManager.lockScreenViewController).vehicleIcon).to(beNil());
+ });
+ });
+
+ });
+
context(@"with a custom color configuration", ^{
__block UIColor *testColor = nil;
__block UIImage *testImage = nil;
@@ -203,6 +316,40 @@ describe(@"a lock screen manager", ^{
});
});
+ context(@"with a dismissable false configuration", ^{
+ beforeEach(^{
+ SDLLockScreenConfiguration *config = [SDLLockScreenConfiguration enabledConfiguration];
+ config.enableDismissGesture = NO;
+
+ testManager = [[SDLLockScreenManager alloc] initWithConfiguration:config notificationDispatcher:nil presenter:fakePresenter];
+ [testManager start];
+ });
+
+ describe(@"when a driver distraction notification is posted with lockScreenDismissableEnabled as true", ^{
+ __block SDLRPCNotificationNotification *testDriverDistractionNotification = nil;
+
+ beforeEach(^{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ SDLOnLockScreenStatus *status = [[SDLOnLockScreenStatus alloc] init];
+#pragma clang diagnostic pop
+ status.lockScreenStatus = SDLLockScreenStatusRequired;
+ testManager.lastLockNotification = status;
+
+ SDLOnDriverDistraction *testDriverDistraction = [[SDLOnDriverDistraction alloc] init];
+ testDriverDistraction.lockScreenDismissalEnabled = @YES;
+
+ testDriverDistractionNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidChangeDriverDistractionStateNotification object:nil rpcNotification:testDriverDistraction];
+
+ [[NSNotificationCenter defaultCenter] postNotification:testDriverDistractionNotification];
+ });
+
+ it(@"should not be able to be dismissed", ^{
+ expect(testManager.isLockScreenDismissable).toEventually(equal(NO));
+ });
+ });
+ });
+
describe(@"A lock screen status of OPTIONAL", ^{
__block SDLLockScreenManager *testLockScreenManager = nil;
__block SDLLockScreenConfiguration *testLockScreenConfig = nil;
@@ -211,8 +358,10 @@ describe(@"a lock screen manager", ^{
beforeEach(^{
mockViewControllerPresenter = OCMClassMock([SDLFakeViewControllerPresenter class]);
-
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
SDLOnLockScreenStatus *testOptionalStatus = [[SDLOnLockScreenStatus alloc] init];
+#pragma clang diagnostic pop
testOptionalStatus.lockScreenStatus = SDLLockScreenStatusOptional;
testLockStatusNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidChangeLockScreenStatusNotification object:nil rpcNotification:testOptionalStatus];
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m
index 54c5bb959..73b17fec7 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m
@@ -3,10 +3,10 @@
#import <OCMock/OCMock.h>
#import <SmartDeviceLink/SmartDeviceLink.h>
-#import "SDLGlobals.h"
-#import "SDLMenuManager.h"
+#import "SDLMenuManager.h"
#import "TestConnectionManager.h"
+#import "SDLGlobals.h"
@interface SDLMenuCell()
@@ -668,6 +668,91 @@ describe(@"menu manager", ^{
});
});
+ describe(@"ShowMenu RPC", ^{
+ beforeEach(^{
+ testManager.currentHMILevel = SDLHMILevelFull;
+ testManager.currentSystemContext = SDLSystemContextMain;
+ testManager.displayCapabilities = [[SDLDisplayCapabilities alloc] init];
+ });
+
+ context(@"when open menu RPC can be sent", ^{
+ beforeEach(^{
+ SDLVersion *oldVersion = [SDLVersion versionWithMajor:6 minor:0 patch:0];
+ id globalMock = OCMPartialMock([SDLGlobals sharedGlobals]);
+ OCMStub([globalMock rpcVersion]).andReturn(oldVersion);
+ });
+
+ it(@"should send showAppMenu RPC", ^{
+ BOOL canSendRPC = [testManager openMenu];
+
+ NSPredicate *showMenu = [NSPredicate predicateWithFormat:@"self isMemberOfClass: %@", [SDLShowAppMenu class]];
+ NSArray *openMenu = [[mockConnectionManager.receivedRequests copy] filteredArrayUsingPredicate:showMenu];
+
+ expect(mockConnectionManager.receivedRequests).toNot(beEmpty());
+ expect(openMenu).to(haveCount(1));
+ expect(canSendRPC).to(equal(YES));
+ });
+
+ it(@"should send showAppMenu RPC with cellID", ^ {
+ testManager.menuCells = @[submenuCell];
+ [mockConnectionManager respondToLastMultipleRequestsWithSuccess:YES];
+ [mockConnectionManager respondToLastMultipleRequestsWithSuccess:YES];
+
+ BOOL canSendRPC = [testManager openSubmenu:submenuCell];
+
+ NSPredicate *addSubmenuPredicate = [NSPredicate predicateWithFormat:@"self isMemberOfClass: %@", [SDLShowAppMenu class]];
+ NSArray *openMenu = [[mockConnectionManager.receivedRequests copy] filteredArrayUsingPredicate:addSubmenuPredicate];
+
+ expect(mockConnectionManager.receivedRequests).toNot(beEmpty());
+ expect(openMenu).to(haveCount(1));
+ expect(canSendRPC).to(equal(YES));
+ });
+ });
+
+ context(@"when open menu RPC can not be sent", ^{
+ it(@"should not send a showAppMenu RPC when cell has no subcells", ^ {
+ BOOL canSendRPC = [testManager openSubmenu:textOnlyCell];
+
+ NSPredicate *addSubmenuPredicate = [NSPredicate predicateWithFormat:@"self isMemberOfClass: %@", [SDLShowAppMenu class]];
+ NSArray *openMenu = [[mockConnectionManager.receivedRequests copy] filteredArrayUsingPredicate:addSubmenuPredicate];
+
+ expect(mockConnectionManager.receivedRequests).to(beEmpty());
+ expect(openMenu).to(haveCount(0));
+ expect(canSendRPC).to(equal(NO));
+ });
+
+ it(@"should not send a showAppMenu RPC when RPC verison is not at least 6.0.0", ^ {
+ SDLVersion *oldVersion = [SDLVersion versionWithMajor:5 minor:0 patch:0];
+ id globalMock = OCMPartialMock([SDLGlobals sharedGlobals]);
+ OCMStub([globalMock rpcVersion]).andReturn(oldVersion);
+
+ BOOL canSendRPC = [testManager openSubmenu:submenuCell];
+
+ NSPredicate *addSubmenuPredicate = [NSPredicate predicateWithFormat:@"self isMemberOfClass: %@", [SDLShowAppMenu class]];
+ NSArray *openMenu = [[mockConnectionManager.receivedRequests copy] filteredArrayUsingPredicate:addSubmenuPredicate];
+
+ expect(mockConnectionManager.receivedRequests).to(beEmpty());
+ expect(openMenu).to(haveCount(0));
+ expect(canSendRPC).to(equal(NO));
+ });
+
+ it(@"should not send a showAppMenu RPC when the cell is not in the menu array", ^ {
+ SDLVersion *oldVersion = [SDLVersion versionWithMajor:6 minor:0 patch:0];
+ id globalMock = OCMPartialMock([SDLGlobals sharedGlobals]);
+ OCMStub([globalMock rpcVersion]).andReturn(oldVersion);
+
+ BOOL canSendRPC = [testManager openSubmenu:submenuCell];
+
+ NSPredicate *addSubmenuPredicate = [NSPredicate predicateWithFormat:@"self isMemberOfClass: %@", [SDLShowAppMenu class]];
+ NSArray *openMenu = [[mockConnectionManager.receivedRequests copy] filteredArrayUsingPredicate:addSubmenuPredicate];
+
+ expect(mockConnectionManager.receivedRequests).to(beEmpty());
+ expect(openMenu).to(haveCount(0));
+ expect(canSendRPC).to(equal(NO));
+ });
+ });
+ });
+
afterEach(^{
testManager = nil;
});
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLPermissionsManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLPermissionsManagerSpec.m
index f0e99b902..05d70a6db 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLPermissionsManagerSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLPermissionsManagerSpec.m
@@ -449,6 +449,37 @@ describe(@"SDLPermissionsManager", ^{
NSNumber<SDLBool> *allDisallowed = changeDicts[1][testRPCNameAllDisallowed];
expect(allDisallowed).to(equal(@NO));
});
+
+ describe(@"when the permission has not changed", ^{
+ __block SDLOnPermissionsChange *testPermissionChangeUpdateNoChange = nil;
+ __block SDLPermissionItem *testPermissionUpdatedNoChange = nil;
+
+ beforeEach(^{
+ numberOfTimesObserverCalled = 0;
+
+ // Create a permission update disallowing our current HMI level for the observed permission
+ SDLParameterPermissions *testParameterPermissions = [[SDLParameterPermissions alloc] init];
+ SDLHMIPermissions *testHMIPermissionsUpdated = [[SDLHMIPermissions alloc] init];
+ testHMIPermissionsUpdated.allowed = @[SDLHMILevelBackground, SDLHMILevelFull];
+ testHMIPermissionsUpdated.userDisallowed = @[SDLHMILevelLimited, SDLHMILevelNone];
+
+ testPermissionUpdatedNoChange = [[SDLPermissionItem alloc] init];
+ testPermissionUpdatedNoChange.rpcName = testRPCNameAllAllowed;
+ testPermissionUpdatedNoChange.hmiPermissions = testHMIPermissionsUpdated;
+ testPermissionUpdatedNoChange.parameterPermissions = testParameterPermissions;
+
+ testPermissionChangeUpdateNoChange = [[SDLOnPermissionsChange alloc] init];
+ testPermissionChangeUpdateNoChange.permissionItem = [NSArray arrayWithObject:testPermissionUpdated];
+
+ // Send the permission update
+ SDLRPCNotificationNotification *updatedNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidChangePermissionsNotification object:nil rpcNotification:testPermissionChangeUpdate];
+ [[NSNotificationCenter defaultCenter] postNotification:updatedNotification];
+ });
+
+ it(@"should not call the filter observer again", ^{
+ expect(numberOfTimesObserverCalled).to(equal(0));
+ });
+ });
});
context(@"to match an all allowed observer", ^{
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLPresentChoiceSetOperationSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLPresentChoiceSetOperationSpec.m
index 05269c997..dda02c40d 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLPresentChoiceSetOperationSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLPresentChoiceSetOperationSpec.m
@@ -234,7 +234,7 @@ describe(@"present choice operation", ^{
NSString *inputData = @"Test";
SDLRPCNotificationNotification *notification = nil;
- OCMStub([testKeyboardDelegate updateAutocompleteWithInput:[OCMArg any] completionHandler:([OCMArg invokeBlockWithArgs:inputData, nil])]);
+ OCMStub([testKeyboardDelegate updateAutocompleteWithInput:[OCMArg any] autoCompleteResultsHandler:([OCMArg invokeBlockWithArgs:@[inputData], nil])]);
// Submit notification
SDLOnKeyboardInput *input = [[SDLOnKeyboardInput alloc] init];
@@ -252,7 +252,7 @@ describe(@"present choice operation", ^{
OCMVerify([testKeyboardDelegate updateAutocompleteWithInput:[OCMArg checkWithBlock:^BOOL(id obj) {
return [(NSString *)obj isEqualToString:inputData];
- }] completionHandler:[OCMArg any]]);
+ }] autoCompleteResultsHandler:[OCMArg any]]);
expect(testConnectionManager.receivedRequests.lastObject).to(beAnInstanceOf([SDLSetGlobalProperties class]));
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLPresentKeyboardOperationSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLPresentKeyboardOperationSpec.m
index 55ec13890..e8a5abdec 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLPresentKeyboardOperationSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLPresentKeyboardOperationSpec.m
@@ -35,7 +35,7 @@ describe(@"present keyboard operation", ^{
testDelegate = OCMProtocolMock(@protocol(SDLKeyboardDelegate));
OCMStub([testDelegate customKeyboardConfiguration]).andReturn(nil);
- testInitialProperties = [[SDLKeyboardProperties alloc] initWithLanguage:SDLLanguageArSa layout:SDLKeyboardLayoutAZERTY keypressMode:SDLKeypressModeResendCurrentEntry limitedCharacterList:nil autoCompleteText:nil];
+ testInitialProperties = [[SDLKeyboardProperties alloc] initWithLanguage:SDLLanguageArSa layout:SDLKeyboardLayoutAZERTY keypressMode:SDLKeypressModeResendCurrentEntry limitedCharacterList:nil autoCompleteText:nil autoCompleteList:nil];
});
it(@"should have a priority of 'normal'", ^{
@@ -163,7 +163,7 @@ describe(@"present keyboard operation", ^{
NSString *inputData = @"Test";
SDLRPCNotificationNotification *notification = nil;
- OCMStub([testDelegate updateAutocompleteWithInput:[OCMArg any] completionHandler:([OCMArg invokeBlockWithArgs:inputData, nil])]);
+ OCMStub([testDelegate updateAutocompleteWithInput:[OCMArg any] autoCompleteResultsHandler:([OCMArg invokeBlockWithArgs:@[inputData], nil])]);
// Submit notification
SDLOnKeyboardInput *input = [[SDLOnKeyboardInput alloc] init];
@@ -181,7 +181,7 @@ describe(@"present keyboard operation", ^{
OCMVerify([testDelegate updateAutocompleteWithInput:[OCMArg checkWithBlock:^BOOL(id obj) {
return [(NSString *)obj isEqualToString:inputData];
- }] completionHandler:[OCMArg any]]);
+ }] autoCompleteResultsHandler:[OCMArg any]]);
expect(testConnectionManager.receivedRequests.lastObject).to(beAnInstanceOf([SDLSetGlobalProperties class]));
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m
index 872f5eb72..31737c214 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m
@@ -90,6 +90,7 @@ describe(@"the streaming video manager", ^{
expect(@(CGSizeEqualToSize(streamingLifecycleManager.screenSize, CGSizeZero))).to(equal(@YES));
expect(@(streamingLifecycleManager.pixelBufferPool == NULL)).to(equal(@YES));
expect(@(streamingLifecycleManager.requestedEncryptionType)).to(equal(@(SDLStreamingEncryptionFlagNone)));
+ expect(@(streamingLifecycleManager.showVideoBackgroundDisplay)).to(equal(@YES));
expect(streamingLifecycleManager.currentAppState).to(equal(SDLAppStateActive));
expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamManagerStateStopped));
expect(streamingLifecycleManager.videoFormat).to(beNil());
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLTextAndGraphicManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLTextAndGraphicManagerSpec.m
index 123f38ca4..71a434df7 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLTextAndGraphicManagerSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLTextAndGraphicManagerSpec.m
@@ -63,6 +63,7 @@ describe(@"text and graphic manager", ^{
expect(testManager.textField3).to(beNil());
expect(testManager.textField4).to(beNil());
expect(testManager.mediaTrackTextField).to(beNil());
+ expect(testManager.title).to(beNil());
expect(testManager.primaryGraphic).to(beNil());
expect(testManager.secondaryGraphic).to(beNil());
expect(testManager.alignment).to(equal(SDLTextAlignmentCenter));
@@ -159,6 +160,14 @@ describe(@"text and graphic manager", ^{
expect(testManager.isDirty).to(beTrue());
});
+ it(@"should set template title", ^{
+ testManager.title = testString;
+
+ expect(testManager.title).to(equal(testString));
+ expect(testManager.inProgressUpdate).to(beNil());
+ expect(testManager.isDirty).to(beTrue());
+ });
+
it(@"should set primary graphic", ^{
testManager.primaryGraphic = testArtwork;
@@ -261,6 +270,14 @@ describe(@"text and graphic manager", ^{
expect(testManager.isDirty).to(beFalse());
});
+ it(@"should set template title text field", ^{
+ testManager.title = testString;
+
+ expect(testManager.title).to(equal(testString));
+ expect(testManager.inProgressUpdate).toNot(beNil());
+ expect(testManager.isDirty).to(beFalse());
+ });
+
it(@"should set primary graphic", ^{
testManager.primaryGraphic = testArtwork;
@@ -325,6 +342,7 @@ describe(@"text and graphic manager", ^{
NSString *textLine3 = @"line3";
NSString *textLine4 = @"line4";
NSString *textMediaTrack = @"line5";
+ NSString *textTitle = @"title";
SDLMetadataType line1Type = SDLMetadataTypeMediaTitle;
SDLMetadataType line2Type = SDLMetadataTypeMediaAlbum;
@@ -340,6 +358,7 @@ describe(@"text and graphic manager", ^{
testManager.textField3 = nil;
testManager.textField4 = nil;
testManager.mediaTrackTextField = nil;
+ testManager.title = nil;
testManager.textField1Type = nil;
testManager.textField2Type = nil;
testManager.textField3Type = nil;
@@ -365,6 +384,17 @@ describe(@"text and graphic manager", ^{
expect(testManager.inProgressUpdate.metadataTags.mainField1).to(beNil());
});
+ it(@"should set title properly", ^{
+ testManager.title = textTitle;
+
+ testManager.batchUpdates = NO;
+ [testManager updateWithCompletionHandler:nil];
+
+ expect(testManager.inProgressUpdate.templateTitle).to(equal(textTitle));
+ expect(testManager.inProgressUpdate.mainField1).to(beEmpty());
+ expect(testManager.inProgressUpdate.metadataTags.mainField1).to(beNil());
+ });
+
it(@"should format a one line text and metadata update properly", ^{
testManager.textField1 = textLine1;
testManager.textField1Type = line1Type;
@@ -455,6 +485,17 @@ describe(@"text and graphic manager", ^{
expect(testManager.inProgressUpdate.metadataTags.mainField1).to(beNil());
});
+ it(@"should set title properly", ^{
+ testManager.title = textTitle;
+
+ testManager.batchUpdates = NO;
+ [testManager updateWithCompletionHandler:nil];
+
+ expect(testManager.inProgressUpdate.templateTitle).to(equal(textTitle));
+ expect(testManager.inProgressUpdate.mainField1).to(beEmpty());
+ expect(testManager.inProgressUpdate.metadataTags.mainField1).to(beNil());
+ });
+
it(@"should format a one line text and metadata update properly", ^{
testManager.textField1 = textLine1;
testManager.textField1Type = line1Type;
@@ -554,6 +595,17 @@ describe(@"text and graphic manager", ^{
expect(testManager.inProgressUpdate.metadataTags.mainField1).to(beNil());
});
+ it(@"should set title properly", ^{
+ testManager.title = textTitle;
+
+ testManager.batchUpdates = NO;
+ [testManager updateWithCompletionHandler:nil];
+
+ expect(testManager.inProgressUpdate.templateTitle).to(equal(textTitle));
+ expect(testManager.inProgressUpdate.mainField1).to(beEmpty());
+ expect(testManager.inProgressUpdate.metadataTags.mainField1).to(beNil());
+ });
+
it(@"should format a one line text and metadata update properly", ^{
testManager.textField1 = textLine1;
testManager.textField1Type = line1Type;
@@ -657,6 +709,17 @@ describe(@"text and graphic manager", ^{
expect(testManager.inProgressUpdate.metadataTags.mainField1).to(beNil());
});
+ it(@"should set title properly", ^{
+ testManager.title = textTitle;
+
+ testManager.batchUpdates = NO;
+ [testManager updateWithCompletionHandler:nil];
+
+ expect(testManager.inProgressUpdate.templateTitle).to(equal(textTitle));
+ expect(testManager.inProgressUpdate.mainField1).to(beEmpty());
+ expect(testManager.inProgressUpdate.metadataTags.mainField1).to(beNil());
+ });
+
it(@"should format a one line text and metadata update properly", ^{
testManager.textField1 = textLine1;
testManager.textField1Type = line1Type;
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLUploadFileOperationSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLUploadFileOperationSpec.m
index e3fb6732f..93254ca78 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLUploadFileOperationSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLUploadFileOperationSpec.m
@@ -12,6 +12,45 @@
#import "TestConnectionManager.h"
#import <zlib.h>
+@interface UploadFileOperationSpecHelpers : NSObject
+
++ (void)testPutFiles:(NSArray<SDLPutFile *> *)putFiles data:(NSData *)testFileData file:(SDLFile *)testFile;
+
+@end
+
+@implementation UploadFileOperationSpecHelpers
+
++ (void)testPutFiles:(NSArray<SDLPutFile *> *)putFiles data:(NSData *)testFileData file:(SDLFile *)testFile {
+ // Test all packets for offset, length, and data
+ for (NSUInteger index = 0; index < putFiles.count; index++) {
+ SDLPutFile *putFile = putFiles[index];
+
+ NSUInteger mtuSize = [[SDLGlobals sharedGlobals] mtuSizeForServiceType:SDLServiceTypeBulkData];
+ NSData *testBulkFileData = [testFileData subdataWithRange:NSMakeRange((index * mtuSize), MIN(putFile.length.unsignedIntegerValue, mtuSize))];
+ unsigned long testBulkFileDataCrc = crc32(0, testBulkFileData.bytes, (uInt)testBulkFileData.length);
+
+ expect(putFile.offset).to(equal(@(index * mtuSize)));
+ expect(putFile.persistentFile).to(equal(@NO));
+ expect(putFile.syncFileName).to(equal(testFile.name));
+ expect(putFile.bulkData).to(equal(testBulkFileData));
+ expect(putFile.crc).to(equal([NSNumber numberWithUnsignedLong:testBulkFileDataCrc]));
+
+ // Length is used to inform the SDL Core of the total incoming packet size
+ if (index == 0) {
+ // The first putfile sent should have the full file size
+ expect(putFile.length).to(equal(@([testFile fileSize])));
+ } else if (index == putFiles.count - 1) {
+ // The last pufile contains the remaining data size
+ expect(putFile.length).to(equal(@([testFile fileSize] - (index * mtuSize))));
+ } else {
+ // All other putfiles contain the max data size for a putfile packet
+ expect(putFile.length).to(equal(@(mtuSize)));
+ }
+ }
+}
+
+@end
+
QuickSpecBegin(SDLUploadFileOperationSpec)
describe(@"Streaming upload of data", ^{
@@ -19,7 +58,7 @@ describe(@"Streaming upload of data", ^{
__block NSData *testFileData = nil;
__block SDLFile *testFile = nil;
__block SDLFileWrapper *testFileWrapper = nil;
- __block NSInteger numberOfPutFiles = 0;
+ __block NSUInteger numberOfPutFiles = 0;
__block TestConnectionManager *testConnectionManager = nil;
__block SDLUploadFileOperation *testOperation = nil;
@@ -38,121 +77,171 @@ describe(@"Streaming upload of data", ^{
numberOfPutFiles = 0;
testOperation = nil;
- testConnectionManager = nil;
+ testConnectionManager = [[TestConnectionManager alloc] init];
successResult = NO;
bytesAvailableResult = NO;
errorResult = nil;
});
- context(@"When uploading data", ^{
+ describe(@"When uploading data", ^{
context(@"data should be split into smaller packets if too large to send all at once", ^{
- context(@"both data in memory and on disk can be uploaded", ^{
- it(@"should split the data from a short chunk of text in memory correctly", ^{
- testFileName = @"TestSmallMemory";
- testFileData = [@"test1234" dataUsingEncoding:NSUTF8StringEncoding];
- testFile = [SDLFile fileWithData:testFileData name:testFileName fileExtension:@"bin"];
- });
-
- it(@"should split the data from a large image in memory correctly", ^{
- testFileName = @"TestLargeMemory";
- UIImage *testImage = [UIImage imageNamed:@"testImagePNG" inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:nil];
- testFileData = UIImageJPEGRepresentation(testImage, 1.0);
- testFile = [SDLFile fileWithData:testFileData name:testFileName fileExtension:@"bin"];
- });
-
- it(@"should split the data from a small text file correctly", ^{
- NSString *fileName = @"testFileJSON";
- testFileName = fileName;
- NSString *textFilePath = [[NSBundle bundleForClass:[self class]] pathForResource:fileName ofType:@"json"];
- NSURL *textFileURL = [[NSURL alloc] initFileURLWithPath:textFilePath];
- testFile = [SDLFile fileAtFileURL:textFileURL name:fileName];
- testFileData = [[NSData alloc] initWithContentsOfURL:textFileURL];
- });
-
- it(@"should split the data from a large image file correctly", ^{
- NSString *fileName = @"testImagePNG";
- testFileName = fileName;
- NSString *imageFilePath = [[NSBundle bundleForClass:[self class]] pathForResource:fileName ofType:@"png"];
- NSURL *imageFileURL = [[NSURL alloc] initFileURLWithPath:imageFilePath];
- testFile = [SDLFile fileAtFileURL:imageFileURL name:fileName];
-
- // For testing: get data to check if data chunks are being created correctly
- testFileData = [[NSData alloc] initWithContentsOfURL:imageFileURL];
- });
-
- afterEach(^{
- testFileWrapper = [SDLFileWrapper wrapperWithFile:testFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
- successResult = success;
- bytesAvailableResult = bytesAvailable;
- errorResult = error;
- }];
-
- numberOfPutFiles = ((([testFile fileSize] - 1) / [[SDLGlobals sharedGlobals] mtuSizeForServiceType:SDLServiceTypeBulkData]) + 1);
-
- testConnectionManager = [[TestConnectionManager alloc] init];
- testOperation = [[SDLUploadFileOperation alloc] initWithFile:testFileWrapper connectionManager:testConnectionManager];
- [testOperation start];
- });
+ it(@"should split the data from a short chunk of text in memory correctly", ^{
+ testFileName = @"TestSmallMemory";
+ testFileData = [@"test1234" dataUsingEncoding:NSUTF8StringEncoding];
+ testFile = [SDLFile fileWithData:testFileData name:testFileName fileExtension:@"bin"];
+ __block NSInteger spaceLeft = 11212512;
+
+ testFileWrapper = [SDLFileWrapper wrapperWithFile:testFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
+ expect(success).to(beTrue());
+ expect(bytesAvailable).to(equal(spaceLeft));
+ expect(error).to(beNil());
+ }];
+
+ numberOfPutFiles = ((([testFile fileSize] - 1) / [[SDLGlobals sharedGlobals] mtuSizeForServiceType:SDLServiceTypeBulkData]) + 1);
+
+ testOperation = [[SDLUploadFileOperation alloc] initWithFile:testFileWrapper connectionManager:testConnectionManager];
+ [testOperation start];
+
+ NSArray<SDLPutFile *> *putFiles = testConnectionManager.receivedRequests;
+ expect(@(putFiles.count)).to(equal(@(numberOfPutFiles)));
+ [UploadFileOperationSpecHelpers testPutFiles:putFiles data:testFileData file:testFile];
+
+ __block SDLPutFileResponse *goodResponse = nil;
+
+ // We must do some cleanup here otherwise the unit test cases will crash
+ for (int i = 0; i < numberOfPutFiles; i++) {
+ spaceLeft -= 1024;
+ goodResponse = [[SDLPutFileResponse alloc] init];
+ goodResponse.success = @YES;
+ goodResponse.spaceAvailable = @(spaceLeft);
+ [testConnectionManager respondToRequestWithResponse:goodResponse requestNumber:i error:nil];
+ }
+
+ expect(testOperation.finished).toEventually(beTrue());
+ expect(testOperation.executing).toEventually(beFalse());
});
- afterEach(^{
- expect(@(testOperation.queuePriority)).to(equal(@(NSOperationQueuePriorityNormal)));
+ it(@"should split the data from a large image in memory correctly", ^{
+ testFileName = @"TestLargeMemory";
+ UIImage *testImage = [UIImage imageNamed:@"testImagePNG" inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:nil];
+ testFileData = UIImageJPEGRepresentation(testImage, 1.0);
+ testFile = [SDLFile fileWithData:testFileData name:testFileName fileExtension:@"bin"];
+ __block NSInteger spaceLeft = 11212512;
+
+ testFileWrapper = [SDLFileWrapper wrapperWithFile:testFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
+ expect(success).to(beTrue());
+ expect(bytesAvailable).to(equal(spaceLeft));
+ expect(error).to(beNil());
+ }];
+
+ numberOfPutFiles = ((([testFile fileSize] - 1) / [[SDLGlobals sharedGlobals] mtuSizeForServiceType:SDLServiceTypeBulkData]) + 1);
+
+ testOperation = [[SDLUploadFileOperation alloc] initWithFile:testFileWrapper connectionManager:testConnectionManager];
+ [testOperation start];
NSArray<SDLPutFile *> *putFiles = testConnectionManager.receivedRequests;
expect(@(putFiles.count)).to(equal(@(numberOfPutFiles)));
+ [UploadFileOperationSpecHelpers testPutFiles:putFiles data:testFileData file:testFile];
- // Test all packets for offset, length, and data
- for (NSUInteger index = 0; index < numberOfPutFiles; index++) {
- SDLPutFile *putFile = putFiles[index];
-
- NSUInteger mtuSize = [[SDLGlobals sharedGlobals] mtuSizeForServiceType:SDLServiceTypeBulkData];
- NSData *testBulkFileData = [testFileData subdataWithRange:NSMakeRange((index * mtuSize), MIN(putFile.length.unsignedIntegerValue, mtuSize))];
- unsigned long testBulkFileDataCrc = crc32(0, testBulkFileData.bytes, (uInt)testBulkFileData.length);
-
- expect(putFile.offset).to(equal(@(index * mtuSize)));
- expect(putFile.persistentFile).to(equal(@NO));
- expect(putFile.syncFileName).to(equal(testFileName));
- expect(putFile.bulkData).to(equal(testBulkFileData));
- expect(putFile.crc).to(equal([NSNumber numberWithUnsignedLong:testBulkFileDataCrc]));
-
- // Length is used to inform the SDL Core of the total incoming packet size
- if (index == 0) {
- // The first putfile sent should have the full file size
- expect(putFile.length).to(equal(@([testFile fileSize])));
- } else if (index == numberOfPutFiles - 1) {
- // The last pufile contains the remaining data size
- expect(putFile.length).to(equal(@([testFile fileSize] - (index * mtuSize))));
- } else {
- // All other putfiles contain the max data size for a putfile packet
- expect(putFile.length).to(equal(@(mtuSize)));
- }
+ __block SDLPutFileResponse *goodResponse = nil;
+
+ // We must do some cleanup here otherwise the unit test cases will crash
+ for (int i = 0; i < numberOfPutFiles; i++) {
+ spaceLeft -= 1024;
+ goodResponse = [[SDLPutFileResponse alloc] init];
+ goodResponse.success = @YES;
+ goodResponse.spaceAvailable = @(spaceLeft);
+ [testConnectionManager respondToRequestWithResponse:goodResponse requestNumber:i error:nil];
}
+
+ expect(testOperation.finished).toEventually(beTrue());
+ expect(testOperation.executing).toEventually(beFalse());
});
- });
- afterEach(^{
- __block SDLPutFileResponse *goodResponse = nil;
+ it(@"should split the data from a small text file correctly", ^{
+ NSString *fileName = @"testFileJSON";
+ testFileName = fileName;
+ NSString *textFilePath = [[NSBundle bundleForClass:[self class]] pathForResource:fileName ofType:@"json"];
+ NSURL *textFileURL = [[NSURL alloc] initFileURLWithPath:textFilePath];
+ testFile = [SDLFile fileAtFileURL:textFileURL name:fileName];
+ testFileData = [[NSData alloc] initWithContentsOfURL:textFileURL];
+ __block NSInteger spaceLeft = 11212512;
+
+ testFileWrapper = [SDLFileWrapper wrapperWithFile:testFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
+ expect(success).to(beTrue());
+ expect(bytesAvailable).to(equal(spaceLeft));
+ expect(error).to(beNil());
+ }];
+
+ numberOfPutFiles = ((([testFile fileSize] - 1) / [[SDLGlobals sharedGlobals] mtuSizeForServiceType:SDLServiceTypeBulkData]) + 1);
+
+ testOperation = [[SDLUploadFileOperation alloc] initWithFile:testFileWrapper connectionManager:testConnectionManager];
+ [testOperation start];
+
+ NSArray<SDLPutFile *> *putFiles = testConnectionManager.receivedRequests;
+ expect(@(putFiles.count)).to(equal(@(numberOfPutFiles)));
+ [UploadFileOperationSpecHelpers testPutFiles:putFiles data:testFileData file:testFile];
+
+ __block SDLPutFileResponse *goodResponse = nil;
+
+ // We must do some cleanup here otherwise the unit test cases will crash
+ for (int i = 0; i < numberOfPutFiles; i++) {
+ spaceLeft -= 1024;
+ goodResponse = [[SDLPutFileResponse alloc] init];
+ goodResponse.success = @YES;
+ goodResponse.spaceAvailable = @(spaceLeft);
+ [testConnectionManager respondToRequestWithResponse:goodResponse requestNumber:i error:nil];
+ }
+
+ expect(testOperation.finished).toEventually(beTrue());
+ expect(testOperation.executing).toEventually(beFalse());
+ });
+
+ it(@"should split the data from a large image file correctly", ^{
+ NSString *fileName = @"testImagePNG";
+ testFileName = fileName;
+ NSString *imageFilePath = [[NSBundle bundleForClass:[self class]] pathForResource:fileName ofType:@"png"];
+ NSURL *imageFileURL = [[NSURL alloc] initFileURLWithPath:imageFilePath];
+ testFile = [SDLFile fileAtFileURL:imageFileURL name:fileName];
+ __block NSInteger spaceLeft = 11212512;
- // We must do some cleanup here otherwise the unit test cases will crash
- NSInteger spaceLeft = 11212512;
- for (int i = 0; i < numberOfPutFiles; i++) {
- spaceLeft -= 1024;
- goodResponse = [[SDLPutFileResponse alloc] init];
- goodResponse.success = @YES;
- goodResponse.spaceAvailable = @(spaceLeft);
- [testConnectionManager respondToRequestWithResponse:goodResponse requestNumber:i error:nil];
- }
-
- expect(@(successResult)).toEventually(equal(@YES));
- expect(@(bytesAvailableResult)).toEventually(equal(spaceLeft));
- expect(errorResult).toEventually(beNil());
- expect(@(testOperation.finished)).toEventually(equal(@YES));
- expect(@(testOperation.executing)).toEventually(equal(@NO));
+ // For testing: get data to check if data chunks are being created correctly
+ testFileData = [[NSData alloc] initWithContentsOfURL:imageFileURL];
+
+ testFileWrapper = [SDLFileWrapper wrapperWithFile:testFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
+ expect(success).to(beTrue());
+ expect(bytesAvailable).to(equal(spaceLeft));
+ expect(error).to(beNil());
+ }];
+
+ numberOfPutFiles = ((([testFile fileSize] - 1) / [[SDLGlobals sharedGlobals] mtuSizeForServiceType:SDLServiceTypeBulkData]) + 1);
+
+ testOperation = [[SDLUploadFileOperation alloc] initWithFile:testFileWrapper connectionManager:testConnectionManager];
+ [testOperation start];
+
+ NSArray<SDLPutFile *> *putFiles = testConnectionManager.receivedRequests;
+ expect(@(putFiles.count)).to(equal(@(numberOfPutFiles)));
+ [UploadFileOperationSpecHelpers testPutFiles:putFiles data:testFileData file:testFile];
+
+ __block SDLPutFileResponse *goodResponse = nil;
+
+ // We must do some cleanup here otherwise the unit test cases will crash
+ for (int i = 0; i < numberOfPutFiles; i++) {
+ spaceLeft -= 1024;
+ goodResponse = [[SDLPutFileResponse alloc] init];
+ goodResponse.success = @YES;
+ goodResponse.spaceAvailable = @(spaceLeft);
+ [testConnectionManager respondToRequestWithResponse:goodResponse requestNumber:i error:nil];
+ }
+
+ expect(testOperation.finished).toEventually(beTrue());
+ expect(testOperation.executing).toEventually(beFalse());
+ });
});
});
- context(@"When a response to the data upload comes back", ^{
+ describe(@"When a response to the data upload comes back", ^{
beforeEach(^{
testFileName = @"TestLargeMemory";
UIImage *testImage = [UIImage imageNamed:@"testImagePNG" inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:nil];
@@ -174,8 +263,8 @@ describe(@"Streaming upload of data", ^{
});
context(@"If data was sent successfully", ^{
- __block SDLPutFileResponse *goodResponse = nil;
- __block NSInteger spaceLeft = 0;
+ __block SDLPutFileResponse *goodResponse = nil;
+ __block NSInteger spaceLeft = 0;
beforeEach(^{
goodResponse = nil;
@@ -190,15 +279,13 @@ describe(@"Streaming upload of data", ^{
goodResponse.spaceAvailable = @(spaceLeft);
[testConnectionManager respondToRequestWithResponse:goodResponse requestNumber:i error:nil];
}
- });
- afterEach(^{
- expect(@(successResult)).toEventually(equal(@YES));
- expect(@(bytesAvailableResult)).toEventually(equal(spaceLeft));
+ expect(successResult).toEventually(beTrue());
+ expect(bytesAvailableResult).toEventually(equal(spaceLeft));
expect(errorResult).toEventually(beNil());
- expect(@(testOperation.finished)).toEventually(equal(@YES));
- expect(@(testOperation.executing)).toEventually(equal(@NO));
+ expect(testOperation.finished).toEventually(beTrue());
+ expect(testOperation.executing).toEventually(beFalse());
});
});
@@ -234,6 +321,10 @@ describe(@"Streaming upload of data", ^{
[testConnectionManager respondToRequestWithResponse:response requestNumber:i error:error];
}
+
+ expect(errorResult.localizedDescription).toEventually(match(responseErrorDescription));
+ expect(errorResult.localizedFailureReason).toEventually(match(responseErrorReason));
+ expect(successResult).toEventually(beFalse());
});
it(@"should have called the completion handler with error if the last packet was not sent successfully", ^{
@@ -255,6 +346,10 @@ describe(@"Streaming upload of data", ^{
[testConnectionManager respondToRequestWithResponse:response requestNumber:i error:error];
}
+
+ expect(errorResult.localizedDescription).toEventually(match(responseErrorDescription));
+ expect(errorResult.localizedFailureReason).toEventually(match(responseErrorReason));
+ expect(successResult).toEventually(beFalse());
});
it(@"should have called the completion handler with error if all packets were not sent successfully", ^{
@@ -269,18 +364,16 @@ describe(@"Streaming upload of data", ^{
[testConnectionManager respondToRequestWithResponse:response requestNumber:i error:[NSError sdl_lifecycle_unknownRemoteErrorWithDescription:responseErrorDescription andReason:responseErrorReason]];
}
- });
- afterEach(^{
expect(errorResult.localizedDescription).toEventually(match(responseErrorDescription));
expect(errorResult.localizedFailureReason).toEventually(match(responseErrorReason));
- expect(@(successResult)).toEventually(equal(@NO));
+ expect(successResult).toEventually(beFalse());
});
});
});
- context(@"When an incorrect file url is passed", ^{
- beforeEach(^{
+ describe(@"when an incorrect file url is passed", ^{
+ it(@"should have called the completion handler with an error", ^{
NSString *fileName = @"testImagePNG";
testFileName = fileName;
NSString *imageFilePath = [[NSBundle bundleForClass:[self class]] pathForResource:fileName ofType:@"png"];
@@ -288,43 +381,31 @@ describe(@"Streaming upload of data", ^{
testFile = [SDLFile fileAtFileURL:imageFileURL name:fileName];
testFileWrapper = [SDLFileWrapper wrapperWithFile:testFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
- successResult = success;
- bytesAvailableResult = bytesAvailable;
- errorResult = error;
+ expect(success).to(beFalse());
+ expect(error).to(equal([NSError sdl_fileManager_fileDoesNotExistError]));
}];
testConnectionManager = [[TestConnectionManager alloc] init];
testOperation = [[SDLUploadFileOperation alloc] initWithFile:testFileWrapper connectionManager:testConnectionManager];
[testOperation start];
});
-
- it(@"should have called the completion handler with an error", ^{
- expect(errorResult).toEventually(equal([NSError sdl_fileManager_fileDoesNotExistError]));
- expect(@(successResult)).toEventually(equal(@NO));
- });
});
- context(@"When empty data is passed", ^{
- beforeEach(^{
+ describe(@"when empty data is passed", ^{
+ it(@"should have called the completion handler with an error", ^{
testFileName = @"TestEmptyMemory";
testFileData = [@"" dataUsingEncoding:NSUTF8StringEncoding];
testFile = [SDLFile fileWithData:testFileData name:testFileName fileExtension:@"bin"];
testFileWrapper = [SDLFileWrapper wrapperWithFile:testFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
- successResult = success;
- bytesAvailableResult = bytesAvailable;
- errorResult = error;
+ expect(error).to(equal([NSError sdl_fileManager_fileDoesNotExistError]));
+ expect(success).to(beFalse());
}];
testConnectionManager = [[TestConnectionManager alloc] init];
testOperation = [[SDLUploadFileOperation alloc] initWithFile:testFileWrapper connectionManager:testConnectionManager];
[testOperation start];
});
-
- it(@"should have called the completion handler with an error", ^{
- expect(errorResult).toEventually(equal([NSError sdl_fileManager_fileDoesNotExistError]));
- expect(@(successResult)).toEventually(equal(@NO));
- });
});
});
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLVersionSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLVersionSpec.m
index 349f66f6d..9621f6e75 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLVersionSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLVersionSpec.m
@@ -2,6 +2,7 @@
#import <Nimble/Nimble.h>
#import "SDLSyncMsgVersion.h"
+#import "SDLMsgVersion.h"
#import "SDLVersion.h"
QuickSpecBegin(SDLVersionSpec)
@@ -57,8 +58,24 @@ describe(@"a version object", ^{
context(@"created from a SyncMsgVersion object", ^{
beforeEach(^{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
SDLSyncMsgVersion *msgVersion = [[SDLSyncMsgVersion alloc] initWithMajorVersion:major minorVersion:minor patchVersion:patch];
testVersion = [[SDLVersion alloc] initWithSyncMsgVersion:msgVersion];
+#pragma clang diagnostic pop
+ });
+
+ it(@"should match the parameters", ^{
+ expect(testVersion.major).to(equal(major));
+ expect(testVersion.minor).to(equal(minor));
+ expect(testVersion.patch).to(equal(patch));
+ });
+ });
+
+ context(@"created from a SDLMsgVersion object", ^{
+ beforeEach(^{
+ SDLMsgVersion *msgVersion = [[SDLMsgVersion alloc] initWithMajorVersion:major minorVersion:minor patchVersion:patch];
+ testVersion = [[SDLVersion alloc] initWithSDLMsgVersion:msgVersion];
});
it(@"should match the parameters", ^{
@@ -76,7 +93,6 @@ describe(@"a version object", ^{
beforeEach(^{
testVersion = [[SDLVersion alloc] initWithMajor:major minor:minor patch:patch];
-
lowerVersion = [[SDLVersion alloc] initWithMajor:4 minor:1 patch:0];
equalVersion = [[SDLVersion alloc] initWithMajor:major minor:minor patch:patch];
higherVersion = [[SDLVersion alloc] initWithMajor:7 minor:2 patch:4];
diff --git a/SmartDeviceLinkTests/Notifications/SDLNotificationDispatcherSpec.m b/SmartDeviceLinkTests/Notifications/SDLNotificationDispatcherSpec.m
index 5b3f87212..cfa34340d 100644
--- a/SmartDeviceLinkTests/Notifications/SDLNotificationDispatcherSpec.m
+++ b/SmartDeviceLinkTests/Notifications/SDLNotificationDispatcherSpec.m
@@ -69,6 +69,7 @@ describe(@"a notification dispatcher", ^{
expect(@([testDispatcher respondsToSelector:@selector(onSetMediaClockTimerResponse:)])).to(beTruthy());
expect(@([testDispatcher respondsToSelector:@selector(onShowConstantTBTResponse:)])).to(beTruthy());
expect(@([testDispatcher respondsToSelector:@selector(onShowResponse:)])).to(beTruthy());
+ expect(@([testDispatcher respondsToSelector:@selector(onShowAppMenuResponse:)])).to(beTruthy());
expect(@([testDispatcher respondsToSelector:@selector(onSliderResponse:)])).to(beTruthy());
expect(@([testDispatcher respondsToSelector:@selector(onSpeakResponse:)])).to(beTruthy());
expect(@([testDispatcher respondsToSelector:@selector(onSubscribeButtonResponse:)])).to(beTruthy());
@@ -122,6 +123,7 @@ describe(@"a notification dispatcher", ^{
expect(@([testDispatcher respondsToSelector:@selector(onSetInteriorVehicleData:)])).to(beTruthy());
expect(@([testDispatcher respondsToSelector:@selector(onSetMediaClockTimer:)])).to(beTruthy());
expect(@([testDispatcher respondsToSelector:@selector(onShow:)])).to(beTruthy());
+ expect(@([testDispatcher respondsToSelector:@selector(onShowAppMenu:)])).to(beTruthy());
expect(@([testDispatcher respondsToSelector:@selector(onShowConstantTBT:)])).to(beTruthy());
expect(@([testDispatcher respondsToSelector:@selector(onSlider:)])).to(beTruthy());
expect(@([testDispatcher respondsToSelector:@selector(onSpeak:)])).to(beTruthy());
diff --git a/SmartDeviceLinkTests/ProxySpecs/SDLHapticManagerSpec.m b/SmartDeviceLinkTests/ProxySpecs/SDLHapticManagerSpec.m
index 497870b9d..b1adaa135 100644
--- a/SmartDeviceLinkTests/ProxySpecs/SDLHapticManagerSpec.m
+++ b/SmartDeviceLinkTests/ProxySpecs/SDLHapticManagerSpec.m
@@ -311,7 +311,7 @@ describe(@"the haptic manager", ^{
OCMVerify(sdlLifecycleManager);
int expectedCount = 2;
- expect(sentHapticRequest.hapticRectData.count).to(equal(expectedCount));
+ expect(sentHapticRequest.hapticRectData.count).toEventually(equal(expectedCount));
if(sentHapticRequest.hapticRectData.count == expectedCount) {
NSArray<SDLHapticRect *> *hapticRectData = sentHapticRequest.hapticRectData;
diff --git a/SmartDeviceLinkTests/ProxySpecs/SDLLockScreenStatusManagerSpec.m b/SmartDeviceLinkTests/ProxySpecs/SDLLockScreenStatusManagerSpec.m
index 98a574f95..acf64f0b8 100644
--- a/SmartDeviceLinkTests/ProxySpecs/SDLLockScreenStatusManagerSpec.m
+++ b/SmartDeviceLinkTests/ProxySpecs/SDLLockScreenStatusManagerSpec.m
@@ -227,7 +227,11 @@ describe(@"the lockscreen status manager", ^{
});
describe(@"when getting lock screen status notification", ^{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
__block SDLOnLockScreenStatus *onLockScreenStatusNotification = nil;
+#pragma clang diagnostic pop
+
beforeEach(^{
lockScreenManager.userSelected = YES;
lockScreenManager.driverDistracted = NO;
diff --git a/SmartDeviceLinkTests/RPCSpecs/EnumSpecs/SDLTextFieldNameSpec.m b/SmartDeviceLinkTests/RPCSpecs/EnumSpecs/SDLTextFieldNameSpec.m
index 6d29ff29e..bacc79853 100644
--- a/SmartDeviceLinkTests/RPCSpecs/EnumSpecs/SDLTextFieldNameSpec.m
+++ b/SmartDeviceLinkTests/RPCSpecs/EnumSpecs/SDLTextFieldNameSpec.m
@@ -18,6 +18,7 @@ describe(@"Individual Enum Value Tests", ^ {
expect(SDLTextFieldNameMainField2).to(equal(@"mainField2"));
expect(SDLTextFieldNameMainField3).to(equal(@"mainField3"));
expect(SDLTextFieldNameMainField4).to(equal(@"mainField4"));
+ expect(SDLTextFieldNameTemplateTitle).to(equal(@"templateTitle"));
expect(SDLTextFieldNameStatusBar).to(equal(@"statusBar"));
expect(SDLTextFieldNameMediaClock).to(equal(@"mediaClock"));
expect(SDLTextFieldNameMediaTrack).to(equal(@"mediaTrack"));
diff --git a/SmartDeviceLinkTests/RPCSpecs/NotificationSpecs/SDLOnDriverDistractionSpec.m b/SmartDeviceLinkTests/RPCSpecs/NotificationSpecs/SDLOnDriverDistractionSpec.m
index b242c0a3a..280e596a7 100644
--- a/SmartDeviceLinkTests/RPCSpecs/NotificationSpecs/SDLOnDriverDistractionSpec.m
+++ b/SmartDeviceLinkTests/RPCSpecs/NotificationSpecs/SDLOnDriverDistractionSpec.m
@@ -17,30 +17,52 @@ QuickSpecBegin(SDLOnDriverDistractionSpec)
describe(@"Getter/Setter Tests", ^ {
it(@"Should set and get correctly", ^ {
- SDLOnDriverDistraction* testNotification = [[SDLOnDriverDistraction alloc] init];
+ SDLOnDriverDistraction *testNotification = [[SDLOnDriverDistraction alloc] init];
testNotification.state = SDLDriverDistractionStateOn;
+ testNotification.lockScreenDismissalEnabled = @1;
expect(testNotification.state).to(equal(SDLDriverDistractionStateOn));
+ expect(testNotification.lockScreenDismissalEnabled).to(beTrue());
+
+ testNotification.lockScreenDismissalEnabled = @0;
+ expect(testNotification.lockScreenDismissalEnabled).to(beFalse());
});
it(@"Should get correctly when initialized", ^ {
- NSMutableDictionary* dict = [@{SDLRPCParameterNameNotification:
+ NSMutableDictionary *dictOn = [@{SDLRPCParameterNameNotification:
@{SDLRPCParameterNameParameters:
- @{SDLRPCParameterNameState:SDLDriverDistractionStateOn},
+ @{SDLRPCParameterNameState:SDLDriverDistractionStateOn,
+ SDLRPCParameterNameLockScreenDismissalEnabled: @1},
SDLRPCParameterNameOperationName:SDLRPCFunctionNameOnDriverDistraction}} mutableCopy];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- SDLOnDriverDistraction* testNotification = [[SDLOnDriverDistraction alloc] initWithDictionary:dict];
+ SDLOnDriverDistraction* testNotificationOn = [[SDLOnDriverDistraction alloc] initWithDictionary:dictOn];
#pragma clang diagnostic pop
- expect(testNotification.state).to(equal(SDLDriverDistractionStateOn));
+ expect(testNotificationOn.state).to(equal(SDLDriverDistractionStateOn));
+ expect(testNotificationOn.lockScreenDismissalEnabled).to(beTrue());
+
+ NSMutableDictionary *dictOff = [@{SDLRPCParameterNameNotification:
+ @{SDLRPCParameterNameParameters:
+ @{SDLRPCParameterNameState:SDLDriverDistractionStateOff,
+ SDLRPCParameterNameLockScreenDismissalEnabled: @0},
+ SDLRPCParameterNameOperationName:SDLRPCFunctionNameOnDriverDistraction}} mutableCopy];
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ SDLOnDriverDistraction *testNotificationOff = [[SDLOnDriverDistraction alloc] initWithDictionary:dictOff];
+#pragma clang diagnostic pop
+
+ expect(testNotificationOff.state).to(equal(SDLDriverDistractionStateOff));
+ expect(testNotificationOff.lockScreenDismissalEnabled).to(beFalse());
});
it(@"Should return nil if not set", ^ {
- SDLOnDriverDistraction* testNotification = [[SDLOnDriverDistraction alloc] init];
+ SDLOnDriverDistraction *testNotification = [[SDLOnDriverDistraction alloc] init];
expect(testNotification.state).to(beNil());
+ expect(testNotification.lockScreenDismissalEnabled).to(beNil());
+ expect(testNotification.lockScreenDismissalEnabled).to(beFalsy());
});
});
diff --git a/SmartDeviceLinkTests/RPCSpecs/NotificationSpecs/SDLOnLockScreenStatusSpec.m b/SmartDeviceLinkTests/RPCSpecs/NotificationSpecs/SDLOnLockScreenStatusSpec.m
index cd12a3d46..4f4a574ee 100644
--- a/SmartDeviceLinkTests/RPCSpecs/NotificationSpecs/SDLOnLockScreenStatusSpec.m
+++ b/SmartDeviceLinkTests/RPCSpecs/NotificationSpecs/SDLOnLockScreenStatusSpec.m
@@ -18,8 +18,11 @@ QuickSpecBegin(SDLOnLockScreenStatusSpec)
describe(@"Getter/Setter Tests", ^ {
it(@"Should set and get correctly", ^ {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
SDLOnLockScreenStatus* testNotification = [[SDLOnLockScreenStatus alloc] init];
-
+#pragma clang diagnostic pop
+
testNotification.driverDistractionStatus = @NO;
testNotification.userSelected = @3;
testNotification.lockScreenStatus = SDLLockScreenStatusRequired;
@@ -51,8 +54,11 @@ describe(@"Getter/Setter Tests", ^ {
});
it(@"Should return nil if not set", ^ {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
SDLOnLockScreenStatus* testNotification = [[SDLOnLockScreenStatus alloc] init];
-
+#pragma clang diagnostic pop
+
expect(testNotification.driverDistractionStatus).to(beNil());
expect(testNotification.userSelected).to(beNil());
expect(testNotification.lockScreenStatus).to(beNil());
diff --git a/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLAlertSpec.m b/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLAlertSpec.m
index 27d853822..22fc58cba 100644
--- a/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLAlertSpec.m
+++ b/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLAlertSpec.m
@@ -9,6 +9,7 @@
#import <Nimble/Nimble.h>
#import "SDLAlert.h"
+#import "SDLImage.h"
#import "SDLTTSChunk.h"
#import "SDLSoftButton.h"
#import "SDLRPCParameterNames.h"
@@ -16,91 +17,310 @@
QuickSpecBegin(SDLAlertSpec)
-SDLTTSChunk* tts = [[SDLTTSChunk alloc] init];
-SDLSoftButton* button = [[SDLSoftButton alloc] init];
-
-describe(@"Getter/Setter Tests", ^ {
- it(@"Should set and get correctly", ^ {
- SDLAlert* testRequest = [[SDLAlert alloc] init];
-
- testRequest.alertText1 = @"alert#1";
- testRequest.alertText2 = @"alert#2";
- testRequest.alertText3 = @"alert#3";
- testRequest.ttsChunks = [@[tts] mutableCopy];
- testRequest.duration = @4357;
- testRequest.playTone = @YES;
- testRequest.progressIndicator = @NO;
- testRequest.softButtons = [@[button] mutableCopy];
-
- expect(testRequest.alertText1).to(equal(@"alert#1"));
- expect(testRequest.alertText2).to(equal(@"alert#2"));
- expect(testRequest.alertText3).to(equal(@"alert#3"));
- expect(testRequest.ttsChunks).to(equal([@[tts] mutableCopy]));
- expect(testRequest.duration).to(equal(@4357));
- expect(testRequest.playTone).to(equal(@YES));
- expect(testRequest.progressIndicator).to(equal(@NO));
- expect(testRequest.softButtons).to(equal([@[button] mutableCopy]));
- });
-
- it(@"Should get correctly when initialized", ^ {
- NSMutableDictionary<NSString *, id> *dict = [@{SDLRPCParameterNameRequest:
- @{SDLRPCParameterNameParameters:
- @{SDLRPCParameterNameAlertText1:@"alert#1",
- SDLRPCParameterNameAlertText2:@"alert#2",
- SDLRPCParameterNameAlertText3:@"alert#3",
- SDLRPCParameterNameTTSChunks:[@[tts] mutableCopy],
- SDLRPCParameterNameDuration:@4357,
- SDLRPCParameterNamePlayTone:@YES,
- SDLRPCParameterNameProgressIndicator:@NO,
- SDLRPCParameterNameSoftButtons:[@[button] mutableCopy]},
- SDLRPCParameterNameOperationName:SDLRPCFunctionNameAlert}} mutableCopy];
+SDLTTSChunk *tts = [[SDLTTSChunk alloc] init];
+SDLSoftButton *button = [[SDLSoftButton alloc] init];
+SDLImage *testImage = [[SDLImage alloc] initWithName:@"testImage" isTemplate:YES];
+
+describe(@"Alert spec", ^{
+ UInt16 defaultDuration = 5000;
+
+ NSString *testText1 = @"Test Text 1";
+ NSString *testText2 = @"Test Text 2";
+ NSString *testText3 = @"Test Text 3";
+ NSString *testTTSString = @"Test TTS";
+ BOOL testPlayTone = YES;
+ BOOL testProgressIndicator = YES;
+ UInt16 testDuration = 7847;
+
+ describe(@"initializer tests", ^{
+ it(@"should initialize correctly with initWithAlertText1:alertText2:duration:", ^{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- SDLAlert* testRequest = [[SDLAlert alloc] initWithDictionary:dict];
+ SDLAlert *testAlert = [[SDLAlert alloc] initWithAlertText1:testText1 alertText2:testText2 duration:testDuration];
#pragma clang diagnostic pop
-
- expect(testRequest.alertText1).to(equal(@"alert#1"));
- expect(testRequest.alertText2).to(equal(@"alert#2"));
- expect(testRequest.alertText3).to(equal(@"alert#3"));
- expect(testRequest.ttsChunks).to(equal([@[tts] mutableCopy]));
- expect(testRequest.duration).to(equal(@4357));
- expect(testRequest.playTone).to(equal(@YES));
- expect(testRequest.progressIndicator).to(equal(@NO));
- expect(testRequest.softButtons).to(equal([@[button] mutableCopy]));
- });
- it(@"Should handle NSNull", ^{
- NSMutableDictionary* dict = [@{SDLRPCParameterNameRequest:
- @{SDLRPCParameterNameParameters:
- @{SDLRPCParameterNameAlertText1:@"alert#1",
- SDLRPCParameterNameAlertText2:@"alert#2",
- SDLRPCParameterNameAlertText3:@"alert#3",
- SDLRPCParameterNameTTSChunks:[@[tts] mutableCopy],
- SDLRPCParameterNameDuration:@4357,
- SDLRPCParameterNamePlayTone:@YES,
- SDLRPCParameterNameProgressIndicator:@NO,
- SDLRPCParameterNameSoftButtons:[NSNull null]},
- SDLRPCParameterNameOperationName:SDLRPCFunctionNameAlert}} mutableCopy];
+ expect(testAlert.alertText1).to(equal(testText1));
+ expect(testAlert.alertText2).to(equal(testText2));
+ expect(testAlert.alertText3).to(beNil());
+ expect(testAlert.ttsChunks).to(beNil());
+ expect(testAlert.duration).to(equal(testDuration));
+ expect(testAlert.playTone).to(beFalse());
+ expect(testAlert.progressIndicator).to(beFalse());
+ expect(testAlert.softButtons).to(beNil());
+ expect(testAlert.alertIcon).to(beNil());
+ });
+
+ it(@"should initialize correctly with initWithAlertText1:alertText2:alertText3:", ^{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ SDLAlert *testAlert = [[SDLAlert alloc] initWithAlertText1:testText1 alertText2:testText2 alertText3:testText3];
+#pragma clang diagnostic pop
+
+ expect(testAlert.alertText1).to(equal(testText1));
+ expect(testAlert.alertText2).to(equal(testText2));
+ expect(testAlert.alertText3).to(equal(testText3));
+ expect(testAlert.ttsChunks).to(beNil());
+ expect(testAlert.duration).to(equal(defaultDuration));
+ expect(testAlert.playTone).to(beFalse());
+ expect(testAlert.progressIndicator).to(beFalse());
+ expect(testAlert.softButtons).to(beNil());
+ expect(testAlert.alertIcon).to(beNil());
+ });
+
+ it(@"should initialize correctly with initWithAlertText1:alertText2:alertText3:duration:", ^{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ SDLAlert *testAlert = [[SDLAlert alloc] initWithAlertText1:testText1 alertText2:testText2 alertText3:testText3 duration:testDuration];
+#pragma clang diagnostic pop
+
+ expect(testAlert.alertText1).to(equal(testText1));
+ expect(testAlert.alertText2).to(equal(testText2));
+ expect(testAlert.alertText3).to(equal(testText3));
+ expect(testAlert.ttsChunks).to(beNil());
+ expect(testAlert.duration).to(equal(testDuration));
+ expect(testAlert.playTone).to(beFalse());
+ expect(testAlert.progressIndicator).to(beFalse());
+ expect(testAlert.softButtons).to(beNil());
+ expect(testAlert.alertIcon).to(beNil());
+ });
+
+ it(@"should initialize correctly with initWithAlertText1:alertText2:alertText3:duration:softButtons:", ^{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ SDLAlert *testAlert = [[SDLAlert alloc] initWithAlertText1:testText1 alertText2:testText2 alertText3:testText3 duration:testDuration softButtons:@[button]];
+#pragma clang diagnostic pop
+
+ expect(testAlert.alertText1).to(equal(testText1));
+ expect(testAlert.alertText2).to(equal(testText2));
+ expect(testAlert.alertText3).to(equal(testText3));
+ expect(testAlert.ttsChunks).to(beNil());
+ expect(testAlert.duration).to(equal(testDuration));
+ expect(testAlert.playTone).to(beFalse());
+ expect(testAlert.progressIndicator).to(beFalse());
+ expect(testAlert.softButtons).to(haveCount(1));
+ expect(testAlert.alertIcon).to(beNil());
+ });
+
+ it(@"should initialize correctly with initWithTTS:alertText1:alertText2:playTone:duration:", ^{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ SDLAlert *testAlert = [[SDLAlert alloc] initWithTTS:testTTSString alertText1:testText1 alertText2:testText2 playTone:testPlayTone duration:testDuration];
+#pragma clang diagnostic pop
+
+ expect(testAlert.alertText1).to(equal(testText1));
+ expect(testAlert.alertText2).to(equal(testText2));
+ expect(testAlert.alertText3).to(beNil());
+ expect(testAlert.ttsChunks.firstObject.text).to(equal(testTTSString));
+ expect(testAlert.duration).to(equal(testDuration));
+ expect(testAlert.playTone).to(beTrue());
+ expect(testAlert.progressIndicator).to(beFalse());
+ expect(testAlert.softButtons).to(beNil());
+ expect(testAlert.alertIcon).to(beNil());
+ });
+
+ it(@"should initialize correctly with initWithTTS:alertText1:alertText2:alertText3:playTone:duration:", ^{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ SDLAlert *testAlert = [[SDLAlert alloc] initWithTTS:testTTSString alertText1:testText1 alertText2:testText2 alertText3:testText3 playTone:testPlayTone duration:testDuration];
+#pragma clang diagnostic pop
+
+ expect(testAlert.alertText1).to(equal(testText1));
+ expect(testAlert.alertText2).to(equal(testText2));
+ expect(testAlert.alertText3).to(equal(testText3));
+ expect(testAlert.ttsChunks.firstObject.text).to(equal(testTTSString));
+ expect(testAlert.duration).to(equal(testDuration));
+ expect(testAlert.playTone).to(equal(testPlayTone));
+ expect(testAlert.progressIndicator).to(beFalse());
+ expect(testAlert.softButtons).to(beNil());
+ expect(testAlert.alertIcon).to(beNil());
+ });
+
+ it(@"should initialize correctly with initWithTTS:playTone:", ^{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- SDLAlert* testRequest = [[SDLAlert alloc] initWithDictionary:dict];
+ SDLAlert *testAlert = [[SDLAlert alloc] initWithTTS:testTTSString playTone:testPlayTone];
#pragma clang diagnostic pop
- expectAction(^{
- NSArray<SDLSoftButton *> *softButtons = testRequest.softButtons;
- }).to(raiseException());
+
+ expect(testAlert.alertText1).to(beNil());
+ expect(testAlert.alertText2).to(beNil());
+ expect(testAlert.alertText3).to(beNil());
+ expect(testAlert.ttsChunks.firstObject.text).to(equal(testTTSString));
+ expect(testAlert.duration).to(equal(defaultDuration));
+ expect(testAlert.playTone).to(equal(testPlayTone));
+ expect(testAlert.progressIndicator).to(beFalse());
+ expect(testAlert.softButtons).to(beNil());
+ expect(testAlert.alertIcon).to(beNil());
+ });
+
+ it(@"should initialize correctly with initWithTTSChunks:alertText1:alertText2:alertText3:playTone:softButtons:", ^{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ SDLAlert *testAlert = [[SDLAlert alloc] initWithTTSChunks:@[tts] alertText1:testText1 alertText2:testText2 alertText3:testText3 playTone:testPlayTone softButtons:@[button]];
+#pragma clang diagnostic pop
+
+ expect(testAlert.alertText1).to(equal(testText1));
+ expect(testAlert.alertText2).to(equal(testText2));
+ expect(testAlert.alertText3).to(equal(testText3));
+ expect(testAlert.ttsChunks).to(haveCount(1));
+ expect(testAlert.duration).to(equal(defaultDuration));
+ expect(testAlert.playTone).to(equal(testPlayTone));
+ expect(testAlert.progressIndicator).to(beFalse());
+ expect(testAlert.softButtons).to(haveCount(1));
+ expect(testAlert.alertIcon).to(beNil());
+ });
+
+ it(@"should initialize correctly with initWithTTSChunks:alertText1:alertText2:alertText3:playTone:duration:softButtons:", ^{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ SDLAlert *testAlert = [[SDLAlert alloc] initWithTTSChunks:@[tts] alertText1:testText1 alertText2:testText2 alertText3:testText3 playTone:testPlayTone duration:testDuration softButtons:@[button]];
+#pragma clang diagnostic pop
+
+ expect(testAlert.alertText1).to(equal(testText1));
+ expect(testAlert.alertText2).to(equal(testText2));
+ expect(testAlert.alertText3).to(equal(testText3));
+ expect(testAlert.ttsChunks).to(haveCount(1));
+ expect(testAlert.duration).to(equal(testDuration));
+ expect(testAlert.playTone).to(equal(testPlayTone));
+ expect(testAlert.progressIndicator).to(beFalse());
+ expect(testAlert.softButtons).to(haveCount(1));
+ expect(testAlert.alertIcon).to(beNil());
+ });
+
+ it(@"should initialize correctly with initWithAlertText1:alertText2:", ^{
+ SDLAlert *testAlert = [[SDLAlert alloc] initWithAlertText1:testText1 alertText2:testText2];
+
+ expect(testAlert.alertText1).to(equal(testText1));
+ expect(testAlert.alertText2).to(equal(testText2));
+ expect(testAlert.alertText3).to(beNil());
+ expect(testAlert.ttsChunks).to(beNil());
+ expect(testAlert.duration).to(equal(defaultDuration));
+ expect(testAlert.playTone).to(beFalse());
+ expect(testAlert.progressIndicator).to(beFalse());
+ expect(testAlert.softButtons).to(beNil());
+ expect(testAlert.alertIcon).to(beNil());
+ });
+
+ it(@"should initialize correctly with initWithTTSChunks:playTone:", ^{
+ SDLAlert *testAlert = [[SDLAlert alloc] initWithTTSChunks:@[tts] playTone:testPlayTone];
+
+ expect(testAlert.alertText1).to(beNil());
+ expect(testAlert.alertText2).to(beNil());
+ expect(testAlert.alertText3).to(beNil());
+ expect(testAlert.ttsChunks).to(haveCount(1));
+ expect(testAlert.duration).to(equal(defaultDuration));
+ expect(testAlert.playTone).to(equal(testPlayTone));
+ expect(testAlert.progressIndicator).to(beFalse());
+ expect(testAlert.softButtons).to(beNil());
+ expect(testAlert.alertIcon).to(beNil());
+ });
+
+ it(@"should initialize correctly with initWithAlertText1:alertText2:alertText3:ttsChunks:playTone:progressIndicator:duration:softButtons:alertIcon:", ^{
+ SDLAlert *testAlert = [[SDLAlert alloc] initWithAlertText1:testText1 alertText2:testText2 alertText3:testText3 ttsChunks:@[tts] playTone:testPlayTone progressIndicator:testProgressIndicator duration:testDuration softButtons:@[button] alertIcon:testImage];
+
+ expect(testAlert.alertText1).to(equal(testText1));
+ expect(testAlert.alertText2).to(equal(testText2));
+ expect(testAlert.alertText3).to(equal(testText3));
+ expect(testAlert.ttsChunks).to(haveCount(1));
+ expect(testAlert.duration).to(equal(testDuration));
+ expect(testAlert.playTone).to(equal(testPlayTone));
+ expect(testAlert.progressIndicator).to(beTrue());
+ expect(testAlert.softButtons).to(haveCount(1));
+ expect(testAlert.alertIcon.value).to(equal(testImage.value));
+ });
});
-
- it(@"Should return nil if not set", ^ {
- SDLAlert* testRequest = [[SDLAlert alloc] init];
-
- expect(testRequest.alertText1).to(beNil());
- expect(testRequest.alertText2).to(beNil());
- expect(testRequest.alertText3).to(beNil());
- expect(testRequest.ttsChunks).to(beNil());
- expect(testRequest.duration).to(beNil());
- expect(testRequest.playTone).to(beNil());
- expect(testRequest.progressIndicator).to(beNil());
- expect(testRequest.softButtons).to(beNil());
+
+ describe(@"Getter/Setter Tests", ^ {
+ it(@"Should set and get correctly", ^ {
+ SDLAlert* testRequest = [[SDLAlert alloc] init];
+
+ testRequest.alertText1 = @"alert#1";
+ testRequest.alertText2 = @"alert#2";
+ testRequest.alertText3 = @"alert#3";
+ testRequest.ttsChunks = @[tts];
+ testRequest.duration = @4357;
+ testRequest.playTone = @YES;
+ testRequest.progressIndicator = @NO;
+ testRequest.softButtons = @[button];
+ testRequest.alertIcon = testImage;
+
+ expect(testRequest.alertText1).to(equal(@"alert#1"));
+ expect(testRequest.alertText2).to(equal(@"alert#2"));
+ expect(testRequest.alertText3).to(equal(@"alert#3"));
+ expect(testRequest.ttsChunks).to(equal(@[tts]));
+ expect(testRequest.duration).to(equal(@4357));
+ expect(testRequest.playTone).to(equal(@YES));
+ expect(testRequest.progressIndicator).to(equal(@NO));
+ expect(testRequest.softButtons).to(equal(@[button]));
+ expect(testRequest.alertIcon).to(equal(testImage));
+ });
+
+ it(@"Should get correctly when initialized", ^ {
+ NSDictionary<NSString *, id> *dict = @{SDLRPCParameterNameRequest:
+ @{SDLRPCParameterNameParameters:
+ @{SDLRPCParameterNameAlertText1: @"alert#1",
+ SDLRPCParameterNameAlertText2: @"alert#2",
+ SDLRPCParameterNameAlertText3: @"alert#3",
+ SDLRPCParameterNameTTSChunks: @[tts],
+ SDLRPCParameterNameDuration: @4357,
+ SDLRPCParameterNamePlayTone: @YES,
+ SDLRPCParameterNameProgressIndicator: @NO,
+ SDLRPCParameterNameSoftButtons: @[button],
+ SDLRPCParameterNameAlertIcon: testImage
+ },
+ SDLRPCParameterNameOperationName: SDLRPCFunctionNameAlert
+ }
+ };
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ SDLAlert* testRequest = [[SDLAlert alloc] initWithDictionary:dict];
+#pragma clang diagnostic pop
+
+ expect(testRequest.alertText1).to(equal(@"alert#1"));
+ expect(testRequest.alertText2).to(equal(@"alert#2"));
+ expect(testRequest.alertText3).to(equal(@"alert#3"));
+ expect(testRequest.ttsChunks).to(equal([@[tts] mutableCopy]));
+ expect(testRequest.duration).to(equal(@4357));
+ expect(testRequest.playTone).to(equal(@YES));
+ expect(testRequest.progressIndicator).to(equal(@NO));
+ expect(testRequest.softButtons).to(equal([@[button] mutableCopy]));
+ });
+
+ it(@"Should handle NSNull", ^{
+ NSDictionary* dict = @{SDLRPCParameterNameRequest:
+ @{SDLRPCParameterNameParameters:
+ @{SDLRPCParameterNameAlertText1: @"alert#1",
+ SDLRPCParameterNameAlertText2: @"alert#2",
+ SDLRPCParameterNameAlertText3: @"alert#3",
+ SDLRPCParameterNameTTSChunks: @[tts],
+ SDLRPCParameterNameDuration: @4357,
+ SDLRPCParameterNamePlayTone: @YES,
+ SDLRPCParameterNameProgressIndicator: @NO,
+ SDLRPCParameterNameSoftButtons: [NSNull null],
+ SDLRPCParameterNameAlertIcon: testImage
+ },
+ SDLRPCParameterNameOperationName:SDLRPCFunctionNameAlert}
+ };
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ SDLAlert* testRequest = [[SDLAlert alloc] initWithDictionary:dict];
+#pragma clang diagnostic pop
+ expectAction(^{
+ NSArray<SDLSoftButton *> *softButtons = testRequest.softButtons;
+ }).to(raiseException());
+ });
+
+ it(@"Should return nil if not set", ^ {
+ SDLAlert* testRequest = [[SDLAlert alloc] init];
+
+ expect(testRequest.alertText1).to(beNil());
+ expect(testRequest.alertText2).to(beNil());
+ expect(testRequest.alertText3).to(beNil());
+ expect(testRequest.ttsChunks).to(beNil());
+ expect(testRequest.duration).to(beNil());
+ expect(testRequest.playTone).to(beNil());
+ expect(testRequest.progressIndicator).to(beNil());
+ expect(testRequest.softButtons).to(beNil());
+ });
});
});
diff --git a/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLRegisterAppInterfaceSpec.m b/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLRegisterAppInterfaceSpec.m
index fbc22b5a2..a867ecef6 100644
--- a/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLRegisterAppInterfaceSpec.m
+++ b/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLRegisterAppInterfaceSpec.m
@@ -18,6 +18,7 @@
#import "SDLRPCFunctionNames.h"
#import "SDLRegisterAppInterface.h"
#import "SDLSyncMsgVersion.h"
+#import "SDLMsgVersion.h"
#import "SDLTemplateColorScheme.h"
#import "SDLTTSChunk.h"
@@ -37,17 +38,28 @@ describe(@"RegisterAppInterface Tests", ^{
__block NSArray<SDLAppHMIType> *appTypes = @[SDLAppHMITypeMedia, SDLAppHMITypeNavigation, SDLAppHMITypeInformation];
__block SDLLanguage language = SDLLanguageElGr;
__block SDLLanguage hmiDisplayLanguage = SDLLanguageArSa;
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
__block SDLSyncMsgVersion *version = nil;
+#pragma clang diagnostic pop
+ __block SDLMsgVersion *msgVersion = nil;
__block SDLTTSChunk *chunk = nil;
__block SDLDeviceInfo *info = nil;
__block SDLAppInfo *appInfo = nil;
__block SDLTemplateColorScheme *colorScheme = nil;
-
- __block SDLSyncMsgVersion *currentSyncMsgVersion = [[SDLSyncMsgVersion alloc] initWithMajorVersion:5 minorVersion:1 patchVersion:0];
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ __block SDLSyncMsgVersion *currentSyncMsgVersion = [[SDLSyncMsgVersion alloc] initWithMajorVersion:6 minorVersion:0 patchVersion:0];
+#pragma clang diagnostic pop
+ __block SDLMsgVersion * currentSDLMsgVersion = [[SDLMsgVersion alloc] initWithMajorVersion:6 minorVersion:0 patchVersion:0];
beforeEach(^{
testRegisterAppInterface = nil;
- version = [[SDLSyncMsgVersion alloc] init];
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ version = [[SDLSyncMsgVersion alloc] initWithMajorVersion:0 minorVersion:0 patchVersion:0];
+#pragma clang diagnostic pop
+ msgVersion = [[SDLMsgVersion alloc] initWithMajorVersion:0 minorVersion:0 patchVersion:0];
chunk = [[SDLTTSChunk alloc] init];
info = [[SDLDeviceInfo alloc] init];
appInfo = [[SDLAppInfo alloc] init];
@@ -56,8 +68,10 @@ describe(@"RegisterAppInterface Tests", ^{
it(@"Should set and get correctly", ^ {
testRegisterAppInterface = [[SDLRegisterAppInterface alloc] init];
-
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
testRegisterAppInterface.syncMsgVersion = version;
+#pragma clang diagnostic pop
testRegisterAppInterface.appName = appName;
testRegisterAppInterface.ttsName = @[chunk];
testRegisterAppInterface.ngnMediaScreenAppName = shortAppName;
@@ -73,8 +87,12 @@ describe(@"RegisterAppInterface Tests", ^{
testRegisterAppInterface.appInfo = appInfo;
testRegisterAppInterface.dayColorScheme = colorScheme;
testRegisterAppInterface.nightColorScheme = colorScheme;
-
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
expect(testRegisterAppInterface.syncMsgVersion).to(equal(version));
+#pragma clang diagnostic pop
+ testRegisterAppInterface.sdlMsgVersion = msgVersion;
+ expect(testRegisterAppInterface.sdlMsgVersion).to(equal(msgVersion));
expect(testRegisterAppInterface.appName).to(equal(appName));
expect(testRegisterAppInterface.ttsName).to(contain(chunk));
expect(testRegisterAppInterface.ngnMediaScreenAppName).to(equal(shortAppName));
@@ -92,33 +110,46 @@ describe(@"RegisterAppInterface Tests", ^{
expect(testRegisterAppInterface.nightColorScheme).to(equal(colorScheme));
});
- it(@"Should get correctly when initialized with a dictionary", ^ {
- NSDictionary* dict = @{SDLRPCParameterNameRequest:
- @{SDLRPCParameterNameParameters:
- @{SDLRPCParameterNameSyncMessageVersion:version,
- SDLRPCParameterNameAppName:appName,
- SDLRPCParameterNameTTSName:[@[chunk] mutableCopy],
- SDLRPCParameterNameNGNMediaScreenAppName:shortAppName,
- SDLRPCParameterNameVRSynonyms:@[vrSynonyms],
- SDLRPCParameterNameIsMediaApplication:isMediaApp,
- SDLRPCParameterNameLanguageDesired:SDLLanguageNoNo,
- SDLRPCParameterNameHMIDisplayLanguageDesired:SDLLanguagePtPt,
- SDLRPCParameterNameAppHMIType:appTypes,
- SDLRPCParameterNameHashId:resumeHash,
- SDLRPCParameterNameDeviceInfo:info,
- SDLRPCParameterNameFullAppID:fullAppId,
- SDLRPCParameterNameAppId:appId,
- SDLRPCParameterNameAppInfo:appInfo,
- SDLRPCParameterNameDayColorScheme: colorScheme,
- SDLRPCParameterNameNightColorScheme: colorScheme,
- },
- SDLRPCParameterNameOperationName:SDLRPCFunctionNameRegisterAppInterface}};
+ describe(@"Setting With Dictionary", ^{
+ __block NSDictionary *dict = nil;
+ beforeEach( ^{
+ dict = @{SDLRPCParameterNameRequest:
+ @{SDLRPCParameterNameParameters:
+ @{SDLRPCParameterNameSyncMessageVersion:@{
+ SDLRPCParameterNameMajorVersion: @6,
+ SDLRPCParameterNameMinorVersion: @0,
+ SDLRPCParameterNamePatchVersion: @0
+ },
+ SDLRPCParameterNameAppName:appName,
+ SDLRPCParameterNameTTSName:[@[chunk] mutableCopy],
+ SDLRPCParameterNameNGNMediaScreenAppName:shortAppName,
+ SDLRPCParameterNameVRSynonyms:@[vrSynonyms],
+ SDLRPCParameterNameIsMediaApplication:isMediaApp,
+ SDLRPCParameterNameLanguageDesired:SDLLanguageNoNo,
+ SDLRPCParameterNameHMIDisplayLanguageDesired:SDLLanguagePtPt,
+ SDLRPCParameterNameAppHMIType:appTypes,
+ SDLRPCParameterNameHashId:resumeHash,
+ SDLRPCParameterNameDeviceInfo:info,
+ SDLRPCParameterNameFullAppID:fullAppId,
+ SDLRPCParameterNameAppId:appId,
+ SDLRPCParameterNameAppInfo:appInfo,
+ SDLRPCParameterNameDayColorScheme: colorScheme,
+ SDLRPCParameterNameNightColorScheme: colorScheme,
+ },
+ SDLRPCParameterNameOperationName:SDLRPCFunctionNameRegisterAppInterface}};
+ });
+
+ it(@"Should get correctly when initialized with a dictionary and get syncMsgVersion first", ^ {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
SDLRegisterAppInterface* testRegisterAppInterface = [[SDLRegisterAppInterface alloc] initWithDictionary:dict];
#pragma clang diagnostic pop
- expect(testRegisterAppInterface.syncMsgVersion).to(equal(version));
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ expect(testRegisterAppInterface.syncMsgVersion).to(equal(currentSyncMsgVersion));
+#pragma clang diagnostic pop
+ expect(testRegisterAppInterface.sdlMsgVersion).to(equal(currentSDLMsgVersion));
expect(testRegisterAppInterface.appName).to(match(appName));
expect(testRegisterAppInterface.ttsName).to(equal([@[chunk] mutableCopy]));
expect(testRegisterAppInterface.ngnMediaScreenAppName).to(match(shortAppName));
@@ -136,11 +167,42 @@ describe(@"RegisterAppInterface Tests", ^{
expect(testRegisterAppInterface.nightColorScheme).to(equal(colorScheme));
});
+ it(@"Should get correctly when initialized with a dictionary and sdlMsgVersion first", ^ {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ SDLRegisterAppInterface* testRegisterAppInterface = [[SDLRegisterAppInterface alloc] initWithDictionary:dict];
+#pragma clang diagnostic pop
+ expect(testRegisterAppInterface.sdlMsgVersion).to(equal(currentSDLMsgVersion));
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ expect(testRegisterAppInterface.syncMsgVersion).to(equal(currentSyncMsgVersion));
+#pragma clang diagnostic pop
+ expect(testRegisterAppInterface.appName).to(match(appName));
+ expect(testRegisterAppInterface.ttsName).to(equal([@[chunk] mutableCopy]));
+ expect(testRegisterAppInterface.ngnMediaScreenAppName).to(match(shortAppName));
+ expect(testRegisterAppInterface.vrSynonyms).to(equal(@[vrSynonyms]));
+ expect(testRegisterAppInterface.isMediaApplication).to(equal(isMediaApp));
+ expect(testRegisterAppInterface.languageDesired).to(equal(SDLLanguageNoNo));
+ expect(testRegisterAppInterface.hmiDisplayLanguageDesired).to(equal(SDLLanguagePtPt));
+ expect(testRegisterAppInterface.appHMIType).to(equal(appTypes));
+ expect(testRegisterAppInterface.hashID).to(match(resumeHash));
+ expect(testRegisterAppInterface.deviceInfo).to(equal(info));
+ expect(testRegisterAppInterface.fullAppID).to(match(fullAppId));
+ expect(testRegisterAppInterface.appID).to(match(appId));
+ expect(testRegisterAppInterface.appInfo).to(equal(appInfo));
+ expect(testRegisterAppInterface.dayColorScheme).to(equal(colorScheme));
+ expect(testRegisterAppInterface.nightColorScheme).to(equal(colorScheme));
+ });
+ });
+
describe(@"initializers", ^{
it(@"init", ^{
testRegisterAppInterface = [[SDLRegisterAppInterface alloc] init];
-
- expect(testRegisterAppInterface.syncMsgVersion).to(beNil());
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ expect(testRegisterAppInterface.syncMsgVersion).to(equal(version));
+#pragma clang diagnostic pop
+ expect(testRegisterAppInterface.sdlMsgVersion).to(beNil());
expect(testRegisterAppInterface.appName).to(beNil());
expect(testRegisterAppInterface.ttsName).to(beNil());
expect(testRegisterAppInterface.ngnMediaScreenAppName).to(beNil());
@@ -173,7 +235,11 @@ describe(@"RegisterAppInterface Tests", ^{
SDLRegisterAppInterface *testRegisterAppInterface = [[SDLRegisterAppInterface alloc] initWithLifecycleConfiguration:testLifecyleConfiguration];
expect(testRegisterAppInterface.fullAppID).to(match(fullAppId));
expect(testRegisterAppInterface.appID).to(match(expectedAppId));
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
expect(testRegisterAppInterface.syncMsgVersion).to(equal(currentSyncMsgVersion));
+#pragma clang diagnostic pop
+ expect(testRegisterAppInterface.sdlMsgVersion).to(equal(currentSDLMsgVersion));
expect(testRegisterAppInterface.appName).to(equal(appName));
expect(testRegisterAppInterface.ttsName).to(contain(chunk));
expect(testRegisterAppInterface.ngnMediaScreenAppName).to(equal(shortAppName));
@@ -197,7 +263,11 @@ describe(@"RegisterAppInterface Tests", ^{
expect(testRegisterAppInterface.fullAppID).to(beNil());
expect(testRegisterAppInterface.appID).to(match(appId));
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
expect(testRegisterAppInterface.syncMsgVersion).to(equal(currentSyncMsgVersion));
+#pragma clang diagnostic pop
+ expect(testRegisterAppInterface.sdlMsgVersion).to(equal(currentSDLMsgVersion));
expect(testRegisterAppInterface.appName).to(equal(appName));
expect(testRegisterAppInterface.ttsName).to(beNil());
expect(testRegisterAppInterface.ngnMediaScreenAppName).to(beNil());
@@ -218,10 +288,13 @@ describe(@"RegisterAppInterface Tests", ^{
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
SDLRegisterAppInterface *testRegisterAppInterface = [[SDLRegisterAppInterface alloc] initWithAppName:appName appId:appId languageDesired:language isMediaApp:isMediaApp appTypes:appTypes shortAppName:shortAppName];
#pragma clang diagnostic pop
-
expect(testRegisterAppInterface.fullAppID).to(beNil());
expect(testRegisterAppInterface.appID).to(match(appId));
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
expect(testRegisterAppInterface.syncMsgVersion).to(equal(currentSyncMsgVersion));
+#pragma clang diagnostic pop
+ expect(testRegisterAppInterface.sdlMsgVersion).to(equal(currentSDLMsgVersion));
expect(testRegisterAppInterface.appName).to(equal(appName));
expect(testRegisterAppInterface.ttsName).to(beNil());
expect(testRegisterAppInterface.ngnMediaScreenAppName).to(equal(shortAppName));
@@ -239,13 +312,17 @@ describe(@"RegisterAppInterface Tests", ^{
expect(testRegisterAppInterface.nightColorScheme).to(beNil());
});
it(@"initWithAppName:appId:languageDesired:isMediaApp:appTypes:shortAppName:ttsName:vrSynonyms:hmiDisplayLanguageDesired:resumeHash:", ^{
- #pragma clang diagnostic push
- #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
SDLRegisterAppInterface *testRegisterAppInterface = [[SDLRegisterAppInterface alloc] initWithAppName:appName appId:appId languageDesired:language isMediaApp:isMediaApp appTypes:appTypes shortAppName:shortAppName ttsName:@[chunk] vrSynonyms:@[vrSynonyms] hmiDisplayLanguageDesired:hmiDisplayLanguage resumeHash:resumeHash];
-
+#pragma clang diagnostic pop
expect(testRegisterAppInterface.fullAppID).to(beNil());
expect(testRegisterAppInterface.appID).to(match(appId));
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
expect(testRegisterAppInterface.syncMsgVersion).to(equal(currentSyncMsgVersion));
+#pragma clang diagnostic pop
+ expect(testRegisterAppInterface.sdlMsgVersion).to(equal(currentSDLMsgVersion));
expect(testRegisterAppInterface.appName).to(equal(appName));
expect(testRegisterAppInterface.ttsName).to(contain(chunk));
expect(testRegisterAppInterface.ngnMediaScreenAppName).to(equal(shortAppName));
@@ -261,15 +338,17 @@ describe(@"RegisterAppInterface Tests", ^{
expect(testRegisterAppInterface.appInfo).toNot(beNil());
expect(testRegisterAppInterface.dayColorScheme).to(beNil());
expect(testRegisterAppInterface.nightColorScheme).to(beNil());
- #pragma clang diagnostic pop
});
-
it(@"initWithAppName:appId:fullAppId:languageDesired:isMediaApp:appTypes:shortAppName:ttsName:vrSynonyms:hmiDisplayLanguageDesired:resumeHash:dayColorScheme:nightColorScheme:", ^{
SDLRegisterAppInterface *testRegisterAppInterface = [[SDLRegisterAppInterface alloc] initWithAppName:appName appId:appId fullAppId:fullAppId languageDesired:language isMediaApp:isMediaApp appTypes:appTypes shortAppName:shortAppName ttsName:@[chunk] vrSynonyms:@[vrSynonyms] hmiDisplayLanguageDesired:hmiDisplayLanguage resumeHash:resumeHash dayColorScheme:colorScheme nightColorScheme:colorScheme];
expect(testRegisterAppInterface.fullAppID).to(match(fullAppId));
expect(testRegisterAppInterface.appID).to(match(appId));
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
expect(testRegisterAppInterface.syncMsgVersion).to(equal(currentSyncMsgVersion));
+#pragma clang diagnostic pop
+ expect(testRegisterAppInterface.sdlMsgVersion).to(equal(currentSDLMsgVersion));
expect(testRegisterAppInterface.appName).to(equal(appName));
expect(testRegisterAppInterface.ttsName).to(contain(chunk));
expect(testRegisterAppInterface.ngnMediaScreenAppName).to(equal(shortAppName));
diff --git a/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLShowAppMenuSpec.m b/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLShowAppMenuSpec.m
new file mode 100644
index 000000000..4557c014a
--- /dev/null
+++ b/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLShowAppMenuSpec.m
@@ -0,0 +1,50 @@
+//
+// SDLShowAppMenuSpec.m
+// SmartDeviceLinkTests
+//
+// Created by Justin Gluck on 7/15/19.
+// Copyright © 2019 smartdevicelink. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+#import <Quick/Quick.h>
+#import <Nimble/Nimble.h>
+
+#import "SDLRPCParameterNames.h"
+#import "SDLRPCFunctionNames.h"
+#import "SDLShowAppMenu.h"
+
+QuickSpecBegin(SDLShowAppMenuSpec)
+describe(@"Getter/Setter Tests", ^ {
+ __block UInt32 menuId = 4345645;
+
+ it(@"Should set and get correctly", ^ {
+ SDLShowAppMenu *testRequest = [[SDLShowAppMenu alloc] init];
+
+ testRequest.menuID = @(menuId);
+
+ expect(testRequest.menuID).to(equal(testRequest.menuID));
+ });
+
+ it(@"Should get correctly when initialized with dictonary", ^ {
+ NSDictionary<NSString *, id> *dict = [@{SDLRPCParameterNameRequest:
+ @{SDLRPCParameterNameParameters:
+ @{SDLRPCParameterNameMenuId:@4345645,
+ },
+ SDLRPCParameterNameOperationName:SDLRPCFunctionNameShowAppMenu}} mutableCopy];
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ SDLShowAppMenu* testRequest = [[SDLShowAppMenu alloc] initWithDictionary:dict];
+#pragma clang diagnostic pop
+ expect(testRequest.menuID).to(equal(@(menuId)));
+ });
+
+ it(@"Should return nil if not set", ^ {
+ SDLShowAppMenu *testRequest = [[SDLShowAppMenu alloc] init];
+
+ expect(testRequest.menuID).to(beNil());
+ });
+
+});
+QuickSpecEnd
diff --git a/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLShowSpec.m b/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLShowSpec.m
index d9274e8e9..8fae13aa0 100644
--- a/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLShowSpec.m
+++ b/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLShowSpec.m
@@ -38,6 +38,7 @@ describe(@"Getter/Setter Tests", ^ {
testRequest.statusBar = @"status";
testRequest.mediaClock = @"TheTime";
testRequest.mediaTrack = @"In The Clear";
+ testRequest.templateTitle = @"Hello World";
testRequest.graphic = image1;
testRequest.secondaryGraphic = image2;
testRequest.softButtons = [@[button] mutableCopy];
@@ -52,6 +53,7 @@ describe(@"Getter/Setter Tests", ^ {
expect(testRequest.statusBar).to(equal(@"status"));
expect(testRequest.mediaClock).to(equal(@"TheTime"));
expect(testRequest.mediaTrack).to(equal(@"In The Clear"));
+ expect(testRequest.templateTitle).to(equal(@"Hello World"));
expect(testRequest.graphic).to(equal(image1));
expect(testRequest.secondaryGraphic).to(equal(image2));
expect(testRequest.softButtons).to(equal([@[button] mutableCopy]));
@@ -71,6 +73,7 @@ describe(@"Getter/Setter Tests", ^ {
expect(testRequest.statusBar).to(beNil());
expect(testRequest.mediaClock).to(beNil());
expect(testRequest.mediaTrack).to(beNil());
+ expect(testRequest.templateTitle).to(beNil());
expect(testRequest.graphic).to(beNil());
expect(testRequest.secondaryGraphic).to(beNil());
expect(testRequest.softButtons).to(beNil());
@@ -86,6 +89,7 @@ describe(@"Getter/Setter Tests", ^ {
__block NSString *testStatusBarString = @"Test Status";
__block NSString *testMediaClockString = @"Test Clock";
__block NSString *testMediaTrackString = @"Test Track";
+ __block NSString *testTemplateTitleString = @"Hello World";
__block SDLImage *testGraphic = nil;
__block NSArray<NSString *> *testCustomPresets = nil;
__block SDLSoftButton *testButton = nil;
@@ -115,6 +119,7 @@ describe(@"Getter/Setter Tests", ^ {
expect(testShow.statusBar).to(beNil());
expect(testShow.mediaClock).to(beNil());
expect(testShow.mediaTrack).to(beNil());
+ expect(testShow.templateTitle).to(beNil());
expect(testShow.graphic).to(beNil());
expect(testShow.secondaryGraphic).to(beNil());
expect(testShow.softButtons).to(beNil());
@@ -130,6 +135,7 @@ describe(@"Getter/Setter Tests", ^ {
expect(testShow.statusBar).to(beNil());
expect(testShow.mediaClock).to(beNil());
expect(testShow.mediaTrack).to(beNil());
+ expect(testShow.templateTitle).to(beNil());
expect(testShow.graphic).to(beNil());
expect(testShow.secondaryGraphic).to(beNil());
expect(testShow.softButtons).to(beNil());
@@ -147,6 +153,7 @@ describe(@"Getter/Setter Tests", ^ {
expect(testShow.statusBar).to(beNil());
expect(testShow.mediaClock).to(beNil());
expect(testShow.mediaTrack).to(beNil());
+ expect(testShow.templateTitle).to(beNil());
expect(testShow.graphic).to(beNil());
expect(testShow.secondaryGraphic).to(beNil());
expect(testShow.softButtons).to(beNil());
@@ -165,6 +172,7 @@ describe(@"Getter/Setter Tests", ^ {
expect(testShow.statusBar).to(beNil());
expect(testShow.mediaClock).to(beNil());
expect(testShow.mediaTrack).to(beNil());
+ expect(testShow.templateTitle).to(beNil());
expect(testShow.graphic).to(beNil());
expect(testShow.secondaryGraphic).to(beNil());
expect(testShow.softButtons).to(beNil());
@@ -182,6 +190,7 @@ describe(@"Getter/Setter Tests", ^ {
expect(testShow.statusBar).to(beNil());
expect(testShow.mediaClock).to(beNil());
expect(testShow.mediaTrack).to(beNil());
+ expect(testShow.templateTitle).to(beNil());
expect(testShow.graphic).to(beNil());
expect(testShow.secondaryGraphic).to(beNil());
expect(testShow.softButtons).to(beNil());
@@ -200,6 +209,7 @@ describe(@"Getter/Setter Tests", ^ {
expect(testShow.statusBar).to(beNil());
expect(testShow.mediaClock).to(beNil());
expect(testShow.mediaTrack).to(beNil());
+ expect(testShow.templateTitle).to(beNil());
expect(testShow.graphic).to(beNil());
expect(testShow.secondaryGraphic).to(beNil());
expect(testShow.softButtons).to(beNil());
@@ -217,6 +227,7 @@ describe(@"Getter/Setter Tests", ^ {
expect(testShow.statusBar).to(beNil());
expect(testShow.mediaClock).to(beNil());
expect(testShow.mediaTrack).to(beNil());
+ expect(testShow.templateTitle).to(beNil());
expect(testShow.graphic).to(beNil());
expect(testShow.secondaryGraphic).to(beNil());
expect(testShow.softButtons).to(beNil());
@@ -235,6 +246,7 @@ describe(@"Getter/Setter Tests", ^ {
expect(testShow.statusBar).to(beNil());
expect(testShow.mediaClock).to(beNil());
expect(testShow.mediaTrack).to(beNil());
+ expect(testShow.templateTitle).to(beNil());
expect(testShow.graphic).to(beNil());
expect(testShow.secondaryGraphic).to(beNil());
expect(testShow.softButtons).to(beNil());
@@ -252,6 +264,7 @@ describe(@"Getter/Setter Tests", ^ {
expect(testShow.statusBar).to(equal(testStatusBarString));
expect(testShow.mediaClock).to(equal(testMediaClockString));
expect(testShow.mediaTrack).to(equal(testMediaTrackString));
+ expect(testShow.templateTitle).to(beNil());
expect(testShow.graphic).to(beNil());
expect(testShow.secondaryGraphic).to(beNil());
expect(testShow.softButtons).to(beNil());
@@ -270,6 +283,7 @@ describe(@"Getter/Setter Tests", ^ {
expect(testShow.statusBar).to(beNil());
expect(testShow.mediaClock).to(beNil());
expect(testShow.mediaTrack).to(beNil());
+ expect(testShow.templateTitle).to(beNil());
expect(testShow.graphic).to(beNil());
expect(testShow.secondaryGraphic).to(beNil());
expect(testShow.softButtons).to(beNil());
@@ -287,6 +301,7 @@ describe(@"Getter/Setter Tests", ^ {
expect(testShow.statusBar).to(equal(testStatusBarString));
expect(testShow.mediaClock).to(equal(testMediaClockString));
expect(testShow.mediaTrack).to(equal(testMediaTrackString));
+ expect(testShow.templateTitle).to(beNil());
expect(testShow.graphic).to(equal(testGraphic));
expect(testShow.secondaryGraphic).to(beNil());
expect(testShow.softButtons).to(contain(testButton));
@@ -305,6 +320,7 @@ describe(@"Getter/Setter Tests", ^ {
expect(testShow.statusBar).to(beNil());
expect(testShow.mediaClock).to(beNil());
expect(testShow.mediaTrack).to(beNil());
+ expect(testShow.templateTitle).to(beNil());
expect(testShow.graphic).to(beNil());
expect(testShow.secondaryGraphic).to(beNil());
expect(testShow.softButtons).to(beNil());
@@ -323,6 +339,7 @@ describe(@"Getter/Setter Tests", ^ {
SDLRPCParameterNameStatusBar:@"status",
SDLRPCParameterNameMediaClock:@"TheTime",
SDLRPCParameterNameMediaTrack:@"In The Clear",
+ SDLRPCParameterNameTemplateTitle: @"Hello World",
SDLRPCParameterNameGraphic:image1,
SDLRPCParameterNameSecondaryGraphic:image2,
SDLRPCParameterNameSoftButtons:[@[button] mutableCopy],
@@ -342,6 +359,7 @@ describe(@"Getter/Setter Tests", ^ {
expect(testRequest.statusBar).to(equal(@"status"));
expect(testRequest.mediaClock).to(equal(@"TheTime"));
expect(testRequest.mediaTrack).to(equal(@"In The Clear"));
+ expect(testRequest.templateTitle).to(equal(@"Hello World"));
expect(testRequest.graphic).to(equal(image1));
expect(testRequest.secondaryGraphic).to(equal(image2));
expect(testRequest.softButtons).to(equal([@[button] mutableCopy]));
diff --git a/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLUnpublishAppServiceSpec.m b/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLUnpublishAppServiceSpec.m
new file mode 100644
index 000000000..fa2c66c22
--- /dev/null
+++ b/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLUnpublishAppServiceSpec.m
@@ -0,0 +1,55 @@
+//
+// SDLUnpublishAppServiceSpec.m
+// SmartDeviceLinkTests
+//
+// Created by Bretty White on 7/15/19.
+// Copyright © 2019 smartdevicelink. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+#import <Quick/Quick.h>
+#import <Nimble/Nimble.h>
+
+#import "SDLUnpublishAppService.h"
+#import "SDLRPCParameterNames.h"
+#import "SDLRPCFunctionNames.h"
+
+QuickSpecBegin(SDLUnpublishAppServiceSpec)
+
+describe(@"Getter/Setter Tests", ^ {
+ it(@"Should set and get correctly", ^ {
+ SDLUnpublishAppService* testRequest = [[SDLUnpublishAppService alloc] init];
+
+ testRequest.serviceID = @"idToUnpublish";
+
+ expect(testRequest.serviceID).to(equal(@"idToUnpublish"));
+ });
+
+ it(@"Should get correctly when initialized", ^ {
+ NSDictionary<NSString *, id> *dict = @{SDLRPCParameterNameRequest:
+ @{SDLRPCParameterNameParameters:
+ @{SDLRPCParameterNameServiceID:@"idToUnpublish"},
+ SDLRPCParameterNameOperationName:SDLRPCFunctionNameUnpublishAppService}};
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ SDLUnpublishAppService* testRequest = [[SDLUnpublishAppService alloc] initWithDictionary:dict];
+#pragma clang diagnostic pop
+
+ expect(testRequest.serviceID).to(equal(@"idToUnpublish"));
+ });
+
+ it(@"should properly initialize with serviceID:", ^{
+ SDLUnpublishAppService *testRequest = [[SDLUnpublishAppService alloc] initWithServiceID:@"idToUnpublish"];
+
+ expect(testRequest.serviceID).to(equal(@"idToUnpublish"));
+ });
+
+ it(@"Should return nil if not set", ^ {
+ SDLUnpublishAppService* testRequest = [[SDLUnpublishAppService alloc] init];
+
+ expect(testRequest.serviceID).to(beNil());
+ });
+});
+
+QuickSpecEnd
diff --git a/SmartDeviceLinkTests/RPCSpecs/ResponseSpecs/SDLRegisterAppInterfaceResponseSpec.m b/SmartDeviceLinkTests/RPCSpecs/ResponseSpecs/SDLRegisterAppInterfaceResponseSpec.m
index 4d7918de4..7d03501a5 100644
--- a/SmartDeviceLinkTests/RPCSpecs/ResponseSpecs/SDLRegisterAppInterfaceResponseSpec.m
+++ b/SmartDeviceLinkTests/RPCSpecs/ResponseSpecs/SDLRegisterAppInterfaceResponseSpec.m
@@ -15,20 +15,26 @@
QuickSpecBegin(SDLRegisterAppInterfaceResponseSpec)
-SDLSyncMsgVersion* version = [[SDLSyncMsgVersion alloc] init];
-SDLDisplayCapabilities* info = [[SDLDisplayCapabilities alloc] init];
-SDLButtonCapabilities* button = [[SDLButtonCapabilities alloc] init];
-SDLSoftButtonCapabilities* softButton = [[SDLSoftButtonCapabilities alloc] init];
-SDLPresetBankCapabilities* presetBank = [[SDLPresetBankCapabilities alloc] init];
-SDLAudioPassThruCapabilities* audioPassThru = [[SDLAudioPassThruCapabilities alloc] init];
-SDLVehicleType* vehicle = [[SDLVehicleType alloc] init];
-SDLHMICapabilities *hmiCapabilities = [[SDLHMICapabilities alloc] init];
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+__block SDLSyncMsgVersion* version = [[SDLSyncMsgVersion alloc] initWithMajorVersion:0 minorVersion:0 patchVersion:0];
+#pragma clang diagnostic pop
+__block SDLMsgVersion *sdlVersion = [[SDLMsgVersion alloc] initWithMajorVersion:0 minorVersion:0 patchVersion:0];
+__block SDLDisplayCapabilities* info = [[SDLDisplayCapabilities alloc] init];
+__block SDLButtonCapabilities* button = [[SDLButtonCapabilities alloc] init];
+__block SDLSoftButtonCapabilities* softButton = [[SDLSoftButtonCapabilities alloc] init];
+__block SDLPresetBankCapabilities* presetBank = [[SDLPresetBankCapabilities alloc] init];__block
+__block SDLAudioPassThruCapabilities* audioPassThru = [[SDLAudioPassThruCapabilities alloc] init];
+__block SDLVehicleType* vehicle = [[SDLVehicleType alloc] init];
+__block SDLHMICapabilities *hmiCapabilities = [[SDLHMICapabilities alloc] init];
describe(@"Getter/Setter Tests", ^ {
it(@"Should set and get correctly", ^ {
SDLRegisterAppInterfaceResponse* testResponse = [[SDLRegisterAppInterfaceResponse alloc] init];
-
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
testResponse.syncMsgVersion = version;
+#pragma clang diagnostic pop
testResponse.language = SDLLanguageEsMx;
testResponse.hmiDisplayLanguage = SDLLanguageRuRu;
testResponse.displayCapabilities = info;
@@ -47,8 +53,12 @@ describe(@"Getter/Setter Tests", ^ {
testResponse.sdlVersion = @"sdlVersion";
testResponse.systemSoftwareVersion = @"systemSoftwareVersion";
testResponse.iconResumed = @YES;
-
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
expect(testResponse.syncMsgVersion).to(equal(version));
+#pragma clang diagnostic pop
+ testResponse.sdlMsgVersion = sdlVersion;
+ expect(testResponse.sdlMsgVersion).to(equal(sdlVersion));
expect(testResponse.language).to(equal(SDLLanguageEsMx));
expect(testResponse.hmiDisplayLanguage).to(equal(SDLLanguageRuRu));
expect(testResponse.displayCapabilities).to(equal(info));
@@ -68,61 +78,108 @@ describe(@"Getter/Setter Tests", ^ {
expect(testResponse.systemSoftwareVersion).to(equal(@"systemSoftwareVersion"));
expect(testResponse.iconResumed).to(beTrue());
});
-
- it(@"Should get correctly when initialized", ^ {
- NSDictionary *dict = @{SDLRPCParameterNameRequest:
- @{SDLRPCParameterNameParameters:
- @{SDLRPCParameterNameSyncMessageVersion:version,
- SDLRPCParameterNameLanguage:SDLLanguageEsMx,
- SDLRPCParameterNameHMIDisplayLanguage:SDLLanguageRuRu,
- SDLRPCParameterNameDisplayCapabilities:info,
- SDLRPCParameterNameButtonCapabilities:@[button],
- SDLRPCParameterNameSoftButtonCapabilities:@[softButton],
- SDLRPCParameterNamePresetBankCapabilities:presetBank,
- SDLRPCParameterNameHMIZoneCapabilities:@[SDLHMIZoneCapabilitiesBack, SDLHMIZoneCapabilitiesFront],
- SDLRPCParameterNameSpeechCapabilities:@[SDLSpeechCapabilitiesSAPIPhonemes, SDLSpeechCapabilitiesSilence],
- SDLRPCParameterNameVRCapabilities:@[SDLVRCapabilitiesText],
- SDLRPCParameterNameAudioPassThruCapabilities:@[audioPassThru],
- SDLRPCParameterNamePCMStreamCapabilities: audioPassThru,
- SDLRPCParameterNameVehicleType:vehicle,
- SDLRPCParameterNamePrerecordedSpeech:@[SDLPrerecordedSpeechListen, SDLPrerecordedSpeechHelp],
- SDLRPCParameterNameSupportedDiagnosticModes:@[@67, @99, @111],
- SDLRPCParameterNameHMICapabilities: hmiCapabilities,
- SDLRPCParameterNameSDLVersion: @"sdlVersion",
- SDLRPCParameterNameSystemSoftwareVersion: @"systemSoftwareVersion",
- SDLRPCParameterNameIconResumed: @YES,
- },
- SDLRPCParameterNameOperationName:SDLRPCFunctionNameRegisterAppInterface}};
+ describe(@"Setting With Dictionary", ^{
+ __block NSDictionary *dict = nil;
+
+ beforeEach( ^{
+ dict = @{SDLRPCParameterNameRequest:
+ @{SDLRPCParameterNameParameters:
+ @{SDLRPCParameterNameSyncMessageVersion:@{
+ SDLRPCParameterNameMajorVersion: @6,
+ SDLRPCParameterNameMinorVersion: @0,
+ SDLRPCParameterNamePatchVersion: @0
+ },
+ SDLRPCParameterNameLanguage:SDLLanguageEsMx,
+ SDLRPCParameterNameHMIDisplayLanguage:SDLLanguageRuRu,
+ SDLRPCParameterNameDisplayCapabilities:info,
+ SDLRPCParameterNameButtonCapabilities:@[button],
+ SDLRPCParameterNameSoftButtonCapabilities:@[softButton],
+ SDLRPCParameterNamePresetBankCapabilities:presetBank,
+ SDLRPCParameterNameHMIZoneCapabilities:@[SDLHMIZoneCapabilitiesBack, SDLHMIZoneCapabilitiesFront],
+ SDLRPCParameterNameSpeechCapabilities:@[SDLSpeechCapabilitiesSAPIPhonemes, SDLSpeechCapabilitiesSilence],
+ SDLRPCParameterNameVRCapabilities:@[SDLVRCapabilitiesText],
+ SDLRPCParameterNameAudioPassThruCapabilities:@[audioPassThru],
+ SDLRPCParameterNamePCMStreamCapabilities: audioPassThru,
+ SDLRPCParameterNameVehicleType:vehicle,
+ SDLRPCParameterNamePrerecordedSpeech:@[SDLPrerecordedSpeechListen, SDLPrerecordedSpeechHelp],
+ SDLRPCParameterNameSupportedDiagnosticModes:@[@67, @99, @111],
+ SDLRPCParameterNameHMICapabilities: hmiCapabilities,
+ SDLRPCParameterNameSDLVersion: @"sdlVersion",
+ SDLRPCParameterNameSystemSoftwareVersion: @"systemSoftwareVersion",
+ SDLRPCParameterNameIconResumed: @YES,
+ },
+ SDLRPCParameterNameOperationName:SDLRPCFunctionNameRegisterAppInterface}};
+ });
+
+ it(@"Should get correctly when initialized with a dictionary and get syncMsgVersion first", ^ {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
SDLRegisterAppInterfaceResponse* testResponse = [[SDLRegisterAppInterfaceResponse alloc] initWithDictionary:dict];
#pragma clang diagnostic pop
-
- expect(testResponse.syncMsgVersion).to(equal(version));
- expect(testResponse.language).to(equal(SDLLanguageEsMx));
- expect(testResponse.hmiDisplayLanguage).to(equal(SDLLanguageRuRu));
- expect(testResponse.displayCapabilities).to(equal(info));
- expect(testResponse.buttonCapabilities).to(equal(@[button]));
- expect(testResponse.softButtonCapabilities).to(equal(@[softButton]));
- expect(testResponse.presetBankCapabilities).to(equal(presetBank));
- expect(testResponse.hmiZoneCapabilities).to(equal(@[SDLHMIZoneCapabilitiesBack, SDLHMIZoneCapabilitiesFront]));
- expect(testResponse.speechCapabilities).to(equal(@[SDLSpeechCapabilitiesSAPIPhonemes, SDLSpeechCapabilitiesSilence]));
- expect(testResponse.vrCapabilities).to(equal(@[SDLVRCapabilitiesText]));
- expect(testResponse.audioPassThruCapabilities).to(equal(@[audioPassThru]));
- expect(testResponse.pcmStreamCapabilities).to(equal(audioPassThru));
- expect(testResponse.vehicleType).to(equal(vehicle));
- expect(testResponse.prerecordedSpeech).to(equal(@[SDLPrerecordedSpeechListen, SDLPrerecordedSpeechHelp]));
- expect(testResponse.supportedDiagModes).to(equal(@[@67, @99, @111]));
- expect(testResponse.hmiCapabilities).to(equal(hmiCapabilities));
- expect(testResponse.sdlVersion).to(equal(@"sdlVersion"));
- expect(testResponse.systemSoftwareVersion).to(equal(@"systemSoftwareVersion"));
- expect(testResponse.iconResumed).to(beTrue());
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ expect(testResponse.syncMsgVersion).to(equal([[SDLSyncMsgVersion alloc] initWithMajorVersion:6 minorVersion:0 patchVersion:0]));
+#pragma clang diagnostic pop
+ expect(testResponse.sdlMsgVersion).to(equal([[SDLMsgVersion alloc] initWithMajorVersion:6 minorVersion:0 patchVersion:0]));
+ expect(testResponse.language).to(equal(SDLLanguageEsMx));
+ expect(testResponse.hmiDisplayLanguage).to(equal(SDLLanguageRuRu));
+ expect(testResponse.displayCapabilities).to(equal(info));
+ expect(testResponse.buttonCapabilities).to(equal(@[button]));
+ expect(testResponse.softButtonCapabilities).to(equal(@[softButton]));
+ expect(testResponse.presetBankCapabilities).to(equal(presetBank));
+ expect(testResponse.hmiZoneCapabilities).to(equal(@[SDLHMIZoneCapabilitiesBack, SDLHMIZoneCapabilitiesFront]));
+ expect(testResponse.speechCapabilities).to(equal(@[SDLSpeechCapabilitiesSAPIPhonemes, SDLSpeechCapabilitiesSilence]));
+ expect(testResponse.vrCapabilities).to(equal(@[SDLVRCapabilitiesText]));
+ expect(testResponse.audioPassThruCapabilities).to(equal(@[audioPassThru]));
+ expect(testResponse.pcmStreamCapabilities).to(equal(audioPassThru));
+ expect(testResponse.vehicleType).to(equal(vehicle));
+ expect(testResponse.prerecordedSpeech).to(equal(@[SDLPrerecordedSpeechListen, SDLPrerecordedSpeechHelp]));
+ expect(testResponse.supportedDiagModes).to(equal(@[@67, @99, @111]));
+ expect(testResponse.hmiCapabilities).to(equal(hmiCapabilities));
+ expect(testResponse.sdlVersion).to(equal(@"sdlVersion"));
+ expect(testResponse.systemSoftwareVersion).to(equal(@"systemSoftwareVersion"));
+ expect(testResponse.iconResumed).to(beTrue());
+ });
+
+ it(@"Should get correctly when initialized with a dictionary and get sdlMsgVersion first", ^ {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ SDLRegisterAppInterfaceResponse* testResponse = [[SDLRegisterAppInterfaceResponse alloc] initWithDictionary:dict];
+#pragma clang diagnostic pop
+ expect(testResponse.sdlMsgVersion).to(equal([[SDLMsgVersion alloc] initWithMajorVersion:6 minorVersion:0 patchVersion:0]));
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ expect(testResponse.syncMsgVersion).to(equal([[SDLSyncMsgVersion alloc] initWithMajorVersion:6 minorVersion:0 patchVersion:0]));
+#pragma clang diagnostic pop
+ expect(testResponse.language).to(equal(SDLLanguageEsMx));
+ expect(testResponse.hmiDisplayLanguage).to(equal(SDLLanguageRuRu));
+ expect(testResponse.displayCapabilities).to(equal(info));
+ expect(testResponse.buttonCapabilities).to(equal(@[button]));
+ expect(testResponse.softButtonCapabilities).to(equal(@[softButton]));
+ expect(testResponse.presetBankCapabilities).to(equal(presetBank));
+ expect(testResponse.hmiZoneCapabilities).to(equal(@[SDLHMIZoneCapabilitiesBack, SDLHMIZoneCapabilitiesFront]));
+ expect(testResponse.speechCapabilities).to(equal(@[SDLSpeechCapabilitiesSAPIPhonemes, SDLSpeechCapabilitiesSilence]));
+ expect(testResponse.vrCapabilities).to(equal(@[SDLVRCapabilitiesText]));
+ expect(testResponse.audioPassThruCapabilities).to(equal(@[audioPassThru]));
+ expect(testResponse.pcmStreamCapabilities).to(equal(audioPassThru));
+ expect(testResponse.vehicleType).to(equal(vehicle));
+ expect(testResponse.prerecordedSpeech).to(equal(@[SDLPrerecordedSpeechListen, SDLPrerecordedSpeechHelp]));
+ expect(testResponse.supportedDiagModes).to(equal(@[@67, @99, @111]));
+ expect(testResponse.hmiCapabilities).to(equal(hmiCapabilities));
+ expect(testResponse.sdlVersion).to(equal(@"sdlVersion"));
+ expect(testResponse.systemSoftwareVersion).to(equal(@"systemSoftwareVersion"));
+ expect(testResponse.iconResumed).to(beTrue());
+ });
});
it(@"Should return nil if not set", ^ {
SDLRegisterAppInterfaceResponse* testResponse = [[SDLRegisterAppInterfaceResponse alloc] init];
-
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
expect(testResponse.syncMsgVersion).to(beNil());
+#pragma clang diagnostic pop
+ expect(testResponse.sdlMsgVersion).to(beNil());
expect(testResponse.language).to(beNil());
expect(testResponse.hmiDisplayLanguage).to(beNil());
expect(testResponse.displayCapabilities).to(beNil());
@@ -172,7 +229,11 @@ describe(@"Getter/Setter Tests", ^ {
SDLRegisterAppInterfaceResponse* testResponse = [[SDLRegisterAppInterfaceResponse alloc] initWithDictionary:dict];
#pragma clang diagnostic pop
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
expectAction(^{ [testResponse syncMsgVersion]; }).to(raiseException());
+#pragma clang diagnostic pop
+ expectAction(^{ [testResponse sdlMsgVersion]; }).to(raiseException());
expectAction(^{ [testResponse language]; }).to(raiseException());
expectAction(^{ [testResponse hmiDisplayLanguage]; }).to(raiseException());
expectAction(^{ [testResponse displayCapabilities]; }).to(raiseException());
diff --git a/SmartDeviceLinkTests/RPCSpecs/ResponseSpecs/SDLShowAppMenuResponseSpec.m b/SmartDeviceLinkTests/RPCSpecs/ResponseSpecs/SDLShowAppMenuResponseSpec.m
new file mode 100644
index 000000000..7d32948a5
--- /dev/null
+++ b/SmartDeviceLinkTests/RPCSpecs/ResponseSpecs/SDLShowAppMenuResponseSpec.m
@@ -0,0 +1,19 @@
+//
+// SDLShowAppMenuResponseSpec.m
+// SmartDeviceLinkTests
+//
+// Created by Justin Gluck on 7/17/19.
+// Copyright © 2019 smartdevicelink. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+#import <Quick/Quick.h>
+#import <Nimble/Nimble.h>
+
+#import "SDLShowResponse.h"
+#import "SDLRPCParameterNames.h"
+
+QuickSpecBegin(SDLShowAppMenuResponseSpec)
+
+QuickSpecEnd
diff --git a/SmartDeviceLinkTests/RPCSpecs/ResponseSpecs/SDLUnpublishAppServiceResponseSpec.m b/SmartDeviceLinkTests/RPCSpecs/ResponseSpecs/SDLUnpublishAppServiceResponseSpec.m
new file mode 100644
index 000000000..4a09c39a0
--- /dev/null
+++ b/SmartDeviceLinkTests/RPCSpecs/ResponseSpecs/SDLUnpublishAppServiceResponseSpec.m
@@ -0,0 +1,38 @@
+//
+// SDLUnpublishAppServiceResponseSpec.m
+// SmartDeviceLinkTests
+//
+// Created by Bretty White on 7/15/19.
+// Copyright © 2019 smartdevicelink. All rights reserved.
+//
+
+#import <Quick/Quick.h>
+#import <Nimble/Nimble.h>
+
+#import "SDLUnpublishAppServiceResponse.h"
+#import "SDLRPCParameterNames.h"
+#import "SDLRPCFunctionNames.h"
+
+QuickSpecBegin(SDLUnpublishAppServiceResponseSpec)
+
+describe(@"Getter/Setter Tests", ^{
+ it(@"Should initialize correctly", ^{
+ SDLUnpublishAppServiceResponse *testResponse = [[SDLUnpublishAppServiceResponse alloc] init];
+ expect(testResponse.name).to(equal(SDLRPCFunctionNameUnpublishAppService));
+ });
+
+ it(@"Should initialize correctly with a dictionary", ^{
+ NSDictionary *dict = @{SDLRPCParameterNameRequest:@{
+ SDLRPCParameterNameParameters:@{},
+ SDLRPCParameterNameOperationName:SDLRPCFunctionNameUnpublishAppService}};
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ SDLUnpublishAppServiceResponse *testResponse = [[SDLUnpublishAppServiceResponse alloc] initWithDictionary:dict];
+#pragma clang diagnostic pop
+
+ expect(testResponse.name).to(equal(SDLRPCFunctionNameUnpublishAppService));
+ expect(testResponse.parameters).to(beEmpty());
+ });
+});
+
+QuickSpecEnd
diff --git a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLAppServiceManifestSpec.m b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLAppServiceManifestSpec.m
index 430d869b5..0bdc9fff4 100644
--- a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLAppServiceManifestSpec.m
+++ b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLAppServiceManifestSpec.m
@@ -17,6 +17,7 @@
#import "SDLMediaServiceManifest.h"
#import "SDLRPCParameterNames.h"
#import "SDLRPCFunctionNames.h"
+#import "SDLMsgVersion.h"
#import "SDLSyncMsgVersion.h"
#import "SDLWeatherServiceManifest.h"
@@ -28,7 +29,11 @@ describe(@"Getter/Setter Tests", ^ {
__block SDLAppServiceType testAppServiceType = nil;
__block SDLImage *testServiceIcon = nil;
__block NSNumber<SDLBool> *testAllowAppConsumers = nil;
- __block SDLSyncMsgVersion *testRPCSpecVersion = nil;
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ __block SDLSyncMsgVersion *testSyncMsgVersion = nil;
+#pragma clang diagnostic pop
+ __block SDLMsgVersion *testSDLMsgVersion = nil;
__block NSArray<NSNumber<SDLInt> *> *testHandledRPCs = nil;
__block SDLWeatherServiceManifest *testWeatherServiceManifest = nil;
__block SDLMediaServiceManifest *testMediaServiceManifest = nil;
@@ -40,7 +45,11 @@ describe(@"Getter/Setter Tests", ^ {
testAppServiceType = SDLAppServiceTypeNavigation;
testServiceIcon = [[SDLImage alloc] initWithName:@"testImage" isTemplate:false];
testAllowAppConsumers = @YES;
- testRPCSpecVersion = [[SDLSyncMsgVersion alloc] initWithMajorVersion:5 minorVersion:2 patchVersion:1];
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ testSyncMsgVersion = [[SDLSyncMsgVersion alloc] initWithMajorVersion:5 minorVersion:2 patchVersion:1];
+#pragma clang diagnostic pop
+ testSDLMsgVersion = [[SDLMsgVersion alloc] initWithMajorVersion:5 minorVersion:2 patchVersion:1];
testHandledRPCs = [[NSArray alloc] initWithObjects:[SDLFunctionID.sharedInstance functionIdForName:SDLRPCFunctionNameAddCommand], [SDLFunctionID.sharedInstance functionIdForName:SDLRPCFunctionNameCreateInteractionChoiceSet], nil];
testWeatherServiceManifest = [[SDLWeatherServiceManifest alloc] initWithCurrentForecastSupported:true maxMultidayForecastAmount:3 maxHourlyForecastAmount:0 maxMinutelyForecastAmount:0 weatherForLocationSupported:false];
testMediaServiceManifest = [[SDLMediaServiceManifest alloc] init];
@@ -49,11 +58,15 @@ describe(@"Getter/Setter Tests", ^ {
it(@"Should set and get correctly", ^{
SDLAppServiceManifest *testStruct = [[SDLAppServiceManifest alloc] init];
+
testStruct.serviceName = testServiceName;
testStruct.serviceType = testServiceType;
testStruct.serviceIcon = testServiceIcon;
testStruct.allowAppConsumers = testAllowAppConsumers;
- testStruct.rpcSpecVersion = testRPCSpecVersion;
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ testStruct.rpcSpecVersion = testSyncMsgVersion;
+#pragma clang diagnostic pop
testStruct.handledRPCs = testHandledRPCs;
testStruct.weatherServiceManifest = testWeatherServiceManifest;
testStruct.mediaServiceManifest = testMediaServiceManifest;
@@ -63,38 +76,77 @@ describe(@"Getter/Setter Tests", ^ {
expect(testStruct.serviceType).to(match(testServiceType));
expect(testStruct.serviceIcon).to(equal(testServiceIcon));
expect(testStruct.allowAppConsumers).to(beTrue());
- expect(testStruct.rpcSpecVersion).to(equal(testRPCSpecVersion));
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ expect(testStruct.rpcSpecVersion).to(equal(testSyncMsgVersion));
+#pragma clang diagnostic pop
+ testStruct.maxRPCSpecVersion = testSDLMsgVersion;
+ expect(testStruct.maxRPCSpecVersion).to(equal(testSDLMsgVersion));
+ expect(testStruct.maxRPCSpecVersion).to(equal(testSDLMsgVersion));
expect(testStruct.handledRPCs).to(equal(testHandledRPCs));
expect(testStruct.weatherServiceManifest).to(equal(testWeatherServiceManifest));
expect(testStruct.mediaServiceManifest).to(equal(testMediaServiceManifest));
expect(testStruct.navigationServiceManifest).to(equal(testNavigationServiceManifest));
});
+ describe(@"test initializing with dictionary", ^{
+ __block NSDictionary *dict = nil;
+ beforeEach( ^{
+ dict = @{SDLRPCParameterNameServiceName:testServiceName,
+ SDLRPCParameterNameServiceType:testServiceType,
+ SDLRPCParameterNameServiceIcon:testServiceIcon,
+ SDLRPCParameterNameAllowAppConsumers:testAllowAppConsumers,
+ SDLRPCParameterNameRPCSpecVersion: @{
+ SDLRPCParameterNameMajorVersion: @5,
+ SDLRPCParameterNameMinorVersion: @1,
+ SDLRPCParameterNamePatchVersion: @0
+ },
+ SDLRPCParameterNameHandledRPCs:testHandledRPCs,
+ SDLRPCParameterNameWeatherServiceManifest:testWeatherServiceManifest,
+ SDLRPCParameterNameMediaServiceManifest:testMediaServiceManifest,
+ SDLRPCParameterNameNavigationServiceManifest:testNavigationServiceManifest
+ };
+ });
+ it(@"Should get correctly when initialized with a dictionary and using SycMsgVersion", ^{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ SDLAppServiceManifest *testStruct = [[SDLAppServiceManifest alloc] initWithDictionary:dict];
+#pragma clang diagnostic pop
+ expect(testStruct.serviceName).to(match(testServiceName));
+ expect(testStruct.serviceType).to(equal(testServiceType));
+ expect(testStruct.serviceIcon).to(equal(testServiceIcon));
+ expect(testStruct.allowAppConsumers).to(beTrue());
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ expect(testStruct.rpcSpecVersion).to(equal([[SDLSyncMsgVersion alloc] initWithMajorVersion:5 minorVersion:1 patchVersion:0]));
+#pragma clang diagnostic pop
+ expect(testStruct.maxRPCSpecVersion).to(equal([[SDLMsgVersion alloc] initWithMajorVersion:5 minorVersion:1 patchVersion:0]));
+ expect(testStruct.handledRPCs).to(equal(testHandledRPCs));
+ expect(testStruct.weatherServiceManifest).to(equal(testWeatherServiceManifest));
+ expect(testStruct.mediaServiceManifest).to(equal(testMediaServiceManifest));
+ expect(testStruct.navigationServiceManifest).to(equal(testNavigationServiceManifest));
- it(@"Should get correctly when initialized with a dictionary", ^{
- NSDictionary *dict = @{SDLRPCParameterNameServiceName:testServiceName,
- SDLRPCParameterNameServiceType:testServiceType,
- SDLRPCParameterNameServiceIcon:testServiceIcon,
- SDLRPCParameterNameAllowAppConsumers:testAllowAppConsumers,
- SDLRPCParameterNameRPCSpecVersion:testRPCSpecVersion,
- SDLRPCParameterNameHandledRPCs:testHandledRPCs,
- SDLRPCParameterNameWeatherServiceManifest:testWeatherServiceManifest,
- SDLRPCParameterNameMediaServiceManifest:testMediaServiceManifest,
- SDLRPCParameterNameNavigationServiceManifest:testNavigationServiceManifest
- };
+ });
+
+ it(@"Should get correctly when initialized with a dictionary and using SDLMsgVersion", ^{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
SDLAppServiceManifest *testStruct = [[SDLAppServiceManifest alloc] initWithDictionary:dict];
#pragma clang diagnostic pop
+ expect(testStruct.serviceName).to(match(testServiceName));
+ expect(testStruct.serviceType).to(equal(testServiceType));
+ expect(testStruct.serviceIcon).to(equal(testServiceIcon));
+ expect(testStruct.allowAppConsumers).to(beTrue());
+ expect(testStruct.maxRPCSpecVersion).to(equal([[SDLMsgVersion alloc] initWithMajorVersion:5 minorVersion:1 patchVersion:0]));
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ expect(testStruct.rpcSpecVersion).to(equal([[SDLSyncMsgVersion alloc] initWithMajorVersion:5 minorVersion:1 patchVersion:0]));
+#pragma clang diagnostic pop
+ expect(testStruct.handledRPCs).to(equal(testHandledRPCs));
+ expect(testStruct.weatherServiceManifest).to(equal(testWeatherServiceManifest));
+ expect(testStruct.mediaServiceManifest).to(equal(testMediaServiceManifest));
+ expect(testStruct.navigationServiceManifest).to(equal(testNavigationServiceManifest));
- expect(testStruct.serviceName).to(match(testServiceName));
- expect(testStruct.serviceType).to(equal(testServiceType));
- expect(testStruct.serviceIcon).to(equal(testServiceIcon));
- expect(testStruct.allowAppConsumers).to(beTrue());
- expect(testStruct.rpcSpecVersion).to(equal(testRPCSpecVersion));
- expect(testStruct.handledRPCs).to(equal(testHandledRPCs));
- expect(testStruct.weatherServiceManifest).to(equal(testWeatherServiceManifest));
- expect(testStruct.mediaServiceManifest).to(equal(testMediaServiceManifest));
- expect(testStruct.navigationServiceManifest).to(equal(testNavigationServiceManifest));
+ });
});
it(@"Should init correctly with initWithAppServiceType:", ^{
@@ -104,7 +156,11 @@ describe(@"Getter/Setter Tests", ^ {
expect(testStruct.serviceType).to(equal(testAppServiceType));
expect(testStruct.serviceIcon).to(beNil());
expect(testStruct.allowAppConsumers).to(beNil());
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
expect(testStruct.rpcSpecVersion).to(beNil());
+#pragma clang diagnostic pop
+ expect(testStruct.maxRPCSpecVersion).to(beNil());
expect(testStruct.handledRPCs).to(beNil());
expect(testStruct.weatherServiceManifest).to(beNil());
expect(testStruct.mediaServiceManifest).to(beNil());
@@ -112,13 +168,37 @@ describe(@"Getter/Setter Tests", ^ {
});
it(@"Should init correctly with initWithMediaServiceName:serviceIcon:allowAppConsumers:rpcSpecVersion:handledRPCs:mediaServiceManifest:", ^{
- SDLAppServiceManifest *testStruct = [[SDLAppServiceManifest alloc] initWithMediaServiceName:testServiceName serviceIcon:testServiceIcon allowAppConsumers:testAllowAppConsumers rpcSpecVersion:testRPCSpecVersion handledRPCs:testHandledRPCs mediaServiceManifest:testMediaServiceManifest];
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ SDLAppServiceManifest *testStruct = [[SDLAppServiceManifest alloc] initWithMediaServiceName:testServiceName serviceIcon:testServiceIcon allowAppConsumers:testAllowAppConsumers rpcSpecVersion:testSyncMsgVersion handledRPCs:testHandledRPCs mediaServiceManifest:testMediaServiceManifest];
+#pragma clang diagnostic pop
+ expect(testStruct.serviceName).to(match(testServiceName));
+ expect(testStruct.serviceType).to(equal(SDLAppServiceTypeMedia));
+ expect(testStruct.serviceIcon).to(equal(testServiceIcon));
+ expect(testStruct.allowAppConsumers).to(beTrue());
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ expect(testStruct.rpcSpecVersion).to(equal(testSyncMsgVersion));
+#pragma clang diagnostic pop
+ expect(testStruct.maxRPCSpecVersion).to(equal(testSDLMsgVersion));
+ expect(testStruct.handledRPCs).to(equal(testHandledRPCs));
+ expect(testStruct.weatherServiceManifest).to(beNil());
+ expect(testStruct.mediaServiceManifest).to(equal(testMediaServiceManifest));
+ expect(testStruct.navigationServiceManifest).to(beNil());
+ });
+
+ it(@"Should init correctly with initWithMediaServiceName:serviceIcon:allowAppConsumers:maxRPCSpecVersion:handledRPCs:mediaServiceManifest:", ^{
+ SDLAppServiceManifest *testStruct = [[SDLAppServiceManifest alloc] initWithMediaServiceName:testServiceName serviceIcon:testServiceIcon allowAppConsumers:testAllowAppConsumers maxRPCSpecVersion:testSDLMsgVersion handledRPCs:testHandledRPCs mediaServiceManifest:testMediaServiceManifest];
expect(testStruct.serviceName).to(match(testServiceName));
expect(testStruct.serviceType).to(equal(SDLAppServiceTypeMedia));
expect(testStruct.serviceIcon).to(equal(testServiceIcon));
expect(testStruct.allowAppConsumers).to(beTrue());
- expect(testStruct.rpcSpecVersion).to(equal(testRPCSpecVersion));
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ expect(testStruct.rpcSpecVersion).to(equal(testSyncMsgVersion));
+#pragma clang diagnostic pop
+ expect(testStruct.maxRPCSpecVersion).to(equal(testSDLMsgVersion));
expect(testStruct.handledRPCs).to(equal(testHandledRPCs));
expect(testStruct.weatherServiceManifest).to(beNil());
expect(testStruct.mediaServiceManifest).to(equal(testMediaServiceManifest));
@@ -126,27 +206,76 @@ describe(@"Getter/Setter Tests", ^ {
});
it(@"Should init correctly with initWithWeatherServiceName:serviceIcon:allowAppConsumers:rpcSpecVersion:handledRPCs:weatherServiceManifest:", ^{
- SDLAppServiceManifest *testStruct = [[SDLAppServiceManifest alloc] initWithWeatherServiceName:testServiceName serviceIcon:testServiceIcon allowAppConsumers:testAllowAppConsumers rpcSpecVersion:testRPCSpecVersion handledRPCs:testHandledRPCs weatherServiceManifest:testWeatherServiceManifest];
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ SDLAppServiceManifest *testStruct = [[SDLAppServiceManifest alloc] initWithWeatherServiceName:testServiceName serviceIcon:testServiceIcon allowAppConsumers:testAllowAppConsumers rpcSpecVersion:testSyncMsgVersion handledRPCs:testHandledRPCs weatherServiceManifest:testWeatherServiceManifest];
+#pragma clang diagnostic pop
+ expect(testStruct.serviceName).to(match(testServiceName));
+ expect(testStruct.serviceType).to(equal(SDLAppServiceTypeWeather));
+ expect(testStruct.serviceIcon).to(equal(testServiceIcon));
+ expect(testStruct.allowAppConsumers).to(beTrue());
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ expect(testStruct.rpcSpecVersion).to(equal(testSyncMsgVersion));
+#pragma clang diagnostic pop
+ expect(testStruct.maxRPCSpecVersion).to(equal(testSDLMsgVersion));
+ expect(testStruct.handledRPCs).to(equal(testHandledRPCs));
+ expect(testStruct.weatherServiceManifest).to(equal(testWeatherServiceManifest));
+ expect(testStruct.mediaServiceManifest).to(beNil());
+ expect(testStruct.navigationServiceManifest).to(beNil());
+ });
+
+ it(@"Should init correctly with initWithWeatherServiceName:serviceIcon:allowAppConsumers:maxRPCSpecVersion:handledRPCs:weatherServiceManifest:", ^{
+ SDLAppServiceManifest *testStruct = [[SDLAppServiceManifest alloc] initWithWeatherServiceName:testServiceName serviceIcon:testServiceIcon allowAppConsumers:testAllowAppConsumers maxRPCSpecVersion:testSDLMsgVersion handledRPCs:testHandledRPCs weatherServiceManifest:testWeatherServiceManifest];
expect(testStruct.serviceName).to(match(testServiceName));
expect(testStruct.serviceType).to(equal(SDLAppServiceTypeWeather));
expect(testStruct.serviceIcon).to(equal(testServiceIcon));
expect(testStruct.allowAppConsumers).to(beTrue());
- expect(testStruct.rpcSpecVersion).to(equal(testRPCSpecVersion));
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ expect(testStruct.rpcSpecVersion).to(equal(testSyncMsgVersion));
+#pragma clang diagnostic pop
+ expect(testStruct.maxRPCSpecVersion).to(equal(testSDLMsgVersion));
expect(testStruct.handledRPCs).to(equal(testHandledRPCs));
expect(testStruct.weatherServiceManifest).to(equal(testWeatherServiceManifest));
expect(testStruct.mediaServiceManifest).to(beNil());
expect(testStruct.navigationServiceManifest).to(beNil());
});
+
it(@"Should init correctly with initWithNavigationServiceName:serviceIcon:allowAppConsumers:rpcSpecVersion:handledRPCs:navigationServiceManifest:", ^{
- SDLAppServiceManifest *testStruct = [[SDLAppServiceManifest alloc] initWithNavigationServiceName:testServiceName serviceIcon:testServiceIcon allowAppConsumers:testAllowAppConsumers rpcSpecVersion:testRPCSpecVersion handledRPCs:testHandledRPCs navigationServiceManifest:testNavigationServiceManifest];
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ SDLAppServiceManifest *testStruct = [[SDLAppServiceManifest alloc] initWithNavigationServiceName:testServiceName serviceIcon:testServiceIcon allowAppConsumers:testAllowAppConsumers rpcSpecVersion:testSyncMsgVersion handledRPCs:testHandledRPCs navigationServiceManifest:testNavigationServiceManifest];
+#pragma clang diagnostic pop
+ expect(testStruct.serviceName).to(match(testServiceName));
+ expect(testStruct.serviceType).to(equal(SDLAppServiceTypeNavigation));
+ expect(testStruct.serviceIcon).to(equal(testServiceIcon));
+ expect(testStruct.allowAppConsumers).to(beTrue());
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ expect(testStruct.rpcSpecVersion).to(equal(testSyncMsgVersion));
+#pragma clang diagnostic pop
+ expect(testStruct.maxRPCSpecVersion).to(equal(testSDLMsgVersion));
+ expect(testStruct.handledRPCs).to(equal(testHandledRPCs));
+ expect(testStruct.weatherServiceManifest).to(beNil());
+ expect(testStruct.mediaServiceManifest).to(beNil());
+ expect(testStruct.navigationServiceManifest).to(equal(testNavigationServiceManifest));
+ });
+
+ it(@"Should init correctly with initWithNavigationServiceName:serviceIcon:allowAppConsumers:maxRPCSpecVersion:handledRPCs:navigationServiceManifest:", ^{
+ SDLAppServiceManifest *testStruct = [[SDLAppServiceManifest alloc] initWithNavigationServiceName:testServiceName serviceIcon:testServiceIcon allowAppConsumers:testAllowAppConsumers maxRPCSpecVersion:testSDLMsgVersion handledRPCs:testHandledRPCs navigationServiceManifest:testNavigationServiceManifest];
expect(testStruct.serviceName).to(match(testServiceName));
expect(testStruct.serviceType).to(equal(SDLAppServiceTypeNavigation));
expect(testStruct.serviceIcon).to(equal(testServiceIcon));
expect(testStruct.allowAppConsumers).to(beTrue());
- expect(testStruct.rpcSpecVersion).to(equal(testRPCSpecVersion));
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ expect(testStruct.rpcSpecVersion).to(equal(testSyncMsgVersion));
+#pragma clang diagnostic pop
+ expect(testStruct.maxRPCSpecVersion).to(equal(testSDLMsgVersion));
expect(testStruct.handledRPCs).to(equal(testHandledRPCs));
expect(testStruct.weatherServiceManifest).to(beNil());
expect(testStruct.mediaServiceManifest).to(beNil());
@@ -154,13 +283,37 @@ describe(@"Getter/Setter Tests", ^ {
});
it(@"Should init correctly with initWithServiceName:serviceType:serviceIcon:allowAppConsumers:rpcSpecVersion:handledRPCs:mediaServiceManifest:weatherServiceManifest:navigationServiceManifest:", ^{
- SDLAppServiceManifest *testStruct = [[SDLAppServiceManifest alloc] initWithServiceName:testServiceName serviceType:testServiceType serviceIcon:testServiceIcon allowAppConsumers:testAllowAppConsumers rpcSpecVersion:testRPCSpecVersion handledRPCs:testHandledRPCs mediaServiceManifest:testMediaServiceManifest weatherServiceManifest:testWeatherServiceManifest navigationServiceManifest:testNavigationServiceManifest];
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ SDLAppServiceManifest *testStruct = [[SDLAppServiceManifest alloc] initWithServiceName:testServiceName serviceType:testServiceType serviceIcon:testServiceIcon allowAppConsumers:testAllowAppConsumers rpcSpecVersion:testSyncMsgVersion handledRPCs:testHandledRPCs mediaServiceManifest:testMediaServiceManifest weatherServiceManifest:testWeatherServiceManifest navigationServiceManifest:testNavigationServiceManifest];
+#pragma clang diagnostic pop
+ expect(testStruct.serviceName).to(match(testServiceName));
+ expect(testStruct.serviceType).to(equal(testServiceType));
+ expect(testStruct.serviceIcon).to(equal(testServiceIcon));
+ expect(testStruct.allowAppConsumers).to(beTrue());
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ expect(testStruct.rpcSpecVersion).to(equal(testSyncMsgVersion));
+#pragma clang diagnostic pop
+ expect(testStruct.maxRPCSpecVersion).to(equal(testSDLMsgVersion));
+ expect(testStruct.handledRPCs).to(equal(testHandledRPCs));
+ expect(testStruct.weatherServiceManifest).to(equal(testWeatherServiceManifest));
+ expect(testStruct.mediaServiceManifest).to(equal(testMediaServiceManifest));
+ expect(testStruct.navigationServiceManifest).to(equal(testNavigationServiceManifest));
+ });
+
+ it(@"Should init correctly with initWithServiceName:serviceType:serviceIcon:allowAppConsumers:maxRPCSpecVersion:handledRPCs:mediaServiceManifest:weatherServiceManifest:navigationServiceManifest:", ^{
+ SDLAppServiceManifest *testStruct = [[SDLAppServiceManifest alloc] initWithServiceName:testServiceName serviceType:testServiceType serviceIcon:testServiceIcon allowAppConsumers:testAllowAppConsumers maxRPCSpecVersion:testSDLMsgVersion handledRPCs:testHandledRPCs mediaServiceManifest:testMediaServiceManifest weatherServiceManifest:testWeatherServiceManifest navigationServiceManifest:testNavigationServiceManifest];
expect(testStruct.serviceName).to(match(testServiceName));
expect(testStruct.serviceType).to(equal(testServiceType));
expect(testStruct.serviceIcon).to(equal(testServiceIcon));
expect(testStruct.allowAppConsumers).to(beTrue());
- expect(testStruct.rpcSpecVersion).to(equal(testRPCSpecVersion));
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+ expect(testStruct.rpcSpecVersion).to(equal(testSyncMsgVersion));
+#pragma clang diagnostic pop
+ expect(testStruct.maxRPCSpecVersion).to(equal(testSDLMsgVersion));
expect(testStruct.handledRPCs).to(equal(testHandledRPCs));
expect(testStruct.weatherServiceManifest).to(equal(testWeatherServiceManifest));
expect(testStruct.mediaServiceManifest).to(equal(testMediaServiceManifest));
@@ -174,7 +327,11 @@ describe(@"Getter/Setter Tests", ^ {
expect(testStruct.serviceType).to(beNil());
expect(testStruct.serviceIcon).to(beNil());
expect(testStruct.allowAppConsumers).to(beNil());
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
expect(testStruct.rpcSpecVersion).to(beNil());
+#pragma clang diagnostic pop
+ expect(testStruct.maxRPCSpecVersion).to(beNil());
expect(testStruct.handledRPCs).to(beNil());
expect(testStruct.weatherServiceManifest).to(beNil());
expect(testStruct.mediaServiceManifest).to(beNil());
diff --git a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLKeyboardPropertiesSpec.m b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLKeyboardPropertiesSpec.m
index e535cc100..a4d0d32a3 100644
--- a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLKeyboardPropertiesSpec.m
+++ b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLKeyboardPropertiesSpec.m
@@ -18,38 +18,50 @@
QuickSpecBegin(SDLKeyboardPropertiesSpec)
describe(@"Getter/Setter Tests", ^ {
+ __block SDLLanguage testLanguage = SDLLanguageDaDk;
+ __block SDLKeyboardLayout testLayout = SDLKeyboardLayoutAZERTY;
+ __block SDLKeypressMode testMode = SDLKeypressModeSingleKeypress;
+ __block NSArray<NSString *> *testLimitedCharacterList = @[@"s", @"r", @"f"];
+ __block NSString *testAutoCompleteText = @"Auto Carrot";
+ __block NSArray<NSString *> *testAutoCompleteList = @[@"Hello World", @"How are you"];
+
it(@"Should set and get correctly", ^ {
SDLKeyboardProperties* testStruct = [[SDLKeyboardProperties alloc] init];
- testStruct.language = SDLLanguageDaDk;
- testStruct.keyboardLayout = SDLKeyboardLayoutQWERTZ;
- testStruct.keypressMode = SDLKeypressModeResendCurrentEntry;
- testStruct.limitedCharacterList = [@[@"s", @"r", @"f", @"q"] mutableCopy];
- testStruct.autoCompleteText = @"Auto Carrot";
+ testStruct.language = testLanguage;
+ testStruct.keyboardLayout = testLayout;
+ testStruct.keypressMode = testMode;
+ testStruct.limitedCharacterList = testLimitedCharacterList;
+ testStruct.autoCompleteText = testAutoCompleteText;
+ testStruct.autoCompleteList = testAutoCompleteList;
- expect(testStruct.language).to(equal(SDLLanguageDaDk));
- expect(testStruct.keyboardLayout).to(equal(SDLKeyboardLayoutQWERTZ));
- expect(testStruct.keypressMode).to(equal(SDLKeypressModeResendCurrentEntry));
- expect(testStruct.limitedCharacterList).to(equal([@[@"s", @"r", @"f", @"q"] mutableCopy]));
- expect(testStruct.autoCompleteText).to(equal(@"Auto Carrot"));
+ expect(testStruct.language).to(equal(testLanguage));
+ expect(testStruct.keyboardLayout).to(equal(testLayout));
+ expect(testStruct.keypressMode).to(equal(testMode));
+ expect(testStruct.limitedCharacterList).to(equal(testLimitedCharacterList));
+ expect(testStruct.autoCompleteText).to(equal(testAutoCompleteText));
+ expect(testStruct.autoCompleteList).to(equal(testAutoCompleteList));
});
it(@"Should get correctly when initialized", ^ {
- NSMutableDictionary* dict = [@{SDLRPCParameterNameLanguage:SDLLanguageDaDk,
- SDLRPCParameterNameKeyboardLayout:SDLKeyboardLayoutQWERTZ,
- SDLRPCParameterNameKeypressMode:SDLKeypressModeResendCurrentEntry,
- SDLRPCParameterNameLimitedCharacterList:[@[@"s", @"r", @"f", @"q"] mutableCopy],
- SDLRPCParameterNameAutoCompleteText:@"Auto Carrot"} mutableCopy];
+ NSDictionary* dict = @{SDLRPCParameterNameLanguage: testLanguage,
+ SDLRPCParameterNameKeyboardLayout: testLayout,
+ SDLRPCParameterNameKeypressMode: testMode,
+ SDLRPCParameterNameLimitedCharacterList: testLimitedCharacterList,
+ SDLRPCParameterNameAutoCompleteText: testAutoCompleteText,
+ SDLRPCParameterNameAutoCompleteList: testAutoCompleteList
+ };
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
SDLKeyboardProperties* testStruct = [[SDLKeyboardProperties alloc] initWithDictionary:dict];
#pragma clang diagnostic pop
- expect(testStruct.language).to(equal(SDLLanguageDaDk));
- expect(testStruct.keyboardLayout).to(equal(SDLKeyboardLayoutQWERTZ));
- expect(testStruct.keypressMode).to(equal(SDLKeypressModeResendCurrentEntry));
- expect(testStruct.limitedCharacterList).to(equal([@[@"s", @"r", @"f", @"q"] mutableCopy]));
- expect(testStruct.autoCompleteText).to(equal(@"Auto Carrot"));
+ expect(testStruct.language).to(equal(testLanguage));
+ expect(testStruct.keyboardLayout).to(equal(testLayout));
+ expect(testStruct.keypressMode).to(equal(testMode));
+ expect(testStruct.limitedCharacterList).to(equal(testLimitedCharacterList));
+ expect(testStruct.autoCompleteText).to(equal(testAutoCompleteText));
+ expect(testStruct.autoCompleteList).to(equal(testAutoCompleteList));
});
it(@"Should return nil if not set", ^ {
@@ -60,6 +72,7 @@ describe(@"Getter/Setter Tests", ^ {
expect(testStruct.keypressMode).to(beNil());
expect(testStruct.limitedCharacterList).to(beNil());
expect(testStruct.autoCompleteText).to(beNil());
+ expect(testStruct.autoCompleteList).to(beNil());
});
});
diff --git a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLMediaServiceDataSpec.m b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLMediaServiceDataSpec.m
index 66e98b741..24a215b11 100644
--- a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLMediaServiceDataSpec.m
+++ b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLMediaServiceDataSpec.m
@@ -11,11 +11,13 @@
#import "SDLMediaServiceData.h"
#import "SDLMediaType.h"
+#import "SDLImage.h"
#import "SDLRPCParameterNames.h"
QuickSpecBegin(SDLMediaServiceDataSpec)
describe(@"Getter/Setter Tests", ^{
+ __block SDLImage *testMediaImage = nil;
__block SDLMediaType testMediaType = nil;
__block NSString *testMediaTitle = nil;
__block NSString *testMediaArtist = nil;
@@ -31,6 +33,7 @@ describe(@"Getter/Setter Tests", ^{
beforeEach(^{
testMediaType = SDLMediaTypePodcast;
+ testMediaImage = [[SDLImage alloc] initWithStaticIconName:SDLStaticIconNameKey];
testMediaTitle = @"testMediaTitle";
testMediaArtist = @"testMediaArtist";
testMediaAlbum = @"testMediaAlbum";
@@ -40,6 +43,7 @@ describe(@"Getter/Setter Tests", ^{
it(@"Should set and get correctly", ^{
SDLMediaServiceData *testStruct = [[SDLMediaServiceData alloc] init];
+ testStruct.mediaImage = testMediaImage;
testStruct.mediaType = testMediaType;
testStruct.mediaTitle = testMediaTitle;
testStruct.mediaArtist = testMediaArtist;
@@ -53,6 +57,7 @@ describe(@"Getter/Setter Tests", ^{
testStruct.queueCurrentTrackNumber = @(testQueueCurrentTrackNumber);
testStruct.queueTotalTrackCount = @(testQueueTotalTrackCount);
+ expect(testStruct.mediaImage).to(equal(testMediaImage));
expect(testStruct.mediaType).to(equal(testMediaType));
expect(testStruct.mediaTitle).to(equal(testMediaTitle));
expect(testStruct.mediaArtist).to(equal(testMediaArtist));
@@ -68,7 +73,8 @@ describe(@"Getter/Setter Tests", ^{
});
it(@"Should get correctly when initialized with a dictionary", ^{
- NSDictionary *dict = @{SDLRPCParameterNameMediaType:testMediaType,
+ NSDictionary *dict = @{SDLRPCParameterNameMediaImage:testMediaImage,
+ SDLRPCParameterNameMediaType:testMediaType,
SDLRPCParameterNameMediaTitle:testMediaTitle,
SDLRPCParameterNameMediaArtist:testMediaArtist,
SDLRPCParameterNameMediaAlbum:testMediaAlbum,
@@ -85,7 +91,8 @@ describe(@"Getter/Setter Tests", ^{
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
SDLMediaServiceData *testStruct = [[SDLMediaServiceData alloc] initWithDictionary:dict];
#pragma clang diagnostic pop
-
+
+ expect(testStruct.mediaImage).to(equal(testMediaImage));
expect(testStruct.mediaType).to(equal(testMediaType));
expect(testStruct.mediaTitle).to(equal(testMediaTitle));
expect(testStruct.mediaArtist).to(equal(testMediaArtist));
@@ -100,10 +107,32 @@ describe(@"Getter/Setter Tests", ^{
expect(testStruct.queueTotalTrackCount).to(equal(testQueueTotalTrackCount));
});
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
it(@"Should get correctly when initialized with initWithMediaType:mediaTitle:mediaArtist:mediaAlbum:playlistName:isExplicit:trackPlaybackProgress:trackPlaybackDuration:queuePlaybackProgress:queuePlaybackDuration:queueCurrentTrackNumber:queueTotalTrackCount:", ^{
SDLMediaServiceData *testStruct = [[SDLMediaServiceData alloc] initWithMediaType:testMediaType mediaTitle:testMediaTitle mediaArtist:testMediaArtist mediaAlbum:testMediaAlbum playlistName:testPlaylistName isExplicit:testIsExplicit trackPlaybackProgress:testTrackPlaybackProgress trackPlaybackDuration:testTrackPlaybackDuration queuePlaybackProgress:testQueuePlaybackProgress queuePlaybackDuration:testQueuePlaybackDuration queueCurrentTrackNumber:testQueueCurrentTrackNumber queueTotalTrackCount:testQueueTotalTrackCount];
+#pragma clang diagnostic pop
+
+ expect(testStruct.mediaType).to(equal(testMediaType));
+ expect(testStruct.mediaTitle).to(equal(testMediaTitle));
+ expect(testStruct.mediaArtist).to(equal(testMediaArtist));
+ expect(testStruct.mediaAlbum).to(equal(testMediaAlbum));
+ expect(testStruct.playlistName).to(equal(testPlaylistName));
+ expect(testStruct.isExplicit).to(equal(testIsExplicit));
+ expect(testStruct.trackPlaybackProgress).to(equal(testTrackPlaybackProgress));
+ expect(testStruct.trackPlaybackDuration).to(equal(testTrackPlaybackDuration));
+ expect(testStruct.queuePlaybackProgress).to(equal(testQueuePlaybackProgress));
+ expect(testStruct.queuePlaybackDuration).to(equal(testQueuePlaybackDuration));
+ expect(testStruct.queueCurrentTrackNumber).to(equal(testQueueCurrentTrackNumber));
+ expect(testStruct.queueTotalTrackCount).to(equal(testQueueTotalTrackCount));
+ expect(testStruct.mediaImage).to(beNil());
+ });
+
+ it(@"Should get correctly when initialized with initWithMediaType:mediaImage:mediaTitle:mediaArtist:mediaAlbum:playlistName:isExplicit:trackPlaybackProgress:trackPlaybackDuration:queuePlaybackProgress:queuePlaybackDuration:queueCurrentTrackNumber:queueTotalTrackCount:", ^{
+ SDLMediaServiceData *testStruct = [[SDLMediaServiceData alloc] initWithMediaType:testMediaType mediaImage:testMediaImage mediaTitle:testMediaTitle mediaArtist:testMediaArtist mediaAlbum:testMediaAlbum playlistName:testPlaylistName isExplicit:testIsExplicit trackPlaybackProgress:testTrackPlaybackProgress trackPlaybackDuration:testTrackPlaybackDuration queuePlaybackProgress:testQueuePlaybackProgress queuePlaybackDuration:testQueuePlaybackDuration queueCurrentTrackNumber:testQueueCurrentTrackNumber queueTotalTrackCount:testQueueTotalTrackCount];
expect(testStruct.mediaType).to(equal(testMediaType));
+ expect(testStruct.mediaImage).to(equal(testMediaImage));
expect(testStruct.mediaTitle).to(equal(testMediaTitle));
expect(testStruct.mediaArtist).to(equal(testMediaArtist));
expect(testStruct.mediaAlbum).to(equal(testMediaAlbum));
@@ -120,6 +149,7 @@ describe(@"Getter/Setter Tests", ^{
it(@"Should return nil if not set", ^{
SDLMediaServiceData *testStruct = [[SDLMediaServiceData alloc] init];
+ expect(testStruct.mediaImage).to(beNil());
expect(testStruct.mediaType).to(beNil());
expect(testStruct.mediaTitle).to(beNil());
expect(testStruct.mediaArtist).to(beNil());
diff --git a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLSystemCapabilitySpec.m b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLSystemCapabilitySpec.m
index ea41d0163..42286b97b 100755
--- a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLSystemCapabilitySpec.m
+++ b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLSystemCapabilitySpec.m
@@ -127,7 +127,7 @@ describe(@"Getter/Setter Tests", ^ {
resolution.resolutionHeight = @500;
int32_t maxBitrate = 100;
- NSNumber *hapticDataSupported = @YES;
+ BOOL hapticDataSupported = YES;
SDLVideoStreamingFormat *format1 = [[SDLVideoStreamingFormat alloc] init];
format1.codec = SDLVideoStreamingCodecH264;
diff --git a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testAppAndVehicleIcons@2x.png b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testAppAndVehicleIcons@2x.png
index 3648c2bce..935e31a1b 100644
--- a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testAppAndVehicleIcons@2x.png
+++ b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testAppAndVehicleIcons@2x.png
Binary files differ
diff --git a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testAppAndVehicleIcons@3x.png b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testAppAndVehicleIcons@3x.png
index 3b7684a62..f1b99e2c5 100644
--- a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testAppAndVehicleIcons@3x.png
+++ b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testAppAndVehicleIcons@3x.png
Binary files differ
diff --git a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testLightBackgroundNoAppNoVehicleIcons@2x.png b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testLightBackgroundNoAppNoVehicleIcons@2x.png
index 3648c2bce..935e31a1b 100644
--- a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testLightBackgroundNoAppNoVehicleIcons@2x.png
+++ b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testLightBackgroundNoAppNoVehicleIcons@2x.png
Binary files differ
diff --git a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testLightBackgroundNoAppNoVehicleIcons@3x.png b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testLightBackgroundNoAppNoVehicleIcons@3x.png
index 3b7684a62..f1b99e2c5 100644
--- a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testLightBackgroundNoAppNoVehicleIcons@3x.png
+++ b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testLightBackgroundNoAppNoVehicleIcons@3x.png
Binary files differ
diff --git a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testNoAppNoVehicleIcons@2x.png b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testNoAppNoVehicleIcons@2x.png
index 3648c2bce..935e31a1b 100644
--- a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testNoAppNoVehicleIcons@2x.png
+++ b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testNoAppNoVehicleIcons@2x.png
Binary files differ
diff --git a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testNoAppNoVehicleIcons@3x.png b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testNoAppNoVehicleIcons@3x.png
index 3b7684a62..f1b99e2c5 100644
--- a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testNoAppNoVehicleIcons@3x.png
+++ b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testNoAppNoVehicleIcons@3x.png
Binary files differ
diff --git a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyAppIcon@2x.png b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyAppIcon@2x.png
index 3648c2bce..935e31a1b 100644
--- a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyAppIcon@2x.png
+++ b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyAppIcon@2x.png
Binary files differ
diff --git a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyAppIcon@3x.png b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyAppIcon@3x.png
index 3b7684a62..f1b99e2c5 100644
--- a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyAppIcon@3x.png
+++ b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyAppIcon@3x.png
Binary files differ
diff --git a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyVehicleIcon@2x.png b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyVehicleIcon@2x.png
index 3648c2bce..935e31a1b 100644
--- a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyVehicleIcon@2x.png
+++ b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyVehicleIcon@2x.png
Binary files differ
diff --git a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyVehicleIcon@3x.png b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyVehicleIcon@3x.png
index 3b7684a62..f1b99e2c5 100644
--- a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyVehicleIcon@3x.png
+++ b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyVehicleIcon@3x.png
Binary files differ
diff --git a/SmartDeviceLinkTests/SDLAsynchronousRPCOperationSpec.m b/SmartDeviceLinkTests/SDLAsynchronousRPCOperationSpec.m
index 40fff1d7a..917756334 100644
--- a/SmartDeviceLinkTests/SDLAsynchronousRPCOperationSpec.m
+++ b/SmartDeviceLinkTests/SDLAsynchronousRPCOperationSpec.m
@@ -10,8 +10,9 @@
#import <Nimble/Nimble.h>
#import "SDLAppServiceData.h"
-#import "SDLGetAppServiceDataResponse.h"
#import "SDLAsynchronousRPCOperation.h"
+#import "SDLGetAppServiceDataResponse.h"
+#import "SDLGlobals.h"
#import "TestConnectionManager.h"
QuickSpecBegin(SDLAsynchronousRPCOperationSpec)
@@ -27,7 +28,7 @@ describe(@"sending responses and notifications", ^{
testOperationQueue = [[NSOperationQueue alloc] init];
testOperationQueue.name = @"com.sdl.RPCResponse.testqueue";
- testOperationQueue.maxConcurrentOperationCount = 3;
+ testOperationQueue.underlyingQueue = [SDLGlobals sharedGlobals].sdlProcessingQueue;
});
context(@"when a single request succeeds", ^{
@@ -49,7 +50,7 @@ describe(@"sending responses and notifications", ^{
context(@"when multiple request succeed", ^{
__block NSMutableArray< __kindof SDLRPCMessage *> *sendRPCs = nil;
- __block int rpcCount = (int)testOperationQueue.maxConcurrentOperationCount + 3;
+ int rpcCount = 9;
beforeEach(^{
sendRPCs = [NSMutableArray array];
@@ -64,8 +65,6 @@ describe(@"sending responses and notifications", ^{
[testOperationQueue addOperation:testOperation];
}
- [NSThread sleepForTimeInterval:0.5];
-
expect(testConnectionManager.receivedRequests.count).toEventually(equal(rpcCount));
expect(testConnectionManager.receivedRequests).toEventually(equal(sendRPCs));
});
diff --git a/SmartDeviceLinkTests/SDLRPCFunctionNamesSpec.m b/SmartDeviceLinkTests/SDLRPCFunctionNamesSpec.m
index dc28ebf28..d1022ac90 100644
--- a/SmartDeviceLinkTests/SDLRPCFunctionNamesSpec.m
+++ b/SmartDeviceLinkTests/SDLRPCFunctionNamesSpec.m
@@ -86,6 +86,7 @@ describe(@"Individual Enum Value Tests", ^ {
expect(SDLRPCFunctionNameSubscribeWayPoints).to(equal(@"SubscribeWayPoints"));
expect(SDLRPCFunctionNameSyncPData).to(equal(@"SyncPData"));
expect(SDLRPCFunctionNameSystemRequest).to(equal(@"SystemRequest"));
+ expect(SDLRPCFunctionNameUnpublishAppService).to(equal(@"UnpublishAppService"));
expect(SDLRPCFunctionNameUnregisterAppInterface).to(equal(@"UnregisterAppInterface"));
expect(SDLRPCFunctionNameUnsubscribeButton).to(equal(@"UnsubscribeButton"));
expect(SDLRPCFunctionNameUnsubscribeVehicleData).to(equal(@"UnsubscribeVehicleData"));
diff --git a/SmartDeviceLinkTests/SDLScreenManagerSpec.m b/SmartDeviceLinkTests/SDLScreenManagerSpec.m
index 5bb3943c5..02882be78 100644
--- a/SmartDeviceLinkTests/SDLScreenManagerSpec.m
+++ b/SmartDeviceLinkTests/SDLScreenManagerSpec.m
@@ -11,12 +11,15 @@
#import "SDLSoftButtonState.h"
#import "SDLTextAndGraphicManager.h"
#import "TestConnectionManager.h"
+#import "SDLVersion.h"
+#import "SDLGlobals.h"
+#import "SDLMenuCell.h"
+#import "SDLMenuManager.h"
@interface SDLSoftButtonManager()
@property (weak, nonatomic) id<SDLConnectionManagerType> connectionManager;
@property (weak, nonatomic) SDLFileManager *fileManager;
-
@property (strong, nonatomic) NSOperationQueue *transactionQueue;
@property (copy, nonatomic, nullable) SDLHMILevel currentLevel;
@@ -36,6 +39,7 @@
@property (strong, nonatomic) SDLTextAndGraphicManager *textAndGraphicManager;
@property (strong, nonatomic) SDLSoftButtonManager *softButtonManager;
+@property (strong, nonatomic) SDLMenuManager *menuManager;
@end
diff --git a/SmartDeviceLinkTests/TestResponse.m b/SmartDeviceLinkTests/TestResponse.m
index f949f3b1b..0af400104 100644
--- a/SmartDeviceLinkTests/TestResponse.m
+++ b/SmartDeviceLinkTests/TestResponse.m
@@ -22,4 +22,8 @@
return self;
}
+- (NSString *)description {
+ return [NSString stringWithFormat:@"Test response: %@, error: %@", _testResponse, _testError];
+}
+
@end
diff --git a/SmartDeviceLinkTests/TestUtilities/TestRequestProgressResponse.m b/SmartDeviceLinkTests/TestUtilities/TestRequestProgressResponse.m
index 64afa7107..c40081063 100644
--- a/SmartDeviceLinkTests/TestUtilities/TestRequestProgressResponse.m
+++ b/SmartDeviceLinkTests/TestUtilities/TestRequestProgressResponse.m
@@ -21,4 +21,8 @@
return self;
}
+- (NSString *)description {
+ return [NSString stringWithFormat:@"Progress Response: correlation id: %@, percent complete: %0.03f, error: %@", _correlationId, _percentComplete, _error];
+}
+
@end
diff --git a/SmartDeviceLinkTests/UtilitiesSpecs/Touches/DispatchTimerSpec.m b/SmartDeviceLinkTests/UtilitiesSpecs/Touches/DispatchTimerSpec.m
deleted file mode 100644
index 771d2c4bb..000000000
--- a/SmartDeviceLinkTests/UtilitiesSpecs/Touches/DispatchTimerSpec.m
+++ /dev/null
@@ -1,47 +0,0 @@
-//
-// DispatchTimerSpec.m
-// SmartDeviceLink-iOS
-//
-// Created by Muller, Alexander (A.) on 7/1/16.
-// Copyright © 2016 smartdevicelink. All rights reserved.
-//
-
-#import <Foundation/Foundation.h>
-
-#import <Quick/Quick.h>
-#import <Nimble/Nimble.h>
-#import <OCMock/OCMock.h>
-
-#import "dispatch_timer.h"
-
-QuickSpecBegin(DispatchTimerSpec)
-
-describe(@"dispatch_timer Tests", ^{
- context(@"Creating", ^{
- it(@"should be successful within specified time", ^{
- waitUntilTimeout(4, ^(void (^done)(void)) {
- __block double currentTime = [[NSDate date] timeIntervalSince1970];
- dispatch_create_timer(2.5, false, ^{
- double difference = [[NSDate date] timeIntervalSince1970] - currentTime;
- expect(@(difference)).to(beCloseTo(@2.5).within(0.1));
- done();
- });
- });
- });
-
- it(@"should be cancellable and not fire", ^{
- __block dispatch_source_t timer;
- waitUntilTimeout(2, ^(void (^done)(void)) {
- timer = dispatch_create_timer(2.5, false, ^{
- fail();
- });
- [NSThread sleepForTimeInterval:0.5];
- dispatch_stop_timer(timer);
- done();
- });
- expect(@(dispatch_source_testcancel(timer))).to(beGreaterThan(@0));
- });
- });
-});
-
-QuickSpecEnd \ No newline at end of file
diff --git a/SmartDeviceLinkTests/UtilitiesSpecs/Touches/SDLTouchManagerSpec.m b/SmartDeviceLinkTests/UtilitiesSpecs/Touches/SDLTouchManagerSpec.m
index 25fad6316..24a06dcb0 100644
--- a/SmartDeviceLinkTests/UtilitiesSpecs/Touches/SDLTouchManagerSpec.m
+++ b/SmartDeviceLinkTests/UtilitiesSpecs/Touches/SDLTouchManagerSpec.m
@@ -31,6 +31,55 @@
@property (nonatomic, assign) CGFloat previousPinchDistance;
@property (nonatomic, strong, nullable) SDLPinchGesture *currentPinchGesture;
@property (nonatomic, strong, nullable) dispatch_source_t singleTapTimer;
+
+@end
+
+@interface TestGroup : NSObject
+
++ (void)testTouchesWithTimeout:(CGFloat)timeoutTime
+ numTimesCalled:(NSUInteger)numTimesHandlerCalled expected:(NSUInteger)expectedNumTimesHandlerCalled
+ singleTap:(BOOL)didCallSingleTap expected:(BOOL)expectedDidCallSingleTap
+ doubleTap:(BOOL)didCallDoubleTap expected:(BOOL)expectedDidCallDoubleTap
+ beginPan:(BOOL)didCallBeginPan expected:(BOOL)expectedDidCallBeginPan
+ movePan:(BOOL)didCallMovePan expected:(BOOL)expectedDidCallMovePan
+ endPan:(BOOL)didCallEndPan expected:(BOOL)expectedDidCallEndPan
+ cancelPan:(BOOL)didCallCancelPan expected:(BOOL)expectedDidCallCancelPan
+ beginPinch:(BOOL)didCallBeginPinch expected:(BOOL)expectedDidCallBeginPinch
+ movePinch:(BOOL)didCallMovePinch expected:(BOOL)expectedDidCallMovePinch
+ endPinch:(BOOL)didCallEndPinch expected:(BOOL)expectedDidCallEndPinch
+ cancelPinch:(BOOL)didCallCancelPinch expected:(BOOL)expectedDidCallCancelPinch;
+
+@end
+
+@implementation TestGroup
+
++ (void)testTouchesWithTimeout:(CGFloat)timeoutTime
+ numTimesCalled:(NSUInteger)numTimesHandlerCalled expected:(NSUInteger)expectedNumTimesHandlerCalled
+ singleTap:(BOOL)didCallSingleTap expected:(BOOL)expectedDidCallSingleTap
+ doubleTap:(BOOL)didCallDoubleTap expected:(BOOL)expectedDidCallDoubleTap
+ beginPan:(BOOL)didCallBeginPan expected:(BOOL)expectedDidCallBeginPan
+ movePan:(BOOL)didCallMovePan expected:(BOOL)expectedDidCallMovePan
+ endPan:(BOOL)didCallEndPan expected:(BOOL)expectedDidCallEndPan
+ cancelPan:(BOOL)didCallCancelPan expected:(BOOL)expectedDidCallCancelPan
+ beginPinch:(BOOL)didCallBeginPinch expected:(BOOL)expectedDidCallBeginPinch
+ movePinch:(BOOL)didCallMovePinch expected:(BOOL)expectedDidCallMovePinch
+ endPinch:(BOOL)didCallEndPinch expected:(BOOL)expectedDidCallEndPinch
+ cancelPinch:(BOOL)didCallCancelPinch expected:(BOOL)expectedDidCallCancelPinch
+{
+ expect(didCallSingleTap).withTimeout(timeoutTime).toEventually(expectedDidCallSingleTap ? beTrue() : beFalse());
+ expect(didCallDoubleTap).withTimeout(timeoutTime).toEventually(expectedDidCallDoubleTap ? beTrue() : beFalse());
+ expect(didCallBeginPan).withTimeout(timeoutTime).toEventually(expectedDidCallBeginPan ? beTrue() : beFalse());
+ expect(didCallMovePan).withTimeout(timeoutTime).toEventually(expectedDidCallMovePan ? beTrue() : beFalse());
+ expect(didCallEndPan).withTimeout(timeoutTime).toEventually(expectedDidCallEndPan ? beTrue() : beFalse());
+ expect(didCallCancelPan).withTimeout(timeoutTime).toEventually(expectedDidCallCancelPan ? beTrue() : beFalse());
+ expect(didCallBeginPinch).withTimeout(timeoutTime).toEventually(expectedDidCallBeginPinch ? beTrue() : beFalse());
+ expect(didCallMovePinch).withTimeout(timeoutTime).toEventually(expectedDidCallMovePinch ? beTrue() : beFalse());
+ expect(didCallEndPinch).withTimeout(timeoutTime).toEventually(expectedDidCallEndPinch ? beTrue() : beFalse());
+ expect(didCallCancelPinch).withTimeout(timeoutTime).toEventually(expectedDidCallCancelPinch ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
+}
+
@end
QuickSpecBegin(SDLTouchManagerSpec)
@@ -255,6 +304,10 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallSingleTap = YES;
expectedNumTimesHandlerCalled = 2;
+
+ expect(didCallSingleTap).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallSingleTap ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
});
@@ -302,6 +355,10 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallSingleTap = YES;
expectedNumTimesHandlerCalled = 3;
+
+ expect(didCallSingleTap).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallSingleTap ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
});
@@ -356,6 +413,10 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallDoubleTap = YES;
expectedNumTimesHandlerCalled = 4;
+
+ expect(didCallDoubleTap).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallDoubleTap ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
});
@@ -376,6 +437,10 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallDoubleTap = NO;
expectedNumTimesHandlerCalled = 4;
+
+ expect(didCallDoubleTap).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallDoubleTap ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
});
});
@@ -410,6 +475,10 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallSingleTap = NO;
expectedNumTimesHandlerCalled = 2;
+
+ expect(didCallSingleTap).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallSingleTap ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
});
@@ -441,6 +510,10 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallDoubleTap = NO;
expectedNumTimesHandlerCalled = 4;
+
+ expect(didCallDoubleTap).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallDoubleTap ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
it(@"should not issue delegate callbacks when a double tap is canceled before the start of the second tap", ^{
@@ -452,6 +525,10 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallDoubleTap = NO;
expectedNumTimesHandlerCalled = 3;
+
+ expect(didCallDoubleTap).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallDoubleTap ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
});
@@ -604,6 +681,13 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallEndPan = YES;
expectedDidCallCancelPan = NO;
expectedNumTimesHandlerCalled = 4;
+
+ expect(didCallBeginPan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallBeginPan ? beTrue() : beFalse());
+ expect(didCallMovePan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallMovePan ? beTrue() : beFalse());
+ expect(didCallEndPan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallEndPan ? beTrue() : beFalse());
+ expect(didCallCancelPan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallCancelPan ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
});
@@ -638,6 +722,13 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallEndPan = NO;
expectedDidCallCancelPan = YES;
expectedNumTimesHandlerCalled = 3;
+
+ expect(didCallBeginPan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallBeginPan ? beTrue() : beFalse());
+ expect(didCallMovePan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallMovePan ? beTrue() : beFalse());
+ expect(didCallEndPan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallEndPan ? beTrue() : beFalse());
+ expect(didCallCancelPan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallCancelPan ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
it(@"should issue a cancel pan delegate callback when a pan is canceled right after second move detected", ^{
@@ -685,6 +776,13 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallEndPan = NO;
expectedDidCallCancelPan = YES;
expectedNumTimesHandlerCalled = 4;
+
+ expect(didCallBeginPan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallBeginPan ? beTrue() : beFalse());
+ expect(didCallMovePan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallMovePan ? beTrue() : beFalse());
+ expect(didCallEndPan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallEndPan ? beTrue() : beFalse());
+ expect(didCallCancelPan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallCancelPan ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
it(@"should not issue a cancel pan delegate callback if the cancel onTouchEvent is received while a pan gesture is not in progress", ^{
@@ -695,6 +793,13 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallEndPan = NO;
expectedDidCallCancelPan = NO;
expectedNumTimesHandlerCalled = 1;
+
+ expect(didCallBeginPan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallBeginPan ? beTrue() : beFalse());
+ expect(didCallMovePan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallMovePan ? beTrue() : beFalse());
+ expect(didCallEndPan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallEndPan ? beTrue() : beFalse());
+ expect(didCallCancelPan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallCancelPan ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
afterEach(^{
@@ -815,7 +920,7 @@ describe(@"SDLTouchManager Tests", ^{
[invocation getArgument:&point atIndex:4];
expect(touchManagerCallback).to(equal(touchManager));
- expect(@(CGPointEqualToPoint(point, pinchStartCenter))).to(beTruthy());
+ expect(@(CGPointEqualToPoint(point, pinchStartCenter))).to(beTrue());
};
pinchMoveTests = ^(NSInvocation* invocation) {
@@ -828,7 +933,7 @@ describe(@"SDLTouchManager Tests", ^{
[invocation getArgument:&scale atIndex:4];
expect(touchManagerCallback).to(equal(touchManager));
- expect(@(CGPointEqualToPoint(point, pinchMoveCenter))).to(beTruthy());
+ expect(@(CGPointEqualToPoint(point, pinchMoveCenter))).to(beTrue());
expect(@(scale)).to(beCloseTo(@(pinchMoveScale)).within(0.0001));
};
@@ -840,7 +945,7 @@ describe(@"SDLTouchManager Tests", ^{
[invocation getArgument:&point atIndex:4];
expect(touchManagerCallback).to(equal(touchManager));
- expect(@(CGPointEqualToPoint(point, pinchEndCenter))).to(beTruthy());
+ expect(@(CGPointEqualToPoint(point, pinchEndCenter))).to(beTrue());
};
performTouchEvent(touchManager, pinchStartFirstFingerOnTouchEvent);
@@ -854,6 +959,13 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallEndPinch = YES;
expectedDidCallCancelPinch = NO;
expectedNumTimesHandlerCalled = 4;
+
+ expect(didCallBeginPinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallBeginPinch ? beTrue() : beFalse());
+ expect(didCallMovePinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallMovePinch ? beTrue() : beFalse());
+ expect(didCallEndPinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallEndPinch ? beTrue() : beFalse());
+ expect(didCallCancelPinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallCancelPinch ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
});
@@ -905,6 +1017,13 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallEndPinch = YES;
expectedDidCallCancelPinch = NO;
expectedNumTimesHandlerCalled = 4;
+
+ expect(didCallBeginPinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallBeginPinch ? beTrue() : beFalse());
+ expect(didCallMovePinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallMovePinch ? beTrue() : beFalse());
+ expect(didCallEndPinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallEndPinch ? beTrue() : beFalse());
+ expect(didCallCancelPinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallCancelPinch ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
});
@@ -939,6 +1058,13 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallEndPinch = NO;
expectedDidCallCancelPinch = YES;
expectedNumTimesHandlerCalled = 3;
+
+ expect(didCallBeginPinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallBeginPinch ? beTrue() : beFalse());
+ expect(didCallMovePinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallMovePinch ? beTrue() : beFalse());
+ expect(didCallEndPinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallEndPinch ? beTrue() : beFalse());
+ expect(didCallCancelPinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallCancelPinch ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
it(@"should notify delegates if pinch is canceled while it is in progress", ^{
@@ -986,6 +1112,13 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallEndPinch = NO;
expectedDidCallCancelPinch = YES;
expectedNumTimesHandlerCalled = 4;
+
+ expect(didCallBeginPinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallBeginPinch ? beTrue() : beFalse());
+ expect(didCallMovePinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallMovePinch ? beTrue() : beFalse());
+ expect(didCallEndPinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallEndPinch ? beTrue() : beFalse());
+ expect(didCallCancelPinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallCancelPinch ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
it(@"should not issue a cancel pinch delegate callback if the cancel onTouchEvent is received while a pinch gesture is not in progress", ^{
@@ -996,6 +1129,13 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallEndPinch = NO;
expectedDidCallCancelPinch = NO;
expectedNumTimesHandlerCalled = 1;
+
+ expect(didCallBeginPinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallBeginPinch ? beTrue() : beFalse());
+ expect(didCallMovePinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallMovePinch ? beTrue() : beFalse());
+ expect(didCallEndPinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallEndPinch ? beTrue() : beFalse());
+ expect(didCallCancelPinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallCancelPinch ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
afterEach(^{
@@ -1003,22 +1143,6 @@ describe(@"SDLTouchManager Tests", ^{
});
});
});
-
- afterEach(^{
- CGFloat timeoutTime = touchManager.tapTimeThreshold + additionalWaitTime;
- expect(@(didCallSingleTap)).withTimeout(timeoutTime).toEventually(expectedDidCallSingleTap ? beTruthy() : beFalsy());
- expect(@(didCallDoubleTap)).withTimeout(timeoutTime).toEventually(expectedDidCallDoubleTap ? beTruthy() : beFalsy());
- expect(@(didCallBeginPan)).withTimeout(timeoutTime).toEventually(expectedDidCallBeginPan ? beTruthy() : beFalsy());
- expect(@(didCallMovePan)).withTimeout(timeoutTime).toEventually(expectedDidCallMovePan ? beTruthy() : beFalsy());
- expect(@(didCallEndPan)).withTimeout(timeoutTime).toEventually(expectedDidCallEndPan ? beTruthy() : beFalsy());
- expect(@(didCallCancelPan)).withTimeout(timeoutTime).toEventually(expectedDidCallCancelPan ? beTruthy() : beFalsy());
- expect(@(didCallBeginPinch)).withTimeout(timeoutTime).toEventually(expectedDidCallBeginPinch ? beTruthy() : beFalsy());
- expect(@(didCallMovePinch)).withTimeout(timeoutTime).toEventually(expectedDidCallMovePinch ? beTruthy() : beFalsy());
- expect(@(didCallEndPinch)).withTimeout(timeoutTime).toEventually(expectedDidCallEndPinch ? beTruthy() : beFalsy());
- expect(@(didCallCancelPinch)).withTimeout(timeoutTime).toEventually(expectedDidCallCancelPinch ? beTruthy() : beFalsy());
-
- expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
- });
});
});