Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement SDL 0157 - Choice Set Manager #975

Merged
merged 54 commits into from
Jun 27, 2018
Merged
Show file tree
Hide file tree
Changes from 53 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
e8323e1
Stub out new choice set manager classes
joeljfischer May 21, 2018
8bf60fa
Update documentation
joeljfischer May 21, 2018
46ac2b7
Setting up internals of choice set manager
joeljfischer May 22, 2018
02617d1
Choice set manager state machine additions
joeljfischer May 22, 2018
4efba03
* Add ScreenManager convenience `endUpdates`
joeljfischer May 22, 2018
9bc4833
* Add ChoiceSetManager to internal log file module map
joeljfischer May 22, 2018
9c6d211
Implement ScreenManager Methods / Properties as passthrough
joeljfischer May 23, 2018
6b85bc6
Rejigger ChoiceSetManager to use operations
joeljfischer May 23, 2018
5690738
Add new ChoiceManager operations
joeljfischer May 24, 2018
1685ffc
Remove unused code
joeljfischer May 24, 2018
a7b8e94
Add names for choice set operations
joeljfischer May 24, 2018
d0ccfcc
Merge branch 'develop' into feature/issue_970_mobile_choice_manager
joeljfischer May 29, 2018
f4a5d3f
Working on presenting keyboard delegates
joeljfischer May 29, 2018
217f63d
Add choice set operations to log module map
joeljfischer May 30, 2018
8cf5116
Updates to PresentChoiceSetOperation
joeljfischer May 30, 2018
f8cce42
Startup the choice set manager correctly
joeljfischer May 30, 2018
0967ada
Fix choice set manager files not being public
joeljfischer May 30, 2018
fb485f2
* Fix Choice ids not being set properly
joeljfischer May 31, 2018
2b33f9f
Fix preloaded choice sets having non-matching ids
joeljfischer May 31, 2018
c630ea6
Fix crashes when optional keyboard delegate methods aren’t present
joeljfischer Jun 1, 2018
444d02a
Fix default keyboard properties
joeljfischer Jun 1, 2018
a8910ce
Fix setting keyboard configuration
joeljfischer Jun 1, 2018
e5bd3d0
Use a searchable choice set in the example app
joeljfischer Jun 1, 2018
cc14fda
Numerous choice set manager fixes
joeljfischer Jun 1, 2018
79d5891
Merge branch 'develop' into feature/issue_970_mobile_choice_manager
joeljfischer Jun 5, 2018
7f9d9d5
Fix choice set manager deletions having wrong ids
joeljfischer Jun 8, 2018
4c4efd2
Fail if invalid choice sets are created
joeljfischer Jun 8, 2018
dfd1fbb
Fix present keyboard operation
joeljfischer Jun 8, 2018
e658b77
Fix keyboard properties not getting sent if custom ones weren’t set
joeljfischer Jun 8, 2018
792bb0e
Fixes for choice set manager
joeljfischer Jun 8, 2018
3b5b7c0
Automatically set vrHelpItem positions
joeljfischer Jun 8, 2018
3a8ae4f
update example app
joeljfischer Jun 8, 2018
4d1f0b0
Start on choice set manager unit tests
joeljfischer Jun 8, 2018
8660fec
Use c function instead of #define
joeljfischer Jun 8, 2018
7674b44
SDLChoiceSet tests
joeljfischer Jun 8, 2018
6c35b87
Stub the rest of the specs
joeljfischer Jun 8, 2018
ef0b79f
CheckChoiceVROperation tests
joeljfischer Jun 11, 2018
ca1477f
Delete choices operation tests
joeljfischer Jun 12, 2018
c8bdf93
Preload choice operation tests
joeljfischer Jun 12, 2018
32394ee
Fixes to preload choices operation tests
joeljfischer Jun 12, 2018
ef4dd7b
Present keyboard tests
joeljfischer Jun 12, 2018
470c320
Stub present choice set tests
joeljfischer Jun 12, 2018
650f235
Additional small updates
joeljfischer Jun 12, 2018
c47a662
Present Choice Set Operation tests
joeljfischer Jun 13, 2018
133faf4
In progress choice set manager tests
joeljfischer Jun 13, 2018
9e316bf
Preloading choice operations can now have cells removed
joeljfischer Jun 14, 2018
786eedf
Additional ChoiceSetManager tests
joeljfischer Jun 14, 2018
0ef0b3a
Finish choice set manager tests
joeljfischer Jun 14, 2018
7092424
Test fixes
joeljfischer Jun 14, 2018
607f7ce
Fix remaining test cases
joeljfischer Jun 15, 2018
a664564
Remove unused delegate
joeljfischer Jun 15, 2018
bfe4754
Update obj-c example app for choicesetmanager
joeljfischer Jun 15, 2018
1b046de
Add row index to choice set delegate
joeljfischer Jun 22, 2018
aa39378
Fix obj-c app using incorrect delegate
joeljfischer Jun 25, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions SmartDeviceLink-iOS.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ ss.public_header_files = [
'SmartDeviceLink/SDLChangeRegistrationResponse.h',
'SmartDeviceLink/SDLCharacterSet.h',
'SmartDeviceLink/SDLChoice.h',
'SmartDeviceLink/SDLChoiceCell.h',
'SmartDeviceLink/SDLChoiceSet.h',
'SmartDeviceLink/SDLChoiceSetDelegate.h',
'SmartDeviceLink/SDLClimateControlCapabilities.h',
'SmartDeviceLink/SDLClimateControlData.h',
'SmartDeviceLink/SDLClusterModeStatus.h',
Expand Down Expand Up @@ -127,6 +130,7 @@ ss.public_header_files = [
'SmartDeviceLink/SDLImageResolution.h',
'SmartDeviceLink/SDLImageType.h',
'SmartDeviceLink/SDLInteractionMode.h',
'SmartDeviceLink/SDLKeyboardDelegate.h',
'SmartDeviceLink/SDLKeyboardEvent.h',
'SmartDeviceLink/SDLKeyboardLayout.h',
'SmartDeviceLink/SDLKeyboardProperties.h',
Expand Down
150 changes: 147 additions & 3 deletions SmartDeviceLink-iOS.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0930"
LastUpgradeVersion = "0940"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand All @@ -26,7 +26,18 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
codeCoverageEnabled = "YES"
onlyGenerateCoverageForSpecifiedTargets = "YES"
shouldUseLaunchSchemeArgsEnv = "YES">
<CodeCoverageTargets>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "5D61FA1B1A84237100846EE7"
BuildableName = "SmartDeviceLink.framework"
BlueprintName = "SmartDeviceLink"
ReferencedContainer = "container:SmartDeviceLink-iOS.xcodeproj">
</BuildableReference>
</CodeCoverageTargets>
<Testables>
<TestableReference
skipped = "NO">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0930"
LastUpgradeVersion = "0940"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand All @@ -14,7 +14,7 @@
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "5D4346601E6F38E600B639C6"
BlueprintIdentifier = "88802CD720853AE600E9EBC6"
BuildableName = "SmartDeviceLinkSwift.framework"
BlueprintName = "SmartDeviceLinkSwift"
ReferencedContainer = "container:SmartDeviceLink-iOS.xcodeproj">
Expand Down Expand Up @@ -45,7 +45,7 @@
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "5D4346601E6F38E600B639C6"
BlueprintIdentifier = "88802CD720853AE600E9EBC6"
BuildableName = "SmartDeviceLinkSwift.framework"
BlueprintName = "SmartDeviceLinkSwift"
ReferencedContainer = "container:SmartDeviceLink-iOS.xcodeproj">
Expand All @@ -63,7 +63,7 @@
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "5D4346601E6F38E600B639C6"
BlueprintIdentifier = "88802CD720853AE600E9EBC6"
BuildableName = "SmartDeviceLinkSwift.framework"
BlueprintName = "SmartDeviceLinkSwift"
ReferencedContainer = "container:SmartDeviceLink-iOS.xcodeproj">
Expand Down
4 changes: 4 additions & 0 deletions SmartDeviceLink.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ ss.public_header_files = [
'SmartDeviceLink/SDLChangeRegistrationResponse.h',
'SmartDeviceLink/SDLCharacterSet.h',
'SmartDeviceLink/SDLChoice.h',
'SmartDeviceLink/SDLChoiceCell.h',
'SmartDeviceLink/SDLChoiceSet.h',
'SmartDeviceLink/SDLChoiceSetDelegate.h',
'SmartDeviceLink/SDLClimateControlCapabilities.h',
'SmartDeviceLink/SDLClimateControlData.h',
'SmartDeviceLink/SDLClusterModeStatus.h',
Expand Down Expand Up @@ -127,6 +130,7 @@ ss.public_header_files = [
'SmartDeviceLink/SDLImageResolution.h',
'SmartDeviceLink/SDLImageType.h',
'SmartDeviceLink/SDLInteractionMode.h',
'SmartDeviceLink/SDLKeyboardDelegate.h',
'SmartDeviceLink/SDLKeyboardEvent.h',
'SmartDeviceLink/SDLKeyboardLayout.h',
'SmartDeviceLink/SDLKeyboardProperties.h',
Expand Down
2 changes: 2 additions & 0 deletions SmartDeviceLink/SDLAsynchronousOperation.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

@interface SDLAsynchronousOperation : NSOperation

@property (copy, nonatomic, readonly, nullable) NSError *error;

- (void)finishOperation;

@end
5 changes: 3 additions & 2 deletions SmartDeviceLink/SDLAsynchronousOperation.m
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@ - (void)start {

- (void)finishOperation {
[self willChangeValueForKey:@"isExecuting"];
[self willChangeValueForKey:@"isFinished"];
executing = NO;
[self didChangeValueForKey:@"isExecuting"];

[self willChangeValueForKey:@"isFinished"];
finished = YES;
[self didChangeValueForKey:@"isFinished"];
[self didChangeValueForKey:@"isExecuting"];
}

#pragma mark - Property Overrides
Expand Down
24 changes: 24 additions & 0 deletions SmartDeviceLink/SDLCheckChoiceVROptionalOperation.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// SDLCheckChoiceVROptionalOperation.h
// SmartDeviceLink
//
// Created by Joel Fischer on 5/24/18.
// Copyright © 2018 smartdevicelink. All rights reserved.
//

#import "SDLAsynchronousOperation.h"

@protocol SDLConnectionManagerType;

NS_ASSUME_NONNULL_BEGIN


@interface SDLCheckChoiceVROptionalOperation : SDLAsynchronousOperation

@property (assign, nonatomic, getter=isVROptional) BOOL vrOptional;

- (instancetype)initWithConnectionManager:(id<SDLConnectionManagerType>)connectionManager;

@end

NS_ASSUME_NONNULL_END
100 changes: 100 additions & 0 deletions SmartDeviceLink/SDLCheckChoiceVROptionalOperation.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
//
// SDLCheckChoiceVROptionalOperation.m
// SmartDeviceLink
//
// Created by Joel Fischer on 5/24/18.
// Copyright © 2018 smartdevicelink. All rights reserved.
//

#import "SDLCheckChoiceVROptionalOperation.h"

#import "SDLChoice.h"
#import "SDLCreateInteractionChoiceSet.h"
#import "SDLConnectionManagerType.h"
#import "SDLLogMacros.h"

NS_ASSUME_NONNULL_BEGIN

@interface SDLCheckChoiceVROptionalOperation()

@property (weak, nonatomic) id<SDLConnectionManagerType> connectionManager;
@property (copy, nonatomic, nullable) NSError *internalError;

@end

@implementation SDLCheckChoiceVROptionalOperation

- (instancetype)initWithConnectionManager:(id<SDLConnectionManagerType>)connectionManager {
self = [super init];
if (!self) { return nil; }

_connectionManager = connectionManager;

return self;
}

- (void)start {
[super start];

[self sdl_sendTestChoices];
}

- (void)sdl_sendTestChoices {
__weak typeof(self) weakself = self;
[self.connectionManager sendConnectionManagerRequest:[self.class sdl_testCellWithVR:NO] withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) {
if (error == nil) {
SDLLogD(@"Connected head unit supports choice cells without voice commands. Cells without voice will be sent without voice from now on (no placeholder voice).");

weakself.vrOptional = YES;
weakself.internalError = nil;
[weakself finishOperation];
return;
}

// Check for choice sets with VR
[self.connectionManager sendConnectionManagerRequest:[self.class sdl_testCellWithVR:YES] withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) {
if (error == nil) {
SDLLogW(@"Connected head unit does not support choice cells without voice commands. Cells without voice will be sent with placeholder voices from now on.");

weakself.vrOptional = NO;
weakself.internalError = nil;
[weakself finishOperation];
return;
}

SDLLogE(@"Connected head unit has rejected all choice cells, choice manager disabled. Error: %@, Response: %@", error, response);
weakself.vrOptional = NO;
weakself.internalError = error;
[weakself finishOperation];
}];
}];
}

+ (SDLCreateInteractionChoiceSet *)sdl_testCellWithVR:(BOOL)hasVR {
SDLChoice *choice = [[SDLChoice alloc] init];
choice.choiceID = @0;
choice.menuName = @"Test Cell";
choice.vrCommands = hasVR ? @[@"Test VR"] : nil;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shows up on Manticore's Voice tab. Could be confusing for developers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, that's unavoidable. This has to have a VR command to be valid, and it's used for the keyboard.


SDLCreateInteractionChoiceSet *choiceSet = [[SDLCreateInteractionChoiceSet alloc] initWithId:0 choiceSet:@[choice]];

return choiceSet;
}

#pragma mark - Property Overrides

- (nullable NSString *)name {
return @"com.sdl.choicesetmanager.checkVROptional";
}

- (NSOperationQueuePriority)queuePriority {
return NSOperationQueuePriorityVeryHigh;
}

- (nullable NSError *)error {
return self.internalError;
}

@end

NS_ASSUME_NONNULL_END
87 changes: 87 additions & 0 deletions SmartDeviceLink/SDLChoiceCell.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
//
// SDLChoiceCell.h
// SmartDeviceLink
//
// Created by Joel Fischer on 5/21/18.
// Copyright © 2018 Livio. All rights reserved.
//

#import <Foundation/Foundation.h>

@class SDLArtwork;

NS_ASSUME_NONNULL_BEGIN

@interface SDLChoiceCell: NSObject
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be handy to have a cellSelectedHandler on the SDLChoiceCell. That way, when the SDLChoiceSetDelegate's choiceSet:didSelectChoice:withSource is called, the handler can be triggered. Otherwise, I have to check the cell's text and figure out what I'm going to do based on that... which can get messy.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem with blocks is that we'd have to store all of them...and there could be a lot. For now, I've added a row index to the delegate callback, which should be sufficient. If we want to go to blocks, we can do so in a later release.


/**
Maps to Choice.menuName. The primary text of the cell. Duplicates within an `SDLChoiceSet` are not permitted and will result in the `SDLChoiceSet` failing to initialize.
*/
@property (copy, nonatomic, readonly) NSString *text;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add to documentation that duplicate texts will fail.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


/**
Maps to Choice.secondaryText. Optional secondary text of the cell, if available. Duplicates within an `SDLChoiceSet` are permitted.
*/
@property (copy, nonatomic, readonly, nullable) NSString *secondaryText;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add to documentation that duplicate secondaryTexts are ok.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


/**
Maps to Choice.tertiaryText. Optional tertitary text of the cell, if available. Duplicates within an `SDLChoiceSet` are permitted.
*/
@property (copy, nonatomic, readonly, nullable) NSString *tertiaryText;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add to documentation that duplicate tertiaryTexts are ok.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


/**
Maps to Choice.vrCommands. Optional voice commands the user can speak to activate the cell. If not set and the head unit requires it, this will be set to the number in the list that this item appears. However, this would be a very poor experience for a user if the choice set is presented as a voice only interaction or both interaction mode. Therefore, consider not setting this only when you know the choice set will be presented as a touch only interaction.
*/
@property (copy, nonatomic, readonly, nullable) NSArray<NSString *> *voiceCommands;

/**
Maps to Choice.image. Optional image for the cell. This will be uploaded before the cell is used when the cell is preloaded or presented for the first time.
*/
@property (strong, nonatomic, readonly, nullable) SDLArtwork *artwork;

/**
Maps to Choice.secondaryImage. Optional secondary image for the cell. This will be uploaded before the cell is used when the cell is preloaded or presented for the first time.
*/
@property (strong, nonatomic, readonly, nullable) SDLArtwork *secondaryArtwork;

/**
Initialize the cell with nothing. This is unavailable

@return A crash, probably
*/
- (instancetype)init NS_UNAVAILABLE;

/**
Initialize the cell with text and nothing else.

@param text The primary text of the cell.
@return The cell
*/
- (instancetype)initWithText:(NSString *)text;

/**
Initialize the cell with text, optional artwork, and optional voice commands

@param text The primary text of the cell
@param artwork The primary artwork of the cell
@param voiceCommands Strings that can be spoken by the user to activate this cell in a voice or both interaction mode
@return The cell
*/
- (instancetype)initWithText:(NSString *)text artwork:(nullable SDLArtwork *)artwork voiceCommands:(nullable NSArray<NSString *> *)voiceCommands;

/**
Initialize the cell with all optional items

@param text The primary text
@param secondaryText The secondary text
@param tertiaryText The tertiary text
@param voiceCommands Strings that can be spoken by the user to activate this cell in a voice or both interaction mode
@param artwork The primary artwork
@param secondaryArtwork The secondary artwork
@return The cell
*/
- (instancetype)initWithText:(NSString *)text secondaryText:(nullable NSString *)secondaryText tertiaryText:(nullable NSString *)tertiaryText voiceCommands:(nullable NSArray<NSString *> *)voiceCommands artwork:(nullable SDLArtwork *)artwork secondaryArtwork:(nullable SDLArtwork *)secondaryArtwork;

@end

NS_ASSUME_NONNULL_END
Loading