diff options
author | NicoleYarroch <nicole@livio.io> | 2018-05-15 09:23:55 -0400 |
---|---|---|
committer | NicoleYarroch <nicole@livio.io> | 2018-05-15 09:23:55 -0400 |
commit | d67e67b7c8857978f2167445b93ca1e7e2e68b8f (patch) | |
tree | 0c17f3a60af715f749c148b121fef49135eb05a3 | |
parent | c670715bf9761677210929f89355adebf186c2e6 (diff) | |
parent | cc5eae8907aaab89a9634c259be62382b145a5ac (diff) | |
download | sdl_ios-d67e67b7c8857978f2167445b93ca1e7e2e68b8f.tar.gz |
Merge branch 'develop' into feature/issue_620_swift_sdl_example_app
-rw-r--r-- | SmartDeviceLink/SDLLifecycleManager.m | 1 | ||||
-rw-r--r-- | SmartDeviceLink/SDLMenuManager.h | 5 | ||||
-rw-r--r-- | SmartDeviceLink/SDLMenuManager.m | 16 | ||||
-rw-r--r-- | SmartDeviceLink/SDLScreenManager.h | 5 | ||||
-rw-r--r-- | SmartDeviceLink/SDLScreenManager.m | 7 | ||||
-rw-r--r-- | SmartDeviceLink/SDLSoftButtonManager.h | 5 | ||||
-rw-r--r-- | SmartDeviceLink/SDLSoftButtonManager.m | 21 | ||||
-rw-r--r-- | SmartDeviceLink/SDLTextAndGraphicManager.h | 11 | ||||
-rw-r--r-- | SmartDeviceLink/SDLTextAndGraphicManager.m | 29 | ||||
-rw-r--r-- | SmartDeviceLink/SDLVoiceCommandManager.h | 5 | ||||
-rw-r--r-- | SmartDeviceLink/SDLVoiceCommandManager.m | 11 | ||||
-rw-r--r-- | SmartDeviceLinkTests/DevAPISpecs/SDLSoftButtonManagerSpec.m | 73 |
12 files changed, 178 insertions, 11 deletions
diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m index d2d6f2f99..58cc78e1e 100644 --- a/SmartDeviceLink/SDLLifecycleManager.m +++ b/SmartDeviceLink/SDLLifecycleManager.m @@ -229,6 +229,7 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; [self.fileManager stop]; [self.permissionManager stop]; [self.lockScreenManager stop]; + [self.screenManager stop]; [self.streamManager stop]; [self.systemCapabilityManager stop]; [self.responseDispatcher clear]; diff --git a/SmartDeviceLink/SDLMenuManager.h b/SmartDeviceLink/SDLMenuManager.h index acf1aff99..cd3ead610 100644 --- a/SmartDeviceLink/SDLMenuManager.h +++ b/SmartDeviceLink/SDLMenuManager.h @@ -27,6 +27,11 @@ typedef void(^SDLMenuUpdateCompletionHandler)(NSError *__nullable error); - (instancetype)initWithConnectionManager:(id<SDLConnectionManagerType>)connectionManager fileManager:(SDLFileManager *)fileManager; +/** + * Stops the manager. This method is used internally. + */ +- (void)stop; + @property (copy, nonatomic) NSArray<SDLMenuCell *> *menuCells; @end diff --git a/SmartDeviceLink/SDLMenuManager.m b/SmartDeviceLink/SDLMenuManager.m index 39b6bc91c..291cb8911 100644 --- a/SmartDeviceLink/SDLMenuManager.m +++ b/SmartDeviceLink/SDLMenuManager.m @@ -90,6 +90,20 @@ UInt32 const MenuCellIdMin = 1; return self; } +- (void)stop { + _lastMenuId = MenuCellIdMin; + _menuCells = @[]; + _oldMenuCells = @[]; + + _currentHMILevel = SDLHMILevelNone; + _currentSystemContext = SDLSystemContextMain; + _displayCapabilities = nil; + _inProgressUpdate = nil; + _hasQueuedUpdate = NO; + _waitingOnHMIUpdate = NO; + _waitingUpdateMenuCells = @[]; +} + #pragma mark - Setters - (void)setMenuCells:(NSArray<SDLMenuCell *> *)menuCells { @@ -365,7 +379,7 @@ UInt32 const MenuCellIdMin = 1; - (BOOL)sdl_callHandlerForCells:(NSArray<SDLMenuCell *> *)cells command:(SDLOnCommand *)onCommand { for (SDLMenuCell *cell in cells) { - if (cell.cellId == onCommand.cmdID.unsignedIntegerValue) { + if (cell.cellId == onCommand.cmdID.unsignedIntegerValue && cell.handler != nil) { cell.handler(onCommand.triggerSource); return YES; } diff --git a/SmartDeviceLink/SDLScreenManager.h b/SmartDeviceLink/SDLScreenManager.h index 70d57ccf4..c3dc1e020 100644 --- a/SmartDeviceLink/SDLScreenManager.h +++ b/SmartDeviceLink/SDLScreenManager.h @@ -52,6 +52,11 @@ typedef void(^SDLScreenManagerUpdateCompletionHandler)(NSError *__nullable error - (instancetype)initWithConnectionManager:(id<SDLConnectionManagerType>)connectionManager fileManager:(SDLFileManager *)fileManager; /** + * Stops the manager. This method is used internally. + */ +- (void)stop; + +/** Delays all screen updates until endUpdatesWithCompletionHandler: is called. */ - (void)beginUpdates; diff --git a/SmartDeviceLink/SDLScreenManager.m b/SmartDeviceLink/SDLScreenManager.m index f0de151d2..798659283 100644 --- a/SmartDeviceLink/SDLScreenManager.m +++ b/SmartDeviceLink/SDLScreenManager.m @@ -45,6 +45,13 @@ NS_ASSUME_NONNULL_BEGIN return self; } +- (void)stop { + [self.textAndGraphicManager stop]; + [self.softButtonManager stop]; + [self.menuManager stop]; + [self.voiceCommandMenuManager stop]; +} + - (nullable SDLSoftButtonObject *)softButtonObjectNamed:(NSString *)name { return [self.softButtonManager softButtonObjectNamed:name]; } diff --git a/SmartDeviceLink/SDLSoftButtonManager.h b/SmartDeviceLink/SDLSoftButtonManager.h index 04f646d8d..b163fe599 100644 --- a/SmartDeviceLink/SDLSoftButtonManager.h +++ b/SmartDeviceLink/SDLSoftButtonManager.h @@ -49,6 +49,11 @@ typedef void(^SDLSoftButtonUpdateCompletionHandler)(NSError *__nullable error); - (instancetype)initWithConnectionManager:(id<SDLConnectionManagerType>)connectionManager fileManager:(SDLFileManager *)fileManager; /** + * Stops the manager. This method is used internally. + */ +- (void)stop; + +/** Cause all transitions in between `beginUpdates` and this method call to occur in one RPC update. @param handler The handler called once the update is completed. diff --git a/SmartDeviceLink/SDLSoftButtonManager.m b/SmartDeviceLink/SDLSoftButtonManager.m index 023dcdc85..262808088 100644 --- a/SmartDeviceLink/SDLSoftButtonManager.m +++ b/SmartDeviceLink/SDLSoftButtonManager.m @@ -74,6 +74,20 @@ NS_ASSUME_NONNULL_BEGIN return self; } +- (void)stop { + _softButtonObjects = @[]; + _currentMainField1 = nil; + + _inProgressUpdate = nil; + _inProgressHandler = nil; + _hasQueuedUpdate = NO; + _queuedUpdateHandler = nil; + _currentLevel = SDLHMILevelNone; + _displayCapabilities = nil; + _softButtonCapabilities = nil; + _waitingOnHMILevelUpdateToSetButtons = NO; +} + - (void)setSoftButtonObjects:(NSArray<SDLSoftButtonObject *> *)softButtonObjects { if (self.currentLevel == nil || [self.currentLevel isEqualToString:SDLHMILevelNone]) { _waitingOnHMILevelUpdateToSetButtons = YES; @@ -202,12 +216,15 @@ NS_ASSUME_NONNULL_BEGIN self.inProgressHandler = [handler copy]; self.inProgressUpdate = [[SDLShow alloc] init]; self.inProgressUpdate.mainField1 = self.currentMainField1 ?: @""; + + BOOL headUnitSupportsImages = self.softButtonCapabilities ? self.softButtonCapabilities.imageSupported.boolValue : NO; + if (self.softButtonObjects == nil) { SDLLogV(@"Soft button objects are nil, sending an empty array"); self.inProgressUpdate.softButtons = @[]; } else if (([self sdl_currentStateHasImages] && ![self sdl_allCurrentStateImagesAreUploaded]) - && (self.softButtonCapabilities ? !self.softButtonCapabilities.imageSupported : YES)) { - // The images don't yet exist on the head unit, or we cannot use images, send a text update if possible, otherwise, don't send anything yet + || !headUnitSupportsImages) { + // The images don't yet exist on the head unit, or we cannot use images, send a text update, if possible. Otherwise, don't send anything yet. NSArray<SDLSoftButton *> *textOnlyButtons = [self sdl_textButtonsForCurrentState]; if (textOnlyButtons != nil) { SDLLogV(@"Soft button images unavailable, sending text buttons"); diff --git a/SmartDeviceLink/SDLTextAndGraphicManager.h b/SmartDeviceLink/SDLTextAndGraphicManager.h index 4becbd77d..a3a9c23be 100644 --- a/SmartDeviceLink/SDLTextAndGraphicManager.h +++ b/SmartDeviceLink/SDLTextAndGraphicManager.h @@ -46,9 +46,11 @@ typedef void(^SDLTextAndGraphicUpdateCompletionHandler)(NSError *__nullable erro @property (copy, nonatomic, nullable) SDLMetadataType textField4Type; /** - If you want to make a graphic blank, set it to this artwork + * If you want to remove the current artwork, set it to this blank artwork. + * + * This artwork is set to null on disconnects to prevent a `sdl_fileManager_fileDoesNotExistError` error when the artwork is sent again on reconnects. */ -@property (strong, nonatomic, readonly) SDLArtwork *blankArtwork; +@property (strong, nonatomic, readonly, nullable) SDLArtwork *blankArtwork; @property (assign, nonatomic, getter=isBatchingUpdates) BOOL batchUpdates; @@ -62,6 +64,11 @@ typedef void(^SDLTextAndGraphicUpdateCompletionHandler)(NSError *__nullable erro - (instancetype)initWithConnectionManager:(id<SDLConnectionManagerType>)connectionManager fileManager:(SDLFileManager *)fileManager; /** + * Stops the manager. This method is used internally. + */ +- (void)stop; + +/** Update text fields with new text set into the text field properties. Pass an empty string `\@""` to clear the text field. If the system does not support a full 4 fields, this will automatically be concatenated and properly send the field available. diff --git a/SmartDeviceLink/SDLTextAndGraphicManager.m b/SmartDeviceLink/SDLTextAndGraphicManager.m index 7ec1406ea..3ee556dcc 100644 --- a/SmartDeviceLink/SDLTextAndGraphicManager.m +++ b/SmartDeviceLink/SDLTextAndGraphicManager.m @@ -52,7 +52,7 @@ NS_ASSUME_NONNULL_BEGIN @property (strong, nonatomic, nullable) SDLDisplayCapabilities *displayCapabilities; @property (strong, nonatomic, nullable) SDLHMILevel currentLevel; -@property (strong, nonatomic) SDLArtwork *blankArtwork; +@property (strong, nonatomic, nullable) SDLArtwork *blankArtwork; @property (assign, nonatomic) BOOL isDirty; @@ -79,6 +79,31 @@ NS_ASSUME_NONNULL_BEGIN return self; } +- (void)stop { + _textField1 = nil; + _textField2 = nil; + _textField3 = nil; + _textField4 = nil; + _mediaTrackTextField = nil; + _primaryGraphic = nil; + _secondaryGraphic = nil; + _alignment = SDLTextAlignmentCenter; + _textField1Type = nil; + _textField2Type = nil; + _textField3Type = nil; + _textField4Type = nil; + + _inProgressUpdate = nil; + _inProgressHandler = nil; + _queuedImageUpdate = nil; + _hasQueuedUpdate = NO; + _queuedUpdateHandler = nil; + _displayCapabilities = nil; + _currentLevel = SDLHMILevelNone; + _blankArtwork = nil; + _isDirty = NO; +} + #pragma mark - Upload / Send - (void)updateWithCompletionHandler:(nullable SDLTextAndGraphicUpdateCompletionHandler)handler { @@ -589,7 +614,7 @@ NS_ASSUME_NONNULL_BEGIN return (_hasQueuedUpdate || _queuedUpdateHandler != nil); } -- (SDLArtwork *)blankArtwork { +- (nullable SDLArtwork *)blankArtwork { if (_blankArtwork != nil) { return _blankArtwork; } diff --git a/SmartDeviceLink/SDLVoiceCommandManager.h b/SmartDeviceLink/SDLVoiceCommandManager.h index bf8d13fb9..8c3f3f78f 100644 --- a/SmartDeviceLink/SDLVoiceCommandManager.h +++ b/SmartDeviceLink/SDLVoiceCommandManager.h @@ -26,6 +26,11 @@ typedef void(^SDLMenuUpdateCompletionHandler)(NSError *__nullable error); - (instancetype)initWithConnectionManager:(id<SDLConnectionManagerType>)connectionManager; +/** + * Stops the manager. This method is used internally. + */ +- (void)stop; + @property (copy, nonatomic) NSArray<SDLVoiceCommand *> *voiceCommands; @end diff --git a/SmartDeviceLink/SDLVoiceCommandManager.m b/SmartDeviceLink/SDLVoiceCommandManager.m index 884e5fbf6..d1883d648 100644 --- a/SmartDeviceLink/SDLVoiceCommandManager.m +++ b/SmartDeviceLink/SDLVoiceCommandManager.m @@ -71,6 +71,17 @@ UInt32 const VoiceCommandIdMin = 1900000000; return self; } +- (void)stop { + _lastVoiceCommandId = VoiceCommandIdMin; + _voiceCommands = @[]; + _oldVoiceCommands = @[]; + + _waitingOnHMIUpdate = NO; + _currentHMILevel = SDLHMILevelNone; + _inProgressUpdate = nil; + _hasQueuedUpdate = NO; +} + #pragma mark - Setters - (void)setVoiceCommands:(NSArray<SDLVoiceCommand *> *)voiceCommands { diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLSoftButtonManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLSoftButtonManagerSpec.m index 0115d318e..edd06554e 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLSoftButtonManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLSoftButtonManagerSpec.m @@ -60,10 +60,13 @@ describe(@"a soft button manager", ^{ __block SDLSoftButtonObject *testObject2 = nil; __block NSString *object2Name = @"O2 Name"; __block NSString *object2State1Name = @"O2S1 Name"; + __block NSString *object2State2Name = @"O2S2 Name"; __block NSString *object2State1Text = @"O2S1 Text"; + __block NSString *object2State2Text = @"O2S2 Text"; __block NSString *object2State1ArtworkName = @"O2S1 Artwork"; __block SDLArtwork *object2State1Art = [[SDLArtwork alloc] initWithData:[@"TestData" dataUsingEncoding:NSUTF8StringEncoding] name:object2State1ArtworkName fileExtension:@"png" persistent:YES]; __block SDLSoftButtonState *object2State1 = [[SDLSoftButtonState alloc] initWithStateName:object2State1Name text:object2State1Text artwork:object2State1Art]; + __block SDLSoftButtonState *object2State2 = [[SDLSoftButtonState alloc] initWithStateName:object2State2Name text:object2State2Text image:nil]; beforeEach(^{ testFileManager = OCMClassMock([SDLFileManager class]); @@ -156,8 +159,14 @@ describe(@"a soft button manager", ^{ }); }); - describe(@"uploading the images", ^{ - context(@"when files are already on the file system", ^{ + describe(@"uploading soft buttons to a head unit that supports images", ^{ + beforeEach(^{ + SDLSoftButtonCapabilities *softButtonImagesSupported = [[SDLSoftButtonCapabilities alloc] init]; + softButtonImagesSupported.imageSupported = @YES; + testManager.softButtonCapabilities = softButtonImagesSupported; + }); + + context(@"when button artworks are already on the file system", ^{ beforeEach(^{ OCMStub([testFileManager hasUploadedFile:[OCMArg isNotNil]]).andReturn(YES); @@ -184,7 +193,7 @@ describe(@"a soft button manager", ^{ }); }); - context(@"when files are not already on the file system, before upload finishes", ^{ + context(@"when button artworks are not already on the file system, before upload finishes", ^{ beforeEach(^{ OCMStub([testFileManager hasUploadedFile:[OCMArg isNotNil]]).andReturn(NO); @@ -211,7 +220,7 @@ describe(@"a soft button manager", ^{ }); }); - context(@"when files are not already on the file system, after upload finishes", ^{ + context(@"when button artworks are not already on the file system, after upload finishes", ^{ beforeEach(^{ OCMStub([testFileManager hasUploadedFile:[OCMArg isNotNil]]).andReturn(NO); OCMStub([testFileManager uploadArtworks:[OCMArg any] completionHandler:[OCMArg invokeBlock]]); @@ -240,6 +249,62 @@ describe(@"a soft button manager", ^{ }); }); + describe(@"uploading soft buttons to a head unit that does not support images", ^{ + beforeEach(^{ + SDLSoftButtonCapabilities *softButtonImagesSupported = [[SDLSoftButtonCapabilities alloc] init]; + softButtonImagesSupported.imageSupported = @NO; + testManager.softButtonCapabilities = softButtonImagesSupported; + }); + + context(@"when the button contains images", ^{ + beforeEach(^{ + testObject1 = [[SDLSoftButtonObject alloc] initWithName:object1Name states:@[object1State1, object1State2] initialStateName:object1State1Name handler:nil]; + testObject2 = [[SDLSoftButtonObject alloc] initWithName:object2Name state:object2State2 handler:nil]; + testManager.softButtonObjects = @[testObject1, testObject2]; + }); + + it(@"should not have attempted to upload any artworks", ^{ + OCMReject([testFileManager uploadArtworks:[OCMArg any] completionHandler:[OCMArg any]]); + }); + + it(@"should set the in progress update to be text buttons", ^{ + NSArray<SDLSoftButton *> *inProgressSoftButtons = testManager.inProgressUpdate.softButtons; + + expect(testManager.hasQueuedUpdate).to(beFalse()); + expect(testManager.inProgressUpdate.mainField1).to(equal(@"")); + expect(inProgressSoftButtons).to(haveCount(2)); + expect(inProgressSoftButtons[0].text).to(equal(object1State1Text)); + expect(inProgressSoftButtons[1].text).to(equal(object2State2Text)); + expect(inProgressSoftButtons[0].image).to(beNil()); + expect(inProgressSoftButtons[1].image.value).to(beNil()); + }); + }); + + context(@"when the button does not contain images", ^{ + beforeEach(^{ + testObject1 = [[SDLSoftButtonObject alloc] initWithName:object1Name states:@[object1State1, object1State2] initialStateName:object1State1Name handler:nil]; + testObject2 = [[SDLSoftButtonObject alloc] initWithName:object2Name state:object2State2 handler:nil]; + testManager.softButtonObjects = @[testObject1, testObject2]; + }); + + it(@"should not have attempted to upload any artworks", ^{ + OCMReject([testFileManager uploadArtworks:[OCMArg any] completionHandler:[OCMArg any]]); + }); + + it(@"should set the in progress update to be text buttons", ^{ + NSArray<SDLSoftButton *> *inProgressSoftButtons = testManager.inProgressUpdate.softButtons; + + expect(testManager.hasQueuedUpdate).to(beFalse()); + expect(testManager.inProgressUpdate.mainField1).to(equal(@"")); + expect(inProgressSoftButtons).to(haveCount(2)); + expect(inProgressSoftButtons[0].text).to(equal(object1State1Text)); + expect(inProgressSoftButtons[1].text).to(equal(object2State2Text)); + expect(inProgressSoftButtons[0].image).to(beNil()); + expect(inProgressSoftButtons[1].image.value).to(beNil()); + }); + }); + }); + describe(@"transitioning soft button states", ^{ beforeEach(^{ OCMStub([testFileManager hasUploadedFile:[OCMArg isNotNil]]).andReturn(YES); |