summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Fischer <joeljfischer@gmail.com>2020-07-09 15:09:29 -0400
committerGitHub <noreply@github.com>2020-07-09 15:09:29 -0400
commit818d2317732f6a4ef1e08b70f3a96e723b4590cc (patch)
tree941d3c23c554a72bc293f36c3ac8f2a4c9ede79f
parentfee59ac0180c9330081add6bfe72d0be37eded87 (diff)
parent6d78493a4a448de1ecec80c953c769ef213a7f1d (diff)
downloadsdl_ios-818d2317732f6a4ef1e08b70f3a96e723b4590cc.tar.gz
Merge pull request #1695 from smartdevicelink/bugfix/issue-1682-tracking-parameter-permissions
Align with Java Suite Permission Manager Parameter Permissions
-rw-r--r--Example Apps/Example ObjC/RPCPermissionsManager.m41
-rw-r--r--Example Apps/Example Swift/RPCPermissionsManager.swift56
-rw-r--r--SmartDeviceLink-iOS.podspec20
-rw-r--r--SmartDeviceLink-iOS.xcodeproj/project.pbxproj30
-rw-r--r--SmartDeviceLink.podspec2
-rw-r--r--SmartDeviceLink/SDLPermissionConstants.h16
-rw-r--r--SmartDeviceLink/SDLPermissionElement.h41
-rw-r--r--SmartDeviceLink/SDLPermissionElement.m41
-rw-r--r--SmartDeviceLink/SDLPermissionFilter.h40
-rw-r--r--SmartDeviceLink/SDLPermissionFilter.m41
-rw-r--r--SmartDeviceLink/SDLPermissionManager.h23
-rw-r--r--SmartDeviceLink/SDLPermissionManager.m143
-rw-r--r--SmartDeviceLink/SDLRPCPermissionStatus.h47
-rw-r--r--SmartDeviceLink/SDLRPCPermissionStatus.m34
-rw-r--r--SmartDeviceLink/SmartDeviceLink.h2
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLPermissionFilterSpec.m176
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLPermissionsManagerSpec.m262
-rw-r--r--SmartDeviceLinkTests/SDLPermissionElementSpec.m59
-rw-r--r--SmartDeviceLinkTests/SDLRPCPermissionStatusSpec.m43
19 files changed, 856 insertions, 261 deletions
diff --git a/Example Apps/Example ObjC/RPCPermissionsManager.m b/Example Apps/Example ObjC/RPCPermissionsManager.m
index d79bde3e2..93d2755e6 100644
--- a/Example Apps/Example ObjC/RPCPermissionsManager.m
+++ b/Example Apps/Example ObjC/RPCPermissionsManager.m
@@ -24,18 +24,23 @@ NS_ASSUME_NONNULL_BEGIN
[self sdlex_checkCurrentPermissionWithManager:manager rpcName:showRPCName];
// Checks if all the RPCs need to create menus are allowed right at this moment
- NSArray<SDLRPCFunctionName> *menuRPCNames = @[SDLRPCFunctionNameAddCommand, SDLRPCFunctionNameCreateInteractionChoiceSet, SDLRPCFunctionNamePerformInteraction];
- [self sdlex_checkCurrentGroupPermissionsWithManager:manager rpcNames:menuRPCNames];
-
- // Set up an observer for permissions changes to media template releated RPCs. Since the `groupType` is set to all allowed, this block is called when the group permissions changes from all allowed. This block is called immediately when created.
- NSArray<SDLRPCFunctionName> *mediaTemplateRPCs = @[SDLRPCFunctionNameSetMediaClockTimer, SDLRPCFunctionNameSubscribeButton];
- SDLPermissionObserverIdentifier allAllowedObserverId = [self sdlex_subscribeGroupPermissionsWithManager:manager rpcNames:mediaTemplateRPCs groupType:SDLPermissionGroupTypeAllAllowed];
+ SDLPermissionElement *addCommandPermissionElement = [[SDLPermissionElement alloc] initWithRPCName:SDLRPCFunctionNameAddCommand parameterPermissions:nil];
+ SDLPermissionElement *createInteractionPermissionElement = [[SDLPermissionElement alloc] initWithRPCName:SDLRPCFunctionNameCreateInteractionChoiceSet parameterPermissions:nil];
+ SDLPermissionElement *performInteractionPermissionElement = [[SDLPermissionElement alloc] initWithRPCName:SDLRPCFunctionNamePerformInteraction parameterPermissions:nil];
+ NSArray<SDLPermissionElement *> *menuRPCPermissions = @[addCommandPermissionElement, createInteractionPermissionElement, performInteractionPermissionElement];
+ [self sdlex_checkCurrentGroupPermissionsWithManager:manager permissionElements:menuRPCPermissions];
+
+ // Set up an observer for permissions changes to media template releated RPCs. Since the `groupType` is set to all allowed, this block is called when the group permissions changes to all-allowed or from all-allowed to some-not-allowed.
+ SDLPermissionElement *setMediaClockPermissionElement = [[SDLPermissionElement alloc] initWithRPCName:SDLRPCFunctionNameSetMediaClockTimer parameterPermissions:nil];
+ SDLPermissionElement *subscribeButtonPermissionElement = [[SDLPermissionElement alloc] initWithRPCName:SDLRPCFunctionNameSubscribeButton parameterPermissions:nil];
+ NSArray<SDLPermissionElement *> *mediaTemplateRPCPermissions = @[setMediaClockPermissionElement, subscribeButtonPermissionElement];
+ SDLPermissionObserverIdentifier allAllowedObserverId = [self sdlex_subscribeGroupPermissionsWithManager:manager permissionElements:mediaTemplateRPCPermissions groupType:SDLPermissionGroupTypeAllAllowed];
// Stop observing permissions changes for the media template releated RPCs
[self sdlex_unsubscribeGroupPermissionsWithManager:manager observerId:allAllowedObserverId];
// Set up an observer for permissions changes to media template releated RPCs. Since the `groupType` is set to any, this block is called when the permission status changes for any of the RPCs being observed. This block is called immediately when created.
- [self sdlex_subscribeGroupPermissionsWithManager:manager rpcNames:mediaTemplateRPCs groupType:SDLPermissionGroupTypeAny];
+ [self sdlex_subscribeGroupPermissionsWithManager:manager permissionElements:mediaTemplateRPCPermissions groupType:SDLPermissionGroupTypeAny];
}
/**
@@ -73,26 +78,26 @@ NS_ASSUME_NONNULL_BEGIN
* @param rpcNames The names of the RPCs
* @return The current permission status for all the RPCs in the group
*/
-+ (SDLPermissionGroupStatus)sdlex_checkCurrentGroupPermissionsWithManager:(SDLManager *)manager rpcNames:(NSArray<SDLRPCFunctionName> *)rpcNames {
- SDLPermissionGroupStatus groupPermissionStatus = [manager.permissionManager groupStatusOfRPCNames:rpcNames];
- NSDictionary<NSString *, NSNumber *> *individualPermissionStatuses = [manager.permissionManager statusesOfRPCNames:rpcNames];
- [self sdlex_logRPCGroupPermissions:rpcNames groupPermissionStatus:groupPermissionStatus individualPermissionStatuses:individualPermissionStatuses];
++ (SDLPermissionGroupStatus)sdlex_checkCurrentGroupPermissionsWithManager:(SDLManager *)manager permissionElements:(NSArray<SDLPermissionElement *> *)permissionElements {
+ SDLPermissionGroupStatus groupPermissionStatus = [manager.permissionManager groupStatusOfRPCPermissions:permissionElements];
+ NSDictionary<NSString *, SDLRPCPermissionStatus *> *individualPermissionStatuses = [manager.permissionManager statusesOfRPCPermissions:permissionElements];
+ [self sdlex_logRPCGroupPermissions:permissionElements groupPermissionStatus:groupPermissionStatus individualPermissionStatuses:individualPermissionStatuses];
return groupPermissionStatus;
}
#pragma mark Subscribe Permissions
/**
- * Sets up a block for observing permission changes for a group of RPCs. This block is called immediately when created and when the permission status changes for the group of RPCs being observed.
+ * Sets up a block for observing permission changes for a group of RPCs. This block is called when the group permissions become all-allowed or from all-allowed to some-not-allowed.
*
* @param manager The SDL Manager
* @param rpcNames The names of the RPCs to be subscribed
* @param groupType The type of changes you want to be notified about for the group
* @return A unique identifier for the subscription. This can be used to later to unsubscribe from the notifications.
*/
-+ (SDLPermissionObserverIdentifier)sdlex_subscribeGroupPermissionsWithManager:(SDLManager *)manager rpcNames:(NSArray<SDLRPCFunctionName> *)rpcNames groupType:(SDLPermissionGroupType)groupType {
- SDLPermissionObserverIdentifier observerId = [manager.permissionManager subscribeToRPCNames:rpcNames groupType:groupType withHandler:^(NSDictionary<SDLPermissionRPCName,NSNumber<SDLBool> *> * _Nonnull change, SDLPermissionGroupStatus status) {
- [self sdlex_logRPCGroupPermissions:rpcNames groupPermissionStatus:status individualPermissionStatuses:change];
++ (SDLPermissionObserverIdentifier)sdlex_subscribeGroupPermissionsWithManager:(SDLManager *)manager permissionElements:(NSArray<SDLPermissionElement *> *)permissionElements groupType:(SDLPermissionGroupType)groupType {
+ SDLPermissionObserverIdentifier observerId = [manager.permissionManager subscribeToRPCPermissions:permissionElements groupType:groupType withHandler:^(NSDictionary<SDLPermissionRPCName,SDLRPCPermissionStatus *> * _Nonnull change, SDLPermissionGroupStatus status) {
+ [self sdlex_logRPCGroupPermissions:permissionElements groupPermissionStatus:status individualPermissionStatuses:change];
}];
return observerId;
}
@@ -126,10 +131,10 @@ NS_ASSUME_NONNULL_BEGIN
* @param groupPermissionStatus The permission status for all RPCs in the group
* @param individualPermissionStatuses The permission status for each of the RPCs in the group
*/
-+ (void)sdlex_logRPCGroupPermissions:(NSArray<NSString *> *)rpcNames groupPermissionStatus:(SDLPermissionGroupStatus)groupPermissionStatus individualPermissionStatuses:(NSDictionary<NSString *, NSNumber *> *)individualPermissionStatuses {
++ (void)sdlex_logRPCGroupPermissions:(NSArray<SDLPermissionElement *> *)rpcNames groupPermissionStatus:(SDLPermissionGroupStatus)groupPermissionStatus individualPermissionStatuses:(NSDictionary<NSString *, SDLRPCPermissionStatus *> *)individualPermissionStatuses {
SDLLogD(@"The group status for %@ has changed to: %lu", rpcNames, (unsigned long)groupPermissionStatus);
- [individualPermissionStatuses enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSNumber * _Nonnull obj, BOOL * _Nonnull stop) {
- [self sdlex_logRPCPermission:key isRPCAllowed:obj.boolValue];
+ [individualPermissionStatuses enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, SDLRPCPermissionStatus * _Nonnull obj, BOOL * _Nonnull stop) {
+ [self sdlex_logRPCPermission:key isRPCAllowed:obj.rpcAllowed];
}];
}
diff --git a/Example Apps/Example Swift/RPCPermissionsManager.swift b/Example Apps/Example Swift/RPCPermissionsManager.swift
index 1efcbe129..144a636f6 100644
--- a/Example Apps/Example Swift/RPCPermissionsManager.swift
+++ b/Example Apps/Example Swift/RPCPermissionsManager.swift
@@ -20,18 +20,23 @@ class RPCPermissionsManager {
_ = checkCurrentPermission(with: manager, rpcName: showRPCName)
// Checks if all the RPCs need to create menus are allowed right at this moment
- let menuRPCNames = [SDLRPCFunctionName.addCommand, SDLRPCFunctionName.createInteractionChoiceSet, SDLRPCFunctionName.performInteraction]
- _ = checkCurrentGroupPermissions(with: manager, rpcNames: menuRPCNames)
-
- // Set up an observer for permissions changes to media template releated RPCs. Since the `groupType` is set to all allowed, this block is called when the group permissions changes from all allowed. This block is called immediately when created.
- let mediaTemplateRPCs = [SDLRPCFunctionName.setMediaClockTimer, SDLRPCFunctionName.subscribeButton]
- let allAllowedObserverId = subscribeGroupPermissions(with: manager, rpcNames: mediaTemplateRPCs, groupType: .allAllowed)
+ let addCommandPermissionElement = SDLPermissionElement(rpcName: SDLRPCFunctionName.addCommand, parameterPermissions: nil)
+ let createInteractionPermissionElement = SDLPermissionElement(rpcName: SDLRPCFunctionName.createInteractionChoiceSet, parameterPermissions: nil)
+ let performInteractionPermissionElement = SDLPermissionElement(rpcName: SDLRPCFunctionName.performInteraction, parameterPermissions: nil)
+ let menuRPCPermissions = [addCommandPermissionElement, createInteractionPermissionElement, performInteractionPermissionElement]
+ _ = checkCurrentGroupPermissions(with: manager, permissionElements: menuRPCPermissions)
+
+ // Set up an observer for permissions changes to media template releated RPCs. Since the `groupType` is set to all allowed, this block is called when the group permissions changes to all-allowed or from all-allowed to some-not-allowed.
+ let setMediaClockPermissionElement = SDLPermissionElement(rpcName: SDLRPCFunctionName.setMediaClockTimer, parameterPermissions: nil)
+ let subscribeButtonPermissionElement = SDLPermissionElement(rpcName: SDLRPCFunctionName.subscribeButton, parameterPermissions: nil)
+ let mediaTemplatePermissions = [setMediaClockPermissionElement, subscribeButtonPermissionElement]
+ let allAllowedObserverId = subscribeGroupPermissions(with: manager, permissionElements: mediaTemplatePermissions, groupType: .allAllowed)
// Stop observing permissions changes for the media template releated RPCs
unsubscribeGroupPermissions(with: manager, observerId: allAllowedObserverId)
// Sets up a block for observing permission changes for a group of RPCs. Since the `groupType` is set to any, this block is called when the permission status changes for any of the RPCs being observed. This block is called immediately when created.
- _ = subscribeGroupPermissions(with: manager, rpcNames: mediaTemplateRPCs, groupType: .any)
+ _ = subscribeGroupPermissions(with: manager, permissionElements: mediaTemplatePermissions, groupType: .any)
}
/// Checks if the `DialNumber` RPC is allowed
@@ -47,24 +52,26 @@ class RPCPermissionsManager {
// MARK: - Check Permissions
private extension RPCPermissionsManager {
- /// Checks if the `Show` RPC is allowed right at this moment
+ /// Checks if the RPC is allowed at the time of the call
///
/// - Parameter manager: The SDL Manager
+ /// - Parameter rpcName: The name of the RPC to check
/// - Returns: true if allowed, false if not
class func checkCurrentPermission(with manager: SDLManager, rpcName: SDLRPCFunctionName) -> Bool {
let isRPCAllowed = manager.permissionManager.isRPCNameAllowed(rpcName)
- logRPCPermission(rpcName: rpcName, isRPCAllowed: isRPCAllowed)
+ SDLLog.d("\(rpcName.rawValue.rawValue) RPC can be sent to SDL Core? \(isRPCAllowed ? "YES" : "NO")")
return isRPCAllowed
}
- /// Checks if all the RPCs need to create menus are allowed right at this moment
+ /// Checks if all the given RPCs are allowed or not at the time of the call
///
/// - Parameter manager: The SDL Manager
- /// - Returns: The rpc names, the group permission status and the permission status for each rpc in the group
- class func checkCurrentGroupPermissions(with manager: SDLManager, rpcNames: [SDLRPCFunctionName]) -> SDLPermissionGroupStatus {
- let groupPermissionStatus = manager.permissionManager.groupStatus(ofRPCNames: rpcNames)
- let individualPermissionStatuses = manager.permissionManager.statuses(ofRPCNames: rpcNames)
- logRPCGroupPermissions(rpcNames: rpcNames, groupPermissionStatus: groupPermissionStatus, individualPermissionStatuses: individualPermissionStatuses)
+ /// - Parameter permissionElements: The RPCs and parameters to be checked
+ /// - Returns: The group permission status
+ class func checkCurrentGroupPermissions(with manager: SDLManager, permissionElements: [SDLPermissionElement]) -> SDLPermissionGroupStatus {
+ let groupPermissionStatus = manager.permissionManager.groupStatus(ofRPCPermissions: permissionElements)
+ let individualPermissionStatuses = manager.permissionManager.statuses(ofRPCPermissions: permissionElements)
+ logRPCGroupPermissions(permissionElements: permissionElements, groupPermissionStatus: groupPermissionStatus, individualPermissionStatuses: individualPermissionStatuses)
return groupPermissionStatus
}
@@ -73,10 +80,11 @@ private extension RPCPermissionsManager {
/// - Parameters:
/// - manager: The SDL Manager
/// - groupType: The type of changes to get notified about
+ /// - permissionElements: The RPCs and parameters to be checked
/// - Returns: A unique id assigned to observer. Use the id to unsubscribe to notifications
- class func subscribeGroupPermissions(with manager: SDLManager, rpcNames: [SDLRPCFunctionName], groupType: SDLPermissionGroupType) -> UUID {
- let permissionAllAllowedObserverId = manager.permissionManager.subscribe(toRPCNames: rpcNames, groupType: groupType, withHandler: { (individualStatuses, groupStatus) in
- self.logRPCGroupPermissions(rpcNames: rpcNames, groupPermissionStatus: groupStatus, individualPermissionStatuses: individualStatuses)
+ class func subscribeGroupPermissions(with manager: SDLManager, permissionElements: [SDLPermissionElement], groupType: SDLPermissionGroupType) -> UUID {
+ let permissionAllAllowedObserverId = manager.permissionManager.subscribe(toRPCPermissions: permissionElements, groupType: groupType, withHandler: { (individualStatuses, groupStatus) in
+ self.logRPCGroupPermissions(permissionElements: permissionElements, groupPermissionStatus: groupStatus, individualPermissionStatuses: individualStatuses)
})
return permissionAllAllowedObserverId
@@ -100,8 +108,8 @@ private extension RPCPermissionsManager {
/// - Parameters:
/// - rpcName: The name of the RPC
/// - isRPCAllowed: The permission status for the RPC
- class func logRPCPermission(rpcName: SDLRPCFunctionName, isRPCAllowed: Bool) {
- SDLLog.d("\(rpcName.rawValue.rawValue) RPC can be sent to SDL Core? \(isRPCAllowed ? "yes" : "no")")
+ class func logRPCPermission(status: SDLRPCPermissionStatus) {
+ SDLLog.d("\(status.rpcName.rawValue.rawValue) RPC can be sent to SDL Core? \(status.isRPCAllowed ? "YES" : "NO"), parameters: \(status.rpcParameters ?? [:])")
}
/// Logs permissions for a group of RPCs
@@ -110,10 +118,10 @@ private extension RPCPermissionsManager {
/// - rpcNames: The names of the RPCs
/// - groupPermissionStatus: The permission status for all RPCs in the group
/// - individualPermissionStatuses: The permission status for each of the RPCs in the group
- class func logRPCGroupPermissions(rpcNames: [SDLRPCFunctionName], groupPermissionStatus: SDLPermissionGroupStatus, individualPermissionStatuses: [SDLRPCFunctionName:NSNumber]) {
- SDLLog.d("The group status for \(rpcNames.map { $0.rawValue.rawValue } ) has changed to: \(groupPermissionStatus.rawValue)")
- for (rpcName, rpcAllowed) in individualPermissionStatuses {
- logRPCPermission(rpcName: rpcName, isRPCAllowed: rpcAllowed.boolValue)
+ class func logRPCGroupPermissions(permissionElements: [SDLPermissionElement], groupPermissionStatus: SDLPermissionGroupStatus, individualPermissionStatuses: [SDLRPCFunctionName: SDLRPCPermissionStatus]) {
+ SDLLog.d("The group status for \(permissionElements.map { $0.rpcName.rawValue } ) has changed to: \(groupPermissionStatus.rawValue)")
+ for (_, status) in individualPermissionStatuses {
+ logRPCPermission(status: status)
}
}
}
diff --git a/SmartDeviceLink-iOS.podspec b/SmartDeviceLink-iOS.podspec
index 3c591e152..d1f247ff7 100644
--- a/SmartDeviceLink-iOS.podspec
+++ b/SmartDeviceLink-iOS.podspec
@@ -42,8 +42,8 @@ ss.public_header_files = [
'SmartDeviceLink/SDLArtwork.h',
'SmartDeviceLink/SDLAudioControlData.h',
'SmartDeviceLink/SDLAudioControlCapabilities.h',
-'SmartDeviceLink/SDLAudioFile.h',
'SmartDeviceLink/SDLAudioPassThruCapabilities.h',
+'SmartDeviceLink/SDLAudioFile.h',
'SmartDeviceLink/SDLAudioStreamingState.h',
'SmartDeviceLink/SDLAudioStreamingIndicator.h',
'SmartDeviceLink/SDLAudioStreamManager.h',
@@ -104,12 +104,12 @@ ss.public_header_files = [
'SmartDeviceLink/SDLDialNumberResponse.h',
'SmartDeviceLink/SDLDIDResult.h',
'SmartDeviceLink/SDLDimension.h',
+'SmartDeviceLink/SDLDirection.h',
'SmartDeviceLink/SDLDisplayCapability.h',
'SmartDeviceLink/SDLDisplayCapabilities.h',
'SmartDeviceLink/SDLDisplayMode.h',
'SmartDeviceLink/SDLDisplayType.h',
'SmartDeviceLink/SDLDistanceUnit.h',
-'SmartDeviceLink/SDLDirection.h',
'SmartDeviceLink/SDLDriverDistractionState.h',
'SmartDeviceLink/SDLECallConfirmationStatus.h',
'SmartDeviceLink/SDLECallInfo.h',
@@ -134,11 +134,11 @@ ss.public_header_files = [
'SmartDeviceLink/SDLFuelType.h',
'SmartDeviceLink/SDLFunctionID.h',
'SmartDeviceLink/SDLGenericResponse.h',
-'SmartDeviceLink/SDLGetCloudAppProperties.h',
-'SmartDeviceLink/SDLGetCloudAppPropertiesResponse.h',
'SmartDeviceLink/SDLGetAppServiceData.h',
'SmartDeviceLink/SDLGetAppServiceDataResponse.h',
'SmartDeviceLink/SDLGetDTCs.h',
+'SmartDeviceLink/SDLGetCloudAppProperties.h',
+'SmartDeviceLink/SDLGetCloudAppPropertiesResponse.h',
'SmartDeviceLink/SDLGetDTCsResponse.h',
'SmartDeviceLink/SDLGetFile.h',
'SmartDeviceLink/SDLGetFileResponse.h',
@@ -204,15 +204,15 @@ ss.public_header_files = [
'SmartDeviceLink/SDLLogTargetAppleSystemLog.h',
'SmartDeviceLink/SDLLogTargetFile.h',
'SmartDeviceLink/SDLLogTargetOSLog.h',
+'SmartDeviceLink/SDLMacros.h',
+'SmartDeviceLink/SDLMaintenanceModeStatus.h',
+'SmartDeviceLink/SDLManager.h',
+'SmartDeviceLink/SDLManagerDelegate.h',
'SmartDeviceLink/SDLMassageCushionFirmness.h',
'SmartDeviceLink/SDLMassageModeData.h',
'SmartDeviceLink/SDLMassageCushion.h',
'SmartDeviceLink/SDLMassageMode.h',
'SmartDeviceLink/SDLMassageZone.h',
-'SmartDeviceLink/SDLMacros.h',
-'SmartDeviceLink/SDLMaintenanceModeStatus.h',
-'SmartDeviceLink/SDLManager.h',
-'SmartDeviceLink/SDLManagerDelegate.h',
'SmartDeviceLink/SDLMediaClockFormat.h',
'SmartDeviceLink/SDLMediaServiceData.h',
'SmartDeviceLink/SDLMediaServiceManifest.h',
@@ -267,6 +267,7 @@ ss.public_header_files = [
'SmartDeviceLink/SDLPerformInteraction.h',
'SmartDeviceLink/SDLPerformInteractionResponse.h',
'SmartDeviceLink/SDLPermissionConstants.h',
+'SmartDeviceLink/SDLPermissionElement.h',
'SmartDeviceLink/SDLPermissionItem.h',
'SmartDeviceLink/SDLPermissionManager.h',
'SmartDeviceLink/SDLPermissionStatus.h',
@@ -309,6 +310,7 @@ ss.public_header_files = [
'SmartDeviceLink/SDLRPCMessageType.h',
'SmartDeviceLink/SDLRPCNotification.h',
'SmartDeviceLink/SDLRPCNotificationNotification.h',
+'SmartDeviceLink/SDLRPCPermissionStatus.h',
'SmartDeviceLink/SDLRPCRequest.h',
'SmartDeviceLink/SDLRPCRequestNotification.h',
'SmartDeviceLink/SDLRPCResponse.h',
@@ -325,7 +327,6 @@ ss.public_header_files = [
'SmartDeviceLink/SDLSeatLocationCapability.h',
'SmartDeviceLink/SDLSeatMemoryAction.h',
'SmartDeviceLink/SDLSeatMemoryActionType.h',
-'SmartDeviceLink/SDLSupportedSeat.h',
'SmartDeviceLink/SDLSecurityType.h',
'SmartDeviceLink/SDLSendHapticData.h',
'SmartDeviceLink/SDLSendHapticDataResponse.h',
@@ -377,6 +378,7 @@ ss.public_header_files = [
'SmartDeviceLink/SDLSubscribeVehicleDataResponse.h',
'SmartDeviceLink/SDLSubscribeWaypoints.h',
'SmartDeviceLink/SDLSubscribeWaypointsResponse.h',
+'SmartDeviceLink/SDLSupportedSeat.h',
'SmartDeviceLink/SDLSyncMsgVersion.h',
'SmartDeviceLink/SDLMsgVersion.h',
'SmartDeviceLink/SDLSyncPData.h',
diff --git a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
index 87c3e38bc..97e696dd1 100644
--- a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
+++ b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
@@ -38,11 +38,18 @@
00E22CED22C2F1B300BC6B08 /* SDLEncryptionConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 00E22CEB22C2F1B300BC6B08 /* SDLEncryptionConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; };
00EADD3322DFE54B0088B608 /* SDLEncryptionLifecycleManagerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 00EADD3222DFE54B0088B608 /* SDLEncryptionLifecycleManagerSpec.m */; };
00EADD3522DFE5670088B608 /* SDLEncryptionConfigurationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 00EADD3422DFE5670088B608 /* SDLEncryptionConfigurationSpec.m */; };
+ 106187B924AA75540045C4EC /* SDLRPCPermissionStatusSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 106187B824AA75540045C4EC /* SDLRPCPermissionStatusSpec.m */; };
+ 106187BA24AA76550045C4EC /* SDLRPCPermissionStatus.h in Headers */ = {isa = PBXBuildFile; fileRef = 106982A824AA3B4700B1F649 /* SDLRPCPermissionStatus.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 106412C6249FB80B0069A97A /* SDLPermissionElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 106412C4249FB80B0069A97A /* SDLPermissionElement.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 106412C7249FB80B0069A97A /* SDLPermissionElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 106412C5249FB80B0069A97A /* SDLPermissionElement.m */; };
+ 106412C824A13F160069A97A /* SDLPermissionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D8204241BCEA8A600D0A41B /* SDLPermissionManager.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 106982AB24AA3B4700B1F649 /* SDLRPCPermissionStatus.m in Sources */ = {isa = PBXBuildFile; fileRef = 106982A924AA3B4700B1F649 /* SDLRPCPermissionStatus.m */; };
10893C162417D78300BA347E /* SDLIconArchiveFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 10893C142417D78300BA347E /* SDLIconArchiveFile.h */; };
10893C172417D78300BA347E /* SDLIconArchiveFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 10893C152417D78300BA347E /* SDLIconArchiveFile.m */; };
10893C1A2418188600BA347E /* SDLCacheFileManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 10893C182418188600BA347E /* SDLCacheFileManager.h */; };
10893C1B2418188600BA347E /* SDLCacheFileManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10893C192418188600BA347E /* SDLCacheFileManager.m */; };
109566F6242986F300E24F66 /* SDLCacheFileManagerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 109566F5242986F300E24F66 /* SDLCacheFileManagerSpec.m */; };
+ 1098F03824A39699004F53CC /* SDLPermissionElementSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 1098F03724A39699004F53CC /* SDLPermissionElementSpec.m */; };
162E82CA1A9BDE8A00906325 /* SDLAmbientLightStatusSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 162E81E21A9BDE8A00906325 /* SDLAmbientLightStatusSpec.m */; };
162E82CB1A9BDE8A00906325 /* SDLAppHMITypeSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 162E81E31A9BDE8A00906325 /* SDLAppHMITypeSpec.m */; };
162E82CC1A9BDE8A00906325 /* SDLAppInterfaceUnregisteredReasonSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 162E81E41A9BDE8A00906325 /* SDLAppInterfaceUnregisteredReasonSpec.m */; };
@@ -782,7 +789,7 @@
5D61FCF91A84238C00846EE7 /* SDLMenuParams.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D61FB0C1A84238A00846EE7 /* SDLMenuParams.m */; };
5D61FCFA1A84238C00846EE7 /* SDLMyKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D61FB0D1A84238A00846EE7 /* SDLMyKey.h */; settings = {ATTRIBUTES = (Public, ); }; };
5D61FCFB1A84238C00846EE7 /* SDLMyKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D61FB0E1A84238A00846EE7 /* SDLMyKey.m */; };
- 5D61FCFC1A84238C00846EE7 /* SDLRPCParameterNames.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D61FB0F1A84238A00846EE7 /* SDLRPCParameterNames.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 5D61FCFC1A84238C00846EE7 /* SDLRPCParameterNames.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D61FB0F1A84238A00846EE7 /* SDLRPCParameterNames.h */; };
5D61FCFD1A84238C00846EE7 /* SDLObjectWithPriority.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D61FB101A84238A00846EE7 /* SDLObjectWithPriority.h */; };
5D61FCFE1A84238C00846EE7 /* SDLObjectWithPriority.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D61FB111A84238A00846EE7 /* SDLObjectWithPriority.m */; };
5D61FCFF1A84238C00846EE7 /* SDLOnAppInterfaceUnregistered.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D61FB121A84238B00846EE7 /* SDLOnAppInterfaceUnregistered.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -1084,7 +1091,6 @@
5D82041F1BCD8E6100D0A41B /* SDLConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D82041D1BCD8E6100D0A41B /* SDLConfiguration.m */; };
5D8204221BCEA89A00D0A41B /* SDLFileManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D8204201BCEA89A00D0A41B /* SDLFileManager.h */; settings = {ATTRIBUTES = (Public, ); }; };
5D8204231BCEA89A00D0A41B /* SDLFileManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D8204211BCEA89A00D0A41B /* SDLFileManager.m */; };
- 5D8204261BCEA8A600D0A41B /* SDLPermissionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D8204241BCEA8A600D0A41B /* SDLPermissionManager.h */; settings = {ATTRIBUTES = (Public, ); }; };
5D8204271BCEA8A600D0A41B /* SDLPermissionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D8204251BCEA8A600D0A41B /* SDLPermissionManager.m */; };
5D82042D1BCEC32F00D0A41B /* SDLFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D82042B1BCEC32F00D0A41B /* SDLFile.h */; settings = {ATTRIBUTES = (Public, ); }; };
5D82042E1BCEC32F00D0A41B /* SDLFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D82042C1BCEC32F00D0A41B /* SDLFile.m */; };
@@ -1775,11 +1781,17 @@
00E22CEB22C2F1B300BC6B08 /* SDLEncryptionConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLEncryptionConfiguration.h; sourceTree = "<group>"; };
00EADD3222DFE54B0088B608 /* SDLEncryptionLifecycleManagerSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLEncryptionLifecycleManagerSpec.m; sourceTree = "<group>"; };
00EADD3422DFE5670088B608 /* SDLEncryptionConfigurationSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLEncryptionConfigurationSpec.m; sourceTree = "<group>"; };
+ 106187B824AA75540045C4EC /* SDLRPCPermissionStatusSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLRPCPermissionStatusSpec.m; sourceTree = "<group>"; };
+ 106412C4249FB80B0069A97A /* SDLPermissionElement.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLPermissionElement.h; sourceTree = "<group>"; };
+ 106412C5249FB80B0069A97A /* SDLPermissionElement.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLPermissionElement.m; sourceTree = "<group>"; };
+ 106982A824AA3B4700B1F649 /* SDLRPCPermissionStatus.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLRPCPermissionStatus.h; sourceTree = "<group>"; };
+ 106982A924AA3B4700B1F649 /* SDLRPCPermissionStatus.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLRPCPermissionStatus.m; sourceTree = "<group>"; };
10893C142417D78300BA347E /* SDLIconArchiveFile.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLIconArchiveFile.h; sourceTree = "<group>"; };
10893C152417D78300BA347E /* SDLIconArchiveFile.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLIconArchiveFile.m; sourceTree = "<group>"; };
10893C182418188600BA347E /* SDLCacheFileManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLCacheFileManager.h; sourceTree = "<group>"; };
10893C192418188600BA347E /* SDLCacheFileManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLCacheFileManager.m; sourceTree = "<group>"; };
109566F5242986F300E24F66 /* SDLCacheFileManagerSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLCacheFileManagerSpec.m; sourceTree = "<group>"; };
+ 1098F03724A39699004F53CC /* SDLPermissionElementSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLPermissionElementSpec.m; sourceTree = "<group>"; };
162E81E21A9BDE8A00906325 /* SDLAmbientLightStatusSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLAmbientLightStatusSpec.m; sourceTree = "<group>"; };
162E81E31A9BDE8A00906325 /* SDLAppHMITypeSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLAppHMITypeSpec.m; sourceTree = "<group>"; };
162E81E41A9BDE8A00906325 /* SDLAppInterfaceUnregisteredReasonSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLAppInterfaceUnregisteredReasonSpec.m; sourceTree = "<group>"; };
@@ -5665,6 +5677,10 @@
5D1665C71CF8CA3D00CC4CA1 /* SDLPermissionFilter.m */,
5D8204241BCEA8A600D0A41B /* SDLPermissionManager.h */,
5D8204251BCEA8A600D0A41B /* SDLPermissionManager.m */,
+ 106412C4249FB80B0069A97A /* SDLPermissionElement.h */,
+ 106412C5249FB80B0069A97A /* SDLPermissionElement.m */,
+ 106982A824AA3B4700B1F649 /* SDLRPCPermissionStatus.h */,
+ 106982A924AA3B4700B1F649 /* SDLRPCPermissionStatus.m */,
);
name = Permissions;
sourceTree = "<group>";
@@ -5754,6 +5770,8 @@
children = (
5D9F50801BE7E6E300FEF399 /* SDLPermissionsManagerSpec.m */,
5DB1BCD71D243AA6002FFC37 /* SDLPermissionFilterSpec.m */,
+ 1098F03724A39699004F53CC /* SDLPermissionElementSpec.m */,
+ 106187B824AA75540045C4EC /* SDLRPCPermissionStatusSpec.m */,
);
name = Permissions;
sourceTree = "<group>";
@@ -6695,6 +6713,8 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
+ 106412C824A13F160069A97A /* SDLPermissionManager.h in Headers */,
+ 106412C6249FB80B0069A97A /* SDLPermissionElement.h in Headers */,
9F425AD222DD980200BE3245 /* SDLWindowCapability.h in Headers */,
9F425ADA22DD983500BE3245 /* SDLDisplayCapability.h in Headers */,
9F425ACE22DD97DE00BE3245 /* SDLTemplateConfiguration.h in Headers */,
@@ -7033,7 +7053,6 @@
1FF7DAB81F75B28E00B46C30 /* SDLFocusableItemHitTester.h in Headers */,
5D61FC3D1A84238C00846EE7 /* SDLAlertResponse.h in Headers */,
5D61FDAD1A84238C00846EE7 /* SDLSubscribeButton.h in Headers */,
- 5D8204261BCEA8A600D0A41B /* SDLPermissionManager.h in Headers */,
5D61FCF41A84238C00846EE7 /* SDLMaintenanceModeStatus.h in Headers */,
5D61FC571A84238C00846EE7 /* SDLButtonPressMode.h in Headers */,
5D3E487B1D6F888E0000BFEF /* SDLRPCResponseNotification.h in Headers */,
@@ -7131,6 +7150,7 @@
1E5AD04C1F1F79640029B8AF /* SDLDefrostZone.h in Headers */,
1E5AD0601F207AB10029B8AF /* SDLRadioState.h in Headers */,
1E5AD0801F20B73E0029B8AF /* SDLButtonPress.h in Headers */,
+ 106187BA24AA76550045C4EC /* SDLRPCPermissionStatus.h in Headers */,
884554AC222453A800BAFB6C /* SDLNavigationServiceManifest.h in Headers */,
8816772C222097C3001FACFF /* SDLNavigationServiceData.h in Headers */,
1E5AD05C1F2064A80029B8AF /* SDLRDSData.h in Headers */,
@@ -7659,6 +7679,7 @@
5D61FDB21A84238C00846EE7 /* SDLSubscribeVehicleData.m in Sources */,
5D61FC991A84238C00846EE7 /* SDLECallInfo.m in Sources */,
5D61FD601A84238C00846EE7 /* SDLRegisterAppInterfaceResponse.m in Sources */,
+ 106982AB24AA3B4700B1F649 /* SDLRPCPermissionStatus.m in Sources */,
5DB996581F268ECB002D8795 /* SDLControlFramePayloadAudioStartServiceAck.m in Sources */,
DAC572621D10C5020004288B /* SDLPinchGesture.m in Sources */,
1EAA471A203406B2000FE74B /* SDLSISData.m in Sources */,
@@ -7866,6 +7887,7 @@
1E5AD0511F1F7BF10029B8AF /* SDLRadioBand.m in Sources */,
88B3BF9D20DA8BBC00943565 /* SDLFuelRange.m in Sources */,
5D61FDDC1A84238C00846EE7 /* SDLTriggerSource.m in Sources */,
+ 106412C7249FB80B0069A97A /* SDLPermissionElement.m in Sources */,
5DADA7761F4DFED60084D17D /* SDLRectangle.m in Sources */,
88EED83F1F33C5A400E6C42E /* SDLSendHapticData.m in Sources */,
5D16545B1D3E7A1600554D93 /* SDLLifecycleManager.m in Sources */,
@@ -8162,6 +8184,7 @@
162E83281A9BDE8B00906325 /* SDLDeleteCommandSpec.m in Sources */,
88A81F6C2200FD4A00A691A9 /* SDLAppServiceRecordSpec.m in Sources */,
162E83531A9BDE8B00906325 /* SDLDiagnosticMessageResponseSpec.m in Sources */,
+ 106187B924AA75540045C4EC /* SDLRPCPermissionStatusSpec.m in Sources */,
8881AFB52225E37800EA870B /* SDLSetCloudAppPropertiesResponseSpec.m in Sources */,
162E83671A9BDE8B00906325 /* SDLSliderResponseSpec.m in Sources */,
8877F5F11F34AA2D00DC128A /* SDLSendHapticDataResponseSpec.m in Sources */,
@@ -8258,6 +8281,7 @@
162E82DE1A9BDE8B00906325 /* SDLFuelCutoffStatusSpec.m in Sources */,
162E83271A9BDE8B00906325 /* SDLCreateInteractionChoiceSetSpec.m in Sources */,
5DAD5F8920508F090025624C /* SDLSoftButtonStateSpec.m in Sources */,
+ 1098F03824A39699004F53CC /* SDLPermissionElementSpec.m in Sources */,
9FA0D01222DF0BAC009CF344 /* SDLDeleteWindowResponseSpec.m in Sources */,
162E83111A9BDE8B00906325 /* SDLOnButtonEventSpec.m in Sources */,
1FF7DAC01F75CF6C00B46C30 /* SDLHapticManagerSpec.m in Sources */,
diff --git a/SmartDeviceLink.podspec b/SmartDeviceLink.podspec
index a525183f5..9cc66bd1d 100644
--- a/SmartDeviceLink.podspec
+++ b/SmartDeviceLink.podspec
@@ -268,6 +268,7 @@ sdefault.public_header_files = [
'SmartDeviceLink/SDLPerformInteraction.h',
'SmartDeviceLink/SDLPerformInteractionResponse.h',
'SmartDeviceLink/SDLPermissionConstants.h',
+'SmartDeviceLink/SDLPermissionElement.h',
'SmartDeviceLink/SDLPermissionItem.h',
'SmartDeviceLink/SDLPermissionManager.h',
'SmartDeviceLink/SDLPermissionStatus.h',
@@ -310,6 +311,7 @@ sdefault.public_header_files = [
'SmartDeviceLink/SDLRPCMessageType.h',
'SmartDeviceLink/SDLRPCNotification.h',
'SmartDeviceLink/SDLRPCNotificationNotification.h',
+'SmartDeviceLink/SDLRPCPermissionStatus.h',
'SmartDeviceLink/SDLRPCRequest.h',
'SmartDeviceLink/SDLRPCRequestNotification.h',
'SmartDeviceLink/SDLRPCResponse.h',
diff --git a/SmartDeviceLink/SDLPermissionConstants.h b/SmartDeviceLink/SDLPermissionConstants.h
index 05b528bfd..2cd9bbc4e 100644
--- a/SmartDeviceLink/SDLPermissionConstants.h
+++ b/SmartDeviceLink/SDLPermissionConstants.h
@@ -10,6 +10,8 @@
#import "NSNumber+NumberType.h"
#import "SDLRPCFunctionNames.h"
+#import "SDLPermissionElement.h"
+#import "SDLRPCPermissionStatus.h"
NS_ASSUME_NONNULL_BEGIN
@@ -60,19 +62,19 @@ typedef NS_ENUM(NSUInteger, SDLPermissionGroupStatus) {
};
/**
- * The PermissionObserver is a block that is passed in to some methods that will be stored and called when specified permissions change.
+ * This is a block that is passed in to some methods that will be stored and called when specified permissions change.
*
- * @param change A dictionary of permission changes containing <key(String): RPC Name, object(BOOL): YES if the RPC is allowed, NO if it is not allowed>
- * @param status The change made to all of the RPCs in the changedDict. Allowed, if all RPCs are now allowed, Disallowed if all RPCs are now disallowed, or Mixed if some are allowed, and some are disallowed
+ * @param change A dictionary of permission changes containing <key(String): RPC Name, object(BOOL): YES if the RPC is allowed, NO if it is not allowed>
+ * @param status The unified group status of the RPCs in the change dictionary. Allowed, if all RPCs are now allowed, Disallowed if all RPCs are now disallowed, or Mixed if some are allowed, and some are disallowed
*/
typedef void (^SDLPermissionsChangedHandler)(NSDictionary<SDLPermissionRPCName, NSNumber *> *_Nonnull change, SDLPermissionGroupStatus status);
/**
- * The SDLObservedPermissionsChangedHandler is a block that is passed in to subscribeToRPCNames:groupType:withHandler: that will be stored and called when specified permissions change.
+ * A block that will be called when specified permissions change. It will return whether each RPC and its parameters are allowed as well as the permission group status of all the RPCs.
*
- * @param change A dictionary of permission changes containing <key(SDLRPCFunctionName): RPC Name, object(BOOL): YES if the RPC is allowed, NO if it is not allowed>
- * @param status The change made to all of the RPCs in the changedDict. Allowed, if all RPCs are now allowed, Disallowed if all RPCs are now disallowed, or Mixed if some are allowed, and some are disallowed
+ * @param change A dictionary of permission changes containing <key(String): SDLPermissionRPCName, object(SDLRPCPermissionStatus)>
+ * @param status The change made to all of the RPCs in the change dictionary. Allowed, if all RPCs are now allowed, Disallowed if all RPCs are now disallowed, or Mixed if some are allowed, and some are disallowed
*/
-typedef void (^SDLSubscribedPermissionsChangedHandler)(NSDictionary<SDLRPCFunctionName, NSNumber *> *_Nonnull change, SDLPermissionGroupStatus status);
+typedef void (^SDLRPCPermissionStatusChangedHandler)(NSDictionary<SDLRPCFunctionName, SDLRPCPermissionStatus *> *_Nonnull change, SDLPermissionGroupStatus status);
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLPermissionElement.h b/SmartDeviceLink/SDLPermissionElement.h
new file mode 100644
index 000000000..94006234f
--- /dev/null
+++ b/SmartDeviceLink/SDLPermissionElement.h
@@ -0,0 +1,41 @@
+//
+// SDLPermissionElement.h
+// SmartDeviceLink
+//
+// Created by James Lapinski on 6/21/20.
+// Copyright © 2020 smartdevicelink. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+#import "SDLParameterPermissions.h"
+#import "SDLRPCFunctionNames.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface SDLPermissionElement : NSObject <NSCopying>
+
+/**
+ * Name of the individual RPC.
+ * Required
+ */
+@property (strong, nonatomic) SDLRPCFunctionName rpcName;
+
+/**
+ * RPC parameters for the individual RPC
+ */
+@property (strong, nonatomic, nullable) NSArray<NSString *> *parameterPermissions;
+
+/**
+ * Creates a new permission element.
+ *
+ * @param rpcName The name of the RPC.
+ * @param parameterPermissions An array parameters for the RPC that should be checked if they are allowed. Note that not all head units may provide this data. If no parameter data is received, we assume that the parameter is not allowed.
+ *
+ * @return An instance of `SDLPermissionElement`.
+ */
+- (instancetype)initWithRPCName:(SDLRPCFunctionName)rpcName parameterPermissions:(nullable NSArray<NSString *> *)parameterPermissions;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLPermissionElement.m b/SmartDeviceLink/SDLPermissionElement.m
new file mode 100644
index 000000000..ea2aa6e4e
--- /dev/null
+++ b/SmartDeviceLink/SDLPermissionElement.m
@@ -0,0 +1,41 @@
+//
+// SDLPermissionElement.m
+// SmartDeviceLink
+//
+// Created by James Lapinski on 6/21/20.
+// Copyright © 2020 smartdevicelink. All rights reserved.
+//
+
+#import "SDLPermissionElement.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@implementation SDLPermissionElement
+
+- (instancetype)initWithRPCName:(SDLRPCFunctionName)rpcName parameterPermissions:(nullable NSArray<NSString *> *)parameterPermissions {
+ self = [super init];
+ if (!self) { return nil; }
+
+ self.rpcName = rpcName;
+ self.parameterPermissions = parameterPermissions;
+
+ return self;
+}
+
+#pragma mark - NSCopying
+
+- (id)copyWithZone:(nullable NSZone *)zone {
+ SDLPermissionElement *newElement = [[self.class allocWithZone:zone] initWithRPCName:[_rpcName copyWithZone:zone] parameterPermissions:[_parameterPermissions copyWithZone:zone]];
+
+ return newElement;
+}
+
+#pragma mark - Description
+
+- (NSString *)description {
+ return [NSString stringWithFormat:@"RPC name: %@, parameter permissions: %@", self.rpcName, self.parameterPermissions];
+}
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLPermissionFilter.h b/SmartDeviceLink/SDLPermissionFilter.h
index f31666bec..e733d2331 100644
--- a/SmartDeviceLink/SDLPermissionFilter.h
+++ b/SmartDeviceLink/SDLPermissionFilter.h
@@ -9,6 +9,7 @@
#import <Foundation/Foundation.h>
#import "SDLPermissionConstants.h"
+#import "SDLPermissionElement.h"
NS_ASSUME_NONNULL_BEGIN
@@ -21,11 +22,6 @@ NS_ASSUME_NONNULL_BEGIN
@property (copy, nonatomic, readonly) SDLPermissionObserverIdentifier identifier;
/**
- * All of the RPC names in this filter group.
- */
-@property (copy, nonatomic, readonly) NSArray<SDLPermissionRPCName> *rpcNames;
-
-/**
* The type of this filter group.
*/
@property (assign, nonatomic, readonly) SDLPermissionGroupType groupType;
@@ -36,7 +32,20 @@ NS_ASSUME_NONNULL_BEGIN
@property (copy, nonatomic, readonly) SDLPermissionsChangedHandler handler;
/**
- * Create a new permission filter group.
+ * The block that will be called on status changes to RPC permission status objects
+ */
+@property (copy, nonatomic, readonly) SDLRPCPermissionStatusChangedHandler rpcPermissionStatusHandler;
+
+/**
+ * All of the permission elements in this filter group.
+ */
+@property (copy, nonatomic, readonly) NSArray<SDLPermissionElement *> *permissionElements;
+
+/// Initializer unavailable
+- (instancetype)init NS_UNAVAILABLE;
+
+/**
+ * Create a new permission filter group with a SDLPermissionsChangedHandler.
*
* @param rpcNames The names of the RPCs to watch permissions of.
* @param groupType The type of notifications to be sent for this filter group.
@@ -44,18 +53,18 @@ NS_ASSUME_NONNULL_BEGIN
*
* @return An instance of `SDLPermissionFilter`.
*/
-- (instancetype)initWithRPCNames:(NSArray<SDLPermissionRPCName> *)rpcNames groupType:(SDLPermissionGroupType)groupType observer:(SDLPermissionsChangedHandler)handler NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithPermissions:(NSArray<SDLPermissionElement *> *)rpcNames groupType:(SDLPermissionGroupType)groupType permissionsHandler:(SDLPermissionsChangedHandler)handler;
/**
- * Create a new permission filter group.
+ * Create a new permission filter group with a SDLRPCPermissionStatusChangedHandler.
*
- * @param rpcNames The names of the RPCs to watch permissions of.
+ * @param rpcNames The names of the RPCs to watch permissions of.
* @param groupType The type of notifications to be sent for this filter group.
- * @param handler The block observer to be called when changes occur.
+ * @param permissionStatusHandler The block observer to be called when changes occur.
*
* @return An instance of `SDLPermissionFilter`.
*/
-+ (instancetype)filterWithRPCNames:(NSArray<SDLPermissionRPCName> *)rpcNames groupType:(SDLPermissionGroupType)groupType observer:(SDLPermissionsChangedHandler)handler NS_SWIFT_UNAVAILABLE("Use the initializer");
+- (instancetype)initWithPermissions:(NSArray<SDLPermissionElement *> *)rpcNames groupType:(SDLPermissionGroupType)groupType permissionStatusHandler:(SDLRPCPermissionStatusChangedHandler)permissionStatusHandler;
/**
* Whether the current filter is equivalent with another filter or not.
@@ -66,6 +75,15 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (BOOL)isEqualToFilter:(SDLPermissionFilter *)otherFilter;
+/**
+ * Converts an array of SDLPermissionElement objects to an array of SDLPermissionRPCName objects
+ *
+ * @param permissionElements The permission elements to convert.
+ *
+ * @return An array of SDLPermissionRPCName objects
+ */
+- (NSArray<SDLPermissionRPCName> *)rpcNamesFromPermissionElements:(NSArray<SDLPermissionElement *> *)permissionElements;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLPermissionFilter.m b/SmartDeviceLink/SDLPermissionFilter.m
index 0d142b3a3..c2ed47a3e 100644
--- a/SmartDeviceLink/SDLPermissionFilter.m
+++ b/SmartDeviceLink/SDLPermissionFilter.m
@@ -11,46 +11,59 @@
NS_ASSUME_NONNULL_BEGIN
-
@implementation SDLPermissionFilter
#pragma mark - Lifecycle
-- (instancetype)init {
- return [self initWithRPCNames:@[]
- groupType:SDLPermissionGroupTypeAny
- observer:^(NSDictionary<SDLPermissionRPCName, NSNumber<SDLBool> *> *_Nonnull change, SDLPermissionGroupStatus status){
- }];
-}
-
-- (instancetype)initWithRPCNames:(NSArray<SDLPermissionRPCName> *)rpcNames groupType:(SDLPermissionGroupType)groupType observer:(SDLPermissionsChangedHandler)observer {
+- (instancetype)initWithPermissions:(NSArray<SDLPermissionElement *> *)rpcNames groupType:(SDLPermissionGroupType)groupType permissionsHandler:(SDLPermissionsChangedHandler)observer {
self = [super init];
if (!self) {
return nil;
}
_identifier = [NSUUID UUID];
- _rpcNames = rpcNames;
+ _permissionElements = rpcNames;
_groupType = groupType;
_handler = observer;
return self;
}
-+ (instancetype)filterWithRPCNames:(NSArray<SDLPermissionRPCName> *)rpcNames groupType:(SDLPermissionGroupType)groupType observer:(SDLPermissionsChangedHandler)observer {
- return [[self alloc] initWithRPCNames:rpcNames groupType:groupType observer:observer];
+- (instancetype)initWithPermissions:(NSArray<SDLPermissionElement *> *)rpcNames groupType:(SDLPermissionGroupType)groupType permissionStatusHandler:(SDLRPCPermissionStatusChangedHandler)permissionStatusHandler {
+ self = [super init];
+ if (!self) { return nil; }
+
+ _identifier = [NSUUID UUID];
+ _permissionElements = rpcNames;
+ _groupType = groupType;
+ _rpcPermissionStatusHandler = permissionStatusHandler;
+
+ return self;
+}
+
+#pragma mark - Helpers
+
+- (NSArray<SDLPermissionRPCName> *)rpcNamesFromPermissionElements:(NSArray<SDLPermissionElement *> *)permissionElements {
+ NSMutableArray *rpcNames = [[NSMutableArray alloc] init];
+ for (SDLPermissionElement *element in permissionElements) {
+ [rpcNames addObject:element.rpcName];
+ }
+
+ return [rpcNames copy];
}
#pragma mark - NSCopying
- (id)copyWithZone:(nullable NSZone *)zone {
- SDLPermissionFilter *newFilter = [[self.class allocWithZone:zone] initWithRPCNames:[_rpcNames copyWithZone:zone] groupType:_groupType observer:[_handler copyWithZone:zone]];
+ SDLPermissionFilter *newFilter = [[self.class allocWithZone:zone] initWithPermissions:[_permissionElements copyWithZone:zone] groupType:_groupType permissionsHandler:[_handler copyWithZone:zone]];
newFilter->_identifier = _identifier;
+ newFilter->_rpcPermissionStatusHandler = _rpcPermissionStatusHandler;
return newFilter;
}
+
#pragma mark - Equality
- (BOOL)isEqual:(id)object {
@@ -73,7 +86,7 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Description
- (NSString *)description {
- return [NSString stringWithFormat:@"identifier: %@, group type: %@, rpcs: %@", self.identifier, @(self.groupType), self.rpcNames];
+ return [NSString stringWithFormat:@"Permission Filter Identifier: %@, group type: %@, RPCs: %@", self.identifier, @(self.groupType), self.permissionElements];
}
@end
diff --git a/SmartDeviceLink/SDLPermissionManager.h b/SmartDeviceLink/SDLPermissionManager.h
index 873bf23c7..1d5442c65 100644
--- a/SmartDeviceLink/SDLPermissionManager.h
+++ b/SmartDeviceLink/SDLPermissionManager.h
@@ -11,6 +11,7 @@
#import "SDLHMILevel.h"
#import "SDLPermissionConstants.h"
#import "SDLRPCFunctionNames.h"
+#import "SDLRPCPermissionStatus.h"
@class SDLPermissionItem;
@class SDLRPCMessage;
@@ -71,7 +72,7 @@ NS_ASSUME_NONNULL_BEGIN
*
* @return AllAllowed if all of the permissions are allowed, AllDisallowed if all the permissions are disallowed, Any if some are allowed, and some are disallowed
*/
-- (SDLPermissionGroupStatus)groupStatusOfRPCNames:(NSArray<SDLRPCFunctionName> *)rpcNames;
+- (SDLPermissionGroupStatus)groupStatusOfRPCPermissions:(NSArray<SDLPermissionElement *> *)rpcNames;
/**
* Retrieve a dictionary with keys that are the passed in RPC names, and objects of an NSNumber<BOOL> specifying if that RPC is currently allowed
@@ -85,11 +86,11 @@ NS_ASSUME_NONNULL_BEGIN
/**
* Retrieve a dictionary with keys that are the passed in RPC names, and objects of an NSNumber<BOOL> specifying if that RPC is currently allowed
*
- * @param rpcNames An array of RPC names to check
+ * @param rpcNames An array of permission elements to check
*
- * @return A dictionary specifying if the passed in RPC names are currently allowed or not
+ * @return A dictionary with specific RPC info contained in a SDLRPCPermissionStatus
*/
-- (NSDictionary<SDLRPCFunctionName, NSNumber *> *)statusesOfRPCNames:(NSArray<SDLRPCFunctionName> *)rpcNames;
+- (NSDictionary<SDLRPCFunctionName, SDLRPCPermissionStatus *> *)statusesOfRPCPermissions:(NSArray<SDLPermissionElement *> *)rpcNames;
/**
* Add an observer for specified RPC names, with a callback that will be called whenever the value changes, as well as immediately with the current status.
@@ -111,13 +112,13 @@ NS_ASSUME_NONNULL_BEGIN
*
* @warning The observer may be called before this method returns, do not attempt to remove the observer from within the observer. That could send `nil` to removeObserverForIdentifier:. If you want functionality like that, call groupStatusOfRPCs: instead.
*
- * @param rpcNames The RPCs to be observed
+ * @param permissionElements The permission elements to be observed
* @param groupType Affects the times that the observer block will be called. If Any, any change to any RPC in rpcNames will cause the observer block to be called. If AllAllowed, the block will be called when: 1. Every RPC in rpcNames becomes allowed 2. The group of rpcNames goes from all being allowed to some or all being disallowed.
* @param handler The block that will be called whenever permissions change.
*
* @return An identifier that can be passed to removeObserverForIdentifer: to remove the observer
*/
-- (SDLPermissionObserverIdentifier)subscribeToRPCNames:(NSArray<SDLRPCFunctionName> *)rpcNames groupType:(SDLPermissionGroupType)groupType withHandler:(SDLSubscribedPermissionsChangedHandler)handler;
+- (SDLPermissionObserverIdentifier)subscribeToRPCPermissions:(NSArray<SDLPermissionElement *> *)permissionElements groupType:(SDLPermissionGroupType)groupType withHandler:(SDLRPCPermissionStatusChangedHandler)handler;
/**
* Remove every current observer
@@ -142,6 +143,16 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (BOOL)rpcNameRequiresEncryption:(SDLRPCFunctionName)rpcName;
+/**
+ * Check whether a parameter of an RPC is allowed
+ *
+ * @param rpcName The name of the RPC to be tested, for example, SDLRPCFunctionNameGetVehicleData
+ * @param parameter The name of the parameter to be tested, for example, rpm
+ *
+ * @return True if the parameter is allowed, false if it is not
+ */
+- (BOOL)isPermissionParameterAllowed:(SDLRPCFunctionName)rpcName parameter:(NSString *)parameter;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLPermissionManager.m b/SmartDeviceLink/SDLPermissionManager.m
index 310dca0b2..aa9f14bf0 100644
--- a/SmartDeviceLink/SDLPermissionManager.m
+++ b/SmartDeviceLink/SDLPermissionManager.m
@@ -12,6 +12,7 @@
#import "SDLNotificationConstants.h"
#import "SDLOnHMIStatus.h"
#import "SDLOnPermissionsChange.h"
+#import "SDLParameterPermissions.h"
#import "SDLPermissionFilter.h"
#import "SDLPermissionItem.h"
#import "SDLPredefinedWindows.h"
@@ -70,27 +71,31 @@ NS_ASSUME_NONNULL_BEGIN
}
- (BOOL)isRPCNameAllowed:(SDLRPCFunctionName)rpcName {
- if (self.permissions[rpcName] == nil || self.currentHMILevel == nil) {
+ return [self.class isRPCNameAllowed:rpcName permissions:self.permissions hmiLevel:self.currentHMILevel];
+}
+
++ (BOOL)isRPCNameAllowed:(SDLRPCFunctionName)rpcName permissions:(NSDictionary<SDLPermissionRPCName, SDLPermissionItem *> *)permissions hmiLevel:(SDLHMILevel)hmiLevel {
+ if (permissions[rpcName] == nil || hmiLevel == nil) {
return NO;
}
- SDLPermissionItem *item = self.permissions[rpcName];
- return [item.hmiPermissions.allowed containsObject:self.currentHMILevel];
+ SDLPermissionItem *item = permissions[rpcName];
+ return [item.hmiPermissions.allowed containsObject:hmiLevel];
}
- (SDLPermissionGroupStatus)groupStatusOfRPCs:(NSArray<SDLPermissionRPCName> *)rpcNames {
- return [self groupStatusOfRPCNames:rpcNames];
+ return [self groupStatusOfRPCPermissions:[self sdl_createPermissionElementsFromRPCNames:rpcNames]];
}
-- (SDLPermissionGroupStatus)groupStatusOfRPCNames:(NSArray<SDLRPCFunctionName> *)rpcNames {
+- (SDLPermissionGroupStatus)groupStatusOfRPCPermissions:(NSArray<SDLPermissionElement *> *)rpcNames {
if (self.currentHMILevel == nil) {
return SDLPermissionGroupStatusUnknown;
}
- return [self.class sdl_groupStatusOfRPCs:rpcNames withPermissions:[self.permissions copy] hmiLevel:self.currentHMILevel];
+ return [self.class sdl_groupStatusOfRPCPermissions:rpcNames withPermissions:[self.permissions copy] hmiLevel:self.currentHMILevel];
}
-+ (SDLPermissionGroupStatus)sdl_groupStatusOfRPCs:(NSArray<SDLPermissionRPCName> *)rpcNames withPermissions:(NSDictionary<SDLPermissionRPCName, SDLPermissionItem *> *)permissions hmiLevel:(SDLHMILevel)hmiLevel {
++ (SDLPermissionGroupStatus)sdl_groupStatusOfRPCPermissions:(NSArray<SDLPermissionElement *> *)rpcNames withPermissions:(NSDictionary<SDLPermissionRPCName, SDLPermissionItem *> *)permissions hmiLevel:(SDLHMILevel)hmiLevel {
// If we don't have an HMI level, then just say everything is disallowed
if (hmiLevel == nil) {
return SDLPermissionGroupStatusUnknown;
@@ -100,7 +105,9 @@ NS_ASSUME_NONNULL_BEGIN
BOOL hasDisallowed = NO;
// Loop through all the RPCs we need to check
- for (NSString *rpcName in rpcNames) {
+ for (SDLPermissionElement *permissionElement in rpcNames) {
+ NSString *rpcName = permissionElement.rpcName;
+
// If at this point in the loop, we have both allowed and disallowed RPCs, return the mixed result
if (hasAllowed && hasDisallowed) {
return SDLPermissionGroupStatusMixed;
@@ -118,6 +125,16 @@ NS_ASSUME_NONNULL_BEGIN
} else {
hasDisallowed = YES;
}
+
+ if (permissionElement.parameterPermissions != nil) {
+ for (NSString *parameter in permissionElement.parameterPermissions) {
+ if ([self.class sdl_isPermissionParameterAllowed:permissionElement.rpcName parameter:parameter permissionItems:permissions hmiLevel:hmiLevel]) {
+ hasAllowed = YES;
+ } else {
+ hasDisallowed = YES;
+ }
+ }
+ }
}
if (hasAllowed && hasDisallowed) {
@@ -130,15 +147,28 @@ NS_ASSUME_NONNULL_BEGIN
}
- (NSDictionary<SDLPermissionRPCName, NSNumber *> *)statusOfRPCs:(NSArray<SDLPermissionRPCName> *)rpcNames {
- return [self statusesOfRPCNames:rpcNames];
+ NSArray *permissionElementsArray = [self sdl_createPermissionElementsFromRPCNames:rpcNames];
+
+ // Convert the dictionary returned from statusesOfRPCNames: to the correct return type
+ return [self sdl_convertPermissionsStatusDictionaryToPermissionsBoolDictionary:[self statusesOfRPCPermissions:permissionElementsArray]];
}
-- (NSDictionary<SDLRPCFunctionName,NSNumber *> *)statusesOfRPCNames:(NSArray<SDLRPCFunctionName> *)rpcNames {
- NSMutableDictionary<SDLRPCFunctionName, NSNumber *> *permissionAllowedDict = [NSMutableDictionary dictionary];
-
- for (SDLRPCFunctionName rpcName in rpcNames) {
- BOOL allowed = [self isRPCNameAllowed:rpcName];
- permissionAllowedDict[rpcName] = @(allowed);
+- (NSDictionary<SDLRPCFunctionName, SDLRPCPermissionStatus *> *)statusesOfRPCPermissions:(NSArray<SDLPermissionElement *> *)rpcNames {
+ NSMutableDictionary<SDLRPCFunctionName, SDLRPCPermissionStatus *> *permissionAllowedDict = [NSMutableDictionary dictionary];
+
+ for (SDLPermissionElement *permissionElement in rpcNames) {
+ if (permissionElement == nil) { continue; }
+
+ NSMutableDictionary<NSString *, NSNumber *> *rpcParameters = [NSMutableDictionary dictionary];
+ if (permissionElement.parameterPermissions != nil) {
+ for (NSString *permissionParameter in permissionElement.parameterPermissions) {
+ BOOL isParameterAllowed = [self.class sdl_isPermissionParameterAllowed:permissionElement.rpcName parameter:permissionParameter permissionItems:self.permissions hmiLevel:self.currentHMILevel];
+ rpcParameters[permissionParameter] = @(isParameterAllowed);
+ }
+ }
+
+ SDLRPCPermissionStatus *permissionStatus = [[SDLRPCPermissionStatus alloc] initWithRPCName:permissionElement.rpcName isRPCAllowed:[self isRPCNameAllowed:permissionElement.rpcName] rpcParameters:rpcParameters];
+ permissionAllowedDict[permissionElement.rpcName] = permissionStatus;
}
return [permissionAllowedDict copy];
@@ -150,7 +180,7 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark Add Observers
- (SDLPermissionObserverIdentifier)addObserverForRPCs:(NSArray<SDLPermissionRPCName> *)rpcNames groupType:(SDLPermissionGroupType)groupType withHandler:(nonnull SDLPermissionsChangedHandler)handler {
- SDLPermissionFilter *filter = [SDLPermissionFilter filterWithRPCNames:rpcNames groupType:groupType observer:handler];
+ SDLPermissionFilter *filter = [[SDLPermissionFilter alloc] initWithPermissions:[self sdl_createPermissionElementsFromRPCNames:rpcNames] groupType:groupType permissionsHandler:handler];
// Store the filter for later use
[self.filters addObject:filter];
@@ -161,14 +191,14 @@ NS_ASSUME_NONNULL_BEGIN
return filter.identifier;
}
-- (SDLPermissionObserverIdentifier)subscribeToRPCNames:(NSArray<SDLRPCFunctionName> *)rpcNames groupType:(SDLPermissionGroupType)groupType withHandler:(SDLPermissionsChangedHandler)handler {
- SDLPermissionFilter *filter = [SDLPermissionFilter filterWithRPCNames:rpcNames groupType:groupType observer:handler];
+- (SDLPermissionObserverIdentifier)subscribeToRPCPermissions:(NSArray<SDLPermissionElement *> *)rpcNames groupType:(SDLPermissionGroupType)groupType withHandler:(SDLRPCPermissionStatusChangedHandler)handler {
+ SDLPermissionFilter *filter = [[SDLPermissionFilter alloc] initWithPermissions:rpcNames groupType:groupType permissionStatusHandler:handler];
// Store the filter for later use
[self.filters addObject:filter];
// Check permission status and group type to see if we need to call handler immediately after setting the observer
- SDLPermissionGroupStatus permissionStatus = [self groupStatusOfRPCNames:filter.rpcNames];
+ SDLPermissionGroupStatus permissionStatus = [self groupStatusOfRPCPermissions:filter.permissionElements];
if ((groupType == SDLPermissionGroupTypeAny) || (groupType == SDLPermissionGroupTypeAllAllowed && permissionStatus == SDLPermissionGroupStatusAllowed)) {
[self sdl_callFilterObserver:filter];
}
@@ -177,10 +207,15 @@ NS_ASSUME_NONNULL_BEGIN
}
- (void)sdl_callFilterObserver:(SDLPermissionFilter *)filter {
- SDLPermissionGroupStatus permissionStatus = [self groupStatusOfRPCNames:filter.rpcNames];
- NSDictionary<SDLPermissionRPCName, NSNumber *> *allowedDict = [self statusesOfRPCNames:filter.rpcNames];
-
- filter.handler(allowedDict, permissionStatus);
+ SDLPermissionGroupStatus permissionStatus = [self groupStatusOfRPCPermissions:filter.permissionElements];
+
+ if (filter.rpcPermissionStatusHandler != nil) {
+ NSDictionary<SDLRPCFunctionName, SDLRPCPermissionStatus *> *allowedDict = [self statusesOfRPCPermissions:filter.permissionElements];
+ filter.rpcPermissionStatusHandler(allowedDict, permissionStatus);
+ } else if (filter.handler != nil) {
+ NSDictionary<SDLRPCFunctionName, NSNumber *> *allowedDict = [self sdl_convertPermissionsStatusDictionaryToPermissionsBoolDictionary:[self statusesOfRPCPermissions:filter.permissionElements]];
+ filter.handler(allowedDict, permissionStatus);
+ }
}
#pragma mark Remove Observers
@@ -230,7 +265,7 @@ NS_ASSUME_NONNULL_BEGIN
for (SDLPermissionFilter *filter in modifiedFilters) {
if (filter.groupType == SDLPermissionGroupTypeAllAllowed) {
SDLPermissionGroupStatus oldStatus = [allAllowedFiltersWithOldStatus[filter.identifier] unsignedIntegerValue];
- SDLPermissionGroupStatus newStatus = [self groupStatusOfRPCNames:filter.rpcNames];
+ SDLPermissionGroupStatus newStatus = [self groupStatusOfRPCPermissions:filter.permissionElements];
// We've already eliminated the case where the permissions could stay the same, so if the permissions changed *to* allowed or *away* from allowed, we need to call the observer.
if (newStatus == SDLPermissionGroupStatusAllowed || oldStatus == SDLPermissionGroupStatusAllowed) {
@@ -260,7 +295,7 @@ NS_ASSUME_NONNULL_BEGIN
if (hmiStatus.windowID != nil && hmiStatus.windowID.integerValue != SDLPredefinedWindowsDefaultWindow) {
return;
}
-
+
SDLHMILevel oldHMILevel = [self.currentHMILevel copy];
self.currentHMILevel = hmiStatus.hmiLevel;
NSArray<SDLPermissionFilter *> *filters = [self.filters copy];
@@ -288,6 +323,39 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark Helper Methods
/**
+ * HAX: Remove this when statusOfRPCs: is no longer supported. Converts a dictionary from <SDLRPCFunctionName, SDLRPCPermissionStatus*> to <SDLPermissionRPCName, NSNumber *>.
+ *
+ * @param permissionStatusDictionary The dictionary containing <SDLRPCFunctionName, SDLRPCPermissionStatus*> to convert.
+ *
+ * @return A <SDLPermissionRPCName, NSNumber *> dictionary.
+ */
+- (NSDictionary<SDLPermissionRPCName, NSNumber *> *)sdl_convertPermissionsStatusDictionaryToPermissionsBoolDictionary:(NSDictionary<SDLRPCFunctionName, SDLRPCPermissionStatus*> *)permissionStatusDictionary {
+ NSMutableDictionary *rpcNameDictionary = [[NSMutableDictionary alloc] init];
+ [permissionStatusDictionary enumerateKeysAndObjectsUsingBlock:^(SDLRPCFunctionName _Nonnull key, SDLRPCPermissionStatus * _Nonnull obj, BOOL * _Nonnull stop) {
+ [rpcNameDictionary setObject:@(obj.rpcAllowed) forKey:key];
+ }];
+
+ return rpcNameDictionary;
+}
+
+/**
+ * Converts an array of RPC name strings to permission elements.
+ *
+ * @param rpcNames The RPC names to convert.
+ *
+ * @return An array of permission elements.
+ */
+- (NSArray<SDLPermissionElement *> *)sdl_createPermissionElementsFromRPCNames:(NSArray<SDLRPCFunctionName> *)rpcNames {
+ NSMutableArray *permissionElements = [[NSMutableArray alloc] init];
+ for (NSString *rpcName in rpcNames) {
+ SDLPermissionElement *permissionElement = [[SDLPermissionElement alloc] initWithRPCName:rpcName parameterPermissions:nil];
+ [permissionElements addObject:permissionElement];
+ }
+
+ return [permissionElements copy];
+}
+
+/**
* Determine if a filter changes based on an HMI level change and the filter's group type settings. This will run through the filter's RPCs, check the permission for each and see if any permission within the filter changes based on some permission now being allowed when it wasn't, or not allowed when it was. This also takes into account the group type setting, so an All Allowed filter will return YES if and only if some permission changed *and* that causes a status change *to* or *from* Allowed.
*
* @param filter The filter to check
@@ -298,7 +366,7 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (BOOL)sdl_didFilterChange:(SDLPermissionFilter *)filter fromHMILevel:(SDLHMILevel)oldHMILevel toHMILevel:(SDLHMILevel)newHMILevel {
BOOL changed = NO;
- for (NSString *rpcName in filter.rpcNames) {
+ for (NSString *rpcName in [filter rpcNamesFromPermissionElements:filter.permissionElements]) {
SDLPermissionItem *item = self.permissions[rpcName];
BOOL newAllowed = [item.hmiPermissions.allowed containsObject:self.currentHMILevel];
BOOL oldAllowed = [item.hmiPermissions.allowed containsObject:oldHMILevel];
@@ -316,8 +384,8 @@ NS_ASSUME_NONNULL_BEGIN
// This is only for the All Allowed group type. Unlike with the Any group type, we need to know if the group status has changed
if (changed) {
- SDLPermissionGroupStatus oldStatus = [self.class sdl_groupStatusOfRPCs:filter.rpcNames withPermissions:self.permissions hmiLevel:oldHMILevel];
- SDLPermissionGroupStatus newStatus = [self.class sdl_groupStatusOfRPCs:filter.rpcNames withPermissions:self.permissions hmiLevel:newHMILevel];
+ SDLPermissionGroupStatus oldStatus = [self.class sdl_groupStatusOfRPCPermissions:filter.permissionElements withPermissions:self.permissions hmiLevel:oldHMILevel];
+ SDLPermissionGroupStatus newStatus = [self.class sdl_groupStatusOfRPCPermissions:filter.permissionElements withPermissions:self.permissions hmiLevel:newHMILevel];
// We've already eliminated the case where the permissions could stay the same, so if the permissions changed *to* allowed or *away* from allowed, we need to call the observer.
if (newStatus == SDLPermissionGroupStatusAllowed || oldStatus == SDLPermissionGroupStatusAllowed) {
@@ -340,7 +408,7 @@ NS_ASSUME_NONNULL_BEGIN
NSMutableDictionary<SDLPermissionFilter *, NSNumber<SDLInt> *> *filtersWithStatus = [NSMutableDictionary dictionary];
for (SDLPermissionFilter *filter in filters) {
if (filter.groupType == SDLPermissionGroupTypeAllAllowed) {
- filtersWithStatus[filter.identifier] = @([self groupStatusOfRPCNames:filter.rpcNames]);
+ filtersWithStatus[filter.identifier] = @([self groupStatusOfRPCPermissions:filter.permissionElements]);
}
}
@@ -362,7 +430,7 @@ NS_ASSUME_NONNULL_BEGIN
for (SDLPermissionFilter *filter in filters) {
NSArray<SDLPermissionItem *> *modifiedPermissionItems = [self sdl_modifiedUpdatedPermissions:updatedPermissions comparedToCurrentPermissions:currentPermissions];
for (SDLPermissionItem *item in modifiedPermissionItems) {
- if ([filter.rpcNames containsObject:item.rpcName]) {
+ if ([[filter rpcNamesFromPermissionElements:filter.permissionElements] containsObject:item.rpcName]) {
[modifiedFilters addObject:filter];
break;
}
@@ -405,6 +473,21 @@ NS_ASSUME_NONNULL_BEGIN
return NO;
}
+- (BOOL)isPermissionParameterAllowed:(SDLRPCFunctionName)rpcName parameter:(NSString *)parameter {
+ return [self.class sdl_isPermissionParameterAllowed:rpcName parameter:parameter permissionItems:self.permissions hmiLevel:self.currentHMILevel];
+}
+
++ (BOOL)sdl_isPermissionParameterAllowed:(SDLRPCFunctionName)rpcName parameter:(NSString *)parameter permissionItems:(NSDictionary<SDLPermissionRPCName, SDLPermissionItem *> *)permissionItems hmiLevel:(SDLHMILevel)hmiLevel {
+ SDLPermissionItem *permissionItem = permissionItems[rpcName];
+ if (permissionItem == nil || ![self isRPCNameAllowed:rpcName permissions:permissionItems hmiLevel:hmiLevel] || permissionItem.parameterPermissions == nil || permissionItem.parameterPermissions.allowed == nil) {
+ return NO;
+ } else if (permissionItem.parameterPermissions.userDisallowed != nil) {
+ return [permissionItem.parameterPermissions.allowed containsObject:parameter] && ![permissionItem.parameterPermissions.userDisallowed containsObject:parameter];
+ } else {
+ return [permissionItem.parameterPermissions.allowed containsObject:parameter];
+ }
+}
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLRPCPermissionStatus.h b/SmartDeviceLink/SDLRPCPermissionStatus.h
new file mode 100644
index 000000000..a431250e0
--- /dev/null
+++ b/SmartDeviceLink/SDLRPCPermissionStatus.h
@@ -0,0 +1,47 @@
+//
+// SDLRPCPermissionStatus.h
+// SmartDeviceLink
+//
+// Created by James Lapinski on 6/29/20.
+// Copyright © 2020 smartdevicelink. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+#import "SDLRPCFunctionNames.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface SDLRPCPermissionStatus : NSObject
+
+/**
+ Name of the individual RPC.
+
+ Required
+ */
+@property (strong, nonatomic, readonly) SDLRPCFunctionName rpcName;
+
+/**
+ * Whether or not the RPC is allowed.
+ */
+@property (assign, nonatomic, readonly, getter=isRPCAllowed) BOOL rpcAllowed;
+
+/**
+ * Holds a dictionary of RPC parameters and objects of an NSNumber<BOOL> specifying if that RPC parameter is currently allowed
+ */
+@property (strong, nonatomic, nullable, readonly) NSDictionary<NSString *, NSNumber *> *rpcParameters;
+
+/**
+ * Initializes a SDLRPCPermissionStatus object.
+ *
+ * @param rpcName The name of the RPC.
+ * @param isRPCAllowed The permission status for the RPC.
+ * @param rpcParameters A dictionary of RPC parameters and objects of an NSNumber<BOOL> specifying if that RPC parameter is currently allowed
+ *
+ * @return An instance of the SDLRPCPermissionStatus class.
+ */
+- (instancetype)initWithRPCName:(SDLRPCFunctionName)rpcName isRPCAllowed:(BOOL)isRPCAllowed rpcParameters:(nullable NSDictionary<NSString *, NSNumber *> *)rpcParameters;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLRPCPermissionStatus.m b/SmartDeviceLink/SDLRPCPermissionStatus.m
new file mode 100644
index 000000000..7c6a8d00a
--- /dev/null
+++ b/SmartDeviceLink/SDLRPCPermissionStatus.m
@@ -0,0 +1,34 @@
+//
+// SDLRPCPermissionStatus.m
+// SmartDeviceLink
+//
+// Created by James Lapinski on 6/29/20.
+// Copyright © 2020 smartdevicelink. All rights reserved.
+//
+
+#import "SDLRPCPermissionStatus.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@implementation SDLRPCPermissionStatus
+
+- (instancetype)initWithRPCName:(SDLRPCFunctionName)rpcName isRPCAllowed:(BOOL)isRPCAllowed rpcParameters:(nullable NSDictionary<NSString *,NSNumber *> *)rpcParameters {
+ self = [super init];
+ if (!self) { return nil; }
+
+ _rpcName = rpcName;
+ _rpcAllowed = isRPCAllowed;
+ _rpcParameters = rpcParameters;
+
+ return self;
+}
+
+#pragma mark - Description
+
+- (NSString *)description {
+ return [NSString stringWithFormat:@"RPC Permission status, RPC name: %@, allowed: %@, RPC parameters %@", self.rpcName, (self.isRPCAllowed ? @"YES" : @"NO"), self.rpcParameters];
+}
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SmartDeviceLink.h b/SmartDeviceLink/SmartDeviceLink.h
index 542c2a208..177d60bd7 100644
--- a/SmartDeviceLink/SmartDeviceLink.h
+++ b/SmartDeviceLink/SmartDeviceLink.h
@@ -435,6 +435,8 @@ FOUNDATION_EXPORT const unsigned char SmartDeviceLinkVersionString[];
// Permissions
#import "SDLPermissionConstants.h"
+#import "SDLPermissionElement.h"
+#import "SDLRPCPermissionStatus.h"
#import "SDLPermissionManager.h"
// Screen
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLPermissionFilterSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLPermissionFilterSpec.m
index be190c40d..757c6411b 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLPermissionFilterSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLPermissionFilterSpec.m
@@ -2,6 +2,7 @@
#import <Nimble/Nimble.h>
#import "SDLPermissionConstants.h"
+#import "SDLPermissionElement.h"
#import "SDLPermissionFilter.h"
QuickSpecBegin(SDLPermissionFilterSpec)
@@ -9,141 +10,148 @@ QuickSpecBegin(SDLPermissionFilterSpec)
describe(@"A filter", ^{
__block NSString *testRPCName1 = nil;
__block NSString *testRPCName2 = nil;
-
+ __block SDLPermissionElement *testPermissionElement1 = nil;
+ __block SDLPermissionElement *testPermissionElement2 = nil;
+
beforeEach(^{
testRPCName1 = @"testRPCName1";
testRPCName2 = @"testRPCName2";
+ testPermissionElement1 = [[SDLPermissionElement alloc] initWithRPCName:testRPCName1 parameterPermissions:nil];
+ testPermissionElement2 = [[SDLPermissionElement alloc] initWithRPCName:testRPCName2 parameterPermissions:nil];
});
-
+
describe(@"should initialize correctly", ^{
- __block NSArray<SDLPermissionRPCName> *testRPCNames = nil;
+ __block NSArray<SDLPermissionElement *> *testPermissionElements = nil;
__block SDLPermissionGroupType testGroupType = SDLPermissionGroupTypeAny;
__block SDLPermissionFilter *testFilter = nil;
-
+
__block NSDictionary<SDLPermissionRPCName, NSNumber<SDLBool> *> *testObserverReturnChangedDict = nil;
-
+ __block NSDictionary<SDLPermissionRPCName, SDLRPCPermissionStatus *> *testRPCPermissionStatusReturnChangedDict = nil;
+
beforeEach(^{
- testRPCNames = @[testRPCName1, testRPCName2];
+ testPermissionElements = @[testPermissionElement1, testPermissionElement2];
testGroupType = SDLPermissionGroupTypeAny;
});
-
- context(@"using initWithRPCNames:changeType:observer:", ^{
- beforeEach(^{
- testFilter = [[SDLPermissionFilter alloc] initWithRPCNames:testRPCNames groupType:testGroupType observer:^(NSDictionary<SDLPermissionRPCName,NSNumber<SDLBool> *> * _Nonnull changedDict, SDLPermissionGroupStatus status) {
- testObserverReturnChangedDict = changedDict;
- }];
- });
-
- it(@"should set the rpcNames array correctly", ^{
- expect(testFilter.rpcNames).to(equal(testRPCNames));
- });
-
- describe(@"it should set up the observer correctly", ^{
- __block NSDictionary<SDLPermissionRPCName,NSNumber<SDLBool> *> *testObserverChangedDict = nil;
- __block NSNumber<SDLBool> *testRPCName1Bool = nil;
- __block NSNumber<SDLBool> *testRPCName2Bool = nil;
- __block SDLPermissionGroupStatus testObserverGroupStatus = SDLPermissionGroupStatusUnknown;
-
+
+ context(@"using initWithRPCNames:changeType:permissionsHandler:rpcPermissionStatusHandler", ^{
+ context(@"using SDLPermissionsChangedHandler init", ^{
beforeEach(^{
- testRPCName1Bool = @YES;
- testRPCName2Bool = @NO;
- testObserverChangedDict = @{testRPCName1: testRPCName1Bool,
- testRPCName2: testRPCName2Bool};
- testObserverGroupStatus = SDLPermissionGroupStatusMixed;
-
- testFilter.handler(testObserverChangedDict, testObserverGroupStatus);
+ testFilter = [[SDLPermissionFilter alloc] initWithPermissions:testPermissionElements groupType:testGroupType permissionsHandler:^(NSDictionary<SDLPermissionRPCName,NSNumber *> * _Nonnull change, SDLPermissionGroupStatus status) {
+ testObserverReturnChangedDict = change;
+ }];
});
-
- it(@"should call the changedDict correctly", ^{
- expect(testObserverReturnChangedDict).to(equal(testObserverChangedDict));
+
+ it(@"should set the rpcNames array correctly", ^{
+ expect([testFilter rpcNamesFromPermissionElements:testPermissionElements]).to(equal([testFilter rpcNamesFromPermissionElements:testPermissionElements]));
});
-
- it(@"should call the status correctly", ^{
- expect(@(testObserverGroupStatus)).to(equal(@(testObserverGroupStatus)));
+
+ describe(@"it should set up the observer correctly", ^{
+ __block NSDictionary<SDLPermissionRPCName,NSNumber<SDLBool> *> *testObserverChangedDict = nil;
+ __block NSNumber<SDLBool> *testRPCName1Bool = nil;
+ __block NSNumber<SDLBool> *testRPCName2Bool = nil;
+ __block SDLPermissionGroupStatus testObserverGroupStatus = SDLPermissionGroupStatusUnknown;
+
+ beforeEach(^{
+ testRPCName1Bool = @YES;
+ testRPCName2Bool = @NO;
+ testObserverChangedDict = @{testRPCName1: testRPCName1Bool,
+ testRPCName2: testRPCName2Bool};
+ testObserverGroupStatus = SDLPermissionGroupStatusMixed;
+
+ testFilter.handler(testObserverChangedDict, testObserverGroupStatus);
+ });
+
+ it(@"should call the changedDict correctly", ^{
+ expect(testObserverReturnChangedDict).to(equal(testObserverChangedDict));
+ });
+
+ it(@"should call the status correctly", ^{
+ expect(@(testObserverGroupStatus)).to(equal(@(testObserverGroupStatus)));
+ });
});
});
- });
-
- context(@"using filterWithRPCNames:changeType:observer:", ^{
- beforeEach(^{
- testFilter = [SDLPermissionFilter filterWithRPCNames:testRPCNames groupType:testGroupType observer:^(NSDictionary<SDLPermissionRPCName,NSNumber<SDLBool> *> * _Nonnull changedDict, SDLPermissionGroupStatus status) {
- testObserverReturnChangedDict = changedDict;
- }];
- });
-
- it(@"should set the rpcNames array correctly", ^{
- expect(testFilter.rpcNames).to(equal(testRPCNames));
- });
-
- describe(@"it should set up the observer correctly", ^{
- __block NSDictionary<SDLPermissionRPCName,NSNumber<SDLBool> *> *testObserverChangedDict = nil;
- __block NSNumber<SDLBool> *testRPCName1Bool = nil;
- __block NSNumber<SDLBool> *testRPCName2Bool = nil;
- __block SDLPermissionGroupStatus testObserverGroupStatus = SDLPermissionGroupStatusUnknown;
-
+
+ context(@"using the SDLRPCPermissionStatusChangedHandler init", ^{
beforeEach(^{
- testRPCName1Bool = @YES;
- testRPCName2Bool = @NO;
- testObserverChangedDict = @{testRPCName1: testRPCName1Bool,
- testRPCName2: testRPCName2Bool};
- testObserverGroupStatus = SDLPermissionGroupStatusMixed;
-
- testFilter.handler(testObserverChangedDict, testObserverGroupStatus);
+ testFilter = [[SDLPermissionFilter alloc] initWithPermissions:testPermissionElements groupType:testGroupType permissionStatusHandler:^(NSDictionary<SDLRPCFunctionName,SDLRPCPermissionStatus *> * _Nonnull change, SDLPermissionGroupStatus status) {
+ testRPCPermissionStatusReturnChangedDict = change;
+ }];
});
-
- it(@"should call the changedDict correctly", ^{
- expect(testObserverReturnChangedDict).to(equal(testObserverChangedDict));
+
+ it(@"should set the permission elements array correctly", ^{
+ expect(testFilter.permissionElements).to(equal(testPermissionElements));
});
-
- it(@"should call the status correctly", ^{
- expect(@(testObserverGroupStatus)).to(equal(@(testObserverGroupStatus)));
+
+ describe(@"it should set up the observer correctly", ^{
+ __block NSDictionary<SDLPermissionRPCName, SDLRPCPermissionStatus *> *testObserverChangedDict = nil;
+ __block SDLRPCPermissionStatus *rpcPermissionStatus1 = nil;
+ __block SDLRPCPermissionStatus *rpcPermissionStatus2 = nil;
+ __block SDLPermissionGroupStatus testObserverGroupStatus = SDLPermissionGroupStatusUnknown;
+
+ beforeEach(^{
+ rpcPermissionStatus1 = [[SDLRPCPermissionStatus alloc] initWithRPCName:testRPCName1 isRPCAllowed:YES rpcParameters:nil];
+ rpcPermissionStatus2 = [[SDLRPCPermissionStatus alloc] initWithRPCName:testRPCName2 isRPCAllowed:NO rpcParameters:nil];
+ testObserverChangedDict = @{testRPCName1: rpcPermissionStatus1,
+ testRPCName2: rpcPermissionStatus2};
+ testObserverGroupStatus = SDLPermissionGroupStatusMixed;
+
+ testFilter.rpcPermissionStatusHandler(testObserverChangedDict, testObserverGroupStatus);
+ });
+
+ it(@"should call the changedDict correctly", ^{
+ expect(testRPCPermissionStatusReturnChangedDict).to(equal(testObserverChangedDict));
+ });
+
+ it(@"should call the status correctly", ^{
+ expect(@(testObserverGroupStatus)).to(equal(@(testObserverGroupStatus)));
+ });
});
});
});
});
-
+
describe(@"copying a filter", ^{
__block SDLPermissionFilter *testFilter = nil;
__block SDLPermissionFilter *testCopiedFilter = nil;
-
+
beforeEach(^{
- testFilter = [SDLPermissionFilter filterWithRPCNames:@[testRPCName1] groupType:SDLPermissionGroupTypeAny observer:^(NSDictionary<SDLPermissionRPCName,NSNumber<SDLBool> *> * _Nonnull changedDict, SDLPermissionGroupStatus status) {}];
+ testFilter = [[SDLPermissionFilter alloc] initWithPermissions:@[testPermissionElement1] groupType:SDLPermissionGroupTypeAny permissionsHandler:^(NSDictionary<SDLPermissionRPCName,NSNumber *> * _Nonnull change, SDLPermissionGroupStatus status) {}];
testCopiedFilter = [testFilter copy];
});
-
+
it(@"should say copied filters are not the same instance", ^{
expect(testCopiedFilter).toNot(beIdenticalTo(testFilter));
});
-
+
it(@"should copy the identifier correctly", ^{
expect(testCopiedFilter.identifier).to(equal(testFilter.identifier));
});
-
+
it(@"should copy the filter array correctly", ^{
- expect(testCopiedFilter.rpcNames).to(equal(testFilter.rpcNames));
+ expect(testCopiedFilter.permissionElements).to(equal(testFilter.permissionElements));
});
-
+
it(@"should copy the change type correctly", ^{
expect(@(testCopiedFilter.groupType)).to(equal(@(testFilter.groupType)));
});
});
-
+
describe(@"testing equality", ^{
__block SDLPermissionFilter *testSameFilter1 = nil;
__block SDLPermissionFilter *testSameFilter2 = nil;
__block SDLPermissionFilter *testDifferentFilter = nil;
-
+
beforeEach(^{
- testSameFilter1 = [SDLPermissionFilter filterWithRPCNames:@[testRPCName1] groupType:SDLPermissionGroupTypeAny observer:^(NSDictionary<SDLPermissionRPCName,NSNumber<SDLBool> *> * _Nonnull changedDict, SDLPermissionGroupStatus status) {}];
+ testSameFilter1 = [[SDLPermissionFilter alloc] initWithPermissions:@[testPermissionElement1] groupType:(SDLPermissionGroupType)SDLPermissionGroupTypeAny permissionsHandler:^(NSDictionary<SDLPermissionRPCName,NSNumber *> * _Nonnull change, SDLPermissionGroupStatus status) {}];
testSameFilter2 = [testSameFilter1 copy];
-
- testDifferentFilter = [SDLPermissionFilter filterWithRPCNames:@[testRPCName1] groupType:SDLPermissionGroupTypeAny observer:^(NSDictionary<SDLPermissionRPCName,NSNumber<SDLBool> *> * _Nonnull changedDict, SDLPermissionGroupStatus status) {}];
+
+ testDifferentFilter = [[SDLPermissionFilter alloc] initWithPermissions:@[testPermissionElement1] groupType:(SDLPermissionGroupType)SDLPermissionGroupTypeAny permissionsHandler:^(NSDictionary<SDLPermissionRPCName,NSNumber *> * _Nonnull change, SDLPermissionGroupStatus status) {}];
});
-
+
it(@"should say copied filters are the same", ^{
expect(testSameFilter1).to(equal(testSameFilter2));
});
-
+
it(@"should say new filters are different", ^{
expect(testSameFilter1).toNot(equal(testDifferentFilter));
});
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLPermissionsManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLPermissionsManagerSpec.m
index bee6548c2..05020ef37 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLPermissionsManagerSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLPermissionsManagerSpec.m
@@ -28,12 +28,20 @@ QuickSpecBegin(SDLPermissionsManagerSpec)
describe(@"SDLPermissionsManager", ^{
__block SDLPermissionManager *testPermissionsManager = nil;
-
+
__block NSString *testRPCNameAllAllowed = nil;
__block NSString *testRPCNameAllDisallowed = nil;
__block NSString *testRPCNameFullLimitedAllowed = nil;
__block NSString *testRPCNameFullLimitedBackgroundAllowed = nil;
-
+
+ __block NSString *testRPCParameterNameAllAllowed = nil;
+ __block NSString *testRPCParameterNameAllDisallowed = nil;
+ __block NSString *testRPCParameterNameFullLimitedAllowed = nil;
+
+ __block SDLParameterPermissions *testParameterPermissionAllowed = nil;
+ __block SDLParameterPermissions *testParameterPermissionUserDisallowed = nil;
+ __block SDLParameterPermissions *testParameterPermissionFullLimitedAllowed = nil;
+
__block SDLPermissionItem *testPermissionAllAllowed = nil;
__block SDLHMIPermissions *testHMIPermissionsAllAllowed = nil;
__block SDLPermissionItem *testPermissionAllDisallowed = nil;
@@ -42,85 +50,109 @@ describe(@"SDLPermissionsManager", ^{
__block SDLHMIPermissions *testHMIPermissionsFullLimitedAllowed = nil;
__block SDLPermissionItem *testPermissionFullLimitedBackgroundAllowed = nil;
__block SDLHMIPermissions *testHMIPermissionsFullLimitedBackgroundAllowed = nil;
-
+
__block SDLOnPermissionsChange *testPermissionsChange = nil;
-
+
__block SDLOnHMIStatus *testLimitedHMIStatus = nil;
__block SDLOnHMIStatus *testBackgroundHMIStatus = nil;
__block SDLOnHMIStatus *testNoneHMIStatus = nil;
-
+
__block SDLRPCNotificationNotification *testPermissionsNotification = nil;
__block SDLRPCNotificationNotification *limitedHMINotification = nil;
__block SDLRPCNotificationNotification *backgroundHMINotification = nil;
__block SDLRPCNotificationNotification *noneHMINotification = nil;
-
+
+ __block SDLPermissionElement *testPermissionElementAllAllowed = nil;
+ __block SDLPermissionElement *testPermissionElementFullLimitedAllowed = nil;
+ __block SDLPermissionElement *testPermissionElementDisallowed = nil;
+
beforeEach(^{
// Permission Names
testRPCNameAllAllowed = @"AllAllowed";
testRPCNameAllDisallowed = @"AllDisallowed";
testRPCNameFullLimitedAllowed = @"FullAndLimitedAllowed";
testRPCNameFullLimitedBackgroundAllowed = @"FullAndLimitedAndBackgroundAllowed";
-
+
+ // Parameter Permission Names
+ testRPCParameterNameAllAllowed = @"AllAllowed";
+ testRPCParameterNameAllDisallowed = @"AllDisallowed";
+ testRPCParameterNameFullLimitedAllowed = @"FullAndLimitedAllowed";
+
// Create a manager
testPermissionsManager = [[SDLPermissionManager alloc] init];
-
+
// Permission states
testHMIPermissionsAllAllowed = [[SDLHMIPermissions alloc] init];
testHMIPermissionsAllAllowed.allowed = @[SDLHMILevelBackground, SDLHMILevelFull, SDLHMILevelLimited, SDLHMILevelNone];
-
+
testHMIPermissionsAllDisallowed = [[SDLHMIPermissions alloc] init];
testHMIPermissionsAllDisallowed.userDisallowed = @[SDLHMILevelBackground, SDLHMILevelFull, SDLHMILevelLimited, SDLHMILevelNone];
-
+
testHMIPermissionsFullLimitedAllowed = [[SDLHMIPermissions alloc] init];
testHMIPermissionsFullLimitedAllowed.allowed = @[SDLHMILevelFull, SDLHMILevelLimited];
testHMIPermissionsFullLimitedAllowed.userDisallowed = @[SDLHMILevelBackground, SDLHMILevelNone];
-
+
testHMIPermissionsFullLimitedBackgroundAllowed = [[SDLHMIPermissions alloc] init];
testHMIPermissionsFullLimitedBackgroundAllowed.allowed = @[SDLHMILevelFull, SDLHMILevelLimited, SDLHMILevelBackground];
testHMIPermissionsFullLimitedBackgroundAllowed.userDisallowed = @[SDLHMILevelNone];
-
+
+ // Assemble Parameter Permissions
+ testParameterPermissionAllowed = [[SDLParameterPermissions alloc] init];
+ testParameterPermissionAllowed.allowed = @[testRPCParameterNameAllAllowed];
+
+ testParameterPermissionUserDisallowed = [[SDLParameterPermissions alloc] init];
+ testParameterPermissionUserDisallowed.userDisallowed = @[testRPCParameterNameAllDisallowed];
+
+ testParameterPermissionFullLimitedAllowed = [[SDLParameterPermissions alloc] init];
+ testParameterPermissionFullLimitedAllowed.allowed = @[testRPCParameterNameAllAllowed, testRPCParameterNameFullLimitedAllowed];
+
// Assemble Permissions
SDLParameterPermissions *testParameterPermissions = [[SDLParameterPermissions alloc] init];
-
+
testPermissionAllAllowed = [[SDLPermissionItem alloc] init];
testPermissionAllAllowed.rpcName = testRPCNameAllAllowed;
testPermissionAllAllowed.hmiPermissions = testHMIPermissionsAllAllowed;
- testPermissionAllAllowed.parameterPermissions = testParameterPermissions;
-
+ testPermissionAllAllowed.parameterPermissions = testParameterPermissionAllowed;
+
testPermissionAllDisallowed = [[SDLPermissionItem alloc] init];
testPermissionAllDisallowed.rpcName = testRPCNameAllDisallowed;
testPermissionAllDisallowed.hmiPermissions = testHMIPermissionsAllDisallowed;
- testPermissionAllDisallowed.parameterPermissions = testParameterPermissions;
-
+ testPermissionAllDisallowed.parameterPermissions = testParameterPermissionUserDisallowed;
+
testPermissionFullLimitedAllowed = [[SDLPermissionItem alloc] init];
testPermissionFullLimitedAllowed.rpcName = testRPCNameFullLimitedAllowed;
testPermissionFullLimitedAllowed.hmiPermissions = testHMIPermissionsFullLimitedAllowed;
- testPermissionFullLimitedAllowed.parameterPermissions = testParameterPermissions;
-
+ testPermissionFullLimitedAllowed.parameterPermissions = testParameterPermissionFullLimitedAllowed;
+
testPermissionFullLimitedBackgroundAllowed = [[SDLPermissionItem alloc] init];
testPermissionFullLimitedBackgroundAllowed.rpcName = testRPCNameFullLimitedBackgroundAllowed;
testPermissionFullLimitedBackgroundAllowed.hmiPermissions = testHMIPermissionsFullLimitedBackgroundAllowed;
testPermissionFullLimitedBackgroundAllowed.parameterPermissions = testParameterPermissions;
-
+
// Create OnHMIStatus objects
testLimitedHMIStatus = [[SDLOnHMIStatus alloc] init];
testLimitedHMIStatus.hmiLevel = SDLHMILevelLimited;
-
+
testBackgroundHMIStatus = [[SDLOnHMIStatus alloc] init];
testBackgroundHMIStatus.hmiLevel = SDLHMILevelBackground;
-
+
testNoneHMIStatus = [[SDLOnHMIStatus alloc] init];
testNoneHMIStatus.hmiLevel = SDLHMILevelNone;
-
+
// Create OnPermissionsChange object
testPermissionsChange = [[SDLOnPermissionsChange alloc] init];
testPermissionsChange.permissionItem = @[testPermissionAllAllowed, testPermissionAllDisallowed, testPermissionFullLimitedAllowed, testPermissionFullLimitedBackgroundAllowed];
-
+
// Permission Notifications
testPermissionsNotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidChangePermissionsNotification object:nil rpcNotification:testPermissionsChange];
limitedHMINotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidChangeHMIStatusNotification object:nil rpcNotification:testLimitedHMIStatus];
backgroundHMINotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidChangeHMIStatusNotification object:nil rpcNotification:testBackgroundHMIStatus];
noneHMINotification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidChangeHMIStatusNotification object:nil rpcNotification:testNoneHMIStatus];
+
+ // Permission Elements
+ testPermissionElementAllAllowed = [[SDLPermissionElement alloc] initWithRPCName:testRPCNameAllAllowed parameterPermissions:@[testRPCParameterNameAllAllowed]];
+ testPermissionElementFullLimitedAllowed = [[SDLPermissionElement alloc] initWithRPCName:testRPCNameFullLimitedAllowed parameterPermissions:@[testRPCParameterNameFullLimitedAllowed]];
+ testPermissionElementDisallowed = [[SDLPermissionElement alloc] initWithRPCName:testRPCNameAllDisallowed parameterPermissions:@[testRPCParameterNameAllDisallowed]];
});
it(@"should clear when stopped", ^{
@@ -131,7 +163,7 @@ describe(@"SDLPermissionsManager", ^{
expect(testPermissionsManager.currentHMILevel).to(beNil());
expect(testPermissionsManager.requiresEncryption).to(beFalse());
});
-
+
describe(@"checking if a permission is allowed", ^{
__block NSString *someRPCName = nil;
__block SDLRPCFunctionName someRPCFunctionName = nil;
@@ -164,7 +196,7 @@ describe(@"SDLPermissionsManager", ^{
});
});
});
-
+
context(@"when permissions exist but no HMI level", ^{
context(@"deprecated isRPCAllowed: method", ^{
beforeEach(^{
@@ -191,7 +223,7 @@ describe(@"SDLPermissionsManager", ^{
});
});
});
-
+
context(@"when permissions exist", ^{
context(@"deprecated isRPCAllowed: method", ^{
context(@"and the permission is allowed", ^{
@@ -254,10 +286,10 @@ describe(@"SDLPermissionsManager", ^{
});
});
});
-
+
describe(@"checking the group status of RPCs", ^{
__block SDLPermissionGroupStatus testResultStatus = SDLPermissionGroupStatusUnknown;
-
+
context(@"with no permissions data", ^{
context(@"deprecated groupStatusOfRPCs: method", ^{
beforeEach(^{
@@ -272,9 +304,9 @@ describe(@"SDLPermissionsManager", ^{
});
});
- context(@"groupStatusOfRPCNames: method", ^{
+ context(@"groupStatusOfRPCPermissions: method", ^{
beforeEach(^{
- testResultStatus = [testPermissionsManager groupStatusOfRPCNames:@[testRPCNameAllAllowed, testRPCNameAllDisallowed]];
+ testResultStatus = [testPermissionsManager groupStatusOfRPCPermissions:@[testPermissionElementAllAllowed, testPermissionElementFullLimitedAllowed]];
});
it(@"should return unknown", ^{
@@ -282,7 +314,7 @@ describe(@"SDLPermissionsManager", ^{
});
});
});
-
+
context(@"for an all allowed group", ^{
context(@"deprecated groupStatusOfRPCs: method", ^{
beforeEach(^{
@@ -299,12 +331,12 @@ describe(@"SDLPermissionsManager", ^{
});
});
- context(@"groupStatusOfRPCNames: method", ^{
+ context(@"groupStatusOfRPCPermissions: method", ^{
beforeEach(^{
[[NSNotificationCenter defaultCenter] postNotification:limitedHMINotification];
[[NSNotificationCenter defaultCenter] postNotification:testPermissionsNotification];
- testResultStatus = [testPermissionsManager groupStatusOfRPCNames:@[testRPCNameAllAllowed, testRPCNameFullLimitedAllowed]];
+ testResultStatus = [testPermissionsManager groupStatusOfRPCPermissions:@[testPermissionElementAllAllowed, testPermissionElementFullLimitedAllowed]];
});
it(@"should return allowed", ^{
@@ -312,7 +344,7 @@ describe(@"SDLPermissionsManager", ^{
});
});
});
-
+
context(@"for an all disallowed group", ^{
context(@"deprecated groupStatusOfRPCs: method", ^{
beforeEach(^{
@@ -329,12 +361,12 @@ describe(@"SDLPermissionsManager", ^{
});
});
- context(@"groupStatusOfRPCNames: method", ^{
+ context(@"groupStatusOfRPCPermissions: method", ^{
beforeEach(^{
[[NSNotificationCenter defaultCenter] postNotification:backgroundHMINotification];
[[NSNotificationCenter defaultCenter] postNotification:testPermissionsNotification];
- testResultStatus = [testPermissionsManager groupStatusOfRPCNames:@[testRPCNameFullLimitedAllowed, testRPCNameAllDisallowed]];
+ testResultStatus = [testPermissionsManager groupStatusOfRPCPermissions:@[testPermissionElementFullLimitedAllowed, testPermissionElementDisallowed]];
});
it(@"should return disallowed", ^{
@@ -342,7 +374,7 @@ describe(@"SDLPermissionsManager", ^{
});
});
});
-
+
context(@"for a mixed group", ^{
context(@"deprecated groupStatusOfRPCs: method", ^{
beforeEach(^{
@@ -359,12 +391,12 @@ describe(@"SDLPermissionsManager", ^{
});
});
- context(@"groupStatusOfRPCNames: method", ^{
+ context(@"groupStatusOfRPCPermissions: method", ^{
beforeEach(^{
[[NSNotificationCenter defaultCenter] postNotification:limitedHMINotification];
[[NSNotificationCenter defaultCenter] postNotification:testPermissionsNotification];
- testResultStatus = [testPermissionsManager groupStatusOfRPCNames:@[testRPCNameAllAllowed, testRPCNameAllDisallowed]];
+ testResultStatus = [testPermissionsManager groupStatusOfRPCPermissions:@[testPermissionElementAllAllowed, testPermissionElementDisallowed]];
});
it(@"should return mixed", ^{
@@ -373,9 +405,18 @@ describe(@"SDLPermissionsManager", ^{
});
});
});
-
+
describe(@"checking the status of RPCs", ^{
__block NSDictionary<SDLPermissionRPCName, NSNumber *> *testResultPermissionStatusDict = nil;
+ __block NSDictionary<SDLRPCFunctionName, SDLRPCPermissionStatus *> *testResultRPCPermissionStatusDict = nil;
+ __block SDLRPCPermissionStatus *allowedResultStatus = nil;
+ __block SDLRPCPermissionStatus *disallowedResultStatus = nil;
+
+ __block NSDictionary *testAllowedDict = nil;
+ __block SDLRPCPermissionStatus *testAllowedStatus = nil;
+ __block NSDictionary *testDisallowedDict = nil;
+ __block SDLRPCPermissionStatus *testDisallowedStatus = nil;
+
context(@"with no permissions data", ^{
context(@"deprecated statusOfRPCs: method", ^{
beforeEach(^{
@@ -391,18 +432,30 @@ describe(@"SDLPermissionsManager", ^{
});
});
- context(@"statusesOfRPCNames: method", ^{
+ context(@"statusesOfRPCPermissions: method", ^{
beforeEach(^{
- testResultPermissionStatusDict = [testPermissionsManager statusesOfRPCNames:@[testRPCNameAllAllowed, testRPCNameAllDisallowed]];
+ testResultRPCPermissionStatusDict = [testPermissionsManager statusesOfRPCPermissions:@[testPermissionElementAllAllowed, testPermissionElementDisallowed]];
+ allowedResultStatus = testResultRPCPermissionStatusDict[testPermissionElementAllAllowed.rpcName];
+ disallowedResultStatus = testResultRPCPermissionStatusDict[testPermissionElementDisallowed.rpcName];
+
+ testAllowedDict = [[NSDictionary alloc] initWithObjectsAndKeys:@(0), testRPCParameterNameAllAllowed, nil];
+ testAllowedStatus = [[SDLRPCPermissionStatus alloc] initWithRPCName:testPermissionElementAllAllowed.rpcName isRPCAllowed:YES rpcParameters:testAllowedDict];
+ testDisallowedDict = [[NSDictionary alloc] initWithObjectsAndKeys:@(0), testRPCParameterNameAllDisallowed, nil];
+ testDisallowedStatus = [[SDLRPCPermissionStatus alloc] initWithRPCName:testPermissionElementDisallowed.rpcName isRPCAllowed:YES rpcParameters:testDisallowedDict];
});
- it(@"should return correct permission statuses", ^{
- expect(testResultPermissionStatusDict[testRPCNameAllAllowed]).to(equal(@NO));
- expect(testResultPermissionStatusDict[testRPCNameAllDisallowed]).to(equal(@NO));
+ it(@"should return the correct permission statuses", ^{
+ expect(allowedResultStatus.rpcName).to(equal(testAllowedStatus.rpcName));
+ expect(allowedResultStatus.rpcParameters).to(equal(testAllowedStatus.rpcParameters));
+ expect(allowedResultStatus.rpcAllowed).to(equal(@NO));
+
+ expect(disallowedResultStatus.rpcName).to(equal(testDisallowedStatus.rpcName));
+ expect(disallowedResultStatus.rpcParameters).to(equal(testDisallowedStatus.rpcParameters));
+ expect(disallowedResultStatus.rpcAllowed).to(equal(@NO));
});
});
});
-
+
context(@"with permissions data", ^{
context(@"deprecated statusOfRPCs: method", ^{
beforeEach(^{
@@ -420,17 +473,31 @@ describe(@"SDLPermissionsManager", ^{
});
});
- context(@"statusesOfRPCNames: method", ^{
+ context(@"statusesOfRPCPermissions: method", ^{
beforeEach(^{
[[NSNotificationCenter defaultCenter] postNotification:limitedHMINotification];
[[NSNotificationCenter defaultCenter] postNotification:testPermissionsNotification];
- testResultPermissionStatusDict = [testPermissionsManager statusesOfRPCNames:@[testRPCNameAllAllowed, testRPCNameAllDisallowed]];
+ testResultRPCPermissionStatusDict = [testPermissionsManager statusesOfRPCPermissions:@[testPermissionElementAllAllowed, testPermissionElementDisallowed]];
+
+ allowedResultStatus = testResultRPCPermissionStatusDict[testPermissionElementAllAllowed.rpcName];
+ disallowedResultStatus = testResultRPCPermissionStatusDict[testPermissionElementDisallowed.rpcName];
+
+ testAllowedDict = [[NSDictionary alloc] initWithObjectsAndKeys:@(1), testRPCParameterNameAllAllowed, nil];
+ testAllowedStatus = [[SDLRPCPermissionStatus alloc] initWithRPCName:testPermissionElementAllAllowed.rpcName isRPCAllowed:YES rpcParameters:testAllowedDict];
+
+ testDisallowedDict = [[NSDictionary alloc] initWithObjectsAndKeys:@(0), testRPCParameterNameAllDisallowed, nil];
+ testDisallowedStatus = [[SDLRPCPermissionStatus alloc] initWithRPCName:testPermissionElementDisallowed.rpcName isRPCAllowed:NO rpcParameters:testDisallowedDict];
});
- it(@"should return correct permission statuses", ^{
- expect(testResultPermissionStatusDict[testRPCNameAllAllowed]).to(equal(@YES));
- expect(testResultPermissionStatusDict[testRPCNameAllDisallowed]).to(equal(@NO));
+ it(@"should return the correct permission statuses", ^{
+ expect(allowedResultStatus.rpcName).to(equal(testAllowedStatus.rpcName));
+ expect(allowedResultStatus.rpcParameters).to(equal(testAllowedStatus.rpcParameters));
+ expect(allowedResultStatus.rpcAllowed).to(equal(testAllowedStatus.rpcAllowed));
+
+ expect(disallowedResultStatus.rpcName).to(equal(testDisallowedStatus.rpcName));
+ expect(disallowedResultStatus.rpcParameters).to(equal(testDisallowedStatus.rpcParameters));
+ expect(disallowedResultStatus.rpcAllowed).to(equal(testDisallowedStatus.rpcAllowed));
});
});
});
@@ -558,13 +625,13 @@ describe(@"SDLPermissionsManager", ^{
});
});
- describe(@"adding a new observer with subscribeToRPCNames:groupType:Handler", ^{
+ describe(@"adding a new observer with subscribeToRPCPermissions:groupType:Handler", ^{
context(@"when no data is present", ^{
__block BOOL testObserverCalled = NO;
beforeEach(^{
testObserverCalled = NO;
- [testPermissionsManager subscribeToRPCNames:@[testRPCNameAllAllowed, testRPCNameAllDisallowed] groupType:SDLPermissionGroupTypeAny withHandler:^(NSDictionary<SDLPermissionRPCName,NSNumber *> * _Nonnull change, SDLPermissionGroupStatus status) {
+ [testPermissionsManager subscribeToRPCPermissions:@[testPermissionElementAllAllowed, testPermissionElementDisallowed] groupType:SDLPermissionGroupTypeAny withHandler:^(NSDictionary<SDLPermissionRPCName,NSNumber *> * _Nonnull change, SDLPermissionGroupStatus status) {
testObserverCalled = YES;
}];
});
@@ -586,7 +653,7 @@ describe(@"SDLPermissionsManager", ^{
[[NSNotificationCenter defaultCenter] postNotification:testPermissionsNotification];
// This should not be called even with data currently present, the handler will only be called when an permissions update occurs after the RPC is subscribed to
- [testPermissionsManager subscribeToRPCNames:@[testRPCNameAllAllowed, testRPCNameAllDisallowed] groupType:SDLPermissionGroupTypeAny withHandler:^(NSDictionary<SDLPermissionRPCName,NSNumber *> * _Nonnull change, SDLPermissionGroupStatus status) {
+ [testPermissionsManager subscribeToRPCPermissions:@[testPermissionElementAllAllowed, testPermissionElementDisallowed] groupType:SDLPermissionGroupTypeAny withHandler:^(NSDictionary<SDLPermissionRPCName,NSNumber *> * _Nonnull change, SDLPermissionGroupStatus status) {
testObserverCalled = YES;
}];
});
@@ -1094,6 +1161,91 @@ describe(@"SDLPermissionsManager", ^{
});
});
+ describe(@"checking parameter permissions", ^{
+ __block SDLRPCFunctionName someRPCFunctionName = nil;
+ __block NSString *someRPCParameterName = nil;
+ __block BOOL testResultBOOL = NO;
+
+ context(@"when no permissions exist", ^{
+ beforeEach(^{
+ someRPCFunctionName = @"SomeRPCFunctionName";
+ someRPCParameterName = @"SomeRPCParameterName";
+ testResultBOOL = [testPermissionsManager isPermissionParameterAllowed:someRPCFunctionName parameter:someRPCParameterName];
+ });
+
+ it(@"should not be allowed", ^{
+ expect(testResultBOOL).to(beFalse());
+ });
+ });
+
+ context(@"when permissions exist but no HMI level", ^{
+ beforeEach(^{
+ [[NSNotificationCenter defaultCenter] postNotification:testPermissionsNotification];
+ testResultBOOL = [testPermissionsManager isPermissionParameterAllowed:testRPCNameAllAllowed parameter:testRPCParameterNameAllAllowed];
+ });
+
+ it(@"should not be allowed", ^{
+ expect(testResultBOOL).to(beFalse());
+ });
+ });
+
+ context(@"when permissions exist and HMI level exists", ^{
+ context(@"and the parameter permission is allowed", ^{
+ beforeEach(^{
+ [[NSNotificationCenter defaultCenter] postNotification:limitedHMINotification];
+ [[NSNotificationCenter defaultCenter] postNotification:testPermissionsNotification];
+
+ testResultBOOL = [testPermissionsManager isPermissionParameterAllowed:testRPCNameAllAllowed parameter:testRPCParameterNameAllAllowed];
+ });
+
+ it(@"should be allowed", ^{
+ expect(testResultBOOL).to(beTrue());
+ });
+ });
+
+ context(@"and the parameter permission is denied", ^{
+ beforeEach(^{
+ [[NSNotificationCenter defaultCenter] postNotification:limitedHMINotification];
+ [[NSNotificationCenter defaultCenter] postNotification:testPermissionsNotification];
+
+ testResultBOOL = [testPermissionsManager isPermissionParameterAllowed:testRPCNameAllDisallowed parameter:testRPCParameterNameAllDisallowed];
+ });
+
+ it(@"should not be allowed", ^{
+ expect(testResultBOOL).to(beFalse());
+ });
+ });
+
+ context(@"when user disallowed parameter permissions is not nil", ^{
+ context(@"and the parameter is disallowed", ^{
+ beforeEach(^{
+ [[NSNotificationCenter defaultCenter] postNotification:limitedHMINotification];
+ [[NSNotificationCenter defaultCenter] postNotification:testPermissionsNotification];
+
+ testResultBOOL = [testPermissionsManager isPermissionParameterAllowed:testRPCNameFullLimitedAllowed parameter:testRPCParameterNameAllDisallowed];
+ });
+
+ it(@"should not be allowed", ^{
+ expect(testResultBOOL).to(beFalse());
+ });
+ });
+
+ context(@"and the parameter is allowed", ^{
+ beforeEach(^{
+ [[NSNotificationCenter defaultCenter] postNotification:limitedHMINotification];
+ [[NSNotificationCenter defaultCenter] postNotification:testPermissionsNotification];
+
+ testResultBOOL = [testPermissionsManager isPermissionParameterAllowed:testRPCNameFullLimitedAllowed parameter:testRPCParameterNameAllAllowed];
+ });
+
+ it(@"should be allowed", ^{
+ expect(testResultBOOL).to(beTrue());
+ });
+ });
+ });
+ });
+ });
+
describe(@"removing observers", ^{
context(@"removing the only observer", ^{
__block NSInteger numberOfTimesObserverCalled = 0;
diff --git a/SmartDeviceLinkTests/SDLPermissionElementSpec.m b/SmartDeviceLinkTests/SDLPermissionElementSpec.m
new file mode 100644
index 000000000..2fac3a7c2
--- /dev/null
+++ b/SmartDeviceLinkTests/SDLPermissionElementSpec.m
@@ -0,0 +1,59 @@
+//
+// SDLPermissionElementSpec.m
+// SmartDeviceLinkTests
+//
+// Created by James Lapinski on 6/24/20.
+// Copyright © 2020 smartdevicelink. All rights reserved.
+//
+
+#import <Quick/Quick.h>
+#import <Nimble/Nimble.h>
+
+#import "SDLParameterPermissions.h"
+#import "SDLPermissionElement.h"
+
+QuickSpecBegin(SDLPermissionElementSpec)
+
+describe(@"A permission element", ^{
+ __block NSString *testRPCName1 = nil;
+ __block NSArray<NSString *> *parameterPermissions = nil;
+ __block NSString *testParameterRPCName = nil;
+
+ beforeEach(^{
+ testRPCName1 = @"testRPCName1";
+ testParameterRPCName = @"testParameterRPCName";
+ parameterPermissions = @[testParameterRPCName];
+ });
+
+ describe(@"it should initialize correctly", ^{
+ __block SDLPermissionElement *testPermissionElement = nil;
+
+ beforeEach(^{
+ testPermissionElement = [[SDLPermissionElement alloc] initWithRPCName:testRPCName1 parameterPermissions:parameterPermissions];
+ });
+
+ it(@"should set the rpcName and parameterPermissions correctly", ^{
+ expect(testPermissionElement.rpcName).to(equal(testRPCName1));
+ expect(testPermissionElement.parameterPermissions).to(equal(parameterPermissions));
+ });
+ });
+
+ describe(@"copying a permission element", ^{
+ __block SDLPermissionElement *testPermissionElement = nil;
+ __block SDLPermissionElement *testPermissionElementCopy = nil;
+
+ beforeEach(^{
+ testPermissionElement = [[SDLPermissionElement alloc] initWithRPCName:testRPCName1 parameterPermissions:parameterPermissions];
+ testPermissionElementCopy = [testPermissionElement copy];
+ });
+
+ it(@"should copy correctly", ^{
+ expect(testPermissionElementCopy).toNot(beIdenticalTo(testPermissionElement));
+ expect(testPermissionElementCopy.rpcName).to(equal(testPermissionElement.rpcName));
+ expect(testPermissionElementCopy.parameterPermissions).to(equal(testPermissionElement.parameterPermissions));
+ });
+ });
+});
+
+
+QuickSpecEnd
diff --git a/SmartDeviceLinkTests/SDLRPCPermissionStatusSpec.m b/SmartDeviceLinkTests/SDLRPCPermissionStatusSpec.m
new file mode 100644
index 000000000..f0c0082c5
--- /dev/null
+++ b/SmartDeviceLinkTests/SDLRPCPermissionStatusSpec.m
@@ -0,0 +1,43 @@
+//
+// SDLRPCPermissionStatusSpec.m
+// SmartDeviceLinkTests
+//
+// Created by James Lapinski on 6/29/20.
+// Copyright © 2020 smartdevicelink. All rights reserved.
+//
+
+#import <Quick/Quick.h>
+#import <Nimble/Nimble.h>
+
+#import "SDLRPCPermissionStatus.h"
+
+QuickSpecBegin(SDLRPCPermissionStatusSpec)
+
+describe(@"A rpc permission status", ^{
+ __block NSString *testRPCName = nil;
+ __block NSString *testParameterName = nil;
+ __block BOOL isRPCAllowed = NO;
+ __block NSMutableDictionary<NSString *,NSNumber *> *allowedParameters = nil;
+
+ beforeEach(^{
+ testRPCName = @"testRPCName";
+ testParameterName = @"testParameterRPCName";
+ allowedParameters = [@{ testParameterName: @0 } mutableCopy];
+ });
+
+ describe(@"it should initialize correctly", ^{
+ __block SDLRPCPermissionStatus *testSDLRPCPermissionStatusSpec = nil;
+
+ beforeEach(^{
+ testSDLRPCPermissionStatusSpec = [[SDLRPCPermissionStatus alloc] initWithRPCName:testRPCName isRPCAllowed:isRPCAllowed rpcParameters:allowedParameters];
+ });
+
+ it(@"should set rpcName, isRPCAllowed, rpcParameters correctly", ^{
+ expect(testSDLRPCPermissionStatusSpec.rpcName).to(equal(testRPCName));
+ expect(testSDLRPCPermissionStatusSpec.isRPCAllowed).to(equal(isRPCAllowed));
+ expect(testSDLRPCPermissionStatusSpec.rpcParameters[testParameterName]).to(equal(@NO));
+ });
+ });
+});
+
+QuickSpecEnd