diff options
author | Justin Beharry <justin.beharry@livio.io> | 2022-08-09 12:17:37 -0400 |
---|---|---|
committer | Justin Beharry <justin.beharry@livio.io> | 2022-08-09 12:17:37 -0400 |
commit | 794e7f3f2ee4b6c87afa6f31f1027770551354e2 (patch) | |
tree | 60712d49b0c11f1d642bec80b701fce70ce92c2a /Example Apps | |
parent | 2561046c4088ab92d59a2298e946f76cabc65a73 (diff) | |
download | sdl_ios-794e7f3f2ee4b6c87afa6f31f1027770551354e2.tar.gz |
Disable remote control on IAP, enable only for TCP
-Disable remote control startup
-On IAP show alert when clicking remote control menu item
Diffstat (limited to 'Example Apps')
-rw-r--r-- | Example Apps/Example ObjC/MenuManager.m | 11 | ||||
-rw-r--r-- | Example Apps/Example ObjC/ProxyManager.m | 19 | ||||
-rw-r--r-- | Example Apps/Example ObjC/RemoteControlManager.h | 3 | ||||
-rw-r--r-- | Example Apps/Example ObjC/RemoteControlManager.m | 10 | ||||
-rw-r--r-- | Example Apps/Example Swift/MenuManager.swift | 16 | ||||
-rw-r--r-- | Example Apps/Example Swift/ProxyManager.swift | 19 | ||||
-rw-r--r-- | Example Apps/Example Swift/RemoteControlManager.swift | 10 | ||||
-rw-r--r-- | Example Apps/Shared/AppConstants.h | 1 | ||||
-rw-r--r-- | Example Apps/Shared/AppConstants.m | 1 |
9 files changed, 72 insertions, 18 deletions
diff --git a/Example Apps/Example ObjC/MenuManager.m b/Example Apps/Example ObjC/MenuManager.m index 83894fd89..bcf61a008 100644 --- a/Example Apps/Example ObjC/MenuManager.m +++ b/Example Apps/Example ObjC/MenuManager.m @@ -168,6 +168,15 @@ NS_ASSUME_NONNULL_BEGIN } + (SDLMenuCell *)sdlex_menuCellRemoteWithManager:(SDLManager *)manager remoteManager:(RemoteControlManager *)remoteManager { + SDLArtwork * _Nonnull remoteControlIcon = [SDLArtwork artworkWithImage:[[UIImage imageNamed:RemoteControlIconName] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] asImageFormat:SDLArtworkImageFormatPNG]; + + // Clicking on cell shows alert message when remote control permissions are disabled + if (![remoteManager isPermissionEnabled]) { + return [[SDLMenuCell alloc] initWithTitle: ACRemoteMenuName secondaryText:nil tertiaryText:nil icon:remoteControlIcon secondaryArtwork:nil voiceCommands:nil handler:^(SDLTriggerSource _Nonnull triggerSource) { + [AlertManager sendAlertWithManager:manager image:nil textField1:AlertRemoteControlPermissionWarningText textField2:nil]; + }]; + } + // Let's give an example of 2 templates NSMutableArray *submenuItems = [NSMutableArray array]; NSString *errorMessage = @"Changing the template failed"; @@ -199,7 +208,7 @@ NS_ASSUME_NONNULL_BEGIN }]; [submenuItems addObject:viewClimateCell]; - return [[SDLMenuCell alloc] initWithTitle:ACRemoteMenuName secondaryText:nil tertiaryText:nil icon:[SDLArtwork artworkWithImage:[[UIImage imageNamed:RemoteControlIconName] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] asImageFormat:SDLArtworkImageFormatPNG] secondaryArtwork:nil submenuLayout:SDLMenuLayoutList subCells:[submenuItems copy]]; + return [[SDLMenuCell alloc] initWithTitle:ACRemoteMenuName secondaryText:nil tertiaryText:nil icon:remoteControlIcon secondaryArtwork:nil submenuLayout:SDLMenuLayoutList subCells:[submenuItems copy]]; } #pragma mark - Voice Commands diff --git a/Example Apps/Example ObjC/ProxyManager.m b/Example Apps/Example ObjC/ProxyManager.m index 15c7ff283..daed74d55 100644 --- a/Example Apps/Example ObjC/ProxyManager.m +++ b/Example Apps/Example ObjC/ProxyManager.m @@ -23,6 +23,7 @@ NS_ASSUME_NONNULL_BEGIN // Describes the first time the HMI state goes non-none and full. @property (assign, nonatomic) SDLHMILevel firstHMILevel; +@property (assign, nonatomic, getter=isRemoteControlEnabled) BOOL remoteControlEnabled; @property (strong, nonatomic) RemoteControlManager *remoteControlManager; @property (strong, nonatomic) VehicleDataManager *vehicleDataManager; @property (strong, nonatomic) PerformInteractionManager *performManager; @@ -52,6 +53,7 @@ NS_ASSUME_NONNULL_BEGIN return nil; } + _remoteControlEnabled = NO; _state = ProxyStateStopped; _firstHMILevel = SDLHMILevelNone; @@ -71,8 +73,7 @@ NS_ASSUME_NONNULL_BEGIN self.performManager = [[PerformInteractionManager alloc] initWithManager:self.sdlManager]; self.buttonManager = [[ButtonManager alloc] initWithManager:self.sdlManager refreshUIHandler:self.refreshUIHandler]; self.subscribeButtonManager = [[SubscribeButtonManager alloc] initWithManager:self.sdlManager]; - self.remoteControlManager = [[RemoteControlManager alloc] initWithManager:self.sdlManager softButtons:[self.buttonManager allScreenSoftButtons]]; - + self.remoteControlManager = [[RemoteControlManager alloc] initWithManager:self.sdlManager hasPermission:[self isRemoteControlEnabled] softButtons:[self.buttonManager allScreenSoftButtons]]; [weakSelf sdlex_updateProxyState:ProxyStateConnected]; [RPCPermissionsManager setupPermissionsCallbacksWithManager:weakSelf.sdlManager]; @@ -102,18 +103,19 @@ NS_ASSUME_NONNULL_BEGIN [self sdlex_updateProxyState:ProxyStateSearchingForConnection]; SDLConfiguration *config = (proxyTransportType == ProxyTransportTypeIAP) ? [self.class sdlex_iapConfiguration] : [self.class sdlex_tcpConfiguration]; + self.remoteControlEnabled = (proxyTransportType == ProxyTransportTypeTCP) ? YES : NO; self.sdlManager = [[SDLManager alloc] initWithConfiguration:config delegate:self]; [self sdlex_startManager]; } + (SDLConfiguration *)sdlex_iapConfiguration { - SDLLifecycleConfiguration *lifecycleConfig = [self.class sdlex_setLifecycleConfigurationPropertiesOnConfiguration:[SDLLifecycleConfiguration defaultConfigurationWithAppName:ExampleAppName fullAppId:ExampleFullAppId]]; + SDLLifecycleConfiguration *lifecycleConfig = [self.class sdlex_setLifecycleConfigurationPropertiesOnConfiguration:[SDLLifecycleConfiguration defaultConfigurationWithAppName:ExampleAppName fullAppId:ExampleFullAppId] enableRemote:NO]; return [self sdlex_setupManagerConfigurationWithLifecycleConfiguration:lifecycleConfig]; } + (SDLConfiguration *)sdlex_tcpConfiguration { - SDLLifecycleConfiguration *lifecycleConfig = [self.class sdlex_setLifecycleConfigurationPropertiesOnConfiguration:[SDLLifecycleConfiguration debugConfigurationWithAppName:ExampleAppName fullAppId:ExampleFullAppId ipAddress:[Preferences sharedPreferences].ipAddress port:[Preferences sharedPreferences].port]]; + SDLLifecycleConfiguration *lifecycleConfig = [self.class sdlex_setLifecycleConfigurationPropertiesOnConfiguration:[SDLLifecycleConfiguration debugConfigurationWithAppName:ExampleAppName fullAppId:ExampleFullAppId ipAddress:[Preferences sharedPreferences].ipAddress port:[Preferences sharedPreferences].port] enableRemote:YES]; return [self sdlex_setupManagerConfigurationWithLifecycleConfiguration:lifecycleConfig]; } @@ -124,7 +126,7 @@ NS_ASSUME_NONNULL_BEGIN return [[SDLConfiguration alloc] initWithLifecycle:lifecycleConfiguration lockScreen:lockScreenConfiguration logging:[self.class sdlex_logConfiguration] fileManager:[SDLFileManagerConfiguration defaultConfiguration] encryption:[SDLEncryptionConfiguration defaultConfiguration]]; } -+ (SDLLifecycleConfiguration *)sdlex_setLifecycleConfigurationPropertiesOnConfiguration:(SDLLifecycleConfiguration *)config { ++ (SDLLifecycleConfiguration *)sdlex_setLifecycleConfigurationPropertiesOnConfiguration:(SDLLifecycleConfiguration *)config enableRemote:(BOOL)hasRemote { UIImage *appLogo = [[UIImage imageNamed:ExampleAppLogoName] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; SDLArtwork *appIconArt = [SDLArtwork persistentArtworkWithImage:appLogo asImageFormat:SDLArtworkImageFormatPNG]; @@ -135,7 +137,12 @@ NS_ASSUME_NONNULL_BEGIN config.language = SDLLanguageEnUs; config.languagesSupported = @[SDLLanguageEnUs, SDLLanguageFrCa, SDLLanguageEsMx]; config.appType = SDLAppHMITypeDefault; - config.additionalAppTypes = @[SDLAppHMITypeRemoteControl]; + + // On actional hardware, the app requires permissions to do remote control which this example app will not have. + // Only use the remote control type on the TCP connection. + if (hasRemote) { + config.additionalAppTypes = @[SDLAppHMITypeRemoteControl]; + } SDLRGBColor *green = [[SDLRGBColor alloc] initWithRed:126 green:188 blue:121]; SDLRGBColor *white = [[SDLRGBColor alloc] initWithRed:249 green:251 blue:254]; diff --git a/Example Apps/Example ObjC/RemoteControlManager.h b/Example Apps/Example ObjC/RemoteControlManager.h index a81e0aea0..1bfdf95fd 100644 --- a/Example Apps/Example ObjC/RemoteControlManager.h +++ b/Example Apps/Example ObjC/RemoteControlManager.h @@ -15,10 +15,11 @@ NS_ASSUME_NONNULL_BEGIN @interface RemoteControlManager : NSObject +@property (assign, nonatomic, getter=isPermissionEnabled, readonly) BOOL permissionEnabled; @property (copy, nonatomic, readonly) NSString *climateDataString; - (instancetype)init NS_UNAVAILABLE; -- (instancetype)initWithManager:(SDLManager *)manager softButtons:(NSArray<SDLSoftButtonObject *> *)buttons; +- (instancetype)initWithManager:(SDLManager *)manager hasPermission:(BOOL)enabled softButtons:(NSArray<SDLSoftButtonObject *> *)buttons; - (void)start; - (void)showClimateControl; diff --git a/Example Apps/Example ObjC/RemoteControlManager.m b/Example Apps/Example ObjC/RemoteControlManager.m index 0eb3a3cd1..b3353b1b6 100644 --- a/Example Apps/Example ObjC/RemoteControlManager.m +++ b/Example Apps/Example ObjC/RemoteControlManager.m @@ -14,7 +14,9 @@ @interface RemoteControlManager() @property (strong, nonatomic) SDLManager *sdlManager; +@property (assign, nonatomic, getter=isPermissionEnabled, readwrite) BOOL permissionEnabled; @property (strong, nonatomic) NSArray<SDLSoftButtonObject *> *homeButtons; + @property (strong, nonatomic) SDLRemoteControlCapabilities *remoteControlCapabilities; @property (strong, nonatomic) NSString *climateModuleId; @property (strong, nonatomic) NSNumber<SDLBool> *hasConsent; @@ -26,17 +28,23 @@ @implementation RemoteControlManager -- (instancetype)initWithManager:(SDLManager *)manager softButtons:(NSArray<SDLSoftButtonObject *> *)buttons { +- (instancetype)initWithManager:(SDLManager *)manager hasPermission:(BOOL)permission softButtons:(NSArray<SDLSoftButtonObject *> *)buttons { self = [super init]; if (!self) { return nil; } _sdlManager = manager; + _permissionEnabled = permission; _homeButtons = buttons; return self; } - (void)start { + if (![self isPermissionEnabled]) { + SDLLogD(@"Missing permissions for Remote Control Manager. Example remote control works only on TCP."); + return; + } + [self.sdlManager.systemCapabilityManager subscribeToCapabilityType:SDLSystemCapabilityTypeRemoteControl withUpdateHandler:^(SDLSystemCapability * _Nullable capability, BOOL subscribed, NSError * _Nullable error) { if (!capability.remoteControlCapability) { SDLLogE(@"SDL errored getting remote control module information: %@", error); diff --git a/Example Apps/Example Swift/MenuManager.swift b/Example Apps/Example Swift/MenuManager.swift index 6cb0a76d1..9616a771e 100644 --- a/Example Apps/Example Swift/MenuManager.swift +++ b/Example Apps/Example Swift/MenuManager.swift @@ -210,11 +210,21 @@ private extension MenuManager { /// Menu item that shows remote control example /// - /// - Parameter manager: The SDL Manager + /// - Parameters: + /// - manager: The SDL Manager + /// - remoteManager: The manager for controling and viewing remote control data /// - Returns: A SDLMenuCell object class func menuCellRemoteControl(with manager: SDLManager, remoteManager: RemoteControlManager) -> SDLMenuCell { - var submenuItems = [SDLMenuCell]() + let remoteControlIcon = SDLArtwork(image: UIImage(named: RemoteControlIconName)!.withRenderingMode(.alwaysTemplate), persistent: true, as: .PNG) + + // Clicking on cell shows alert message when remote control permissions are disabled + if (!remoteManager.isPermissionEnabled) { + return SDLMenuCell(title: ACRemoteMenuName, secondaryText: nil, tertiaryText: nil, icon: remoteControlIcon, secondaryArtwork: nil, voiceCommands: nil, handler: { _ in + AlertManager.sendAlert(textField1: AlertRemoteControlPermissionWarningText, sdlManager: manager) + }) + } + var submenuItems = [SDLMenuCell]() // Climate Control Menu submenuItems.append(SDLMenuCell(title: ACRemoteControlClimateMenuName, secondaryText: nil, tertiaryText: nil, icon: nil, secondaryArtwork: nil, voiceCommands: nil, handler: { (triggerSource) in manager.screenManager.changeLayout(SDLTemplateConfiguration(predefinedLayout: .tilesOnly)) { err in @@ -244,7 +254,7 @@ private extension MenuManager { }) })) - return SDLMenuCell(title: ACRemoteMenuName, secondaryText: nil, tertiaryText: nil, icon: SDLArtwork(image: UIImage(named: RemoteControlIconName)!.withRenderingMode(.alwaysTemplate), persistent: true, as: .PNG), secondaryArtwork: nil, submenuLayout: .list, subCells: submenuItems) + return SDLMenuCell(title: ACRemoteMenuName, secondaryText: nil, tertiaryText: nil, icon: remoteControlIcon, secondaryArtwork: nil, submenuLayout: .list, subCells: submenuItems) } } diff --git a/Example Apps/Example Swift/ProxyManager.swift b/Example Apps/Example Swift/ProxyManager.swift index 45ebcd88e..3c081ac13 100644 --- a/Example Apps/Example Swift/ProxyManager.swift +++ b/Example Apps/Example Swift/ProxyManager.swift @@ -28,6 +28,7 @@ class ProxyManager: NSObject { private var performInteractionManager: PerformInteractionManager! private var remoteControlManager: RemoteControlManager! private var firstHMILevelState: SDLHMILevel + private var isRemoteControlEnabled: Bool weak var delegate: ProxyManagerDelegate? @@ -35,6 +36,7 @@ class ProxyManager: NSObject { static let sharedManager = ProxyManager() private override init() { firstHMILevelState = .none + isRemoteControlEnabled = false; super.init() } } @@ -49,6 +51,7 @@ extension ProxyManager { delegate?.didChangeProxyState(ProxyState.searching) sdlManager = SDLManager(configuration: (proxyTransportType == .iap) ? ProxyManager.iapConfiguration : ProxyManager.tcpConfiguration, delegate: self) + self.isRemoteControlEnabled = proxyTransportType == .tcp ? true : false startManager() } @@ -75,7 +78,7 @@ private extension ProxyManager { /// - Returns: A SDLConfiguration object class var iapConfiguration: SDLConfiguration { let lifecycleConfiguration = SDLLifecycleConfiguration(appName: ExampleAppName, fullAppId: ExampleFullAppId) - return setupManagerConfiguration(with: lifecycleConfiguration) + return setupManagerConfiguration(with: lifecycleConfiguration, enableRemote: false) } /// Configures a TCP transport layer with the IP address and port of the remote SDL Core instance. @@ -83,19 +86,25 @@ private extension ProxyManager { /// - Returns: A SDLConfiguration object class var tcpConfiguration: SDLConfiguration { let lifecycleConfiguration = SDLLifecycleConfiguration(appName: ExampleAppName, fullAppId: ExampleFullAppId, ipAddress: AppUserDefaults.shared.ipAddress!, port: UInt16(AppUserDefaults.shared.port!)!) - return setupManagerConfiguration(with: lifecycleConfiguration) + return setupManagerConfiguration(with: lifecycleConfiguration, enableRemote: true) } /// Helper method for setting additional configuration parameters for both TCP and iAP transport layers. /// /// - Parameter lifecycleConfiguration: The transport layer configuration /// - Returns: A SDLConfiguration object - class func setupManagerConfiguration(with lifecycleConfiguration: SDLLifecycleConfiguration) -> SDLConfiguration { + class func setupManagerConfiguration(with lifecycleConfiguration: SDLLifecycleConfiguration, enableRemote: Bool) -> SDLConfiguration { lifecycleConfiguration.shortAppName = ExampleAppNameShort let appIcon = UIImage(named: ExampleAppLogoName)?.withRenderingMode(.alwaysOriginal) lifecycleConfiguration.appIcon = appIcon != nil ? SDLArtwork(image: appIcon!, persistent: true, as: .PNG) : nil lifecycleConfiguration.appType = .default - lifecycleConfiguration.additionalAppTypes = [.remoteControl] + + // On actional hardware, the app requires permissions to do remote control which this example app will not have. + // Only use the remote control type on the TCP connection. + if (enableRemote) { + lifecycleConfiguration.additionalAppTypes = [.remoteControl] + } + lifecycleConfiguration.language = .enUs lifecycleConfiguration.languagesSupported = [.enUs, .esMx, .frCa] lifecycleConfiguration.ttsName = [SDLTTSChunk(text: "S D L", type: .text)] @@ -138,7 +147,7 @@ private extension ProxyManager { self.subscribeButtonManager = SubscribeButtonManager(sdlManager: self.sdlManager) self.vehicleDataManager = VehicleDataManager(sdlManager: self.sdlManager, refreshUIHandler: self.refreshUIHandler) self.performInteractionManager = PerformInteractionManager(sdlManager: self.sdlManager) - self.remoteControlManager = RemoteControlManager(sdlManager: self.sdlManager, homeButtons: self.buttonManager.allScreenSoftButtons()) + self.remoteControlManager = RemoteControlManager(sdlManager: self.sdlManager, permission: self.isRemoteControlEnabled, homeButtons: self.buttonManager.allScreenSoftButtons()) RPCPermissionsManager.setupPermissionsCallbacks(with: self.sdlManager) diff --git a/Example Apps/Example Swift/RemoteControlManager.swift b/Example Apps/Example Swift/RemoteControlManager.swift index 98f3e0cc7..01b66978a 100644 --- a/Example Apps/Example Swift/RemoteControlManager.swift +++ b/Example Apps/Example Swift/RemoteControlManager.swift @@ -18,6 +18,7 @@ class RemoteControlManager { private var hasConsent: Bool? private var climateData: SDLClimateControlData? + public let isPermissionEnabled: Bool public var climateDataString: String { """ AC: \(optionalNumberBoolToString(climateData?.acEnable)) @@ -42,13 +43,20 @@ class RemoteControlManager { /// /// - Parameters: /// - sdlManager: The SDL Manager. + /// - permission: Permission from the proxy manager to access remote control data /// - homeButton: An array of SDLSoftButtonObjects that remote control manager can reset to. - init(sdlManager: SDLManager, homeButtons: [SDLSoftButtonObject]) { + init(sdlManager: SDLManager, permission: Bool, homeButtons: [SDLSoftButtonObject]) { self.sdlManager = sdlManager + self.isPermissionEnabled = permission self.homeButtons = homeButtons } func start() { + if (!self.isPermissionEnabled) { + SDLLog.d("Missing permissions for Remote Control Manager. Example remote control works only on TCP.") + return + } + // Retrieve remote control information and store module ids self.sdlManager.systemCapabilityManager.subscribe(capabilityType: .remoteControl) { (capability, subscribed, error) in guard capability?.remoteControlCapability != nil else { diff --git a/Example Apps/Shared/AppConstants.h b/Example Apps/Shared/AppConstants.h index a2d262235..c460fb434 100644 --- a/Example Apps/Shared/AppConstants.h +++ b/Example Apps/Shared/AppConstants.h @@ -59,6 +59,7 @@ extern NSString * const AlertScrollableMessageCancelledWarningText; extern NSString * const AlertScrollableMessageGeneralWarningText; extern NSString * const AlertVehicleDataPermissionsWarningText; extern NSString * const AlertVehicleDataGeneralWarningText; +extern NSString * const AlertRemoteControlPermissionWarningText; extern NSString * const AlertSpeechPermissionsWarningText; #pragma mark - SDL Text-To-Speech diff --git a/Example Apps/Shared/AppConstants.m b/Example Apps/Shared/AppConstants.m index 21181a8d7..41a549137 100644 --- a/Example Apps/Shared/AppConstants.m +++ b/Example Apps/Shared/AppConstants.m @@ -56,6 +56,7 @@ NSString * const AlertScrollableMessageCancelledWarningText = @"Scrollable Messa NSString * const AlertScrollableMessageGeneralWarningText = @"Scrollable Message could not be displayed"; NSString * const AlertVehicleDataPermissionsWarningText = @"This app does not have the required permissions to access vehicle data"; NSString * const AlertVehicleDataGeneralWarningText = @"Something went wrong while getting vehicle data"; +NSString * const AlertRemoteControlPermissionWarningText = @"This app does not have the required permissions to access remote control data"; NSString * const AlertSpeechPermissionsWarningText = @"You must give this app permission to access Speech Recognition"; #pragma mark - SDL Text-To-Speech |