diff options
author | Jacob Keeler <jacob.keeler@livioradio.com> | 2018-06-06 16:30:15 -0400 |
---|---|---|
committer | Jacob Keeler <jacob.keeler@livioradio.com> | 2018-06-06 16:30:15 -0400 |
commit | 8d85f7139a8ff4444c24e8b70f64b02539a45058 (patch) | |
tree | 4850c32b3d56a200009a6c4d661ba6a86135d1c5 | |
parent | 47b7b86071d92b9074c504075cd25f563bc9d46b (diff) | |
parent | 51c427ee43c42bf72d65b5f964cdbdd00ae1de4d (diff) | |
download | sdl_core-8d85f7139a8ff4444c24e8b70f64b02539a45058.tar.gz |
Merge remote-tracking branch 'origin/develop' into feature/audio_file_playback_tts_chunks
62 files changed, 1597 insertions, 130 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 62c665d595..674091f508 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 @@ -196,6 +196,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..f06012893e 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 @@ -36,6 +36,7 @@ #include "application_manager/commands/mobile/on_system_request_notification.h" #include "interfaces/MOBILE_API.h" #include "utils/file_system.h" +#include "policy/policy_table/enums.h" #include "application_manager/application_manager.h" #include "application_manager/policies/policy_handler_interface.h" @@ -65,19 +66,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 +119,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 +205,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 b5573c0680..25e6040f81 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 @@ -840,8 +840,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); @@ -851,7 +852,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; if (file_system::FileExists(application_impl.app_icon_path())) { application[strings::icon] = application_impl.app_icon_path(); } @@ -873,18 +874,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..f0331d0ced 100644 --- a/src/components/application_manager/src/commands/mobile/system_request.cc +++ b/src/components/application_manager/src/commands/mobile/system_request.cc @@ -41,6 +41,7 @@ Copyright (c) 2013, Ford Motor Company #include "application_manager/policies/policy_handler_interface.h" #include "interfaces/MOBILE_API.h" #include "utils/file_system.h" +#include "policy/policy_table/enums.h" #include "formatters/CFormatterJsonBase.h" #include "json/json.h" #include "utils/helpers.h" @@ -454,17 +455,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 +508,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 +614,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 d10ede4637..46620e878a 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 437c4756bd..2710285597 100644 --- a/src/components/application_manager/src/smart_object_keys.cc +++ b/src/components/application_manager/src/smart_object_keys.cc @@ -160,6 +160,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/application_manager/test/commands/CMakeLists.txt b/src/components/application_manager/test/commands/CMakeLists.txt index 8dafc16471..be236fdb49 100644 --- a/src/components/application_manager/test/commands/CMakeLists.txt +++ b/src/components/application_manager/test/commands/CMakeLists.txt @@ -65,6 +65,7 @@ set(LIBRARIES AMMobileCommandsLibrary connectionHandler jsoncpp + Policy ) create_cotired_test("commands_test" "${SOURCES}" "${LIBRARIES}" ) diff --git a/src/components/application_manager/test/commands/mobile/on_system_request_notification_test.cc b/src/components/application_manager/test/commands/mobile/on_system_request_notification_test.cc index 7840e35cec..60af9381e8 100644 --- a/src/components/application_manager/test/commands/mobile/on_system_request_notification_test.cc +++ b/src/components/application_manager/test/commands/mobile/on_system_request_notification_test.cc @@ -54,6 +54,7 @@ using application_manager::commands::CommandImpl; using application_manager::MockMessageHelper; using test::components::policy_test::MockPolicyHandlerInterface; using namespace mobile_apis; +using testing::SaveArg; using testing::Mock; using testing::Return; using testing::ReturnRef; @@ -61,17 +62,35 @@ using testing::_; namespace { const uint32_t kConnectionKey = 1u; +const std::string kPolicyAppId = "fake-app-id"; } // namespace class OnSystemRequestNotificationTest - : public CommandsTest<CommandsTestMocks::kIsNice> {}; + : public CommandsTest<CommandsTestMocks::kIsNice> { + public: + OnSystemRequestNotificationTest() : mock_app_(CreateMockApp()) {} + + void PreConditions() { + ON_CALL(app_mngr_, application(kConnectionKey)) + .WillByDefault(Return(mock_app_)); + + ON_CALL(app_mngr_, GetPolicyHandler()) + .WillByDefault(ReturnRef(mock_policy_handler_)); + ON_CALL(*mock_app_, policy_app_id()).WillByDefault(Return(kPolicyAppId)); + } + + protected: + MockAppPtr mock_app_; + MockPolicyHandlerInterface mock_policy_handler_; +}; TEST_F(OnSystemRequestNotificationTest, Run_ProprietaryType_SUCCESS) { - const RequestType::eType kRequestType = RequestType::PROPRIETARY; + const mobile_apis::RequestType::eType request_type = + mobile_apis::RequestType::PROPRIETARY; MessageSharedPtr msg = CreateMessage(); (*msg)[strings::params][strings::connection_key] = kConnectionKey; - (*msg)[strings::msg_params][strings::request_type] = kRequestType; + (*msg)[strings::msg_params][strings::request_type] = request_type; SharedPtr<OnSystemRequestNotification> command = CreateCommand<OnSystemRequestNotification>(msg); @@ -111,11 +130,12 @@ TEST_F(OnSystemRequestNotificationTest, Run_ProprietaryType_SUCCESS) { } TEST_F(OnSystemRequestNotificationTest, Run_HTTPType_SUCCESS) { - const RequestType::eType kRequestType = RequestType::HTTP; + const mobile_apis::RequestType::eType request_type = + mobile_apis::RequestType::HTTP; MessageSharedPtr msg = CreateMessage(); (*msg)[strings::params][strings::connection_key] = kConnectionKey; - (*msg)[strings::msg_params][strings::request_type] = kRequestType; + (*msg)[strings::msg_params][strings::request_type] = request_type; SharedPtr<OnSystemRequestNotification> command = CreateCommand<OnSystemRequestNotification>(msg); @@ -148,11 +168,12 @@ TEST_F(OnSystemRequestNotificationTest, Run_HTTPType_SUCCESS) { } TEST_F(OnSystemRequestNotificationTest, Run_InvalidApp_NoNotification) { - const RequestType::eType kRequestType = RequestType::HTTP; + const mobile_apis::RequestType::eType request_type = + mobile_apis::RequestType::HTTP; MessageSharedPtr msg = CreateMessage(); (*msg)[strings::params][strings::connection_key] = kConnectionKey; - (*msg)[strings::msg_params][strings::request_type] = kRequestType; + (*msg)[strings::msg_params][strings::request_type] = request_type; SharedPtr<OnSystemRequestNotification> command = CreateCommand<OnSystemRequestNotification>(msg); @@ -172,11 +193,12 @@ TEST_F(OnSystemRequestNotificationTest, Run_InvalidApp_NoNotification) { } TEST_F(OnSystemRequestNotificationTest, Run_RequestNotAllowed_NoNotification) { - const RequestType::eType kRequestType = RequestType::HTTP; + const mobile_apis::RequestType::eType request_type = + mobile_apis::RequestType::HTTP; MessageSharedPtr msg = CreateMessage(); (*msg)[strings::params][strings::connection_key] = kConnectionKey; - (*msg)[strings::msg_params][strings::request_type] = kRequestType; + (*msg)[strings::msg_params][strings::request_type] = request_type; SharedPtr<OnSystemRequestNotification> command = CreateCommand<OnSystemRequestNotification>(msg); @@ -199,6 +221,71 @@ TEST_F(OnSystemRequestNotificationTest, Run_RequestNotAllowed_NoNotification) { command->Run(); } +TEST_F( + OnSystemRequestNotificationTest, + Run_RequestTypeAllowedAndRequestSubTypeDisallowed_MessageNotSentToMobile) { + MessageSharedPtr msg = CreateMessage(); + (*msg)[strings::params][strings::connection_key] = kConnectionKey; + const auto request_type = mobile_apis::RequestType::HTTP; + (*msg)[strings::msg_params][strings::request_type] = request_type; + const std::string request_subtype = "fakeSubType"; + (*msg)[am::strings::msg_params][am::strings::request_subtype] = + request_subtype; + + PreConditions(); + + EXPECT_CALL(mock_policy_handler_, + IsRequestTypeAllowed(kPolicyAppId, request_type)) + .WillOnce(Return(true)); + EXPECT_CALL(mock_policy_handler_, + IsRequestSubTypeAllowed(kPolicyAppId, request_subtype)) + .WillOnce(Return(false)); + + EXPECT_CALL(app_mngr_, SendMessageToMobile(_, _)).Times(0); + + auto command = CreateCommand<OnSystemRequestNotification>(msg); + + ASSERT_TRUE(command->Init()); + command->Run(); +} + +TEST_F(OnSystemRequestNotificationTest, + Run_RequestTypeAllowedAndRequestSubTypeAllowed_SendMessageToMobile) { + MessageSharedPtr msg = CreateMessage(); + (*msg)[strings::params][strings::connection_key] = kConnectionKey; + const auto request_type = mobile_apis::RequestType::OEM_SPECIFIC; + (*msg)[strings::msg_params][strings::request_type] = request_type; + const std::string request_subtype = "fakeSubType"; + (*msg)[am::strings::msg_params][am::strings::request_subtype] = + request_subtype; + + PreConditions(); + + EXPECT_CALL(mock_policy_handler_, + IsRequestTypeAllowed(kPolicyAppId, request_type)) + .WillOnce(Return(true)); + EXPECT_CALL(mock_policy_handler_, + IsRequestSubTypeAllowed(kPolicyAppId, request_subtype)) + .WillOnce(Return(true)); + + smart_objects::SmartObjectSPtr result; + EXPECT_CALL(app_mngr_, SendMessageToMobile(_, _)) + .WillOnce((SaveArg<0>(&result))); + + auto command = CreateCommand<OnSystemRequestNotification>(msg); + + ASSERT_TRUE(command->Init()); + command->Run(); + + EXPECT_EQ(application_manager::MessageType::kNotification, + (*result)[strings::params][strings::message_type].asInt()); + EXPECT_EQ(request_type, + (*result)[strings::msg_params][strings::request_type].asInt()); + EXPECT_EQ( + request_subtype, + (*result)[strings::msg_params][strings::request_subtype].asString()); +} + } // namespace on_system_request_notification } // namespace mobile_commands_test } // namespace commands_test diff --git a/src/components/application_manager/test/commands/mobile/register_app_interface_request_test.cc b/src/components/application_manager/test/commands/mobile/register_app_interface_request_test.cc index b7a004f199..2e3e5fbfdf 100644 --- a/src/components/application_manager/test/commands/mobile/register_app_interface_request_test.cc +++ b/src/components/application_manager/test/commands/mobile/register_app_interface_request_test.cc @@ -161,6 +161,12 @@ class RegisterAppInterfaceRequestTest .WillByDefault(ReturnRef(kDummyDiagModes)); ON_CALL(mock_policy_handler_, GetAppRequestTypes(_)) .WillByDefault(Return(std::vector<std::string>())); + ON_CALL(mock_policy_handler_, GetAppRequestTypeState(_)) + .WillByDefault(Return(policy::RequestType::State::EMPTY)); + ON_CALL(mock_policy_handler_, GetAppRequestSubTypes(_)) + .WillByDefault(Return(std::vector<std::string>())); + ON_CALL(mock_policy_handler_, GetAppRequestSubTypeState(_)) + .WillByDefault(Return(policy::RequestSubType::State::EMPTY)); ON_CALL(mock_policy_handler_, GetUserConsentForDevice(_)) .WillByDefault(Return(policy::DeviceConsent::kDeviceAllowed)); ON_CALL(app_mngr_, GetDeviceTransportType(_)) diff --git a/src/components/application_manager/test/commands/mobile/system_request_test.cc b/src/components/application_manager/test/commands/mobile/system_request_test.cc index 0e07889b4b..219ac54a8e 100644 --- a/src/components/application_manager/test/commands/mobile/system_request_test.cc +++ b/src/components/application_manager/test/commands/mobile/system_request_test.cc @@ -56,11 +56,14 @@ using am::commands::CommandImpl; using am::commands::MessageSharedPtr; using am::MockHmiInterfaces; using am::event_engine::Event; +using am::MessageType; using policy_test::MockPolicyHandlerInterface; using ::utils::SharedPtr; using ::testing::_; +using ::testing::DoAll; using ::testing::Return; using ::testing::ReturnRef; +using ::testing::SaveArg; namespace { const uint32_t kConnectionKey = 2u; @@ -70,6 +73,7 @@ const std::string kAppFolderName = "fake-app-name"; const std::string kAppStorageFolder = "fake-storage"; const std::string kSystemFilesPath = "/fake/system/files"; const std::string kFileName = "Filename"; +const uint32_t kHmiAppId = 3u; } // namespace class SystemRequestTest @@ -96,6 +100,7 @@ class SystemRequestTest ON_CALL(*mock_app_, app_id()).WillByDefault(Return(kConnectionKey)); ON_CALL(*mock_app_, policy_app_id()).WillByDefault(Return(kAppPolicyId)); ON_CALL(*mock_app_, folder_name()).WillByDefault(Return(kAppFolderName)); + ON_CALL(*mock_app_, hmi_app_id()).WillByDefault(Return(kHmiAppId)); ON_CALL(app_mngr_settings_, system_files_path()) .WillByDefault(ReturnRef(kSystemFilesPath)); @@ -128,6 +133,105 @@ TEST_F(SystemRequestTest, Run_HTTP_FileName_no_binary_data_REJECTED) { command->Run(); } +TEST_F(SystemRequestTest, + Run_RequestTypeAllowedAndRequestSubTypeAllowed_SendHMIRequest) { + MessageSharedPtr msg = CreateIVSUMessage(); + + (*msg)[am::strings::msg_params][am::strings::request_type] = + mobile_apis::RequestType::OEM_SPECIFIC; + + const std::string request_subtype = "fakeSubType"; + (*msg)[am::strings::msg_params][am::strings::request_subtype] = + request_subtype; + + const std::vector<uint8_t> binary_data = {1u, 2u}; + (*msg)[am::strings::params][am::strings::binary_data] = binary_data; + + PreConditions(); + + EXPECT_CALL(mock_policy_handler_, + IsRequestTypeAllowed(kAppPolicyId, + mobile_apis::RequestType::OEM_SPECIFIC)) + .WillOnce(Return(true)); + + EXPECT_CALL(mock_policy_handler_, + IsRequestSubTypeAllowed(kAppPolicyId, request_subtype)) + .WillOnce(Return(true)); + + EXPECT_CALL(app_mngr_, + SaveBinary(binary_data, kSystemFilesPath, kFileName, 0u)) + .WillOnce(Return(mobile_apis::Result::SUCCESS)); + + smart_objects::SmartObjectSPtr result; + EXPECT_CALL(app_mngr_, ManageHMICommand(_)) + .WillOnce(DoAll(SaveArg<0>(&result), Return(true))); + + SharedPtr<SystemRequest> command(CreateCommand<SystemRequest>(msg)); + ASSERT_TRUE(command->Init()); + command->Run(); + + EXPECT_EQ(MessageType::kRequest, + (*result)[am::strings::params][am::strings::message_type].asInt()); + EXPECT_EQ( + mobile_apis::RequestType::OEM_SPECIFIC, + (*result)[am::strings::msg_params][am::strings::request_type].asInt()); + EXPECT_EQ( + request_subtype, + (*msg)[am::strings::msg_params][am::strings::request_subtype].asString()); +} + +TEST_F( + SystemRequestTest, + Run_RequestTypeAllowedAndRequestSubTypeDisallowed_SendDisallowedResponse) { + MessageSharedPtr msg = CreateIVSUMessage(); + + (*msg)[am::strings::msg_params][am::strings::request_type] = + mobile_apis::RequestType::OEM_SPECIFIC; + + const std::string request_subtype = "fakeSubType2"; + (*msg)[am::strings::msg_params][am::strings::request_subtype] = + request_subtype; + + PreConditions(); + + EXPECT_CALL(mock_policy_handler_, + IsRequestTypeAllowed(kAppPolicyId, + mobile_apis::RequestType::OEM_SPECIFIC)) + .WillOnce(Return(true)); + + EXPECT_CALL(mock_policy_handler_, + IsRequestSubTypeAllowed(kAppPolicyId, request_subtype)) + .WillOnce(Return(false)); + + ExpectManageMobileCommandWithResultCode(mobile_apis::Result::DISALLOWED); + EXPECT_CALL(app_mngr_, ManageHMICommand(_)).Times(0); + + SharedPtr<SystemRequest> command(CreateCommand<SystemRequest>(msg)); + ASSERT_TRUE(command->Init()); + command->Run(); +} + +TEST_F(SystemRequestTest, Run_RequestTypeDisallowed_SendDisallowedResponse) { + MessageSharedPtr msg = CreateIVSUMessage(); + + (*msg)[am::strings::msg_params][am::strings::request_type] = + mobile_apis::RequestType::OEM_SPECIFIC; + + PreConditions(); + + EXPECT_CALL(mock_policy_handler_, + IsRequestTypeAllowed(kAppPolicyId, + mobile_apis::RequestType::OEM_SPECIFIC)) + .WillOnce(Return(false)); + + ExpectManageMobileCommandWithResultCode(mobile_apis::Result::DISALLOWED); + EXPECT_CALL(app_mngr_, ManageHMICommand(_)).Times(0); + + SharedPtr<SystemRequest> command(CreateCommand<SystemRequest>(msg)); + ASSERT_TRUE(command->Init()); + command->Run(); +} + } // namespace system_request } // namespace mobile_commands_test } // namespace commands_test diff --git a/src/components/application_manager/test/policy_handler_test.cc b/src/components/application_manager/test/policy_handler_test.cc index d9e1cefa01..3cd34bfaaa 100644 --- a/src/components/application_manager/test/policy_handler_test.cc +++ b/src/components/application_manager/test/policy_handler_test.cc @@ -1377,10 +1377,30 @@ TEST_F(PolicyHandlerTest, IsRequestTypeAllowed) { mobile_apis::RequestType::eType type = mobile_apis::RequestType::eType::EMERGENCY; + + EXPECT_CALL(*mock_policy_manager_, GetAppRequestTypesState(kPolicyAppId_)) + .WillOnce(Return(policy::RequestType::State::AVAILABLE)); + EXPECT_CALL(*mock_policy_manager_, GetAppRequestTypes(kPolicyAppId_)) - .WillOnce(Return(std::vector<std::string>())); + .WillOnce(Return(std::vector<std::string>({"HTTP"}))); + // Act + EXPECT_FALSE(policy_handler_.IsRequestTypeAllowed(kPolicyAppId_, type)); +} + +TEST_F(PolicyHandlerTest, IsRequestSubTypeAllowed) { + // Arrange + EnablePolicyAndPolicyManagerMock(); + + // Check expectations + EXPECT_CALL(*mock_policy_manager_, GetAppRequestSubTypesState(kPolicyAppId_)) + .WillOnce(Return(policy::RequestSubType::State::AVAILABLE)); + EXPECT_CALL(*mock_policy_manager_, GetAppRequestSubTypes(kPolicyAppId_)) + .WillOnce( + Return(std::vector<std::string>({"fakeSubType", "fakeSubType2"}))); + // Act - policy_handler_.IsRequestTypeAllowed(kPolicyAppId_, type); + const std::string subtype = "fakeSubType"; + EXPECT_TRUE(policy_handler_.IsRequestSubTypeAllowed(kPolicyAppId_, subtype)); } TEST_F(PolicyHandlerTest, GetVehicleInfo) { 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_external/policy/policy_manager.h b/src/components/include/policy/policy_external/policy/policy_manager.h index 24905671fa..7970d525c5 100644 --- a/src/components/include/policy/policy_external/policy/policy_manager.h +++ b/src/components/include/policy/policy_external/policy/policy_manager.h @@ -41,6 +41,7 @@ #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" @@ -487,6 +488,22 @@ class PolicyManager : public usage_statistics::StatisticsManager { const std::string& device_id_to) = 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 @@ -495,6 +512,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/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/include/test/application_manager/policies/mock_policy_handler_interface.h b/src/components/include/test/application_manager/policies/mock_policy_handler_interface.h index 931fd6cfb4..dfd537c678 100644 --- a/src/components/include/test/application_manager/policies/mock_policy_handler_interface.h +++ b/src/components/include/test/application_manager/policies/mock_policy_handler_interface.h @@ -197,6 +197,18 @@ class MockPolicyHandlerInterface : public policy::PolicyHandlerInterface { MOCK_CONST_METHOD2(IsRequestTypeAllowed, bool(const std::string& policy_app_id, mobile_apis::RequestType::eType type)); + MOCK_CONST_METHOD2(IsRequestSubTypeAllowed, + bool(const std::string& policy_app_id, + const std::string& request_subtype)); + MOCK_CONST_METHOD1( + GetAppRequestTypeState, + policy::RequestType::State(const std::string& policy_app_id)); + MOCK_CONST_METHOD1( + GetAppRequestSubTypeState, + policy::RequestSubType::State(const std::string& policy_app_id)); + MOCK_CONST_METHOD1( + GetAppRequestSubTypes, + const std::vector<std::string>(const std::string& policy_app_id)); MOCK_CONST_METHOD1( GetAppRequestTypes, const std::vector<std::string>(const std::string& policy_app_id)); diff --git a/src/components/include/test/policy/policy_external/policy/mock_cache_manager.h b/src/components/include/test/policy/policy_external/policy/mock_cache_manager.h index 5aa92446b6..02931114f0 100644 --- a/src/components/include/test/policy/policy_external/policy/mock_cache_manager.h +++ b/src/components/include/test/policy/policy_external/policy/mock_cache_manager.h @@ -250,6 +250,13 @@ class MockCacheManagerInterface : public ::policy::CacheManagerInterface { MOCK_METHOD2(OnDeviceSwitching, void(const std::string& device_id_from, const std::string& device_id_to)); + MOCK_CONST_METHOD2(GetAppRequestSubTypes, + void(const std::string& policy_app_id, + std::vector<std::string>& request_subtypes)); + MOCK_CONST_METHOD1(GetAppRequestTypesState, + RequestType::State(const std::string& policy_app_id)); + MOCK_CONST_METHOD1(GetAppRequestSubTypesState, + RequestSubType::State(const std::string& policy_app_id)); }; } // namespace policy_test diff --git a/src/components/include/test/policy/policy_external/policy/mock_policy_manager.h b/src/components/include/test/policy/policy_external/policy/mock_policy_manager.h index 9e487da4ba..96e484acae 100644 --- a/src/components/include/test/policy/policy_external/policy/mock_policy_manager.h +++ b/src/components/include/test/policy/policy_external/policy/mock_policy_manager.h @@ -218,6 +218,13 @@ class MockPolicyManager : public PolicyManager { MOCK_METHOD2(OnDeviceSwitching, void(const std::string& device_id_from, const std::string& device_id_to)); + MOCK_CONST_METHOD1( + GetAppRequestSubTypes, + const std::vector<std::string>(const std::string& policy_app_id)); + MOCK_CONST_METHOD1(GetAppRequestTypesState, + RequestType::State(const std::string& policy_app_id)); + MOCK_CONST_METHOD1(GetAppRequestSubTypesState, + RequestSubType::State(const std::string& policy_app_id)); }; } // namespace policy_manager_test } // namespace components diff --git a/src/components/include/test/policy/policy_regular/policy/mock_cache_manager.h b/src/components/include/test/policy/policy_regular/policy/mock_cache_manager.h index ed3a5088c1..cf20dcb666 100644 --- a/src/components/include/test/policy/policy_regular/policy/mock_cache_manager.h +++ b/src/components/include/test/policy/policy_regular/policy/mock_cache_manager.h @@ -214,6 +214,13 @@ class MockCacheManagerInterface : public CacheManagerInterface { MOCK_METHOD2(OnDeviceSwitching, void(const std::string& device_id_from, const std::string& device_id_to)); + MOCK_CONST_METHOD2(GetAppRequestSubTypes, + void(const std::string& policy_app_id, + std::vector<std::string>& request_subtypes)); + MOCK_CONST_METHOD1(GetAppRequestTypesState, + RequestType::State(const std::string& policy_app_id)); + MOCK_CONST_METHOD1(GetAppRequestSubTypesState, + RequestSubType::State(const std::string& policy_app_id)); }; } // namespace policy_test diff --git a/src/components/include/test/policy/policy_regular/policy/mock_policy_manager.h b/src/components/include/test/policy/policy_regular/policy/mock_policy_manager.h index 82012b83c7..0b8823d307 100644 --- a/src/components/include/test/policy/policy_regular/policy/mock_policy_manager.h +++ b/src/components/include/test/policy/policy_regular/policy/mock_policy_manager.h @@ -226,6 +226,14 @@ class MockPolicyManager : public PolicyManager { MOCK_METHOD2(OnDeviceSwitching, void(const std::string& device_id_from, const std::string& device_id_to)); + + MOCK_CONST_METHOD1( + GetAppRequestSubTypes, + const std::vector<std::string>(const std::string& policy_app_id)); + MOCK_CONST_METHOD1(GetAppRequestTypesState, + RequestType::State(const std::string& policy_app_id)); + MOCK_CONST_METHOD1(GetAppRequestSubTypesState, + RequestSubType::State(const std::string& policy_app_id)); }; } // namespace policy_manager_test diff --git a/src/components/interfaces/HMI_API.xml b/src/components/interfaces/HMI_API.xml index 8b6c8ce98f..2f066cd98a 100644 --- a/src/components/interfaces/HMI_API.xml +++ b/src/components/interfaces/HMI_API.xml @@ -1165,13 +1165,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" /> @@ -1186,6 +1186,7 @@ <element name="EMERGENCY" /> <element name="MEDIA" /> <element name="FOTA" /> + <element name="OEM_SPECIFIC"/> </enum> <enum name="ECallConfirmationStatus"> @@ -2014,6 +2015,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> @@ -3023,6 +3032,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> @@ -3049,6 +3063,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> @@ -4974,6 +4993,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 5e47c8cc61..3e31497c28 100644 --- a/src/components/interfaces/MOBILE_API.xml +++ b/src/components/interfaces/MOBILE_API.xml @@ -2220,6 +2220,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> @@ -5442,6 +5443,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. @@ -6041,6 +6047,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/cache_manager.h b/src/components/policy/policy_external/include/policy/cache_manager.h index bda456c90a..f41ddb14cd 100644 --- a/src/components/policy/policy_external/include/policy/cache_manager.h +++ b/src/components/policy/policy_external/include/policy/cache_manager.h @@ -84,6 +84,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. */ @@ -642,8 +658,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; virtual const MetaInfo GetMetaInfo() const OVERRIDE; diff --git a/src/components/policy/policy_external/include/policy/cache_manager_interface.h b/src/components/policy/policy_external/include/policy/cache_manager_interface.h index b9e9f73646..1d74780f19 100644 --- a/src/components/policy/policy_external/include/policy/cache_manager_interface.h +++ b/src/components/policy/policy_external/include/policy/cache_manager_interface.h @@ -47,6 +47,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() {} @@ -79,6 +89,21 @@ class CacheManagerInterface { const PTString& hmi_level, const PTString& rpc, 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 @@ -706,6 +731,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 Gets meta information * @return meta information */ diff --git a/src/components/policy/policy_external/include/policy/policy_helper.h b/src/components/policy/policy_external/include/policy/policy_helper.h index 6945f45b45..e399b44719 100644 --- a/src/components/policy/policy_external/include/policy/policy_helper.h +++ b/src/components/policy/policy_external/include/policy/policy_helper.h @@ -192,6 +192,14 @@ struct CheckAppPolicy { */ bool IsRequestTypeChanged(const AppPoliciesValueType& app_policy) const; + /** + * @brief Checks whether App RequestSubTypes have been changed by + * udpated + * @param app_policy Reference to updated application policy + * @return True if changed, otherwise - false + */ + bool IsRequestSubTypeChanged(const AppPoliciesValueType& app_policy) const; + private: PolicyManagerImpl* pm_; const utils::SharedPtr<policy_table::Table> update_; diff --git a/src/components/policy/policy_external/include/policy/policy_manager_impl.h b/src/components/policy/policy_external/include/policy/policy_manager_impl.h index 97a2e60055..fcd9c9f69a 100644 --- a/src/components/policy/policy_external/include/policy/policy_manager_impl.h +++ b/src/components/policy/policy_external/include/policy/policy_manager_impl.h @@ -538,6 +538,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 @@ -546,6 +562,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_external/include/policy/policy_table/enums.h b/src/components/policy/policy_external/include/policy/policy_table/enums.h index fa37cfe7a5..96a6748436 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,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_external/include/policy/policy_table/types.h b/src/components/policy/policy_external/include/policy/policy_table/types.h index 53f5a35b99..8309b14228 100644 --- a/src/components/policy/policy_external/include/policy/policy_table/types.h +++ b/src/components/policy/policy_external/include/policy/policy_table/types.h @@ -102,6 +102,8 @@ typedef Map<DeviceParams, 0, 255> DeviceData; typedef Array<Enum<RequestType>, 0, 255> RequestsTypeArray; +typedef Strings RequestSubTypes; + #ifdef SDL_REMOTE_CONTROL typedef Map<Strings, 0, 255> RemoteRpcs; typedef Map<RemoteRpcs, 0, 255> AccessModules; @@ -173,6 +175,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; #ifdef SDL_REMOTE_CONTROL diff --git a/src/components/policy/policy_external/include/policy/policy_types.h b/src/components/policy/policy_external/include/policy/policy_types.h index 232191cfea..9682b3d58d 100644 --- a/src/components/policy/policy_external/include/policy/policy_types.h +++ b/src/components/policy/policy_external/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; }; /** @@ -503,7 +506,8 @@ enum PermissionsCheckResult { 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 }; /** diff --git a/src/components/policy/policy_external/include/policy/sql_pt_queries.h b/src/components/policy/policy_external/include/policy/sql_pt_queries.h index a69df20cfc..646cc7663b 100644 --- a/src/components/policy/policy_external/include/policy/sql_pt_queries.h +++ b/src/components/policy/policy_external/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; @@ -98,6 +102,7 @@ extern const std::string kDeleteExternalConsentEntities; 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_external/include/policy/sql_pt_representation.h b/src/components/policy/policy_external/include/policy/sql_pt_representation.h index 54dfb9f0b7..c32e3205ef 100644 --- a/src/components/policy/policy_external/include/policy/sql_pt_representation.h +++ b/src/components/policy/policy_external/include/policy/sql_pt_representation.h @@ -133,6 +133,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; @@ -168,6 +171,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: virtual std::string GetLockScreenIconUrl() const; diff --git a/src/components/policy/policy_external/src/cache_manager.cc b/src/components/policy/policy_external/src/cache_manager.cc index 5aa39cb2f4..00bb1e4a1c 100644 --- a/src/components/policy/policy_external/src/cache_manager.cc +++ b/src/components/policy/policy_external/src/cache_manager.cc @@ -41,6 +41,7 @@ #include <vector> #include "utils/file_system.h" +#include "utils/helpers.h" #include "json/reader.h" #include "json/features.h" #include "json/writer.h" @@ -638,13 +639,11 @@ void CacheManager::RemoveAppConsentForGroup(const std::string& app_id, } } -using rpc::policy_table_interface_base::RequestTypes; -using rpc::policy_table_interface_base::RequestType; - void CacheManager::ProcessUpdate( const policy_table::ApplicationPolicies::const_iterator initial_policy_iter) { using namespace policy; + using rpc::policy_table_interface_base::RequestTypes; const RequestTypes& new_request_types = *(initial_policy_iter->second.RequestType); @@ -2392,6 +2391,32 @@ bool CacheManager::ResetPT(const std::string& file_name) { return result; } +policy::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::const_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 policy::RequestType::State::UNAVAILABLE; + } + const policy_table::RequestTypes& request_types = + *app_policies_iter->second.RequestType; + if (!request_types.is_initialized()) { + LOG4CXX_TRACE(logger_, + "Request types for " << policy_app_id << " are OMITTED"); + return RequestType::State::OMITTED; + } + if (request_types.empty()) { + LOG4CXX_TRACE(logger_, + "Request types for " << policy_app_id << " are EMPTY"); + return policy::RequestType::State::EMPTY; + } + return policy::RequestType::State::AVAILABLE; +} + void CacheManager::GetAppRequestTypes( const std::string& policy_app_id, std::vector<std::string>& request_types) const { @@ -2411,16 +2436,64 @@ void CacheManager::GetAppRequestTypes( return; } if (policy_iter->second.RequestType.is_initialized()) { - 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 (const auto& request_type : *policy_iter->second.RequestType) { + request_types.push_back(EnumToJsonString(request_type)); } } 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::const_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_subtypes = + *app_policies_iter->second.RequestSubType; + if (!request_subtypes.is_initialized()) { + LOG4CXX_TRACE(logger_, + "Request subtypes for " << policy_app_id << " are OMITTED"); + return RequestSubType::State::OMITTED; + } + if (request_subtypes.empty()) { + LOG4CXX_TRACE(logger_, + "Request subtypes for " << policy_app_id << " are EMPTY"); + return RequestSubType::State::EMPTY; + } + return RequestSubType::State::AVAILABLE; +} + +void CacheManager::GetAppRequestSubTypes( + const std::string& policy_app_id, + std::vector<std::string>& request_subtypes) const { + LOG4CXX_AUTO_TRACE(logger_); + CACHE_MANAGER_CHECK_VOID(); + if (kDeviceId == policy_app_id) { + LOG4CXX_DEBUG(logger_, + "Request subtypes not applicable for app_id " << kDeviceId); + return; + } + sync_primitives::AutoLock auto_lock(cache_lock_); + 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 (const auto& request_subtype : *policy_iter->second.RequestSubType) { + request_subtypes.push_back(request_subtype); + } + return; +} + const MetaInfo CacheManager::GetMetaInfo() const { LOG4CXX_AUTO_TRACE(logger_); sync_primitives::AutoLock auto_lock(cache_lock_); diff --git a/src/components/policy/policy_external/src/policy_helper.cc b/src/components/policy/policy_external/src/policy_helper.cc index 8be0372c03..39b9399c24 100644 --- a/src/components/policy/policy_external/src/policy_helper.cc +++ b/src/components/policy/policy_external/src/policy_helper.cc @@ -322,9 +322,21 @@ 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); - AddResult(app_id, RESULT_REQUEST_TYPE_CHANGED); + 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) { + LOG4CXX_TRACE(logger_, + "Request types were changed for application: " << app_id); + SetPendingPermissions(app_policy, RESULT_REQUEST_TYPE_CHANGED); + AddResult(app_id, RESULT_REQUEST_TYPE_CHANGED); + } + if (is_request_subtype_changed) { + LOG4CXX_TRACE( + logger_, "Request subtypes were changed for application: " << app_id); + SetPendingPermissions(app_policy, RESULT_REQUEST_SUBTYPE_CHANGED); + AddResult(app_id, RESULT_REQUEST_SUBTYPE_CHANGED); + } } if (RESULT_NO_CHANGES == result) { @@ -389,17 +401,18 @@ void policy::CheckAppPolicy::SetPendingPermissions( break; case RESULT_REQUEST_TYPE_CHANGED: permissions_diff.requestTypeChanged = 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 Request Types from PTU (not from cache) + for (const auto& request_type : *app_policy.second.RequestType) { + permissions_diff.requestType.push_back(EnumToJsonString(request_type)); + } + break; + case RESULT_REQUEST_SUBTYPE_CHANGED: + permissions_diff.requestSubTypeChanged = true; + // Getting Request SubTypes from PTU (not from cache) + for (const auto& request_subtype : *app_policy.second.RequestSubType) { + permissions_diff.requestSubType.push_back(request_subtype); + } break; default: return; @@ -484,6 +497,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(); +} + void FillActionsForAppPolicies::operator()( const policy::CheckAppPolicyResults::value_type& value) { const std::string app_id = value.first; @@ -510,6 +549,7 @@ void FillActionsForAppPolicies::operator()( case RESULT_CONSENT_NOT_REQIURED: case RESULT_PERMISSIONS_REVOKED: case RESULT_REQUEST_TYPE_CHANGED: + case RESULT_REQUEST_SUBTYPE_CHANGED: break; case RESULT_NO_CHANGES: default: diff --git a/src/components/policy/policy_external/src/policy_manager_impl.cc b/src/components/policy/policy_external/src/policy_manager_impl.cc index 433a7a6bca..56de26af64 100644 --- a/src/components/policy/policy_external/src/policy_manager_impl.cc +++ b/src/components/policy/policy_external/src/policy_manager_impl.cc @@ -563,6 +563,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_external/src/policy_table/enums.cc b/src/components/policy/policy_external/src/policy_table/enums.cc index beea68a276..881ae8cbf9 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,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; } @@ -652,6 +656,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 ""; } @@ -737,6 +745,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_external/src/policy_table/types.cc b/src/components/policy/policy_external/src/policy_table/types.cc index da83626448..6d0bc9d697 100644 --- a/src/components/policy/policy_external/src/policy_table/types.cc +++ b/src/components/policy/policy_external/src/policy_table/types.cc @@ -238,6 +238,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")) #ifdef SDL_REMOTE_CONTROL @@ -251,6 +252,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__); @@ -303,6 +305,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; } @@ -337,6 +342,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")); } @@ -368,6 +376,7 @@ void ApplicationParams::SetPolicyTableType(PolicyTableType pt_type) { PolicyBase::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); #ifdef SDL_REMOTE_CONTROL diff --git a/src/components/policy/policy_external/src/policy_table/validation.cc b/src/components/policy/policy_external/src/policy_table/validation.cc index 48a8578855..6936948c84 100644 --- a/src/components/policy/policy_external/src/policy_table/validation.cc +++ b/src/components/policy/policy_external/src/policy_table/validation.cc @@ -89,6 +89,7 @@ bool ApplicationPoliciesSection::Validate() const { continue; } + LOG4CXX_TRACE(logger_, "Checking app Request Types..."); RequestTypes& app_request_types = *iter->second.RequestType; if (app_request_types.is_omitted()) { @@ -133,6 +134,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_external/src/sql_pt_ext_representation.cc b/src/components/policy/policy_external/src/sql_pt_ext_representation.cc index f58a7f0b82..5bb602244e 100644 --- a/src/components/policy/policy_external/src/sql_pt_ext_representation.cc +++ b/src/components/policy/policy_external/src/sql_pt_ext_representation.cc @@ -670,6 +670,11 @@ bool SQLPTExtRepresentation::SaveApplicationPoliciesSection( return false; } + if (!query_delete.Exec(sql_pt::kDeleteRequestSubType)) { + LOG4CXX_WARN(logger_, "Incorrect delete from request subtype."); + return false; + } + // First, all predefined apps (e.g. default, pre_DataConsent) should be saved, // otherwise another app with the predefined permissions can get incorrect // permissions @@ -713,18 +718,17 @@ bool SQLPTExtRepresentation::SaveSpecificAppPolicy( if (!SetDefaultPolicy(app.first)) { return false; } - if (!SaveRequestType(app.first, *app.second.RequestType)) { - return false; - } } else if (kPreDataConsentId.compare(app.second.get_string()) == 0) { if (!SetPredataPolicy(app.first)) { return false; } - if (!SaveRequestType(app.first, *app.second.RequestType)) { - return false; - } } - + if (!SaveRequestType(app.first, *app.second.RequestType)) { + return false; + } + if (!SaveRequestSubType(app.first, *app.second.RequestSubType)) { + return false; + } // Stop saving other params, since predefined permissions already set return true; } @@ -771,6 +775,10 @@ bool SQLPTExtRepresentation::SaveSpecificAppPolicy( return false; } + if (!SaveRequestSubType(app.first, *app.second.RequestSubType)) { + return false; + } + return true; } diff --git a/src/components/policy/policy_external/src/sql_pt_queries.cc b/src/components/policy/policy_external/src/sql_pt_queries.cc index 9702c315b0..ee53eb1487 100644 --- a/src/components/policy/policy_external/src/sql_pt_queries.cc +++ b/src/components/policy/policy_external/src/sql_pt_queries.cc @@ -271,13 +271,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`( " @@ -482,6 +490,7 @@ const std::string kDropSchema = "DROP INDEX IF EXISTS `app_type.fk_app_type_application1_idx`; " "DROP TABLE IF EXISTS `app_type`; " "DROP TABLE IF EXISTS `request_type`; " + "DROP TABLE IF EXISTS `request_subtype`; " "DROP INDEX IF EXISTS `nickname.fk_nickname_application1_idx`; " "DROP TABLE IF EXISTS `nickname`; " "DROP INDEX IF EXISTS `app_level.fk_app_level_language2_idx`; " @@ -636,6 +645,19 @@ const std::string kInsertRequestType = "INSERT OR IGNORE 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 = @@ -760,6 +782,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`"; @@ -805,6 +832,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_external/src/sql_pt_representation.cc b/src/components/policy/policy_external/src/sql_pt_representation.cc index 4315d99b3a..b05716dc3f 100644 --- a/src/components/policy/policy_external/src/sql_pt_representation.cc +++ b/src/components/policy/policy_external/src/sql_pt_representation.cc @@ -786,6 +786,9 @@ bool SQLPTRepresentation::GatherApplicationPoliciesSection( if (!GatherRequestType(app_id, &*params.RequestType)) { return false; } + if (!GatherRequestSubType(app_id, &*params.RequestSubType)) { + return false; + } (*policies).apps[app_id] = params; } @@ -1175,15 +1178,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; } @@ -1583,11 +1654,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()); @@ -1907,6 +2003,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)) { diff --git a/src/components/policy/policy_external/test/sql_pt_representation_test.cc b/src/components/policy/policy_external/test/sql_pt_representation_test.cc index a657a01145..0b0831eaad 100644 --- a/src/components/policy/policy_external/test/sql_pt_representation_test.cc +++ b/src/components/policy/policy_external/test/sql_pt_representation_test.cc @@ -407,7 +407,8 @@ TEST_F(SQLPTRepresentationTest, query.Prepare(query_select); query.Next(); - const int policy_tables_number = 32; + // 33 - is current total tables number created by schema + const int policy_tables_number = 33; ASSERT_EQ(policy_tables_number, query.GetInteger(0)); const std::string query_select_count_of_iap_buffer_full = 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..7f27ab2676 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,8 @@ 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 }; void SetPendingPermissions(const AppPoliciesValueType& app_policy, @@ -126,6 +127,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..e0fc808e2f 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; }; /** @@ -471,7 +474,8 @@ enum PermissionsCheckResult { 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 }; /** 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..1d51b81af4 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,32 @@ 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()) { + LOG4CXX_DEBUG(logger_, + "Request types for " << policy_app_id << " are OMITTED"); + return RequestType::State::OMITTED; + } + if (request_types.empty()) { + LOG4CXX_DEBUG(logger_, + "Request types for " << policy_app_id << " are 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 +1595,60 @@ 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 (const auto& request_type : *policy_iter->second.RequestType) { + request_types.push_back(EnumToJsonString(request_type)); + } + 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_subtypes = + *app_policies_iter->second.RequestSubType; + if (!request_subtypes.is_initialized()) { + LOG4CXX_DEBUG(logger_, + "Request subtypes for " << policy_app_id << " are OMITTED"); + return RequestSubType::State::OMITTED; + } + if (request_subtypes.empty()) { + LOG4CXX_DEBUG(logger_, + "Request subtypes for " << policy_app_id << " are 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 (const auto& request_subtype : *policy_iter->second.RequestSubType) { + request_types.push_back(request_subtype); } 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..796dd25ec4 100644 --- a/src/components/policy/policy_regular/src/policy_helper.cc +++ b/src/components/policy/policy_regular/src/policy_helper.cc @@ -339,9 +339,20 @@ 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) { + SetPendingPermissions(app_policy, RESULT_REQUEST_TYPE_CHANGED); + } + 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_, @@ -412,17 +423,19 @@ void policy::CheckAppPolicy::SetPendingPermissions( case RESULT_REQUEST_TYPE_CHANGED: permissions_diff.priority.clear(); permissions_diff.requestTypeChanged = 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 Request Types from PTU (not from cache) + for (const auto& request_type : *app_policy.second.RequestType) { + permissions_diff.requestType.push_back(EnumToJsonString(request_type)); + } + break; + case RESULT_REQUEST_SUBTYPE_CHANGED: + permissions_diff.priority.clear(); + permissions_diff.requestSubTypeChanged = true; + // Getting Request SubTypes from PTU (not from cache) + for (const auto& request_subtype : *app_policy.second.RequestSubType) { + permissions_diff.requestSubType.push_back(request_subtype); + } break; default: return; @@ -491,6 +504,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..91a5573a04 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`( " @@ -440,6 +448,8 @@ const std::string kDropSchema = "DROP TABLE IF EXISTS `consent_group`; " "DROP INDEX IF EXISTS `app_type.fk_app_type_application1_idx`; " "DROP TABLE IF EXISTS `app_type`; " + "DROP TABLE IF EXISTS `request_type`; " + "DROP TABLE IF EXISTS `request_subtype`; " "DROP INDEX IF EXISTS `nickname.fk_nickname_application1_idx`; " "DROP TABLE IF EXISTS `nickname`; " "DROP INDEX IF EXISTS `app_level.fk_app_level_language2_idx`; " @@ -582,9 +592,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 +718,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 +768,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)) { diff --git a/src/components/policy/policy_regular/test/sql_pt_representation_test.cc b/src/components/policy/policy_regular/test/sql_pt_representation_test.cc index fd83c82b1a..a5f3741331 100644 --- a/src/components/policy/policy_regular/test/sql_pt_representation_test.cc +++ b/src/components/policy/policy_regular/test/sql_pt_representation_test.cc @@ -289,6 +289,7 @@ class SQLPTRepresentationTest : public SQLPTRepresentation, app_policies["default"]["default_hmi"] = Json::Value("FULL"); app_policies["default"]["keep_context"] = Json::Value(true); app_policies["default"]["steal_focus"] = Json::Value(true); + app_policies["default"]["RequestType"] = Json::Value(Json::arrayValue); app_policies["pre_DataConsent"] = Json::Value(Json::objectValue); app_policies["pre_DataConsent"]["memory_kb"] = Json::Value(40); @@ -300,6 +301,9 @@ class SQLPTRepresentationTest : public SQLPTRepresentation, app_policies["pre_DataConsent"]["is_revoked"] = Json::Value(false); app_policies["pre_DataConsent"]["keep_context"] = Json::Value(true); app_policies["pre_DataConsent"]["steal_focus"] = Json::Value(true); + app_policies["pre_DataConsent"]["RequestType"] = + Json::Value(Json::arrayValue); + app_policies["1234"] = Json::Value(Json::objectValue); app_policies["1234"]["memory_kb"] = Json::Value(150); app_policies["1234"]["heart_beat_timeout_ms"] = Json::Value(200); @@ -310,6 +314,8 @@ class SQLPTRepresentationTest : public SQLPTRepresentation, app_policies["1234"]["is_revoked"] = Json::Value(true); app_policies["1234"]["keep_context"] = Json::Value(false); app_policies["1234"]["steal_focus"] = Json::Value(false); + app_policies["1234"]["RequestType"] = Json::Value(Json::arrayValue); + app_policies["device"] = Json::Value(Json::objectValue); app_policies["device"]["groups"] = Json::Value(Json::arrayValue); app_policies["device"]["groups"][0] = Json::Value("default"); @@ -420,7 +426,9 @@ TEST_F(SQLPTRepresentationTest, ASSERT_EQ(0, dbms->FetchOneInt(query_select)); ASSERT_TRUE(reps->RefreshDB()); // Check PT structure destroyed and tables number is 0 - const int32_t total_tables_number = 28; + + // There are 29 tables in the database, now. + const int32_t total_tables_number = 29; ASSERT_EQ(total_tables_number, dbms->FetchOneInt(query_select)); const char* query_select_count_of_iap_buffer_full = "SELECT `count_of_iap_buffer_full` FROM `usage_and_error_count`"; |