summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicoleYarroch <nicole@livio.io>2018-05-15 09:23:55 -0400
committerNicoleYarroch <nicole@livio.io>2018-05-15 09:23:55 -0400
commitd67e67b7c8857978f2167445b93ca1e7e2e68b8f (patch)
tree0c17f3a60af715f749c148b121fef49135eb05a3
parentc670715bf9761677210929f89355adebf186c2e6 (diff)
parentcc5eae8907aaab89a9634c259be62382b145a5ac (diff)
downloadsdl_ios-d67e67b7c8857978f2167445b93ca1e7e2e68b8f.tar.gz
Merge branch 'develop' into feature/issue_620_swift_sdl_example_app
-rw-r--r--SmartDeviceLink/SDLLifecycleManager.m1
-rw-r--r--SmartDeviceLink/SDLMenuManager.h5
-rw-r--r--SmartDeviceLink/SDLMenuManager.m16
-rw-r--r--SmartDeviceLink/SDLScreenManager.h5
-rw-r--r--SmartDeviceLink/SDLScreenManager.m7
-rw-r--r--SmartDeviceLink/SDLSoftButtonManager.h5
-rw-r--r--SmartDeviceLink/SDLSoftButtonManager.m21
-rw-r--r--SmartDeviceLink/SDLTextAndGraphicManager.h11
-rw-r--r--SmartDeviceLink/SDLTextAndGraphicManager.m29
-rw-r--r--SmartDeviceLink/SDLVoiceCommandManager.h5
-rw-r--r--SmartDeviceLink/SDLVoiceCommandManager.m11
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLSoftButtonManagerSpec.m73
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);