diff options
33 files changed, 842 insertions, 72 deletions
diff --git a/src/appMain/sdl_preloaded_pt.json b/src/appMain/sdl_preloaded_pt.json index 1b3f2b0ff5..3aaeba10eb 100644 --- a/src/appMain/sdl_preloaded_pt.json +++ b/src/appMain/sdl_preloaded_pt.json @@ -2352,7 +2352,9 @@ "steal_focus": false,
"priority": "NONE",
"default_hmi": "NONE",
- "groups": ["Base-4"]
+ "groups": ["Base-4"],
+ "RequestType": [],
+ "RequestSubType": []
},
"device": {
"keep_context": false,
diff --git a/src/components/application_manager/include/application_manager/policies/policy_handler.h b/src/components/application_manager/include/application_manager/policies/policy_handler.h index b4653c6cb2..73a05b370e 100644 --- a/src/components/application_manager/include/application_manager/policies/policy_handler.h +++ b/src/components/application_manager/include/application_manager/policies/policy_handler.h @@ -487,6 +487,32 @@ class PolicyHandler : public PolicyHandlerInterface, mobile_apis::RequestType::eType type) const OVERRIDE; /** + * @brief Checks if certain request subtype is allowed for application + * @param policy_app_id Unique applicaion id + * @param request_subtype Request subtype + * @return true, if allowed, otherwise - false + */ + bool IsRequestSubTypeAllowed( + const std::string& policy_app_id, + const std::string& request_subtype) const OVERRIDE; + + /** + * @brief Gets application request types state + * @param policy_app_id Unique application id + * @return request types state + */ + RequestType::State GetAppRequestTypeState( + const std::string& policy_app_id) const OVERRIDE; + + /** + * @brief Gets application request subtypes state + * @param policy_app_id Unique application id + * @return request subtypes state + */ + RequestSubType::State GetAppRequestSubTypeState( + const std::string& policy_app_id) const OVERRIDE; + + /** * @brief Gets application request types * @param policy_app_id Unique application id * @return request types @@ -495,6 +521,14 @@ class PolicyHandler : public PolicyHandlerInterface, const std::string& policy_app_id) const OVERRIDE; /** + * @brief Gets application request subtypes + * @param policy_app_id Unique application id + * @return app request subtypes + */ + const std::vector<std::string> GetAppRequestSubTypes( + const std::string& policy_app_id) const OVERRIDE; + + /** * @brief Gets vehicle information * @return Structure with vehicle information */ diff --git a/src/components/application_manager/include/application_manager/smart_object_keys.h b/src/components/application_manager/include/application_manager/smart_object_keys.h index b5bf111449..8b838bd32a 100644 --- a/src/components/application_manager/include/application_manager/smart_object_keys.h +++ b/src/components/application_manager/include/application_manager/smart_object_keys.h @@ -195,6 +195,7 @@ extern const char* file_type; extern const char* file_size; extern const char* crc32_check_sum; extern const char* request_type; +extern const char* request_subtype; extern const char* persistent_file; extern const char* file_data; extern const char* space_available; diff --git a/src/components/application_manager/src/commands/command_request_impl.cc b/src/components/application_manager/src/commands/command_request_impl.cc index 515d8a998c..527d640c5c 100644 --- a/src/components/application_manager/src/commands/command_request_impl.cc +++ b/src/components/application_manager/src/commands/command_request_impl.cc @@ -39,6 +39,7 @@ #include "application_manager/application_manager.h" #include "application_manager/message_helper.h" #include "smart_objects/smart_object.h" + namespace application_manager { namespace commands { @@ -605,10 +606,8 @@ bool CommandRequestImpl::CheckAllowedParameters() { smart_objects::SmartMap::const_iterator iter_end = s_map.map_end(); for (; iter != iter_end; ++iter) { - if (iter->second.asBool()) { - LOG4CXX_DEBUG(logger_, "Request's param: " << iter->first); - params.insert(iter->first); - } + LOG4CXX_DEBUG(logger_, "Request's param: " << iter->first); + params.insert(iter->first); } mobile_apis::Result::eType check_result = diff --git a/src/components/application_manager/src/commands/mobile/on_system_request_notification.cc b/src/components/application_manager/src/commands/mobile/on_system_request_notification.cc index c29ff3e2d3..78ab666056 100644 --- a/src/components/application_manager/src/commands/mobile/on_system_request_notification.cc +++ b/src/components/application_manager/src/commands/mobile/on_system_request_notification.cc @@ -65,19 +65,40 @@ void OnSystemRequestNotification::Run() { return; } - RequestType::eType request_type = static_cast<RequestType::eType>( - (*message_)[strings::msg_params][strings::request_type].asInt()); + const mobile_apis::RequestType::eType request_type = + static_cast<mobile_apis::RequestType::eType>( + (*message_)[strings::msg_params][strings::request_type].asInt()); const policy::PolicyHandlerInterface& policy_handler = application_manager_.GetPolicyHandler(); + + const std::string stringified_request_type = + rpc::policy_table_interface_base::EnumToJsonString( + static_cast<rpc::policy_table_interface_base::RequestType>( + request_type)); + if (!policy_handler.IsRequestTypeAllowed(app->policy_app_id(), request_type)) { LOG4CXX_WARN(logger_, - "Request type " << request_type + "Request type " << stringified_request_type << " is not allowed by policies"); return; } - if (RequestType::PROPRIETARY == request_type) { + const bool request_subtype_present = + (*message_)[strings::msg_params].keyExists(strings::request_subtype); + if (request_subtype_present) { + const std::string request_subtype = + (*message_)[strings::msg_params][strings::request_subtype].asString(); + if (!policy_handler.IsRequestSubTypeAllowed(app->policy_app_id(), + request_subtype)) { + LOG4CXX_ERROR(logger_, + "Request subtype: " << request_subtype + << " is DISALLOWED by policies"); + return; + } + } + + if (mobile_apis::RequestType::PROPRIETARY == request_type) { /* According to requirements: "If the requestType = PROPRIETARY, add to mobile API fileType = JSON If the requestType = HTTP, add to mobile API fileType = BINARY" @@ -97,7 +118,7 @@ void OnSystemRequestNotification::Run() { #endif // PROPRIETARY_MODE (*message_)[strings::msg_params][strings::file_type] = FileType::JSON; - } else if (RequestType::HTTP == request_type) { + } else if (mobile_apis::RequestType::HTTP == request_type) { (*message_)[strings::msg_params][strings::file_type] = FileType::BINARY; if ((*message_)[strings::msg_params].keyExists(strings::url)) { (*message_)[strings::msg_params][strings::timeout] = @@ -183,8 +204,8 @@ size_t OnSystemRequestNotification::ParsePTString( if (pt_string[i] == '\"' || pt_string[i] == '\\') { result += '\\'; } else if (pt_string[i] == '\n') { - result_length--; // contentLength is adjusted when this character is not - // copied to result. + result_length--; // contentLength is adjusted when this character is + // not copied to result. continue; } result += pt_string[i]; diff --git a/src/components/application_manager/src/commands/mobile/register_app_interface_request.cc b/src/components/application_manager/src/commands/mobile/register_app_interface_request.cc index c799d68609..a58534b52b 100644 --- a/src/components/application_manager/src/commands/mobile/register_app_interface_request.cc +++ b/src/components/application_manager/src/commands/mobile/register_app_interface_request.cc @@ -822,8 +822,9 @@ void RegisterAppInterfaceRequest::SendOnAppRegisteredNotificationToHMI( msg_params[strings::tts_name] = *(application_impl.tts_name()); } + const std::string policy_app_id = application_impl.policy_app_id(); std::string priority; - GetPolicyHandler().GetPriority(application_impl.policy_app_id(), &priority); + GetPolicyHandler().GetPriority(policy_app_id, &priority); if (!priority.empty()) { msg_params[strings::priority] = MessageHelper::GetPriorityCode(priority); @@ -833,7 +834,7 @@ void RegisterAppInterfaceRequest::SendOnAppRegisteredNotificationToHMI( smart_objects::SmartObject& application = msg_params[strings::application]; application[strings::app_name] = application_impl.name(); application[strings::app_id] = application_impl.app_id(); - application[hmi_response::policy_app_id] = application_impl.policy_app_id(); + application[hmi_response::policy_app_id] = policy_app_id; application[strings::icon] = application_impl.app_icon_path(); const smart_objects::SmartObject* ngn_media_screen_name = @@ -853,18 +854,41 @@ void RegisterAppInterfaceRequest::SendOnAppRegisteredNotificationToHMI( application[strings::app_type] = *app_type; } - std::vector<std::string> request_types = - GetPolicyHandler().GetAppRequestTypes(application_impl.policy_app_id()); + const policy::RequestType::State app_request_types_state = + GetPolicyHandler().GetAppRequestTypeState(policy_app_id); + if (policy::RequestType::State::AVAILABLE == app_request_types_state) { + const auto request_types = + GetPolicyHandler().GetAppRequestTypes(policy_app_id); + application[strings::request_type] = SmartObject(SmartType_Array); + smart_objects::SmartObject& request_types_array = + application[strings::request_type]; - application[strings::request_type] = SmartObject(SmartType_Array); - smart_objects::SmartObject& request_array = - application[strings::request_type]; - - uint32_t index = 0; - std::vector<std::string>::const_iterator it = request_types.begin(); - for (; request_types.end() != it; ++it) { - request_array[index] = *it; - ++index; + size_t index = 0; + for (auto it : request_types) { + request_types_array[index] = it; + ++index; + } + } else if (policy::RequestType::State::EMPTY == app_request_types_state) { + application[strings::request_type] = SmartObject(SmartType_Array); + } + + const policy::RequestSubType::State app_request_subtypes_state = + GetPolicyHandler().GetAppRequestSubTypeState(policy_app_id); + if (policy::RequestSubType::State::AVAILABLE == app_request_subtypes_state) { + const auto request_subtypes = + GetPolicyHandler().GetAppRequestSubTypes(policy_app_id); + application[strings::request_subtype] = SmartObject(SmartType_Array); + smart_objects::SmartObject& request_subtypes_array = + application[strings::request_subtype]; + + size_t index = 0; + for (auto it : request_subtypes) { + request_subtypes_array[index] = it; + ++index; + } + } else if (policy::RequestSubType::State::EMPTY == + app_request_subtypes_state) { + application[strings::request_subtype] = SmartObject(SmartType_Array); } application[strings::device_info] = SmartObject(SmartType_Map); diff --git a/src/components/application_manager/src/commands/mobile/system_request.cc b/src/components/application_manager/src/commands/mobile/system_request.cc index fe38b93732..c081510e7c 100644 --- a/src/components/application_manager/src/commands/mobile/system_request.cc +++ b/src/components/application_manager/src/commands/mobile/system_request.cc @@ -454,17 +454,43 @@ void SystemRequest::Run() { const policy::PolicyHandlerInterface& policy_handler = application_manager_.GetPolicyHandler(); + + const std::string stringified_request_type = + rpc::policy_table_interface_base::EnumToJsonString( + static_cast<rpc::policy_table_interface_base::RequestType>( + request_type)); + if (!policy_handler.IsRequestTypeAllowed(application->policy_app_id(), request_type)) { + LOG4CXX_ERROR(logger_, + "RequestType " << stringified_request_type + << " is DISALLOWED by policies"); SendResponse(false, mobile_apis::Result::DISALLOWED); return; } + LOG4CXX_TRACE(logger_, + "RequestType " << stringified_request_type << " is ALLOWED"); + + const bool request_subtype_present = + (*message_)[strings::msg_params].keyExists(strings::request_subtype); + if (request_subtype_present) { + const std::string request_subtype = + (*message_)[strings::msg_params][strings::request_subtype].asString(); + if (!policy_handler.IsRequestSubTypeAllowed(application->policy_app_id(), + request_subtype)) { + LOG4CXX_ERROR(logger_, + "Request subtype: " << request_subtype + << " is DISALLOWED by policies"); + SendResponse(false, mobile_apis::Result::DISALLOWED); + return; + } + LOG4CXX_TRACE(logger_, + "Request subtype: " << request_subtype << " is ALLOWED"); + } - std::string file_name; + std::string file_name = kSYNC; if ((*message_)[strings::msg_params].keyExists(strings::file_name)) { file_name = (*message_)[strings::msg_params][strings::file_name].asString(); - } else { - file_name = kSYNC; } if (!CheckSyntax(file_name)) { @@ -481,8 +507,8 @@ void SystemRequest::Run() { return; } - bool is_system_file = std::string::npos != file_name.find(kSYNC) || - std::string::npos != file_name.find(kIVSU); + const bool is_system_file = std::string::npos != file_name.find(kSYNC) || + std::string::npos != file_name.find(kIVSU); // to avoid override existing file if (is_system_file) { @@ -587,6 +613,10 @@ void SystemRequest::Run() { msg_params[strings::request_type] = (*message_)[strings::msg_params][strings::request_type]; + if (request_subtype_present) { + msg_params[strings::request_subtype] = + (*message_)[strings::msg_params][strings::request_subtype]; + } StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_BasicCommunication); SendHMIRequest(hmi_apis::FunctionID::BasicCommunication_SystemRequest, &msg_params, diff --git a/src/components/application_manager/src/message_helper/message_helper.cc b/src/components/application_manager/src/message_helper/message_helper.cc index a848cf9ad9..d3af65effa 100644 --- a/src/components/application_manager/src/message_helper/message_helper.cc +++ b/src/components/application_manager/src/message_helper/message_helper.cc @@ -2603,12 +2603,23 @@ void MessageHelper::SendOnAppPermissionsChangedNotification( if (permissions.requestTypeChanged) { smart_objects::SmartObject request_types_array( smart_objects::SmartType_Array); - ; + for (uint16_t index = 0; index < permissions.requestType.size(); ++index) { request_types_array[index] = permissions.requestType[index]; } message[strings::msg_params][strings::request_type] = request_types_array; } + if (permissions.requestSubTypeChanged) { + smart_objects::SmartObject request_subtypes_array( + smart_objects::SmartType_Array); + + for (uint16_t index = 0; index < permissions.requestSubType.size(); + ++index) { + request_subtypes_array[index] = permissions.requestSubType[index]; + } + message[strings::msg_params][strings::request_subtype] = + request_subtypes_array; + } app_mngr.ManageHMICommand( utils::MakeShared<smart_objects::SmartObject>(message)); diff --git a/src/components/application_manager/src/policies/policy_handler.cc b/src/components/application_manager/src/policies/policy_handler.cc index 559b9c0035..b9446bcb3c 100644 --- a/src/components/application_manager/src/policies/policy_handler.cc +++ b/src/components/application_manager/src/policies/policy_handler.cc @@ -54,6 +54,7 @@ #include "utils/file_system.h" #include "utils/scope_guard.h" #include "utils/make_shared.h" +#include "utils/helpers.h" #include "policy/policy_manager.h" #ifdef SDL_REMOTE_CONTROL #include "functional_module/plugin_manager.h" @@ -90,7 +91,8 @@ RequestTypeMap TypeToString = { {mobile_apis::RequestType::VEHICLE_DIAGNOSTICS, "VEHICLE_DIAGNOSTICS"}, {mobile_apis::RequestType::EMERGENCY, "EMERGENCY"}, {mobile_apis::RequestType::MEDIA, "MEDIA"}, - {mobile_apis::RequestType::FOTA, "FOTA"}}; + {mobile_apis::RequestType::FOTA, "FOTA"}, + {mobile_apis::RequestType::OEM_SPECIFIC, "OEM_SPECIFIC"}}; const std::string RequestTypeToString(mobile_apis::RequestType::eType type) { RequestTypeMap::const_iterator it = TypeToString.find(type); @@ -1024,7 +1026,7 @@ void PolicyHandler::OnPendingPermissionChange( policy_manager_->RemovePendingPermissionChanges(policy_app_id); } - if (permissions.requestTypeChanged) { + if (permissions.requestTypeChanged || permissions.requestSubTypeChanged) { MessageHelper::SendOnAppPermissionsChangedNotification( app->app_id(), permissions, application_manager_); policy_manager_->RemovePendingPermissionChanges(policy_app_id); @@ -1879,6 +1881,18 @@ void PolicyHandler::OnAppRegisteredOnMobile(const std::string& application_id) { policy_manager_->OnAppRegisteredOnMobile(application_id); } +RequestType::State PolicyHandler::GetAppRequestTypeState( + const std::string& policy_app_id) const { + POLICY_LIB_CHECK(RequestType::State::UNAVAILABLE); + return policy_manager_->GetAppRequestTypesState(policy_app_id); +} + +RequestSubType::State PolicyHandler::GetAppRequestSubTypeState( + const std::string& policy_app_id) const { + POLICY_LIB_CHECK(RequestSubType::State::UNAVAILABLE); + return policy_manager_->GetAppRequestSubTypesState(policy_app_id); +} + bool PolicyHandler::IsRequestTypeAllowed( const std::string& policy_app_id, mobile_apis::RequestType::eType type) const { @@ -1891,17 +1905,66 @@ bool PolicyHandler::IsRequestTypeAllowed( return false; } - std::vector<std::string> request_types = - policy_manager_->GetAppRequestTypes(policy_app_id); + const RequestType::State request_type_state = + policy_manager_->GetAppRequestTypesState(policy_app_id); - // If no request types are assigned to app - any is allowed - if (request_types.empty()) { - return true; + switch (request_type_state) { + case RequestType::State::EMPTY: { + // If empty array of request types is assigned to app - any is allowed + LOG4CXX_TRACE(logger_, "Any Request Type is allowed by policies."); + return true; + } + case RequestType::State::OMITTED: { + // If RequestType parameter omitted for app - any is disallowed + LOG4CXX_TRACE(logger_, "All Request Types are disallowed by policies."); + return false; + } + case RequestType::State::AVAILABLE: { + // If any of request types is available for current application - get them + const auto request_types = + policy_manager_->GetAppRequestTypes(policy_app_id); + return helpers::in_range(request_types, stringified_type); + } + default: + return false; } +} - std::vector<std::string>::const_iterator it = - std::find(request_types.begin(), request_types.end(), stringified_type); - return request_types.end() != it; +bool PolicyHandler::IsRequestSubTypeAllowed( + const std::string& policy_app_id, + const std::string& request_subtype) const { + POLICY_LIB_CHECK(false); + using namespace mobile_apis; + + if (request_subtype.empty()) { + LOG4CXX_ERROR(logger_, "Request subtype to check is empty."); + return false; + } + + const RequestSubType::State request_subtype_state = + policy_manager_->GetAppRequestSubTypesState(policy_app_id); + switch (request_subtype_state) { + case RequestSubType::State::EMPTY: { + // If empty array of request subtypes is assigned to app - any is allowed + LOG4CXX_TRACE(logger_, "Any Request SubType is allowed by policies."); + return true; + } + case RequestSubType::State::OMITTED: { + // If RequestSubType parameter omitted for app - any is disallowed + LOG4CXX_TRACE(logger_, + "All Request SubTypes are disallowed by policies."); + return false; + } + case RequestSubType::State::AVAILABLE: { + // If any of request subtypes is available for current application + // get them all + const auto request_subtypes = + policy_manager_->GetAppRequestSubTypes(policy_app_id); + return helpers::in_range(request_subtypes, request_subtype); + } + default: + return false; + } } const std::vector<std::string> PolicyHandler::GetAppRequestTypes( @@ -1910,6 +1973,12 @@ const std::vector<std::string> PolicyHandler::GetAppRequestTypes( return policy_manager_->GetAppRequestTypes(policy_app_id); } +const std::vector<std::string> PolicyHandler::GetAppRequestSubTypes( + const std::string& policy_app_id) const { + POLICY_LIB_CHECK(std::vector<std::string>()); + return policy_manager_->GetAppRequestSubTypes(policy_app_id); +} + const VehicleInfo policy::PolicyHandler::GetVehicleInfo() const { POLICY_LIB_CHECK(VehicleInfo()); return policy_manager_->GetVehicleInfo(); diff --git a/src/components/application_manager/src/smart_object_keys.cc b/src/components/application_manager/src/smart_object_keys.cc index 421796c388..7e21cb5d33 100644 --- a/src/components/application_manager/src/smart_object_keys.cc +++ b/src/components/application_manager/src/smart_object_keys.cc @@ -159,6 +159,7 @@ const char* file_type = "fileType"; const char* file_size = "fileSize"; const char* crc32_check_sum = "crc"; const char* request_type = "requestType"; +const char* request_subtype = "requestSubType"; const char* persistent_file = "persistentFile"; const char* file_data = "fileData"; const char* space_available = "spaceAvailable"; diff --git a/src/components/include/application_manager/policies/policy_handler_interface.h b/src/components/include/application_manager/policies/policy_handler_interface.h index f0859ece38..d48c7307b9 100644 --- a/src/components/include/application_manager/policies/policy_handler_interface.h +++ b/src/components/include/application_manager/policies/policy_handler_interface.h @@ -49,6 +49,7 @@ #include "smart_objects/smart_object.h" #include "policy/policy_types.h" #include "policy/policy_table/types.h" +#include "policy/cache_manager_interface.h" using namespace ::rpc::policy_table_interface_base; namespace policy { @@ -391,6 +392,32 @@ class PolicyHandlerInterface { mobile_apis::RequestType::eType type) const = 0; /** + * @brief Checks if certain request subtype is allowed for application + * @param policy_app_id Unique applicaion id + * @param request_subtype Request subtype + * @return true, if allowed, otherwise - false + */ + virtual bool IsRequestSubTypeAllowed( + const std::string& policy_app_id, + const std::string& request_subtype) const = 0; + + /** + * @brief Gets application request types state + * @param policy_app_id Unique application id + * @return request types state + */ + virtual RequestType::State GetAppRequestTypeState( + const std::string& policy_app_id) const = 0; + + /** + * @brief Gets application request subtypes state + * @param policy_app_id Unique application id + * @return request subtypes state + */ + virtual RequestSubType::State GetAppRequestSubTypeState( + const std::string& policy_app_id) const = 0; + + /** * @brief Gets application request types * @param policy_app_id Unique application id * @return request types @@ -399,6 +426,14 @@ class PolicyHandlerInterface { const std::string& policy_app_id) const = 0; /** + * @brief Gets application request subtypes + * @param policy_app_id Unique application id + * @return app request subtypes + */ + virtual const std::vector<std::string> GetAppRequestSubTypes( + const std::string& policy_app_id) const = 0; + + /** * @brief Gets vehicle information * @return Structure with vehicle information */ diff --git a/src/components/include/policy/policy_regular/policy/policy_manager.h b/src/components/include/policy/policy_regular/policy/policy_manager.h index 3e90cfc094..84d48a691e 100644 --- a/src/components/include/policy/policy_regular/policy/policy_manager.h +++ b/src/components/include/policy/policy_regular/policy/policy_manager.h @@ -41,6 +41,8 @@ #include "policy/policy_table/types.h" #include "policy/policy_listener.h" #include "policy/usage_statistics/statistics_manager.h" +#include "policy/cache_manager_interface.h" + #ifdef SDL_REMOTE_CONTROL #include "policy/access_remote.h" #endif // SDL_REMOTE_CONTROL @@ -466,6 +468,22 @@ class PolicyManager : public usage_statistics::StatisticsManager { virtual void OnAppsSearchCompleted(const bool trigger_ptu) = 0; /** + * @brief Get state of request types for given application + * @param policy_app_id Unique application id + * @return request type state + */ + virtual RequestType::State GetAppRequestTypesState( + const std::string& policy_app_id) const = 0; + + /** + * @brief Get state of request subtypes for given application + * @param policy_app_id Unique application id + * @return request subtype state + */ + virtual RequestSubType::State GetAppRequestSubTypesState( + const std::string& policy_app_id) const = 0; + + /** * @brief Gets request types for application * @param policy_app_id Unique application id * @return request types of application @@ -474,6 +492,14 @@ class PolicyManager : public usage_statistics::StatisticsManager { const std::string policy_app_id) const = 0; /** + * @brief Gets request subtypes for application + * @param policy_app_id Unique application id + * @return request subtypes of application + */ + virtual const std::vector<std::string> GetAppRequestSubTypes( + const std::string& policy_app_id) const = 0; + + /** * @brief Get information about vehicle * @return vehicle information */ diff --git a/src/components/interfaces/HMI_API.xml b/src/components/interfaces/HMI_API.xml index 2b34de0440..33f23409ea 100644 --- a/src/components/interfaces/HMI_API.xml +++ b/src/components/interfaces/HMI_API.xml @@ -1137,13 +1137,13 @@ </enum> <enum name="RequestType"> - <description>Enumeration listing possible asynchronous requests.</description> - <element name="HTTP" /> - <element name="FILE_RESUME" /> - <element name="AUTH_REQUEST" /> - <element name="AUTH_CHALLENGE" /> - <element name="AUTH_ACK" /> - <element name="PROPRIETARY" /> + <description>Enumeration listing possible asynchronous requests.</description> + <element name="HTTP" /> + <element name="FILE_RESUME" /> + <element name="AUTH_REQUEST" /> + <element name="AUTH_CHALLENGE" /> + <element name="AUTH_ACK" /> + <element name="PROPRIETARY" /> <element name="QUERY_APPS" /> <element name="LAUNCH_APP" /> <element name="LOCK_SCREEN_ICON_URL" /> @@ -1158,6 +1158,7 @@ <element name="EMERGENCY" /> <element name="MEDIA" /> <element name="FOTA" /> + <element name="OEM_SPECIFIC"/> </enum> <enum name="ECallConfirmationStatus"> @@ -1983,6 +1984,14 @@ <description>If SDL omits this parameter - none RequestType is allowed for this app</description> <description>(either this is a pre-registered app or such is dictated by policies).</description> </param> + <param name="requestSubType" type="String" maxlength="100" minsize="0" maxsize="100" array="true" mandatory="false"> + <description> + The list of SystemRequest's requestSubTypes allowed by policies for the named application. + If the app sends a requestSubType which is not specified in this list, then that request should be rejected. + An empty array signifies that any value of requestSubType is allowed for this app. + If this parameter is omitted, then a request with any value of requestSubType is now allowed for this app + </description> + </param> <param name="dayColorScheme" type="Common.TemplateColorScheme" mandatory="false"></param> <param name="nightColorScheme" type="Common.TemplateColorScheme" mandatory="false"></param> </struct> @@ -2986,6 +2995,11 @@ <param name="requestType" type="Common.RequestType" mandatory="true"> <description>The type of system request.</description> </param> + <param name="requestSubType" type="String" maxlength="255" mandatory="false"> + <description> + This parameter is filled for supporting OEM proprietary data exchanges. + </description> + </param> <param name="url" type="String" maxlength="1000" minlength="1" mandatory="false"> <description>Optional array of URL(s) for HTTP requests.</description> </param> @@ -3012,6 +3026,11 @@ <param name="requestType" type="Common.RequestType" mandatory="true"> <description>The type of system request.</description> </param> + <param name="requestSubType" type="String" maxlength="255" mandatory="false"> + <description> + This parameter is filled for supporting OEM proprietary data exchanges. + </description> + </param> <param name="fileName" type="String" maxlength="255" minlength="1" mandatory="true"> <description>The path to file.</description> </param> @@ -4937,6 +4956,14 @@ If SDL omits this parameter - nothing is changed for RequestType in the policies </description> </param> + <param name="requestSubType" type="String" maxlength="100" minsize="0" maxsize="100" array="true" mandatory="false"> + <description> + The list of SystemRequest's requestSubTypes allowed by policies for the named application. + If the app sends a requestSubType which is not specified in this list, then that request should be rejected. + An empty array signifies that any value of requestSubType is allowed for this app. + If this parameter is omitted, then a request with any value of requestSubType is now allowed for this app + </description> + </param> </function> <function name="OnSDLConsentNeeded" messagetype="notification"> diff --git a/src/components/interfaces/MOBILE_API.xml b/src/components/interfaces/MOBILE_API.xml index 2cbae29c8c..34e0744459 100644 --- a/src/components/interfaces/MOBILE_API.xml +++ b/src/components/interfaces/MOBILE_API.xml @@ -2183,6 +2183,7 @@ <element name="EMERGENCY" /> <element name="MEDIA" /> <element name="FOTA" /> + <element name="OEM_SPECIFIC" /> </enum> <enum name="AppHMIType"> <description>Enumeration listing possible app types.</description> @@ -5401,6 +5402,11 @@ Note that Proprietary requests should forward the binary data to the known proprietary module on the system. </description> </param> + <param name="requestSubType" type="String" maxlength="255" mandatory="false"> + <description> + This parameter is filled for supporting OEM proprietary data exchanges. + </description> + </param> <param name="fileName" type="String" maxlength="255" mandatory="false"> <description> Filename of HTTP data to store in predefined system staging area. @@ -6000,6 +6006,11 @@ <param name="requestType" type="RequestType" mandatory="true"> <description>The type of system request.</description> </param> + <param name="requestSubType" type="String" maxlength="255" mandatory="false"> + <description> + This parameter is filled for supporting OEM proprietary data exchanges. + </description> + </param> <param name="url" type="String" maxlength="1000" mandatory="false"> <description> Optional URL for HTTP requests. diff --git a/src/components/policy/policy_external/include/policy/policy_table/enums.h b/src/components/policy/policy_external/include/policy/policy_table/enums.h index fa37cfe7a5..9f80921bb3 100644 --- a/src/components/policy/policy_external/include/policy/policy_table/enums.h +++ b/src/components/policy/policy_external/include/policy/policy_table/enums.h @@ -149,7 +149,8 @@ enum RequestType { RT_VEHICLE_DIAGNOSTICS, RT_EMERGENCY, RT_MEDIA, - RT_FOTA + RT_FOTA, + RT_OEM_SPECIFIC }; bool IsValidEnum(RequestType val); diff --git a/src/components/policy/policy_external/src/policy_table/enums.cc b/src/components/policy/policy_external/src/policy_table/enums.cc index beea68a276..e27da4674e 100644 --- a/src/components/policy/policy_external/src/policy_table/enums.cc +++ b/src/components/policy/policy_external/src/policy_table/enums.cc @@ -605,6 +605,8 @@ bool IsValidEnum(RequestType val) { return true; case RT_FOTA: return true; + case RT_OEM_SPECIFIC: + return true; default: return false; } @@ -652,6 +654,8 @@ const char* EnumToJsonString(RequestType val) { return "MEDIA"; case RT_FOTA: return "FOTA"; + case RT_OEM_SPECIFIC: + return "OEM_SPECIFIC"; default: return ""; } @@ -737,6 +741,10 @@ bool EnumFromJsonString(const std::string& literal, RequestType* result) { if ("FOTA" == literal) { *result = RT_FOTA; return true; + } + if ("OEM_SPECIFIC" == literal) { + *result = RT_OEM_SPECIFIC; + return true; } else { return false; } diff --git a/src/components/policy/policy_regular/include/policy/cache_manager.h b/src/components/policy/policy_regular/include/policy/cache_manager.h index 8c0acd44d2..4a0a09db83 100644 --- a/src/components/policy/policy_regular/include/policy/cache_manager.h +++ b/src/components/policy/policy_regular/include/policy/cache_manager.h @@ -73,6 +73,22 @@ class CacheManager : public CacheManagerInterface { CheckPermissionResult& result); /** + * @brief Get state of request types for given application + * @param policy_app_id Unique application id + * @return request type state + */ + RequestType::State GetAppRequestTypesState( + const std::string& policy_app_id) const OVERRIDE; + + /** + * @brief Get state of request subtypes for given application + * @param policy_app_id Unique application id + * @return request subtype state + */ + RequestSubType::State GetAppRequestSubTypesState( + const std::string& policy_app_id) const OVERRIDE; + + /** * @brief Returns true if Policy Table was not updated yet * from preloaded pt file. */ @@ -597,8 +613,18 @@ class CacheManager : public CacheManagerInterface { * @param policy_app_id Unique application id * @param request_types Request types of application */ - void GetAppRequestTypes(const std::string& policy_app_id, - std::vector<std::string>& request_types) const; + void GetAppRequestTypes( + const std::string& policy_app_id, + std::vector<std::string>& request_types) const OVERRIDE; + + /** + * @brief Gets request subtypes for application + * @param policy_app_id Unique application id + * @param request_subtypes Request subtypes of application to be filled + */ + void GetAppRequestSubTypes( + const std::string& policy_app_id, + std::vector<std::string>& request_subtypes) const OVERRIDE; /** * @brief GetCertificate allows to obtain certificate in order to diff --git a/src/components/policy/policy_regular/include/policy/cache_manager_interface.h b/src/components/policy/policy_regular/include/policy/cache_manager_interface.h index 9f7c7318db..3dd2953865 100644 --- a/src/components/policy/policy_regular/include/policy/cache_manager_interface.h +++ b/src/components/policy/policy_regular/include/policy/cache_manager_interface.h @@ -46,6 +46,16 @@ namespace policy_table = rpc::policy_table_interface_base; namespace policy { +namespace RequestType { +// Describes available RequestType states in policy table +enum class State { UNAVAILABLE = 0, AVAILABLE, EMPTY, OMITTED }; +} // namespace RequestType + +namespace RequestSubType { +// Describes available RequestSubType states in policy table +enum class State { UNAVAILABLE = 0, AVAILABLE, EMPTY, OMITTED }; +} // namespace RequestSubType + class CacheManagerInterface { public: virtual ~CacheManagerInterface() {} @@ -67,6 +77,22 @@ class CacheManagerInterface { CheckPermissionResult& result) = 0; /** + * @brief Get state of request types for given application + * @param policy_app_id Unique application id + * @return request type state + */ + virtual RequestType::State GetAppRequestTypesState( + const std::string& policy_app_id) const = 0; + + /** + * @brief Get state of request subtypes for given application + * @param policy_app_id Unique application id + * @return request subtype state + */ + virtual RequestSubType::State GetAppRequestSubTypesState( + const std::string& policy_app_id) const = 0; + + /** * @brief Returns true if Policy Table was not updated yet * from preloaded pt file. */ @@ -627,6 +653,15 @@ class CacheManagerInterface { std::vector<std::string>& request_types) const = 0; /** + * @brief Gets request subtypes for application + * @param policy_app_id Unique application id + * @param request_subtypes Request subtypes of application to be filled + */ + virtual void GetAppRequestSubTypes( + const std::string& policy_app_id, + std::vector<std::string>& request_subtypes) const = 0; + + /** * @brief GetCertificate allows to obtain certificate in order to * make secure connection * diff --git a/src/components/policy/policy_regular/include/policy/policy_helper.h b/src/components/policy/policy_regular/include/policy/policy_helper.h index 8a60801dd4..debfff68ae 100644 --- a/src/components/policy/policy_regular/include/policy/policy_helper.h +++ b/src/components/policy/policy_regular/include/policy/policy_helper.h @@ -95,7 +95,9 @@ struct CheckAppPolicy { RESULT_CONSENT_NEEDED, RESULT_CONSENT_NOT_REQIURED, RESULT_PERMISSIONS_REVOKED_AND_CONSENT_NEEDED, - RESULT_REQUEST_TYPE_CHANGED + RESULT_REQUEST_TYPE_CHANGED, + RESULT_REQUEST_SUBTYPE_CHANGED, + RESULT_REQUEST_TYPE_AND_SUBTYPE_CHANGED }; void SetPendingPermissions(const AppPoliciesValueType& app_policy, @@ -126,6 +128,7 @@ struct CheckAppPolicy { bool IsConsentRequired(const std::string& app_id, const std::string& group_name) const; bool IsRequestTypeChanged(const AppPoliciesValueType& app_policy) const; + bool IsRequestSubTypeChanged(const AppPoliciesValueType& app_policy) const; private: PolicyManagerImpl* pm_; diff --git a/src/components/policy/policy_regular/include/policy/policy_manager_impl.h b/src/components/policy/policy_regular/include/policy/policy_manager_impl.h index 941db1a67f..8379cf4d82 100644 --- a/src/components/policy/policy_regular/include/policy/policy_manager_impl.h +++ b/src/components/policy/policy_regular/include/policy/policy_manager_impl.h @@ -532,6 +532,22 @@ class PolicyManagerImpl : public PolicyManager { void OnAppsSearchCompleted(const bool trigger_ptu) OVERRIDE; /** + * @brief Get state of request types for given application + * @param policy_app_id Unique application id + * @return request type state + */ + RequestType::State GetAppRequestTypesState( + const std::string& policy_app_id) const OVERRIDE; + + /** + * @brief Get state of request subtypes for given application + * @param policy_app_id Unique application id + * @return request subtype state + */ + RequestSubType::State GetAppRequestSubTypesState( + const std::string& policy_app_id) const OVERRIDE; + + /** * @brief Gets request types for application * @param policy_app_id Unique application id * @return request types of application @@ -540,6 +556,14 @@ class PolicyManagerImpl : public PolicyManager { const std::string policy_app_id) const OVERRIDE; /** + * @brief Gets request subtypes for application + * @param policy_app_id Unique application id + * @return request subtypes of application + */ + const std::vector<std::string> GetAppRequestSubTypes( + const std::string& policy_app_id) const OVERRIDE; + + /** * @brief Get information about vehicle * @return vehicle information */ diff --git a/src/components/policy/policy_regular/include/policy/policy_table/enums.h b/src/components/policy/policy_regular/include/policy/policy_table/enums.h index bd3319dba6..dbe00d0f9c 100644 --- a/src/components/policy/policy_regular/include/policy/policy_table/enums.h +++ b/src/components/policy/policy_regular/include/policy/policy_table/enums.h @@ -134,7 +134,9 @@ enum RequestType { RT_VEHICLE_DIAGNOSTICS, RT_EMERGENCY, RT_MEDIA, - RT_FOTA + RT_FOTA, + RT_OEM_SPECIFIC, + RT_EMPTY // Added to allow empty Request Types handling }; bool IsValidEnum(RequestType val); diff --git a/src/components/policy/policy_regular/include/policy/policy_table/types.h b/src/components/policy/policy_regular/include/policy/policy_table/types.h index 61585776f2..b09ae70716 100644 --- a/src/components/policy/policy_regular/include/policy/policy_table/types.h +++ b/src/components/policy/policy_regular/include/policy/policy_table/types.h @@ -96,6 +96,8 @@ typedef Map<DeviceParams, 0, 255> DeviceData; typedef Array<Enum<RequestType>, 0, 255> RequestTypes; +typedef Strings RequestSubTypes; + #ifdef SDL_REMOTE_CONTROL typedef Map<Strings, 0, 255> RemoteRpcs; typedef Map<RemoteRpcs, 0, 255> AccessModules; @@ -139,6 +141,7 @@ struct ApplicationParams : PolicyBase { Optional<Strings> nicknames; Optional<AppHMITypes> AppHMIType; Optional<RequestTypes> RequestType; + Optional<RequestSubTypes> RequestSubType; Optional<Integer<uint16_t, 0, 65225> > memory_kb; Optional<Integer<uint32_t, 0, UINT_MAX> > heart_beat_timeout_ms; Optional<String<0, 255> > certificate; diff --git a/src/components/policy/policy_regular/include/policy/policy_types.h b/src/components/policy/policy_regular/include/policy/policy_types.h index af1d119e7a..b30baa5955 100644 --- a/src/components/policy/policy_regular/include/policy/policy_types.h +++ b/src/components/policy/policy_regular/include/policy/policy_types.h @@ -267,7 +267,8 @@ struct AppPermissions { , appRevoked(false) , appPermissionsConsentNeeded(false) , appUnauthorized(false) - , requestTypeChanged(false) {} + , requestTypeChanged(false) + , requestSubTypeChanged(false) {} std::string application_id; bool isAppPermissionsRevoked; @@ -280,6 +281,8 @@ struct AppPermissions { DeviceParams deviceInfo; bool requestTypeChanged; std::vector<std::string> requestType; + bool requestSubTypeChanged; + std::vector<std::string> requestSubType; }; /** diff --git a/src/components/policy/policy_regular/include/policy/sql_pt_queries.h b/src/components/policy/policy_regular/include/policy/sql_pt_queries.h index 2ded25e456..5259ffa7e9 100644 --- a/src/components/policy/policy_regular/include/policy/sql_pt_queries.h +++ b/src/components/policy/policy_regular/include/policy/sql_pt_queries.h @@ -65,6 +65,7 @@ extern const std::string kSelectAppGroups; extern const std::string kSelectNicknames; extern const std::string kSelectAppTypes; extern const std::string kSelectRequestTypes; +extern const std::string kSelectRequestSubTypes; extern const std::string kSelectSecondsBetweenRetries; extern const std::string kSelectIgnitionCycles; extern const std::string kSelectKilometers; @@ -78,6 +79,9 @@ extern const std::string kInsertAppGroup; extern const std::string kInsertNickname; extern const std::string kInsertAppType; extern const std::string kInsertRequestType; +extern const std::string kInsertOmittedRequestType; +extern const std::string kInsertOmittedRequestSubType; +extern const std::string kInsertRequestSubType; extern const std::string kInsertMessageType; extern const std::string kInsertLanguage; extern const std::string kInsertMessageString; @@ -97,6 +101,7 @@ extern const std::string kDeleteRpc; extern const std::string kDeleteAppGroup; extern const std::string kDeleteApplication; extern const std::string kDeleteRequestType; +extern const std::string kDeleteRequestSubType; extern const std::string kDeleteDevice; extern const std::string kIncrementIgnitionCycles; extern const std::string kResetIgnitionCycles; diff --git a/src/components/policy/policy_regular/include/policy/sql_pt_representation.h b/src/components/policy/policy_regular/include/policy/sql_pt_representation.h index 6b5d6111f1..e39e0d5873 100644 --- a/src/components/policy/policy_regular/include/policy/sql_pt_representation.h +++ b/src/components/policy/policy_regular/include/policy/sql_pt_representation.h @@ -132,6 +132,9 @@ class SQLPTRepresentation : public virtual PTRepresentation { policy_table::AppHMITypes* app_types) const; bool GatherRequestType(const std::string& app_id, policy_table::RequestTypes* request_types) const; + bool GatherRequestSubType( + const std::string& app_id, + policy_table::RequestSubTypes* request_subtypes) const; bool GatherNickName(const std::string& app_id, policy_table::Strings* nicknames) const; @@ -167,6 +170,9 @@ class SQLPTRepresentation : public virtual PTRepresentation { const policy_table::AppHMITypes& types); bool SaveRequestType(const std::string& app_id, const policy_table::RequestTypes& types); + bool SaveRequestSubType( + const std::string& app_id, + const policy_table::RequestSubTypes& request_subtypes); public: bool UpdateRequired() const; diff --git a/src/components/policy/policy_regular/src/cache_manager.cc b/src/components/policy/policy_regular/src/cache_manager.cc index 6a142374d5..6c198983f2 100644 --- a/src/components/policy/policy_regular/src/cache_manager.cc +++ b/src/components/policy/policy_regular/src/cache_manager.cc @@ -39,6 +39,7 @@ #include <sstream> #include "utils/file_system.h" +#include "utils/helpers.h" #include "json/reader.h" #include "json/features.h" #include "json/writer.h" @@ -1550,6 +1551,28 @@ int32_t CacheManager::GenerateHash(const std::string& str_to_hash) { return result; } +RequestType::State CacheManager::GetAppRequestTypesState( + const std::string& policy_app_id) const { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock auto_lock(cache_lock_); + policy_table::ApplicationPolicies::iterator app_policies_iter = + pt_->policy_table.app_policies_section.apps.find(policy_app_id); + if (pt_->policy_table.app_policies_section.apps.end() == app_policies_iter) { + LOG4CXX_DEBUG(logger_, + "Can't find request types for app_id " << policy_app_id); + return RequestType::State::UNAVAILABLE; + } + const policy_table::RequestTypes& request_types = + *app_policies_iter->second.RequestType; + if (!request_types.is_initialized()) { + return RequestType::State::OMITTED; + } + if (request_types.empty()) { + return RequestType::State::EMPTY; + } + return RequestType::State::AVAILABLE; +} + void CacheManager::GetAppRequestTypes( const std::string& policy_app_id, std::vector<std::string>& request_types) const { @@ -1568,11 +1591,56 @@ void CacheManager::GetAppRequestTypes( "Can't find request types for app_id " << policy_app_id); return; } - policy_table::RequestTypes::iterator it_request_type = - policy_iter->second.RequestType->begin(); - for (; it_request_type != policy_iter->second.RequestType->end(); - ++it_request_type) { - request_types.push_back(EnumToJsonString(*it_request_type)); + + for (auto it_request_types : *policy_iter->second.RequestType) { + request_types.push_back(EnumToJsonString(it_request_types)); + } + return; +} + +RequestSubType::State CacheManager::GetAppRequestSubTypesState( + const std::string& policy_app_id) const { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock auto_lock(cache_lock_); + policy_table::ApplicationPolicies::iterator app_policies_iter = + pt_->policy_table.app_policies_section.apps.find(policy_app_id); + if (pt_->policy_table.app_policies_section.apps.end() == app_policies_iter) { + LOG4CXX_DEBUG(logger_, + "Can't find request subtypes for app_id " << policy_app_id); + return RequestSubType::State::UNAVAILABLE; + } + const policy_table::RequestSubTypes& request_types = + *app_policies_iter->second.RequestSubType; + if (!request_types.is_initialized()) { + return RequestSubType::State::OMITTED; + } + if (request_types.empty()) { + return RequestSubType::State::EMPTY; + } + return RequestSubType::State::AVAILABLE; +} + +void CacheManager::GetAppRequestSubTypes( + const std::string& policy_app_id, + std::vector<std::string>& request_types) const { + LOG4CXX_AUTO_TRACE(logger_); + CACHE_MANAGER_CHECK_VOID(); + sync_primitives::AutoLock auto_lock(cache_lock_); + if (kDeviceId == policy_app_id) { + LOG4CXX_DEBUG(logger_, + "Request subtypes not applicable for app_id " << kDeviceId); + return; + } + policy_table::ApplicationPolicies::iterator policy_iter = + pt_->policy_table.app_policies_section.apps.find(policy_app_id); + if (pt_->policy_table.app_policies_section.apps.end() == policy_iter) { + LOG4CXX_DEBUG(logger_, + "Can't find request subtypes for app_id " << policy_app_id); + return; + } + + for (auto it_request_subtypes : *policy_iter->second.RequestSubType) { + request_types.push_back(it_request_subtypes); } return; } diff --git a/src/components/policy/policy_regular/src/policy_helper.cc b/src/components/policy/policy_regular/src/policy_helper.cc index 95f275769c..4cb1746134 100644 --- a/src/components/policy/policy_regular/src/policy_helper.cc +++ b/src/components/policy/policy_regular/src/policy_helper.cc @@ -339,9 +339,22 @@ bool CheckAppPolicy::operator()(const AppPoliciesValueType& app_policy) { } PermissionsCheckResult result = CheckPermissionsChanges(app_policy); - if (!IsPredefinedApp(app_policy) && IsRequestTypeChanged(app_policy)) { - SetPendingPermissions(app_policy, RESULT_REQUEST_TYPE_CHANGED); - NotifySystem(app_policy); + if (!IsPredefinedApp(app_policy)) { + const bool is_request_type_changed = IsRequestTypeChanged(app_policy); + const bool is_request_subtype_changed = IsRequestSubTypeChanged(app_policy); + + if (is_request_type_changed && is_request_subtype_changed) { + SetPendingPermissions(app_policy, + RESULT_REQUEST_TYPE_AND_SUBTYPE_CHANGED); + } else if (is_request_type_changed) { + SetPendingPermissions(app_policy, RESULT_REQUEST_TYPE_CHANGED); + } else if (is_request_subtype_changed) { + SetPendingPermissions(app_policy, RESULT_REQUEST_SUBTYPE_CHANGED); + } + + if (is_request_type_changed || is_request_subtype_changed) { + NotifySystem(app_policy); + } } if (RESULT_NO_CHANGES == result) { LOG4CXX_INFO(logger_, @@ -409,6 +422,30 @@ void policy::CheckAppPolicy::SetPendingPermissions( permissions_diff.appRevokedPermissions = GetRevokedGroups(app_policy); RemoveRevokedConsents(app_policy, permissions_diff.appRevokedPermissions); break; + case RESULT_REQUEST_TYPE_AND_SUBTYPE_CHANGED: + permissions_diff.priority.clear(); + permissions_diff.requestTypeChanged = true; + permissions_diff.requestSubTypeChanged = true; + { + // Getting RequestTypes from PTU (not from cache) + policy_table::RequestTypes::const_iterator it_request_type = + app_policy.second.RequestType->begin(); + for (; app_policy.second.RequestType->end() != it_request_type; + ++it_request_type) { + permissions_diff.requestType.push_back( + EnumToJsonString(*it_request_type)); + } + } + { + // Getting RequestSubTypes from PTU (not from cache) + policy_table::RequestSubTypes::const_iterator it_request_subtype = + app_policy.second.RequestSubType->begin(); + for (; app_policy.second.RequestSubType->end() != it_request_subtype; + ++it_request_subtype) { + permissions_diff.requestSubType.push_back(*it_request_subtype); + } + } + break; case RESULT_REQUEST_TYPE_CHANGED: permissions_diff.priority.clear(); permissions_diff.requestTypeChanged = true; @@ -422,7 +459,19 @@ void policy::CheckAppPolicy::SetPendingPermissions( EnumToJsonString(*it_request_type)); } } - + break; + case RESULT_REQUEST_SUBTYPE_CHANGED: + permissions_diff.priority.clear(); + permissions_diff.requestSubTypeChanged = true; + { + // Getting RequestSubTypes from PTU (not from cache) + policy_table::RequestSubTypes::const_iterator it_request_subtype = + app_policy.second.RequestSubType->begin(); + for (; app_policy.second.RequestSubType->end() != it_request_subtype; + ++it_request_subtype) { + permissions_diff.requestSubType.push_back(*it_request_subtype); + } + } break; default: return; @@ -491,6 +540,32 @@ bool CheckAppPolicy::IsRequestTypeChanged( return diff.size(); } +bool CheckAppPolicy::IsRequestSubTypeChanged( + const AppPoliciesValueType& app_policy) const { + policy::AppPoliciesConstItr it = + snapshot_->policy_table.app_policies_section.apps.find(app_policy.first); + + if (it == snapshot_->policy_table.app_policies_section.apps.end()) { + if (!app_policy.second.RequestSubType->empty()) { + return true; + } + return false; + } + + if (it->second.RequestSubType->size() != + app_policy.second.RequestSubType->size()) { + return true; + } + + policy_table::RequestSubTypes diff; + std::set_difference(it->second.RequestSubType->begin(), + it->second.RequestSubType->end(), + app_policy.second.RequestSubType->begin(), + app_policy.second.RequestSubType->end(), + std::back_inserter(diff)); + return diff.size(); +} + FillNotificationData::FillNotificationData(Permissions& data, GroupConsent group_state, GroupConsent undefined_group_consent) diff --git a/src/components/policy/policy_regular/src/policy_manager_impl.cc b/src/components/policy/policy_regular/src/policy_manager_impl.cc index 3e08147a4c..a48a9a1ba0 100644 --- a/src/components/policy/policy_regular/src/policy_manager_impl.cc +++ b/src/components/policy/policy_regular/src/policy_manager_impl.cc @@ -385,6 +385,25 @@ const std::vector<std::string> PolicyManagerImpl::GetAppRequestTypes( return request_types; } +RequestType::State PolicyManagerImpl::GetAppRequestTypesState( + const std::string& policy_app_id) const { + LOG4CXX_AUTO_TRACE(logger_); + return cache_->GetAppRequestTypesState(policy_app_id); +} + +RequestSubType::State PolicyManagerImpl::GetAppRequestSubTypesState( + const std::string& policy_app_id) const { + LOG4CXX_AUTO_TRACE(logger_); + return cache_->GetAppRequestSubTypesState(policy_app_id); +} + +const std::vector<std::string> PolicyManagerImpl::GetAppRequestSubTypes( + const std::string& policy_app_id) const { + std::vector<std::string> request_subtypes; + cache_->GetAppRequestSubTypes(policy_app_id, request_subtypes); + return request_subtypes; +} + const VehicleInfo PolicyManagerImpl::GetVehicleInfo() const { return cache_->GetVehicleInfo(); } diff --git a/src/components/policy/policy_regular/src/policy_table/enums.cc b/src/components/policy/policy_regular/src/policy_table/enums.cc index 2145f06a4b..1dae9c5f96 100644 --- a/src/components/policy/policy_regular/src/policy_table/enums.cc +++ b/src/components/policy/policy_regular/src/policy_table/enums.cc @@ -468,6 +468,10 @@ bool IsValidEnum(RequestType val) { return true; case RT_FOTA: return true; + case RT_OEM_SPECIFIC: + return true; + case RT_EMPTY: + return true; default: return false; } @@ -515,6 +519,10 @@ const char* EnumToJsonString(RequestType val) { return "MEDIA"; case RT_FOTA: return "FOTA"; + case RT_OEM_SPECIFIC: + return "OEM_SPECIFIC"; + case RT_EMPTY: + return "EMPTY"; default: return ""; } @@ -600,6 +608,14 @@ bool EnumFromJsonString(const std::string& literal, RequestType* result) { if ("FOTA" == literal) { *result = RT_FOTA; return true; + } + if ("OEM_SPECIFIC" == literal) { + *result = RT_OEM_SPECIFIC; + return true; + } + if ("EMPTY" == literal) { + *result = RT_EMPTY; + return true; } else { return false; } diff --git a/src/components/policy/policy_regular/src/policy_table/types.cc b/src/components/policy/policy_regular/src/policy_table/types.cc index 5f6f85f5dd..c4846c0d40 100644 --- a/src/components/policy/policy_regular/src/policy_table/types.cc +++ b/src/components/policy/policy_regular/src/policy_table/types.cc @@ -164,6 +164,7 @@ ApplicationParams::ApplicationParams(const Json::Value* value__) , nicknames(impl::ValueMember(value__, "nicknames")) , AppHMIType(impl::ValueMember(value__, "AppHMIType")) , RequestType(impl::ValueMember(value__, "RequestType")) + , RequestSubType(impl::ValueMember(value__, "RequestSubType")) , memory_kb(impl::ValueMember(value__, "memory_kb"), 0) , heart_beat_timeout_ms(impl::ValueMember(value__, "heart_beat_timeout_ms")) , certificate(impl::ValueMember(value__, "certificate"), "not_specified") @@ -179,6 +180,7 @@ Json::Value ApplicationParams::ToJsonValue() const { impl::WriteJsonField("nicknames", nicknames, &result__); impl::WriteJsonField("AppHMIType", AppHMIType, &result__); impl::WriteJsonField("RequestType", RequestType, &result__); + impl::WriteJsonField("RequestSubType", RequestSubType, &result__); impl::WriteJsonField("memory_kb", memory_kb, &result__); impl::WriteJsonField( "heart_beat_timeout_ms", heart_beat_timeout_ms, &result__); @@ -189,7 +191,8 @@ Json::Value ApplicationParams::ToJsonValue() const { } bool ApplicationParams::is_valid() const { - // RequestType is not validated since there is high-level validation logic, + // RequestType and RequestSubType are not validated since there is high-level + // validation logic, // which takes into account information not available here. if (!PolicyBase::is_valid()) { return false; @@ -240,6 +243,9 @@ bool ApplicationParams::struct_empty() const { if (RequestType.is_initialized()) { return false; } + if (RequestSubType.is_initialized()) { + return false; + } if (memory_kb.is_initialized()) { return false; } @@ -273,6 +279,9 @@ void ApplicationParams::ReportErrors(rpc::ValidationReport* report__) const { if (!RequestType.is_valid()) { RequestType.ReportErrors(&report__->ReportSubobject("RequestType")); } + if (!RequestSubType.is_valid()) { + RequestSubType.ReportErrors(&report__->ReportSubobject("RequestSubType")); + } if (!priority.is_valid()) { priority.ReportErrors(&report__->ReportSubobject("priority")); } @@ -298,6 +307,7 @@ void ApplicationParams::SetPolicyTableType(PolicyTableType pt_type) { groups.SetPolicyTableType(pt_type); AppHMIType.SetPolicyTableType(pt_type); RequestType.SetPolicyTableType(pt_type); + RequestSubType.SetPolicyTableType(pt_type); memory_kb.SetPolicyTableType(pt_type); heart_beat_timeout_ms.SetPolicyTableType(pt_type); certificate.SetPolicyTableType(pt_type); diff --git a/src/components/policy/policy_regular/src/policy_table/validation.cc b/src/components/policy/policy_regular/src/policy_table/validation.cc index 10b8e4bf7c..e760293ea6 100644 --- a/src/components/policy/policy_regular/src/policy_table/validation.cc +++ b/src/components/policy/policy_regular/src/policy_table/validation.cc @@ -40,11 +40,12 @@ bool ApplicationPoliciesSection::Validate() const { return false; } - PolicyTableType pt_type = GetPolicyTableType(); + const PolicyTableType pt_type = GetPolicyTableType(); if (PT_PRELOADED != pt_type && PT_UPDATE != pt_type) { return true; } + LOG4CXX_TRACE(logger_, "Checking app Request Types..."); if (!it_default_policy->second.RequestType.is_valid()) { LOG4CXX_WARN(logger_, "Default policy RequestTypes are not valid. Will be cleaned."); @@ -65,10 +66,15 @@ bool ApplicationPoliciesSection::Validate() const { ApplicationPolicies::iterator end_iter = apps.end(); while (iter != end_iter) { + if (it_default_policy == iter || it_pre_data_policy == iter) { + ++iter; + continue; + } ApplicationParams& app_params = (*iter).second; - bool is_request_type_omitted = !app_params.RequestType.is_initialized(); - bool is_request_type_valid = app_params.RequestType.is_valid(); - bool is_request_type_empty = app_params.RequestType->empty(); + const bool is_request_type_omitted = + !app_params.RequestType.is_initialized(); + const bool is_request_type_valid = app_params.RequestType.is_valid(); + const bool is_request_type_empty = app_params.RequestType->empty(); if (PT_PRELOADED == pt_type) { if (!is_request_type_valid) { @@ -111,6 +117,33 @@ bool ApplicationPoliciesSection::Validate() const { ++iter; } + LOG4CXX_TRACE(logger_, "Checking app Request SubTypes..."); + iter = apps.begin(); + while (iter != end_iter) { + if (it_default_policy == iter || it_pre_data_policy == iter) { + ++iter; + continue; + } + ApplicationParams& app_params = (*iter).second; + const bool is_request_subtype_omitted = + !app_params.RequestSubType.is_initialized(); + + if (is_request_subtype_omitted) { + LOG4CXX_WARN(logger_, + "App policy RequestSubTypes omitted." + " Will be replaced with default."); + app_params.RequestSubType = apps[kDefaultApp].RequestSubType; + ++iter; + continue; + } + + const bool is_request_subtype_empty = app_params.RequestSubType->empty(); + if (is_request_subtype_empty) { + LOG4CXX_WARN(logger_, "App policy RequestSubTypes empty."); + } + ++iter; + } + return true; } diff --git a/src/components/policy/policy_regular/src/sql_pt_queries.cc b/src/components/policy/policy_regular/src/sql_pt_queries.cc index ef4ef49273..2e727f4c0d 100644 --- a/src/components/policy/policy_regular/src/sql_pt_queries.cc +++ b/src/components/policy/policy_regular/src/sql_pt_queries.cc @@ -258,13 +258,21 @@ const std::string kCreateSchema = " REFERENCES `application`(`id`) " "); " "CREATE TABLE IF NOT EXISTS `request_type`( " - " `request_type` VARCHAR(50) NOT NULL, " + " `request_type` VARCHAR(50), " " `application_id` VARCHAR(45) NOT NULL COLLATE NOCASE, " " PRIMARY KEY(`request_type`,`application_id`), " " CONSTRAINT `fk_app_type_application1` " " FOREIGN KEY(`application_id`) " " REFERENCES `application`(`id`) " "); " + "CREATE TABLE IF NOT EXISTS `request_subtype`( " + " `request_subtype` VARCHAR(50), " + " `application_id` VARCHAR(45) NOT NULL COLLATE NOCASE, " + " PRIMARY KEY(`request_subtype`,`application_id`), " + " CONSTRAINT `fk_request_subtype_app_id` " + " FOREIGN KEY(`application_id`) " + " REFERENCES `application`(`id`) " + "); " "CREATE INDEX IF NOT EXISTS `app_type.fk_app_type_application1_idx` " " ON `app_type`(`application_id` COLLATE NOCASE); " "CREATE TABLE IF NOT EXISTS `consent_group`( " @@ -582,9 +590,22 @@ const std::string kInsertAppType = "INSERT OR IGNORE INTO `app_type` (`application_id`, `name`) VALUES (?, ?)"; const std::string kInsertRequestType = - "INSERT OR IGNORE INTO `request_type` (`application_id`, `request_type`) " + "INSERT INTO `request_type` (`application_id`, `request_type`) " "VALUES (?, ?)"; +const std::string kInsertOmittedRequestType = + "INSERT INTO `request_type` (`application_id`) " + "VALUES (?)"; + +const std::string kInsertRequestSubType = + "INSERT INTO `request_subtype` (`application_id`, " + "`request_subtype`) " + "VALUES (?, ?)"; + +const std::string kInsertOmittedRequestSubType = + "INSERT INTO `request_subtype` (`application_id`) " + "VALUES (?)"; + const std::string kUpdateVersion = "UPDATE `version` SET `number`= ?"; const std::string kInsertMessageType = @@ -695,6 +716,11 @@ const std::string kSelectRequestTypes = "SELECT DISTINCT `request_type` FROM `request_type` WHERE `application_id` " "= ?"; +const std::string kSelectRequestSubTypes = + "SELECT DISTINCT `request_subtype` FROM `request_subtype` WHERE " + "`application_id` " + "= ?"; + const std::string kSelectSecondsBetweenRetries = "SELECT `value` FROM `seconds_between_retry` ORDER BY `index`"; @@ -740,6 +766,8 @@ const std::string kDeleteApplication = "DELETE FROM `application`"; const std::string kDeleteRequestType = "DELETE FROM `request_type`"; +const std::string kDeleteRequestSubType = "DELETE FROM `request_subtype`"; + const std::string kSelectApplicationRevoked = "SELECT `is_revoked` FROM `application` WHERE `id` = ?"; diff --git a/src/components/policy/policy_regular/src/sql_pt_representation.cc b/src/components/policy/policy_regular/src/sql_pt_representation.cc index 9840a08b26..a57230aeb1 100644 --- a/src/components/policy/policy_regular/src/sql_pt_representation.cc +++ b/src/components/policy/policy_regular/src/sql_pt_representation.cc @@ -744,6 +744,10 @@ bool SQLPTRepresentation::GatherApplicationPoliciesSection( return false; } + if (!GatherRequestSubType(app_id, &*params.RequestSubType)) { + return false; + } + (*policies).apps[app_id] = params; } return true; @@ -837,6 +841,7 @@ bool SQLPTRepresentation::SaveFunctionalGroupings( bool SQLPTRepresentation::SaveRpcs(int64_t group_id, const policy_table::Rpc& rpcs) { + LOG4CXX_AUTO_TRACE(logger_); utils::dbms::SQLQuery query(db()); utils::dbms::SQLQuery query_parameter(db()); if (!query.Prepare(sql_pt::kInsertRpc) || @@ -916,6 +921,11 @@ bool SQLPTRepresentation::SaveApplicationPoliciesSection( return false; } + if (!query_delete.Exec(sql_pt::kDeleteRequestSubType)) { + LOG4CXX_WARN(logger_, "Incorrect delete from request subtype."); + return false; + } + // All predefined apps (e.g. default, pre_DataConsent) should be saved first, // otherwise another app with the predefined permissions can get incorrect // permissions @@ -1006,6 +1016,10 @@ bool SQLPTRepresentation::SaveSpecificAppPolicy( return false; } + if (!SaveRequestSubType(app.first, *app.second.RequestSubType)) { + return false; + } + return true; } @@ -1109,15 +1123,83 @@ bool SQLPTRepresentation::SaveRequestType( } policy_table::RequestTypes::const_iterator it; - for (it = types.begin(); it != types.end(); ++it) { + if (!types.empty()) { + LOG4CXX_WARN(logger_, "Request types not empty."); + for (it = types.begin(); it != types.end(); ++it) { + query.Bind(0, app_id); + query.Bind(1, std::string(policy_table::EnumToJsonString(*it))); + if (!query.Exec() || !query.Reset()) { + LOG4CXX_WARN(logger_, "Incorrect insert into request types."); + return false; + } + } + } else if (types.is_initialized()) { + LOG4CXX_WARN(logger_, "Request types empty."); query.Bind(0, app_id); - query.Bind(1, std::string(policy_table::EnumToJsonString(*it))); + query.Bind(1, + std::string(policy_table::EnumToJsonString( + policy_table::RequestType::RT_EMPTY))); if (!query.Exec() || !query.Reset()) { LOG4CXX_WARN(logger_, "Incorrect insert into request types."); return false; } + } else { + utils::dbms::SQLQuery query_omitted(db()); + if (!query_omitted.Prepare(sql_pt::kInsertOmittedRequestType)) { + LOG4CXX_WARN(logger_, "Incorrect insert statement for request types."); + return false; + } + LOG4CXX_WARN(logger_, "Request types omitted."); + query_omitted.Bind(0, app_id); + if (!query_omitted.Exec() || !query_omitted.Reset()) { + LOG4CXX_WARN(logger_, "Incorrect insert into request types."); + return false; + } + } + return true; +} + +bool SQLPTRepresentation::SaveRequestSubType( + const std::string& app_id, + const policy_table::RequestSubTypes& request_subtypes) { + utils::dbms::SQLQuery query(db()); + if (!query.Prepare(sql_pt::kInsertRequestSubType)) { + LOG4CXX_WARN(logger_, "Incorrect insert statement for request subtypes."); + return false; } + policy_table::Strings::const_iterator it; + if (!request_subtypes.empty()) { + LOG4CXX_TRACE(logger_, "Request subtypes are not empty."); + for (it = request_subtypes.begin(); it != request_subtypes.end(); ++it) { + query.Bind(0, app_id); + query.Bind(1, *it); + if (!query.Exec() || !query.Reset()) { + LOG4CXX_WARN(logger_, "Incorrect insert into request subtypes."); + return false; + } + } + } else if (request_subtypes.is_initialized()) { + LOG4CXX_WARN(logger_, "Request subtypes empty."); + query.Bind(0, app_id); + query.Bind(1, std::string("EMPTY")); + if (!query.Exec() || !query.Reset()) { + LOG4CXX_WARN(logger_, "Incorrect insert into request subtypes."); + return false; + } + } else { + utils::dbms::SQLQuery query_omitted(db()); + if (!query_omitted.Prepare(sql_pt::kInsertOmittedRequestSubType)) { + LOG4CXX_WARN(logger_, "Incorrect insert statement for request subtypes."); + return false; + } + LOG4CXX_WARN(logger_, "Request subtypes omitted."); + query_omitted.Bind(0, app_id); + if (!query_omitted.Exec() || !query_omitted.Reset()) { + LOG4CXX_WARN(logger_, "Incorrect insert into request subtypes."); + return false; + } + } return true; } @@ -1529,11 +1611,36 @@ bool SQLPTRepresentation::GatherRequestType( if (!policy_table::EnumFromJsonString(query.GetString(0), &type)) { return false; } + if (policy_table::RequestType::RT_EMPTY == type) { + request_types->mark_initialized(); + continue; + } request_types->push_back(type); } return true; } +bool SQLPTRepresentation::GatherRequestSubType( + const std::string& app_id, + policy_table::RequestSubTypes* request_subtypes) const { + utils::dbms::SQLQuery query(db()); + if (!query.Prepare(sql_pt::kSelectRequestSubTypes)) { + LOG4CXX_WARN(logger_, "Incorrect select from request subtypes."); + return false; + } + + query.Bind(0, app_id); + while (query.Next()) { + const std::string request_subtype = query.GetString(0); + if ("EMPTY" == request_subtype) { + request_subtypes->mark_initialized(); + continue; + } + request_subtypes->push_back(request_subtype); + } + return true; +} + bool SQLPTRepresentation::GatherNickName( const std::string& app_id, policy_table::Strings* nicknames) const { utils::dbms::SQLQuery query(db()); @@ -1858,6 +1965,13 @@ bool SQLPTRepresentation::SetDefaultPolicy(const std::string& app_id) { !SaveRequestType(app_id, request_types)) { return false; } + + policy_table::Strings request_subtypes; + if (!GatherRequestSubType(kDefaultId, &request_subtypes) || + !SaveRequestSubType(app_id, request_subtypes)) { + return false; + } + policy_table::AppHMITypes app_types; if (!GatherAppType(kDefaultId, &app_types) || !SaveAppType(app_id, app_types)) { |