diff options
111 files changed, 7946 insertions, 1246 deletions
diff --git a/src/appMain/hmi_capabilities.json b/src/appMain/hmi_capabilities.json index 4f35059bd5..91ddaf6d6c 100755 --- a/src/appMain/hmi_capabilities.json +++ b/src/appMain/hmi_capabilities.json @@ -325,119 +325,210 @@ "pixelPerInch": 117, "scale": 1 }, + "seatLocationCapability": { + "rows": 2, + "columns": 3, + "levels": 1, + "seats": [ + { + "row": 0, + "col": 0, + "level": 0, + "rowspan": 1, + "levelspan": 1, + "colspan": 1 + } + ] + }, "remoteControlCapability": { "buttonCapabilities": [ { "longPressAvailable": true, "name": "AC_MAX", + "moduleInfo": { + "moduleId": "34045662-a9dc-4823-8435-91056d4c26cb", + "allowMultipleAccess": false + }, "shortPressAvailable": true, "upDownAvailable": false }, { "longPressAvailable": true, "name": "AC", + "moduleInfo": { + "moduleId": "34045662-a9dc-4823-8435-91056d4c26cb", + "allowMultipleAccess": false + }, "shortPressAvailable": true, "upDownAvailable": false }, { "longPressAvailable": true, "name": "RECIRCULATE", + "moduleInfo": { + "moduleId": "34045662-a9dc-4823-8435-91056d4c26cb", + "allowMultipleAccess": false + }, "shortPressAvailable": true, "upDownAvailable": false }, { "longPressAvailable": true, "name": "FAN_UP", + "moduleInfo": { + "moduleId": "34045662-a9dc-4823-8435-91056d4c26cb", + "allowMultipleAccess": false + }, "shortPressAvailable": true, "upDownAvailable": false }, { "longPressAvailable": true, "name": "FAN_DOWN", + "moduleInfo": { + "moduleId": "34045662-a9dc-4823-8435-91056d4c26cb", + "allowMultipleAccess": false + }, "shortPressAvailable": true, "upDownAvailable": false }, { "longPressAvailable": true, "name": "TEMP_UP", + "moduleInfo": { + "moduleId": "34045662-a9dc-4823-8435-91056d4c26cb", + "allowMultipleAccess": false + }, "shortPressAvailable": true, "upDownAvailable": false }, { "longPressAvailable": true, "name": "TEMP_DOWN", + "moduleInfo": { + "moduleId": "34045662-a9dc-4823-8435-91056d4c26cb", + "allowMultipleAccess": false + }, "shortPressAvailable": true, "upDownAvailable": false }, { "longPressAvailable": true, "name": "DEFROST_MAX", + "moduleInfo": { + "moduleId": "34045662-a9dc-4823-8435-91056d4c26cb", + "allowMultipleAccess": false + }, "shortPressAvailable": true, "upDownAvailable": false }, { "longPressAvailable": true, "name": "DEFROST", + "moduleInfo": { + "moduleId": "34045662-a9dc-4823-8435-91056d4c26cb", + "allowMultipleAccess": false + }, "shortPressAvailable": true, "upDownAvailable": false }, { "longPressAvailable": true, "name": "DEFROST_REAR", + "moduleInfo": { + "moduleId": "34045662-a9dc-4823-8435-91056d4c26cb", + "allowMultipleAccess": false + }, "shortPressAvailable": true, "upDownAvailable": false }, { "longPressAvailable": true, "name": "UPPER_VENT", + "moduleInfo": { + "moduleId": "34045662-a9dc-4823-8435-91056d4c26cb", + "allowMultipleAccess": false + }, "shortPressAvailable": true, "upDownAvailable": false }, { "longPressAvailable": true, "name": "LOWER_VENT", + "moduleInfo": { + "moduleId": "34045662-a9dc-4823-8435-91056d4c26cb", + "allowMultipleAccess": false + }, "shortPressAvailable": true, "upDownAvailable": false }, { "longPressAvailable": true, "name": "VOLUME_UP", + "moduleInfo": { + "moduleId": "eb7739ea-b263-4fe1-af9c-9311d1acac2d", + "allowMultipleAccess": false + }, "shortPressAvailable": true, "upDownAvailable": false }, { "longPressAvailable": true, "name": "VOLUME_DOWN", + "moduleInfo": { + "moduleId": "eb7739ea-b263-4fe1-af9c-9311d1acac2d", + "allowMultipleAccess": false + }, "shortPressAvailable": true, "upDownAvailable": false }, { "longPressAvailable": true, "name": "EJECT", + "moduleInfo": { + "moduleId": "eb7739ea-b263-4fe1-af9c-9311d1acac2d", + "allowMultipleAccess": false + }, "shortPressAvailable": true, "upDownAvailable": false }, { "longPressAvailable": true, "name": "SOURCE", + "moduleInfo": { + "moduleId": "eb7739ea-b263-4fe1-af9c-9311d1acac2d", + "allowMultipleAccess": false + }, "shortPressAvailable": true, "upDownAvailable": false }, { "longPressAvailable": true, "name": "SHUFFLE", + "moduleInfo": { + "moduleId": "eb7739ea-b263-4fe1-af9c-9311d1acac2d", + "allowMultipleAccess": false + }, "shortPressAvailable": true, "upDownAvailable": false }, { "longPressAvailable": true, "name": "REPEAT", + "moduleInfo": { + "moduleId": "eb7739ea-b263-4fe1-af9c-9311d1acac2d", + "allowMultipleAccess": false + }, "shortPressAvailable": true, "upDownAvailable": false } ], "climateControlCapabilities": [ { + "moduleInfo": { + "moduleId": "34045662-a9dc-4823-8435-91056d4c26cb", + "allowMultipleAccess": false + }, "acEnableAvailable": true, "acMaxEnableAvailable": true, "autoModeEnableAvailable": true, @@ -470,6 +561,10 @@ ], "radioControlCapabilities": [ { + "moduleInfo": { + "moduleId": "eb7739ea-b263-4fe1-af9c-9311d1acac2d", + "allowMultipleAccess": true + }, "availableHdChannelsAvailable": true, "hdChannelAvailable": true, "moduleName": "radio", @@ -488,6 +583,10 @@ "audioControlCapabilities": [ { "moduleName": "audio", + "moduleInfo": { + "moduleId": "a279fe12-4587-4d12-8514-50f4ea9e9537", + "allowMultipleAccess": true + }, "sourceAvailable": true, "volumeAvailable": true, "equalizerAvailable": true, @@ -498,6 +597,10 @@ "seatControlCapabilities": [ { "moduleName": "driver_seat", + "moduleInfo": { + "moduleId": "06cdec22-920e-4865-bf2e-9518463edc68", + "allowMultipleAccess": false + }, "heatingEnabledAvailable" : true, "coolingEnabledAvailable": true, "heatingLevelAvailable": true, @@ -517,6 +620,10 @@ ], "lightControlCapabilities": { "moduleName": "light", + "moduleInfo": { + "moduleId": "8d73e369-6a1f-4459-ab5a-6e432631881d", + "allowMultipleAccess": false + }, "supportedLights":[ { "statusAvailable":true, @@ -810,6 +917,10 @@ }, "hmiSettingsControlCapabilities": { "moduleName": "hmiSettings", + "moduleInfo": { + "moduleId": "c8cace3c-d482-4be1-8862-624a21e34563", + "allowMultipleAccess": true + }, "distanceUnitAvailable": true, "temperatureUnitAvailable": true, "displayModeUnitAvailable": true diff --git a/src/appMain/sdl_preloaded_pt.json b/src/appMain/sdl_preloaded_pt.json index a3db070a99..e1514dcb4d 100644 --- a/src/appMain/sdl_preloaded_pt.json +++ b/src/appMain/sdl_preloaded_pt.json @@ -913,6 +913,22 @@ "LIMITED", "NONE" ] + }, + "ReleaseInteriorVehicleDataModule": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] + }, + "GetInteriorVehicleDataConsent": { + "hmi_levels": [ + "BACKGROUND", + "FULL", + "LIMITED", + "NONE" + ] } } }, diff --git a/src/appMain/smartDeviceLink.ini b/src/appMain/smartDeviceLink.ini index 0c85a867d0..baf8cf6073 100644 --- a/src/appMain/smartDeviceLink.ini +++ b/src/appMain/smartDeviceLink.ini @@ -390,4 +390,8 @@ HMIOriginID = "HMI_ID" EmbeddedServices = MEDIA, WEATHER, NAVIGATION ; Additional time added to RPC timeout when passing through to App service -RpcPassThroughTimeout = 10000
\ No newline at end of file +RpcPassThroughTimeout = 10000 + +[RCModuleConsent] +; The period (in days) after which consent for module_id should be removed. +PeriodForConsentExpiration = 30 diff --git a/src/components/application_manager/include/application_manager/application.h b/src/components/application_manager/include/application_manager/application.h index de4319acb7..366396d90a 100644 --- a/src/components/application_manager/include/application_manager/application.h +++ b/src/components/application_manager/include/application_manager/application.h @@ -1202,6 +1202,19 @@ class Application : public virtual InitialApplicationData, */ virtual void set_cloud_app_certificate(const std::string& certificate) = 0; + /** + * @brief Set user location + * @param smart object of user location + */ + virtual void set_user_location( + const smart_objects::SmartObject& user_location) = 0; + + /** + * @brief Get user location + * @return smart object of user location + */ + virtual const smart_objects::SmartObject& get_user_location() const = 0; + protected: mutable sync_primitives::Lock hmi_states_lock_; diff --git a/src/components/application_manager/include/application_manager/application_impl.h b/src/components/application_manager/include/application_manager/application_impl.h index 40bb58c009..23dc41ecd7 100644 --- a/src/components/application_manager/include/application_manager/application_impl.h +++ b/src/components/application_manager/include/application_manager/application_impl.h @@ -500,6 +500,11 @@ class ApplicationImpl : public virtual Application, */ void set_cloud_app_certificate(const std::string& certificate) OVERRIDE; + void set_user_location( + const smart_objects::SmartObject& user_location) OVERRIDE; + + const smart_objects::SmartObject& get_user_location() const OVERRIDE; + protected: /** * @brief Clean up application folder. Persistent files will stay @@ -611,6 +616,7 @@ class ApplicationImpl : public virtual Application, std::string cloud_transport_type_; mobile_apis::HybridAppPreference::eType hybrid_app_preference_; std::string certificate_; + smart_objects::SmartObject user_location_; /** * @brief Defines number per time in seconds limits diff --git a/src/components/application_manager/include/application_manager/commands/command_request_impl.h b/src/components/application_manager/include/application_manager/commands/command_request_impl.h index b5a330d907..5e46021c83 100644 --- a/src/components/application_manager/include/application_manager/commands/command_request_impl.h +++ b/src/components/application_manager/include/application_manager/commands/command_request_impl.h @@ -317,6 +317,16 @@ class CommandRequestImpl : public CommandImpl, bool IsResultCodeUnsupported(const ResponseInfo& first, const ResponseInfo& second) const; + /** + * @brief CheckResult checks whether the overall result + * of the responses is successful + * @param first response + * @param second response + * @return true if the overall result is successful + * otherwise - false + */ + bool CheckResult(const ResponseInfo& first, const ResponseInfo& second) const; + protected: /** * @brief Returns policy parameters permissions diff --git a/src/components/application_manager/include/application_manager/hmi_capabilities_impl.h b/src/components/application_manager/include/application_manager/hmi_capabilities_impl.h index c75306345b..e17748a490 100644 --- a/src/components/application_manager/include/application_manager/hmi_capabilities_impl.h +++ b/src/components/application_manager/include/application_manager/hmi_capabilities_impl.h @@ -515,6 +515,11 @@ class HMICapabilitiesImpl : public HMICapabilities { const smart_objects::SmartObject* rc_capability() const OVERRIDE; + void set_seat_location_capability( + const smart_objects::SmartObject& seat_location_capability) OVERRIDE; + + const smart_objects::SmartObject* seat_location_capability() const OVERRIDE; + void Init(resumption::LastState* last_state) OVERRIDE; /* @@ -617,6 +622,7 @@ class HMICapabilitiesImpl : public HMICapabilities { smart_objects::SmartObject* phone_capability_; smart_objects::SmartObject* video_streaming_capability_; smart_objects::SmartObject* rc_capability_; + smart_objects::SmartObject* seat_location_capability_; ApplicationManager& app_mngr_; HMILanguageHandler hmi_language_handler_; diff --git a/src/components/application_manager/include/application_manager/plugin_manager/rpc_plugin.h b/src/components/application_manager/include/application_manager/plugin_manager/rpc_plugin.h index c36f560ed5..61b146f024 100644 --- a/src/components/application_manager/include/application_manager/plugin_manager/rpc_plugin.h +++ b/src/components/application_manager/include/application_manager/plugin_manager/rpc_plugin.h @@ -43,6 +43,10 @@ namespace policy { class PolicyHandlerInterface; } +namespace resumption { +class LastState; +} + namespace application_manager { class CommandFactory; @@ -60,7 +64,8 @@ enum ApplicationEvent { kApplicationExit = 0, kApplicationRegistered, kApplicationUnregistered, - kDeleteApplicationData + kDeleteApplicationData, + kGlobalPropertiesUpdated }; class RPCPlugin { @@ -81,7 +86,8 @@ class RPCPlugin { virtual bool Init(ApplicationManager& app_manager, rpc_service::RPCService& rpc_service, HMICapabilities& hmi_capabilities, - policy::PolicyHandlerInterface& policy_handler) = 0; + policy::PolicyHandlerInterface& policy_handler, + resumption::LastState& last_state) = 0; /** * @brief IsAbleToProcess check if plugin is able to process function * @param function_id RPC identifier diff --git a/src/components/application_manager/include/application_manager/plugin_manager/rpc_plugin_manager_impl.h b/src/components/application_manager/include/application_manager/plugin_manager/rpc_plugin_manager_impl.h index 368817c89c..c3fc79b5f9 100644 --- a/src/components/application_manager/include/application_manager/plugin_manager/rpc_plugin_manager_impl.h +++ b/src/components/application_manager/include/application_manager/plugin_manager/rpc_plugin_manager_impl.h @@ -39,6 +39,10 @@ #include "application_manager/rpc_service.h" #include "utils/optional.h" +namespace resumption { +class LastState; +} + namespace application_manager { namespace plugin_manager { @@ -55,7 +59,8 @@ class RPCPluginManagerImpl : public RPCPluginManager { RPCPluginManagerImpl(ApplicationManager& app_manager, rpc_service::RPCService& rpc_service, HMICapabilities& hmi_capabilities, - policy::PolicyHandlerInterface& policy_handler); + policy::PolicyHandlerInterface& policy_handler, + resumption::LastState& last_state); uint32_t LoadPlugins(const std::string& plugins_path) OVERRIDE; @@ -74,6 +79,7 @@ class RPCPluginManagerImpl : public RPCPluginManager { rpc_service::RPCService& rpc_service_; HMICapabilities& hmi_capabilities_; policy::PolicyHandlerInterface& policy_handler_; + resumption::LastState& last_state_; // RPCPluginManager interface public: 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 d95432af4c..2ee8b96b0a 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 @@ -114,6 +114,7 @@ extern const char* menu_icon; extern const char* keyboard_properties; extern const char* vr_commands; extern const char* position; +extern const char* user_location; extern const char* num_ticks; extern const char* slider_footer; extern const char* menu_id; @@ -196,6 +197,7 @@ extern const char* navigation_capability; extern const char* phone_capability; extern const char* video_streaming_capability; extern const char* rc_capability; +extern const char* seat_location_capability; extern const char* app_services_capabilities; extern const char* day_color_scheme; extern const char* night_color_scheme; diff --git a/src/components/application_manager/rpc_plugins/app_service_rpc_plugin/include/app_service_rpc_plugin/app_service_rpc_plugin.h b/src/components/application_manager/rpc_plugins/app_service_rpc_plugin/include/app_service_rpc_plugin/app_service_rpc_plugin.h index 1120f68327..1765c1e7fa 100644 --- a/src/components/application_manager/rpc_plugins/app_service_rpc_plugin/include/app_service_rpc_plugin/app_service_rpc_plugin.h +++ b/src/components/application_manager/rpc_plugins/app_service_rpc_plugin/include/app_service_rpc_plugin/app_service_rpc_plugin.h @@ -47,7 +47,8 @@ class AppServiceRpcPlugin : public plugins::RPCPlugin { bool Init(app_mngr::ApplicationManager& application_manager, app_mngr::rpc_service::RPCService& rpc_service, app_mngr::HMICapabilities& hmi_capabilities, - policy::PolicyHandlerInterface& policy_handler) OVERRIDE; + policy::PolicyHandlerInterface& policy_handler, + resumption::LastState& last_state) OVERRIDE; bool IsAbleToProcess( const int32_t function_id, diff --git a/src/components/application_manager/rpc_plugins/app_service_rpc_plugin/src/app_service_rpc_plugin.cc b/src/components/application_manager/rpc_plugins/app_service_rpc_plugin/src/app_service_rpc_plugin.cc index 7195ce234f..79c6d9005e 100644 --- a/src/components/application_manager/rpc_plugins/app_service_rpc_plugin/src/app_service_rpc_plugin.cc +++ b/src/components/application_manager/rpc_plugins/app_service_rpc_plugin/src/app_service_rpc_plugin.cc @@ -49,7 +49,9 @@ bool AppServiceRpcPlugin::Init( application_manager::ApplicationManager& app_manager, application_manager::rpc_service::RPCService& rpc_service, application_manager::HMICapabilities& hmi_capabilities, - policy::PolicyHandlerInterface& policy_handler) { + policy::PolicyHandlerInterface& policy_handler, + resumption::LastState& last_state) { + UNUSED(last_state); application_manager_ = &app_manager; command_factory_.reset(new app_service_rpc_plugin::AppServiceCommandFactory( app_manager, rpc_service, hmi_capabilities, policy_handler)); diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/hmi/rc_on_remote_control_settings_notification.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/hmi/rc_on_remote_control_settings_notification.h index 7aa1aa3dba..82e0a8c13b 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/hmi/rc_on_remote_control_settings_notification.h +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/hmi/rc_on_remote_control_settings_notification.h @@ -69,6 +69,7 @@ class RCOnRemoteControlSettingsNotification private: ResourceAllocationManager& resource_allocation_manager_; InteriorDataManager& interior_data_manager_; + RCConsentManager& rc_consent_manager_; /** * @brief Disalows RC functionality for all RC apps * All registered apps will be unsubsribed from OnInteriorVehicleData diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/hmi/rc_set_global_properties_request.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/hmi/rc_set_global_properties_request.h new file mode 100644 index 0000000000..64b11c3d7b --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/hmi/rc_set_global_properties_request.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2019, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_SDL_RPC_PLUGIN_INCLUDE_SDL_RPC_PLUGIN_COMMANDS_HMI_RC_SET_GLOBAL_PROPERTIES_REQUEST_H +#define SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_SDL_RPC_PLUGIN_INCLUDE_SDL_RPC_PLUGIN_COMMANDS_HMI_RC_SET_GLOBAL_PROPERTIES_REQUEST_H + +#include "application_manager/commands/request_to_hmi.h" +#include "rc_rpc_plugin/commands/rc_command_request.h" + +namespace rc_rpc_plugin { +namespace app_mngr = application_manager; + +namespace commands { + +class RCSetGlobalPropertiesRequest : public app_mngr::commands::RequestToHMI { + public: + /** + * @brief RCSetGlobalPropertiesRequest class constructor + * + * @param message Command message as smart pointer to SmartObject + * @param params structure that contains references to + * parameters used in remote сontrol commands + */ + RCSetGlobalPropertiesRequest( + const app_mngr::commands::MessageSharedPtr& message, + const RCCommandParams& params); + /** + * @brief Execute command + */ + void Run() OVERRIDE; + + ~RCSetGlobalPropertiesRequest(); +}; +} // namespace commands +} // namespace rc_rpc_plugin + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_SDL_RPC_PLUGIN_INCLUDE_SDL_RPC_PLUGIN_COMMANDS_HMI_RC_SET_GLOBAL_PROPERTIES_REQUEST_H diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/hmi/rc_set_global_properties_response.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/hmi/rc_set_global_properties_response.h new file mode 100644 index 0000000000..2e1494364c --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/hmi/rc_set_global_properties_response.h @@ -0,0 +1,68 @@ +/* + Copyright (c) 2019, Ford Motor Company + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following + disclaimer in the documentation and/or other materials provided with the + distribution. + + Neither the name of the Ford Motor Company nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_SDL_RPC_PLUGIN_INCLUDE_SDL_RPC_PLUGIN_COMMANDS_HMI_RC_SET_GLOBAL_PROPERTIES_RESPONSE_H +#define SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_SDL_RPC_PLUGIN_INCLUDE_SDL_RPC_PLUGIN_COMMANDS_HMI_RC_SET_GLOBAL_PROPERTIES_RESPONSE_H + +#include "application_manager/commands/response_from_hmi.h" +#include "rc_rpc_plugin/commands/rc_command_request.h" + +namespace rc_rpc_plugin { +namespace app_mngr = application_manager; + +namespace commands { +class RCSetGlobalPropertiesResponse + : public application_manager::commands::ResponseFromHMI { + public: + /** + * @brief RCSetGlobalPropertiesResponse class constructor + * + * @param message Command message as smart pointer to SmartObject + * @param params Structure that contains references to + * parameters used in remote сontrol commands + */ + RCSetGlobalPropertiesResponse( + const application_manager::commands::MessageSharedPtr& message, + const RCCommandParams& params); + + /** + * @brief Execute command + */ + void Run() OVERRIDE; + + ~RCSetGlobalPropertiesResponse(); +}; + +} // namespace commands +} // namespace rc_rpc_plugin + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_SDL_RPC_PLUGIN_INCLUDE_SDL_RPC_PLUGIN_COMMANDS_HMI_RC_SET_GLOBAL_PROPERTIES_RESPONSE_H diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/mobile/button_press_request.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/mobile/button_press_request.h index d6ecfd0128..3946d80508 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/mobile/button_press_request.h +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/mobile/button_press_request.h @@ -64,9 +64,11 @@ class ButtonPressRequest : public RCCommandRequest { /** * @brief IsResourceFree check resource state * @param module_type Resource name + * @param module_id Resource id * @return True if free, otherwise - false */ - bool IsResourceFree(const std::string& module_type) const FINAL; + bool IsResourceFree(const std::string& module_type, + const std::string& module_id) const FINAL; /** * @brief SetResourceState changes state of resource @@ -82,12 +84,18 @@ class ButtonPressRequest : public RCCommandRequest { */ void on_event(const app_mngr::event_engine::Event& event) FINAL; - std::string ModuleType() FINAL; + std::string ModuleType() const FINAL; + + std::string ModuleId() const FINAL; /** * @brief ButtonPressRequest class destructor */ ~ButtonPressRequest(); + + private: + const mobile_apis::ButtonName::eType GetButtonId() const; + std::string GetButtonName() const; }; } // namespace commands diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/mobile/get_interior_vehicle_data_consent_request.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/mobile/get_interior_vehicle_data_consent_request.h new file mode 100644 index 0000000000..4ac1ee59cd --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/mobile/get_interior_vehicle_data_consent_request.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2019, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_INCLUDE_RC_RPC_PLUGIN_COMMANDS_MOBILE_RC_GET_INTERIOR_VEHICLE_DATA_CONSENT_REQUEST_H +#define SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_INCLUDE_RC_RPC_PLUGIN_COMMANDS_MOBILE_RC_GET_INTERIOR_VEHICLE_DATA_CONSENT_REQUEST_H + +#include <string> + +#include "rc_rpc_plugin/commands/rc_command_params.h" +#include "rc_rpc_plugin/commands/rc_command_request.h" +#include "utils/macro.h" + +namespace rc_rpc_plugin { +namespace commands { + +class GetInteriorVehicleDataConsentRequest + : public rc_rpc_plugin::commands::RCCommandRequest { + public: + /** + * @brief GetInteriorVehicleDataConsentRequest constructor + * @param message smart pointer with SmartObject + * @param params structure that contains references to + * parameters used in remote сontrol commands + */ + GetInteriorVehicleDataConsentRequest( + const application_manager::commands::MessageSharedPtr& message, + const RCCommandParams& params); + + /** + * @brief Execute command + */ + void Execute() FINAL; + + void on_event(const app_mngr::event_engine::Event& event) FINAL; + + std::string ModuleType() const FINAL; + + /** + * @brief For this RPC this method isn't correct, because SDL receives array + * of module_ids instead of only one module_id. This method returns empty + * string. + */ + std::string ModuleId() const FINAL; + + ~GetInteriorVehicleDataConsentRequest(); + + private: + /** + * @brief Saves ModuleId consents (saved before moduleids + received moduleId + * consents + date_of_consent) to file. + * + * @param msg_params Message params from response message as SmartObject. + */ + bool SaveModuleIdConsents(std::string& info_out, + const smart_objects::SmartObject& msg_params); + + /** + * @brief Gets calculated vehicle data consent and puts it into provided smart + * object + * @param out_response output smart object + * @return true in case all required consent information was provided in + * output smart object, otherwise returns false + */ + bool GetCalculatedVehicleDataConsent( + smart_objects::SmartObject& out_response) const; + + bool MultipleAccessAllowed( + const smart_objects::SmartArray& module_ids, + smart_objects::SmartArray& out_consents_array) const; +}; + +} // namespace commands +} // namespace rc_rpc_plugin + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_INCLUDE_RC_RPC_PLUGIN_COMMANDS_MOBILE_RC_GET_INTERIOR_VEHICLE_DATA_CONSENT_REQUEST_H diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/mobile/get_interior_vehicle_data_consent_response.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/mobile/get_interior_vehicle_data_consent_response.h new file mode 100644 index 0000000000..c163b02a80 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/mobile/get_interior_vehicle_data_consent_response.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2019, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_INCLUDE_RC_RPC_PLUGIN_COMMANDS_MOBILE_RC_GET_INTERIOR_VEHICLE_DATA_CONSENT_RESPONSE_H +#define SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_INCLUDE_RC_RPC_PLUGIN_COMMANDS_MOBILE_RC_GET_INTERIOR_VEHICLE_DATA_CONSENT_RESPONSE_H + +#include "application_manager/commands/command_response_impl.h" +#include "rc_rpc_plugin/commands/rc_command_params.h" +#include "utils/macro.h" + +namespace rc_rpc_plugin { + +namespace commands { + +class GetInteriorVehicleDataConsentResponse + : public application_manager::commands::CommandResponseImpl { + public: + /** + * @brief GetInteriorVehicleDataConsentResponse constructor + * + * @param message smart pointer with SmartObject + * @param params structure which contains references for next + * entities: ApplicationManager, RPCService, HMICapabilities, + * PolicyHandlerInterface, ResourceAllocationManager, InteriorDataCache, + * InteriorDataManager. + */ + GetInteriorVehicleDataConsentResponse( + const application_manager::commands::MessageSharedPtr& message, + const RCCommandParams& params); + + void Run() OVERRIDE; + + ~GetInteriorVehicleDataConsentResponse(); +}; + +} // namespace commands +} // namespace rc_rpc_plugin + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_INCLUDE_RC_RPC_PLUGIN_COMMANDS_MOBILE_RC_GET_INTERIOR_VEHICLE_DATA_CONSENT_RESPONSE_H diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/mobile/get_interior_vehicle_data_request.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/mobile/get_interior_vehicle_data_request.h index cfb5e72c95..7be37f0756 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/mobile/get_interior_vehicle_data_request.h +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/mobile/get_interior_vehicle_data_request.h @@ -63,8 +63,8 @@ class GetInteriorVehicleDataRequest : public RCCommandRequest { ~GetInteriorVehicleDataRequest(); private: - std::vector<application_manager::ApplicationSharedPtr> - AppsSubscribedToModuleType(const std::string& module_type); + std::vector<application_manager::ApplicationSharedPtr> AppsSubscribedToModule( + const ModuleUid& module); /** * @brief Check if app wants to proceed with already setup subscription @@ -87,7 +87,8 @@ class GetInteriorVehicleDataRequest : public RCCommandRequest { */ void RemoveExcessiveSubscription(); - std::string ModuleType() FINAL; + std::string ModuleType() const FINAL; + std::string ModuleId() const FINAL; bool excessive_subscription_occured_; bool ProcessCapabilities(); void ProcessResponseToMobileFromCache(app_mngr::ApplicationSharedPtr app); diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/mobile/on_interior_vehicle_data_notification.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/mobile/on_interior_vehicle_data_notification.h index 2a7362510d..4663b4b371 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/mobile/on_interior_vehicle_data_notification.h +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/mobile/on_interior_vehicle_data_notification.h @@ -53,13 +53,16 @@ class OnInteriorVehicleDataNotification void Run() OVERRIDE; - std::string ModuleType(); + std::string ModuleType() const; + + std::string ModuleId() const; ~OnInteriorVehicleDataNotification(); private: InteriorDataCache& interior_data_cache_; - void AddDataToCache(const std::string& module_type); + RCCapabilitiesManager& rc_capabilities_manager_; + void AddDataToCache(const ModuleUid& module); }; } // namespace commands } // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/mobile/release_interior_vehicle_data_module_request.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/mobile/release_interior_vehicle_data_module_request.h new file mode 100644 index 0000000000..316dc29a1d --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/mobile/release_interior_vehicle_data_module_request.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2019, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_INCLUDE_RC_RPC_PLUGIN_COMMANDS_MOBILE_RELEASE_INTERIOR_VEHICLE_DATA_MODULE_REQUEST_H +#define SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_INCLUDE_RC_RPC_PLUGIN_COMMANDS_MOBILE_RELEASE_INTERIOR_VEHICLE_DATA_MODULE_REQUEST_H + +#include "rc_rpc_plugin/commands/rc_command_params.h" +#include "rc_rpc_plugin/commands/rc_command_request.h" +#include "utils/macro.h" + +namespace rc_rpc_plugin { +namespace commands { + +class ReleaseInteriorVehicleDataModuleRequest + : public rc_rpc_plugin::commands::RCCommandRequest { + public: + /** + * @brief ReleaseInteriorVehicleDataModule constructor + * @param message smart pointer with SmartObject + * @param params structure that contains references to + * parameters used in remote сontrol commands + */ + ReleaseInteriorVehicleDataModuleRequest( + const application_manager::commands::MessageSharedPtr& message, + const RCCommandParams& params); + + void Execute() FINAL; + + std::string ModuleType() const FINAL; + + std::string ModuleId() const FINAL; + + ~ReleaseInteriorVehicleDataModuleRequest(); + + private: + bool ProcessCapabilities(); +}; + +} // namespace commands +} // namespace rc_rpc_plugin + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_INCLUDE_RC_RPC_PLUGIN_COMMANDS_MOBILE_RELEASE_INTERIOR_VEHICLE_DATA_MODULE_REQUEST_H diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/mobile/release_interior_vehicle_data_module_response.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/mobile/release_interior_vehicle_data_module_response.h new file mode 100644 index 0000000000..42e0775a83 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/mobile/release_interior_vehicle_data_module_response.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2019, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_INCLUDE_RC_RPC_PLUGIN_COMMANDS_MOBILE_RELEASE_INTERIOR_VEHICLE_DATA_MODULE_RESPONSE_H +#define SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_INCLUDE_RC_RPC_PLUGIN_COMMANDS_MOBILE_RELEASE_INTERIOR_VEHICLE_DATA_MODULE_RESPONSE_H + +#include "application_manager/commands/command_response_impl.h" +#include "rc_rpc_plugin/commands/rc_command_params.h" +#include "utils/macro.h" + +namespace rc_rpc_plugin { +namespace commands { + +class ReleaseInteriorVehicleDataModuleResponse + : public application_manager::commands::CommandResponseImpl { + public: + /** + * @brief ReleaseInteriorVehicleDataModuleResponse constructor + * + * @param message smart pointer with SmartObject + * @param params structure which contains references for next + * entities: ApplicationManager, RPCService, HMICapabilities, + * PolicyHandlerInterface, ResourceAllocationManager, InteriorDataCache, + * InteriorDataManager. + */ + ReleaseInteriorVehicleDataModuleResponse( + const application_manager::commands::MessageSharedPtr& message, + const RCCommandParams& params); + + void Run() OVERRIDE; + + ~ReleaseInteriorVehicleDataModuleResponse(); +}; + +} // namespace commands +} // namespace rc_rpc_plugin + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_INCLUDE_RC_RPC_PLUGIN_COMMANDS_MOBILE_RELEASE_INTERIOR_VEHICLE_DATA_MODULE_RESPONSE_H diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/mobile/set_interior_vehicle_data_request.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/mobile/set_interior_vehicle_data_request.h index 128c668ee9..bb152a52f8 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/mobile/set_interior_vehicle_data_request.h +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/mobile/set_interior_vehicle_data_request.h @@ -40,10 +40,6 @@ namespace app_mngr = application_manager; namespace commands { -enum capabilitiesStatus { success, missedLightName, missedParam, readOnly }; - -typedef std::pair<std::string, capabilitiesStatus> ModuleCapability; - class SetInteriorVehicleDataRequest : public RCCommandRequest { public: SetInteriorVehicleDataRequest( @@ -66,9 +62,11 @@ class SetInteriorVehicleDataRequest : public RCCommandRequest { /** * @brief IsResourceFree check resource state * @param module_type Resource name + * @param module_id Resource id * @return True if free, otherwise - false */ - bool IsResourceFree(const std::string& module_type) const FINAL; + bool IsResourceFree(const std::string& module_type, + const std::string& module_id) const FINAL; /** * @brief SetResourceState changes state of resource @@ -85,28 +83,14 @@ class SetInteriorVehicleDataRequest : public RCCommandRequest { void on_event(const app_mngr::event_engine::Event& event) FINAL; /** - * @brief Method that check if READ_ONLY parameters present - * @param request_params params from received message, - * @param module_data_capabilities info for notification to mobile - * @return true if present , false - otherwise - */ - bool AreReadOnlyParamsPresent(const smart_objects::SmartObject& module_data, - ModuleCapability& module_data_capabilities); - - /** - * @brief Method that check if all request parameters are READ_ONLY - * @param request_params params from received message - * @return true if all are read only , false - otherwise - */ - bool AreAllParamsReadOnly(const smart_objects::SmartObject& module_data); - - /** * @brief Method that cuts-off READ_ONLY parameters * @param module_data params to handle */ void CutOffReadOnlyParams(smart_objects::SmartObject& module_data); - std::string ModuleType() FINAL; + std::string ModuleType() const FINAL; + + std::string ModuleId() const FINAL; /** * @brief SetInteriorVehicleDataRequest class destructor @@ -115,14 +99,6 @@ class SetInteriorVehicleDataRequest : public RCCommandRequest { private: /** - * @brief ControlData - * @param module_data received params - * @return value of module data depending on module type - */ - const smart_objects::SmartObject& ControlData( - const smart_objects::SmartObject& module_data); - - /** * @brief CheckAudioSource check that if app wants to change * the audio source from MOBILE_APP to other types of audio * source without keepContext parameter or with keepContext=false diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/rc_command_params.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/rc_command_params.h index 0ca7789791..3b46b7ea30 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/rc_command_params.h +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/rc_command_params.h @@ -50,6 +50,8 @@ namespace rc_rpc_plugin { class ResourceAllocationManager; class InteriorDataCache; class InteriorDataManager; +class RCCapabilitiesManager; +class RCConsentManager; struct RCCommandParams { application_manager::ApplicationManager& application_manager_; @@ -59,6 +61,8 @@ struct RCCommandParams { rc_rpc_plugin::ResourceAllocationManager& resource_allocation_manager_; rc_rpc_plugin::InteriorDataCache& interior_data_cache_; rc_rpc_plugin::InteriorDataManager& interior_data_manager_; + rc_rpc_plugin::RCCapabilitiesManager& rc_capabilities_manager_; + rc_rpc_plugin::RCConsentManager& rc_consent_manager_; }; } // namespace rc_rpc_plugin #endif // SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_INCLUDE_RC_RPC_PLUGIN_COMMANDS_RC_COMMAND_PARAMS_H_ diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/rc_command_request.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/rc_command_request.h index b4e34c083e..6bca1017e0 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/rc_command_request.h +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/commands/rc_command_request.h @@ -37,6 +37,8 @@ #include "rc_rpc_plugin/commands/rc_command_params.h" #include "rc_rpc_plugin/interior_data_cache.h" #include "rc_rpc_plugin/rc_app_extension.h" +#include "rc_rpc_plugin/rc_capabilities_manager.h" +#include "rc_rpc_plugin/rc_consent_manager.h" #include "rc_rpc_plugin/resource_allocation_manager.h" namespace rc_rpc_plugin { @@ -76,6 +78,8 @@ class RCCommandRequest : public app_mngr::commands::CommandRequestImpl { ResourceAllocationManager& resource_allocation_manager_; InteriorDataCache& interior_data_cache_; InteriorDataManager& interior_data_manager_; + RCCapabilitiesManager& rc_capabilities_manager_; + RCConsentManager& rc_consent_manager_; /** * @brief AcquireResource try to allocate resource for application * In case if allocation of resource is not required, return ALLOWED by @@ -94,10 +98,13 @@ class RCCommandRequest : public app_mngr::commands::CommandRequestImpl { * This is default implementation which has to be redefined for RPCs which * need to manage the resources * @param module_type Resource name + * @param module_id Resource id * @return True if free, otherwise - false */ - virtual bool IsResourceFree(const std::string& module_type) const { + virtual bool IsResourceFree(const std::string& module_type, + const std::string& module_id) const { UNUSED(module_type); + UNUSED(module_id); return true; } /** @@ -136,7 +143,24 @@ class RCCommandRequest : public app_mngr::commands::CommandRequestImpl { disallowed_info_ = info; } - virtual std::string ModuleType() = 0; + virtual std::string ModuleType() const = 0; + + /** + * @brief Extracts ModuleId from command message. Each inherited class should + * implement its own functionality + * + * @return ModuleId as string. + */ + virtual std::string ModuleId() const = 0; + + /** + * @brief IsModuleIdProvided checks if moduleId parameter + * is provided in the hmi response + * @param hmi_response response from hmi + * @return true if provided, otherwise - false + */ + + bool IsModuleIdProvided(const smart_objects::SmartObject& hmi_response) const; private: /** @@ -158,9 +182,38 @@ class RCCommandRequest : public app_mngr::commands::CommandRequestImpl { /** * @brief SendGetUserConsent sends consent request to HMI * @param module_type Resource name + * @param module_ids Array of module IDs of the module type that needed user + * consent for acquiring their resources */ - void SendGetUserConsent(const std::string& module_type); + void SendGetUserConsent(const std::string& module_type, + const smart_objects::SmartObject& module_ids); + void ProcessAccessResponse(const app_mngr::event_engine::Event& event); + + /** + * @brief Precesses consents result which has been received from HMI + * If module resource consented, resource state will be switched to state BUSY + * and called method Execute. Otherwise will be sent response to Mobile with + * result code REJECTED. + * @param is_allowed consent result + * @param module_type Module type + * @param module_id Module ID + * @param app_id Application, which has asked for module resource consent. + */ + void ProcessConsentResult(const bool is_allowed, + const std::string& module_type, + const std::string& module_id, + const uint32_t app_id); + /** + * @brief Processes ASK_DRIVE Mode. Tries to retrieve module consents from + * LastState. If consent is absent in LastState, will send + * GetInteriorVehicleDataConsent to HMI. Otherwise will start to process + * consent result. + * @param module_type Module type + * @param module_id Module ID + */ + void ProcessAskDriverMode(const std::string& module_type, + const std::string& module_id); bool IsInterfaceAvailable( const app_mngr::HmiInterfaces::InterfaceID interface) const; diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/interior_data_cache.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/interior_data_cache.h index c7dda761bf..dad37edd1b 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/interior_data_cache.h +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/interior_data_cache.h @@ -37,8 +37,15 @@ namespace rc_rpc_plugin { /** + * @brief ModuleUid uniquely identify a module + * moduleType + moduleID + */ +typedef std::pair<std::string, std::string> ModuleUid; + +/** * @brief The InteriorDataCache interface for caching data class - * Provide ability to cache module data by module type name and clear cache + * Provide ability to cache module data by module type name and module id + * and clear cache */ class InteriorDataCache { public: @@ -49,32 +56,35 @@ class InteriorDataCache { /** * @brief Add module data to cache - * @param module_type module type name + * @param module module type + module id * @param module_data data to be cached */ - virtual void Add(const std::string& module_type, + virtual void Add(const ModuleUid& module, const smart_objects::SmartObject& module_data) = 0; /** * @brief Retrieve Get cached data - * @param module_type data type to get from cache + * @param module data type to get from cache * @return smart object with cached data, or nulll smart object */ virtual smart_objects::SmartObject Retrieve( + const ModuleUid& module) const = 0; + + virtual std::vector<ModuleUid> GetCachedModulesByType( const std::string& module_type) const = 0; /** * @brief Contains check if data exists in cache - * @param module_type module type name to check in cache + * @param module module name + module id to check in cache * @return true if cached, false otherwize */ - virtual bool Contains(const std::string& module_type) const = 0; + virtual bool Contains(const ModuleUid& module) const = 0; /** * @brief Remove cached data - * @param module_type data type to remove from cache + * @param module data type to remove from cache */ - virtual void Remove(const std::string& module_type) = 0; + virtual void Remove(const ModuleUid& module) = 0; /** * @brief Clear clear all cached data diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/interior_data_cache_impl.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/interior_data_cache_impl.h index b40ce4eb4b..d21b0e4162 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/interior_data_cache_impl.h +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/interior_data_cache_impl.h @@ -46,16 +46,19 @@ class InteriorDataCacheImpl : public InteriorDataCache { ~InteriorDataCacheImpl(); - void Add(const std::string& module_type, + void Add(const ModuleUid& module, const smart_objects::SmartObject& module_data) OVERRIDE; - smart_objects::SmartObject Retrieve( + smart_objects::SmartObject Retrieve(const ModuleUid& module) const OVERRIDE; + + std::vector<ModuleUid> GetCachedModulesByType( const std::string& module_type) const OVERRIDE; - bool Contains(const std::string& module_type) const OVERRIDE; - void Remove(const std::string& module_type) OVERRIDE; + + bool Contains(const ModuleUid& module) const OVERRIDE; + void Remove(const ModuleUid& module) OVERRIDE; void Clear() OVERRIDE; private: - std::map<std::string, smart_objects::SmartObject> cached_data_; + std::map<ModuleUid, smart_objects::SmartObject> cached_data_; mutable sync_primitives::Lock cached_data_lock_; }; diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/interior_data_manager.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/interior_data_manager.h index 157e031869..42ae7ea4fe 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/interior_data_manager.h +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/interior_data_manager.h @@ -41,6 +41,12 @@ namespace rc_rpc_plugin { namespace app_mngr = application_manager; namespace plugins = application_manager::plugin_manager; +/** + * @brief ModuleUid uniquely identify a module + * moduleType + moduleID + */ +typedef std::pair<std::string, std::string> ModuleUid; + class InteriorDataManager { public: /** @@ -67,18 +73,19 @@ class InteriorDataManager { /** * @brief StoreRequestToHMITime save information and time stamp of * current interior data subscriptions + * @param module Module resource (module_type + module_id) */ - virtual void StoreRequestToHMITime(const std::string& module_type) = 0; + virtual void StoreRequestToHMITime(const ModuleUid& module) = 0; /** * @brief CheckRequestsToHMIFrequency check that rate limits are not allowed * of bounce during current time frame. calculate amount of requests per - * module type in time frame and checks if it bigger then allowed by ini file - * @param module_type moduletype to calculate frequency on + * module in time frame and checks if it bigger then allowed by ini file + * @param module module to calculate frequency on * @return true if amount of requests was not exceeded, otherwise return * false. */ - virtual bool CheckRequestsToHMIFrequency(const std::string& module_type) = 0; + virtual bool CheckRequestsToHMIFrequency(const ModuleUid& module) = 0; }; } // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/interior_data_manager_impl.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/interior_data_manager_impl.h index b98ba596fb..791016cdcd 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/interior_data_manager_impl.h +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/interior_data_manager_impl.h @@ -61,9 +61,9 @@ class InteriorDataManagerImpl : public InteriorDataManager { void OnDisablingRC() OVERRIDE; - void StoreRequestToHMITime(const std::string& module_type) OVERRIDE; + void StoreRequestToHMITime(const ModuleUid& module) OVERRIDE; - bool CheckRequestsToHMIFrequency(const std::string& module_type) OVERRIDE; + bool CheckRequestsToHMIFrequency(const ModuleUid& module) OVERRIDE; private: /** @@ -83,18 +83,20 @@ class InteriorDataManagerImpl : public InteriorDataManager { application_manager::Application& app); /** - * @brief UnsubscribeFromInteriorVehicleData remove module_type from cache and + * @brief UnsubscribeFromInteriorVehicleData remove module from cache and * send RC.GetInteriorVehicleData(subscribe=false) to HMI - * @param module_type module type that need to be unsubscribed + * @param module module that needs to be unsubscribed */ - void UnsubscribeFromInteriorVehicleData(const std::string& module_type); + void UnsubscribeFromInteriorVehicleData(const ModuleUid& module); + + void UnsubscribeFromInteriorVehicleDataOfType(const std::string& module_type); void ClearOldRequestsToHMIHistory(); /** * @brief AppsModules mapping from applications to list of modules */ typedef std::map<application_manager::ApplicationSharedPtr, - std::vector<std::string> > + std::vector<ModuleUid> > AppsModules; /** @@ -104,11 +106,16 @@ class InteriorDataManagerImpl : public InteriorDataManager { */ AppsModules AppsSubscribedModules(); + typedef std::map<application_manager::ApplicationSharedPtr, + std::vector<std::string> > + AppsModuleTypes; + AppsModuleTypes AppsSubscribedModuleTypes(); + /** * @brief RequestsToHMIHistory mapping from module type to vector of time * stamps */ - typedef std::map<std::string, std::deque<date_time::TimeDuration> > + typedef std::map<ModuleUid, std::deque<date_time::TimeDuration> > RequestsToHMIHistory; RequestsToHMIHistory requests_to_hmi_history_; mutable sync_primitives::Lock requests_to_hmi_history_lock_; diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/rc_app_extension.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/rc_app_extension.h index 36fe9f5bdb..33271e64fd 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/rc_app_extension.h +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/rc_app_extension.h @@ -40,6 +40,103 @@ #include "utils/macro.h" namespace rc_rpc_plugin { + +typedef std::pair<std::string, std::string> ModuleUid; + +struct Grid { + int32_t col_; + int32_t row_; + int32_t level_; + int32_t colspan_; + int32_t rowspan_; + int32_t levelspan_; + + Grid() + : col_(0), row_(0), level_(0), colspan_(0), rowspan_(0), levelspan_(0) {} + + Grid(int32_t col, + int32_t row, + int32_t level, + int32_t colspan, + int32_t rowspan, + int32_t levelspan) + : col_(col) + , row_(row) + , level_(level) + , colspan_(colspan) + , rowspan_(rowspan) + , levelspan_(levelspan) {} + + Grid& operator=(const Grid& grid) { + col_ = grid.col_; + row_ = grid.row_; + level_ = grid.level_; + colspan_ = grid.colspan_; + rowspan_ = grid.rowspan_; + levelspan_ = grid.levelspan_; + + return *this; + } + + bool operator==(const Grid& grid) const { + return col_ == grid.col_ && row_ == grid.row_ && level_ == grid.level_ && + colspan_ == grid.colspan_ && rowspan_ == grid.rowspan_ && + levelspan_ == grid.levelspan_; + } + + /** + * @brief LevelIntersectionExists checks if the grids have an + * intersection by levels. + * @param grid with which to check intersection + * @return true if intersection exists, otherwise - false + */ + bool LevelIntersectionExists(const Grid& grid) const { + const int32_t top_level = (level_ + levelspan_) - 1; + const int32_t grid_top_level = (grid.level_ + grid.levelspan_) - 1; + + const int32_t min_level = std::max(level_, grid.level_); + const int32_t max_level = std::min(top_level, grid_top_level); + if ((max_level - min_level) < 0) { + return false; + } + return true; + } + + /** + * @brief IntersectionExists checks if the grids have an + * intersection. Grid can be represented by its bottom-left + * and top-right coordinates like a rectangle. First, the + * coordinates of the intersection are calculated, then checked + * that the rectangle which is formed by the intersections of two + * grids has non-zero width and height. + * @param grid with which to check intersection + * @return true if intersection exists, otherwise - false + */ + bool IntersectionExists(const Grid& grid) const { + if (!LevelIntersectionExists(grid)) { + return false; + } + + const int32_t right_top_col = (col_ + colspan_) - 1; + const int32_t right_top_row = (row_ + rowspan_) - 1; + const int32_t grid_right_top_col = (grid.col_ + grid.colspan_) - 1; + const int32_t grid_right_top_row = (grid.row_ + grid.rowspan_) - 1; + + const int32_t left = std::max(col_, grid.col_); + const int32_t bottom = std::max(row_, grid.row_); + const int32_t right = std::min(right_top_col, grid_right_top_col); + const int32_t top = std::min(right_top_row, grid_right_top_row); + + const int32_t width = right - left; + const int32_t height = top - bottom; + + if ((width < 0) || (height < 0)) { + return false; + } + return true; + } +}; + class RCAppExtension : public application_manager::AppExtension { public: explicit RCAppExtension(application_manager::AppExtensionUID uid); @@ -49,13 +146,15 @@ class RCAppExtension : public application_manager::AppExtension { * @brief Subscribe to OnInteriorVehicleDataNotification * @param module interior data specification(zone, data type) */ - void SubscribeToInteriorVehicleData(const std::string& module_type); + void SubscribeToInteriorVehicleData(const ModuleUid& module); /** * @brief Unsubscribe from OnInteriorVehicleDataNotification * @param module interior data specification(zone, data type) */ - void UnsubscribeFromInteriorVehicleData(const std::string& module_type); + void UnsubscribeFromInteriorVehicleData(const ModuleUid& module); + + void UnsubscribeFromInteriorVehicleDataOfType(const std::string& module_type); /** * @brief UnsubscribeFromInteriorVehicleData removes all subscriptions for @@ -67,16 +166,40 @@ class RCAppExtension : public application_manager::AppExtension { * @brief Check if application subscribed to OnInteriorVehicleDataNotification * @param module interior data specification(zone, data type) */ - bool IsSubscibedToInteriorVehicleData(const std::string& module_type); + bool IsSubscribedToInteriorVehicleData(const ModuleUid& module); + + bool IsSubscribedToInteriorVehicleDataOfType(const std::string& module_type); /** * @brief get list of subscriptions of application * @return list of subscriptions of application */ - std::set<std::string> InteriorVehicleDataSubscriptions() const; + std::set<ModuleUid> InteriorVehicleDataSubscriptions() const; + + /** + * @brief GetUserLocation + * @return grid of user location + */ + Grid GetUserLocation() const; + + /** + * @brief SetUserLocation sets user location + * from object to the grid + * @param user_location smart object for user_location + */ + void SetUserLocation( + const ns_smart_device_link::ns_smart_objects::SmartObject& user_location); + + /** + * @brief SetUserLocation sets user location from grid + * @param grid grid of user_location + */ + void SetUserLocation(const Grid& grid); private: - std::set<std::string> subscribed_interior_vehicle_data_; + std::set<ModuleUid> subscribed_interior_vehicle_data_; + + Grid user_location_; // AppExtension interface public: diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/rc_capabilities_manager.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/rc_capabilities_manager.h new file mode 100644 index 0000000000..36fd8bbbf9 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/rc_capabilities_manager.h @@ -0,0 +1,184 @@ +/* + Copyright (c) 2019, Ford Motor Company + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following + disclaimer in the documentation and/or other materials provided with the + distribution. + + Neither the name of the Ford Motor Company nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_INCLUDE_RC_RPC_PLUGIN_RC_CAPABILITIES_MANAGER_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_INCLUDE_RC_RPC_PLUGIN_RC_CAPABILITIES_MANAGER_H_ +#include "application_manager/application_manager.h" +#include "rc_rpc_plugin/resource_allocation_manager.h" + +namespace rc_rpc_plugin { + +enum capabilitiesStatus { success, missedLightName, missedParam, readOnly }; +typedef std::pair<std::string, capabilitiesStatus> ModuleTypeCapability; + +class RCCapabilitiesManager { + public: + /** + * @brief CheckIfButtonExistInRCCaps checks if the + * specified button exists in rc_capabilities + * @param button button name + * @return true if present, otherwise - false + */ + virtual bool CheckIfButtonExistInRCCaps( + const mobile_apis::ButtonName::eType button) const = 0; + + /** + * @brief CheckButtonName checks if the button + * corresponds to the module_type + * @param module_type resource name + * @param button_name button name + * @return true if they match, otherwise - false + */ + virtual bool CheckButtonName(const std::string& module_type, + const std::string& button_name) const = 0; + + /** + * @brief CheckIfModuleExistsInCapabilities checks + * if the specified module exists in rc_capabilities + * @param module moduleType + moduleId + * @return true if exists, otherwise - false + */ + virtual bool CheckIfModuleExistsInCapabilities( + const ModuleUid& module) const = 0; + + /** + * @brief GetModuleDataCapabilities checks whether rc module data + * capabilities are presented + * @param module_data smart object of module_data + * @param module_id module id + * @return pair of state and capability status - ModuleCapability + */ + virtual ModuleTypeCapability GetModuleDataCapabilities( + const smart_objects::SmartObject& module_data, + const std::string& module_id) const = 0; + + /** + * @brief ControlData retrieves control data + * for specified module type + * @param module_data smart object of module_data + * @param module_type resource name + * @return smart object of control data + */ + virtual const smart_objects::SmartObject& ControlDataForType( + const smart_objects::SmartObject& module_data, + const std::string& module_type) const = 0; + + /** + * @brief AreReadOnlyParamsPresent checks if there are + * any read only params in the module data + * @param module_data smart object of module_data + * @param module_type resource name + * @param module_data_capabilities smart object of capabilities + * @return true if read only params exist, otherwise - false + */ + virtual bool AreReadOnlyParamsPresent( + const smart_objects::SmartObject& module_data, + const std::string& module_type, + ModuleTypeCapability& module_data_capabilities) const = 0; + + /** + * @brief AreAllParamsReadOnly checks that all params from module + * data are read only + * @param module_data smart object of module_data + * @param module_type resource name + * @return true if all params are read only, otherwise - false + */ + virtual bool AreAllParamsReadOnly( + const smart_objects::SmartObject& module_data, + const std::string& module_type) const = 0; + + /** + * @brief GetDefaultModuleIdFromCapabilities returns the moduleId + * from the first item published by xyz-ControlCapabilities + * @param module_type resource name + * @return default module id from HMI capabilities + */ + virtual const std::string GetDefaultModuleIdFromCapabilities( + const std::string& module_type) const = 0; + + /** + * @brief GetResources get list of ModuleUids(moduleType + moduleId) + * of all known resources + * @return vector contains all known moduleUids + */ + virtual const std::vector<ModuleUid> GetResources() const = 0; + + /** + * @brief GetModuleServiceArea retrieves service area of module, + * if module serviceArea is missed in capabilities, serviceArea is + * assumed to be the same as location, if location + * is missed in capabilities, it is assumed that serviceArea covers + * the whole area of vehicle + * @param module module type + module id + * @return Grid of module service area + */ + virtual Grid GetModuleServiceArea(const ModuleUid& module) const = 0; + + /** + * @brief IsMultipleAccessAllowed checks if multiple access allowed + * for requested module + * @param module module type + module id + * @return true if allowed, otherwise - false + */ + virtual bool IsMultipleAccessAllowed(const ModuleUid& module) const = 0; + + /** + * @brief GetDriverLocationFromSeatLocationCapability retrieves the driver's + * location from seat location capabilities + * @return Grid of driver's location + */ + virtual const Grid GetDriverLocationFromSeatLocationCapability() const = 0; + + /** + * @brief IsSeatLocationCapabilityProvided checks whether all necessary + * parameters are provided in seat location capabilities + * @return true if provided, otherwise - false + */ + virtual bool IsSeatLocationCapabilityProvided() const = 0; + + /** + * @brief GetModuleIdForSeatLocation returns the moduleId if request from + * mobile contains the id parameter and doesn't contain the moduleId + * parameter. If the vehicle support at least one seat control, seat control + * capability includes at least two items. SupportedSeat id shall be converted + * to the moduleId according to capabilities: 1st item from capabilities for + * driver’s seat. 2nd item for front passenger’s seat. + * @param id supported seat id + */ + virtual const std::string GetModuleIdForSeatLocation( + mobile_apis::SupportedSeat::eType id) const = 0; + + virtual ~RCCapabilitiesManager() {} +}; + +} // namespace rc_rpc_plugin +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_INCLUDE_RC_RPC_PLUGIN_RC_CAPABILITIES_MANAGER_H_ diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/rc_capabilities_manager_impl.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/rc_capabilities_manager_impl.h new file mode 100644 index 0000000000..844647940f --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/rc_capabilities_manager_impl.h @@ -0,0 +1,200 @@ +/* + Copyright (c) 2019, Ford Motor Company + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following + disclaimer in the documentation and/or other materials provided with the + distribution. + + Neither the name of the Ford Motor Company nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_INCLUDE_RC_RPC_PLUGIN_RC_CAPABILITIES_MANAGER_IMPL_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_INCLUDE_RC_RPC_PLUGIN_RC_CAPABILITIES_MANAGER_IMPL_H_ +#include "application_manager/application_manager.h" +#include "rc_rpc_plugin/rc_capabilities_manager.h" + +namespace rc_rpc_plugin { +class RCCapabilitiesManagerImpl : public RCCapabilitiesManager { + public: + RCCapabilitiesManagerImpl( + application_manager::HMICapabilities& hmi_capabilities); + + bool CheckIfButtonExistInRCCaps( + const mobile_apis::ButtonName::eType button) const FINAL; + + bool CheckButtonName(const std::string& module_type, + const std::string& button_name) const FINAL; + + bool CheckIfModuleExistsInCapabilities(const ModuleUid& module) const FINAL; + + ModuleTypeCapability GetModuleDataCapabilities( + const smart_objects::SmartObject& module_data, + const std::string& module_id) const FINAL; + + const smart_objects::SmartObject& ControlDataForType( + const smart_objects::SmartObject& module_data, + const std::string& module_type) const FINAL; + + bool AreReadOnlyParamsPresent( + const smart_objects::SmartObject& module_data, + const std::string& module_type, + ModuleTypeCapability& module_data_capabilities) const FINAL; + + bool AreAllParamsReadOnly(const smart_objects::SmartObject& module_data, + const std::string& module_type) const FINAL; + + const std::string GetDefaultModuleIdFromCapabilities( + const std::string& module_type) const FINAL; + + const std::vector<ModuleUid> GetResources() const FINAL; + + Grid GetModuleServiceArea(const ModuleUid& module) const FINAL; + + bool IsMultipleAccessAllowed(const ModuleUid& module) const FINAL; + + const Grid GetDriverLocationFromSeatLocationCapability() const FINAL; + + bool IsSeatLocationCapabilityProvided() const FINAL; + + const std::string GetModuleIdForSeatLocation( + mobile_apis::SupportedSeat::eType id) const FINAL; + + private: + const std::map<std::string, std::string> GetLightCapabilitiesMapping() const; + + const std::map<std::string, std::string> GetModuleDataToCapabilitiesMapping() + const; + + /** + * @brief Check whether the exists light data related to correspondent + * capabilities + * @param capabilities smart object of capabilities + * @param control_data smart object of control_data + * @return pair of state and capability status - ModuleTypeCapability + */ + ModuleTypeCapability GetControlDataCapabilities( + const smart_objects::SmartObject& capabilities, + const smart_objects::SmartObject& control_data) const; + + /** + * @brief Check whether the parameter exist in capabilities + * @param capabilities smart object of capabilities + * @param mapping - map of module data and capabilities + * @param request_parameter - string + * @param switched_off_result - ref of mobile_apis::Result + * @return success if the parameter exists in capabilities, + * otherwise - missedParam + */ + capabilitiesStatus GetItemCapability( + const smart_objects::SmartObject& capabilities, + const std::map<std::string, std::string>& mapping, + const std::string& request_parameter, + const mobile_apis::Result::eType& switched_off_result) const; + + /** + * @brief Check whether the capabilities for light are allowed + * @param capabilities smart object of capabilities + * @param control_data smart object of control_data + * @return pair of state and capability status - ModuleTypeCapability + */ + ModuleTypeCapability GetLightDataCapabilities( + const smart_objects::SmartObject& capabilities, + const smart_objects::SmartObject& control_data) const; + + /** + * @brief Check whether the light name exists in capabilities + * @param capabilities_status smart object of capabilities_status + * @param light_data smart object of light_data + * @return pair of state and capability status - ModuleTypeCapability + */ + ModuleTypeCapability GetLightNameCapabilities( + const smart_objects::SmartObject& capabilities_status, + const smart_objects::SmartObject& light_data) const; + + ModuleTypeCapability GetRadioBandByCapabilities( + const smart_objects::SmartObject& capabilities_status, + const smart_objects::SmartObject& request_parameter) const; + + bool CheckReadOnlyParamsForAudio( + const smart_objects::SmartObject& module_type_params) const; + + bool CheckReadOnlyParamsForLight( + const smart_objects::SmartObject& module_type_params) const; + + smart_objects::SmartObject GetCapabilitiesByModuleIdFromArray( + const smart_objects::SmartObject& module_data_capabilities, + const std::string& module_id) const; + + const bool CheckModuleIdWithCapabilities( + const smart_objects::SmartObject& rc_capabilities, + const ModuleUid& module) const; + + const bool CheckModuleIdWithCapabilitiesArrays( + const smart_objects::SmartObject& control_capabilities, + const std::string& module_id) const; + + const bool CheckModuleIdWithCapabilitiesStructure( + const smart_objects::SmartObject& control_capabilities, + const std::string& module_id) const; + + const std::string GetDefaultModuleIdFromCapabilitiesStructure( + const smart_objects::SmartObject& control_capabilities, + const std::string& module_type) const; + + const std::string GetDefaultModuleIdFromCapabilitiesArray( + const smart_objects::SmartObject& control_capabilities, + const std::string& module_type) const; + + const std::vector<std::string> GetCapabilitiesList() const; + + const std::function<std::string(const std::string& control_cap)> + GetCapabilitiesToModuleTypeMapping() const; + + void GetResourcesFromCapabilitiesStructure( + const smart_objects::SmartObject& control_capabilities, + const std::string& capabitity_key, + std::vector<ModuleUid>& out_resources) const; + + void GetResourcesFromCapabilitiesArray( + const smart_objects::SmartObject& control_capabilities, + const std::string& capability_key, + std::vector<ModuleUid>& out_resources) const; + + Grid GetModuleServiceAreaFromControlCapability( + const smart_objects::SmartObject& control_capabilities) const; + + Grid GetModuleLocationFromControlCapability( + const smart_objects::SmartObject& control_capabilities) const; + + bool IsMultipleAccessAllowedInControlCaps( + const smart_objects::SmartObject& control_capabilities) const; + + Grid GetWholeVehicleArea() const; + + application_manager::HMICapabilities& hmi_capabilities_; +}; + +} // namespace rc_rpc_plugin +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_INCLUDE_RC_RPC_PLUGIN_RC_CAPABILITIES_MANAGER_IMPL_H_ diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/rc_consent_manager.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/rc_consent_manager.h new file mode 100644 index 0000000000..cde7928a14 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/rc_consent_manager.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2019, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_INCLUDE_RC_CONSENT_MANAGER_H +#define SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_INCLUDE_RC_CONSENT_MANAGER_H + +#include <string> + +#include "rc_rpc_types.h" + +namespace ns_smart_device_link { +namespace ns_smart_objects { +class SmartObject; +} // namespace ns_smart_objects +} // namespace ns_smart_device_link + +namespace rc_rpc_plugin { + +class RCConsentManager { + public: + /** + * @brief Saves consents (is_consented + date_of_consent) for module resources + * (module_type + module_id) for specified application + * @param policy_app_id Application id which module consents should be saved + * @param mac_address Device mac address + * @param module_consents - Module resources consents + */ + virtual void SaveModuleConsents( + const std::string& policy_app_id, + const std::string& mac_address, + const rc_rpc_types::ModuleIdConsentVector& module_consents) = 0; + + /** + * @brief Retrieves saved consent for specified module resource (module_type + * + module_id) + * @param app_id Application which related to specified module resource + * @param mac_address Device mac address + * @param module_id Module resource (module_type + module_id) + * @return Module consent state + */ + virtual rc_rpc_plugin::rc_rpc_types::ModuleConsent GetModuleConsent( + const std::string& app_id, + const std::string& mac_address, + const rc_rpc_types::ModuleUid& module_id) const = 0; + + /** + * @brief Remove modules consents from LastState if they exist + */ + virtual void RemoveAllConsents() = 0; + + /** + * @brief Remove all expired module consents from LastState + * if they exist + */ + virtual void RemoveExpiredConsents() = 0; + + virtual ~RCConsentManager() {} +}; + +} // namespace rc_rpc_plugin + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_INCLUDE_RC_CONSENT_MANAGER_H diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/rc_consent_manager_impl.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/rc_consent_manager_impl.h new file mode 100644 index 0000000000..b3c6a0b129 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/rc_consent_manager_impl.h @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2019, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_INCLUDE_RC_CONSENT_MANAGER_IMPL_H +#define SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_INCLUDE_RC_CONSENT_MANAGER_IMPL_H + +#include "rc_consent_manager.h" +#include "resumption/last_state.h" +#include "utils/lock.h" + +namespace Json { +class Value; +} // namespace Json + +namespace rc_rpc_plugin { + +class RCConsentManagerImpl : public RCConsentManager { + public: + RCConsentManagerImpl( + resumption::LastState& last_state, + application_manager::ApplicationManager& application_manager, + const uint32_t period_of_consent_expired); + + void SaveModuleConsents( + const std::string& policy_app_id, + const std::string& mac_address, + const rc_rpc_types::ModuleIdConsentVector& module_consents) OVERRIDE; + + rc_rpc_types::ModuleConsent GetModuleConsent( + const std::string& app_id, + const std::string& mac_address, + const rc_rpc_types::ModuleUid& module_id) const OVERRIDE; + + void RemoveExpiredConsents() OVERRIDE; + + void RemoveAllConsents() OVERRIDE; + + ~RCConsentManagerImpl() OVERRIDE; + + private: + /** + * @brief Saves module consents for specified application + * @param app_module_consents Application consents for which new + * consents should be added or existing ones should be overwritten + * @param consent_to_save module consents which should be saved + */ + void SaveAppModuleConsent( + Json::Value& app_module_consents, + const rc_rpc_types::ModuleIdConsent& consent_to_save); + + /** + * @brief Checks if module consent is expired + * @param module_consent Module consent + * @return ModuleConsentState + */ + rc_rpc_types::ModuleConsentState CheckModuleConsentState( + const Json::Value& module_consent) const; + + /** + * @brief Removes devices expired consents + * @param device Device section in AppConsensts section of LastState in Json + */ + void RemoveDeviceExpiredConsents(Json::Value& device); + + /** + * @brief Remove expired module consents which are related to specified + * application + * @param app_consents Application consents + */ + void RemoveAppExpiredConsents(Json::Value& app_consents); + + /** + * @brief Remove expired module consents which are related to specified + * module type + * @param module_consents Module consents wich should be checked for expired + * consents + */ + void RemoveModuleExpiredConsents(Json::Value& module_consents); + + /** + * @brief Get Remote Control section of LastState. + * In case the section is absent, will be appended a new empty section. + * @return Remote Control section of LastState in Json + */ + Json::Value& GetRemoteControlDataOrAppend() const; + + /** + * @brief Gets Device applications section for specified device mac adress + * In case the section is absent, will be appended a new empty section. + * @param mac_aress Device MAC adress + * @return Device applications section of LastState in Json + */ + Json::Value& GetDeviceApplicationsOrAppend( + const std::string& mac_address) const; + + /** + * @brief Get AppConsentsList section of LastState for specified application. + * In case the consent list is absent, will be appended a new empty section. + * @param policy_app_id Application policy ID + * @param mac_address Device MAC address + * @return AppConsentsList of LastState in Json + */ + Json::Value& GetAppConsentsListOrAppend(const std::string& policy_app_id, + const std::string& mac_address) const; + + /** + * @brief Get Application consents section of Remote Control section of + * LastState with all consents for all applications. In case if this section + * is absent, will be created a new empty section + * @return AppConsents section of RemoteControl section of LastState in Jason + */ + Json::Value& GetAppsConsentsOrAppend() const; + + /** + * @brief Get all module resource consents for specified application and + * module type. In case if section with specified module type consents is + * absent, will be created a new empty section + * @param policy_app_id Application id which contains specified module type + * @param mac_adress MAC address of mobile device that needs user consent for + * acquiring resource + * @param module_type Module type with consents + */ + Json::Value& GetModuleTypeConsentsOrAppend( + const std::string& policy_app_id, + const std::string& mac_address, + const std::string& module_type) const; + + private: + application_manager::ApplicationManager& app_manager_; + resumption::LastState& last_state_; + const uint32_t period_of_consent_expired_; + mutable sync_primitives::Lock dictionary_control_lock_; + mutable sync_primitives::Lock remote_control_lock_; + mutable sync_primitives::Lock device_applications_lock_; + mutable sync_primitives::Lock applications_lock_; + mutable sync_primitives::Lock app_consents_lock_; + mutable sync_primitives::Lock module_consents_lock_; +}; + +} // namespace rc_rpc_plugin + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_INCLUDE_RC_CONSENT_MANAGER_IMPL_H diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/rc_helpers.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/rc_helpers.h index e85ab758ad..7b249cb4b8 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/rc_helpers.h +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/rc_helpers.h @@ -37,6 +37,7 @@ #include <string> #include "application_manager/application.h" #include "rc_rpc_plugin/rc_app_extension.h" +#include "rc_rpc_plugin/rc_rpc_types.h" namespace rc_rpc_plugin { class RCRPCPlugin; @@ -65,10 +66,10 @@ class RCHelpers { GetModuleTypeToCapabilitiesMapping(); /** - * @brief GetModulesList get list of all known modules - * @return vector contains all known modules + * @brief GetModuleTypesList get list of all known module types + * @return vector contains all known module types */ - static const std::vector<std::string> GetModulesList(); + static const std::vector<std::string> GetModuleTypesList(); /** * @brief GetRCExtension extract RC extension from application @@ -80,7 +81,11 @@ class RCHelpers { application_manager::Application& app); static smart_objects::SmartObjectSPtr CreateUnsubscribeRequestToHMI( - const std::string& module_type, const uint32_t correlation_id); + const ModuleUid& module, const uint32_t correlation_id); + + static std::vector<application_manager::ApplicationSharedPtr> + AppsSubscribedToModule(application_manager::ApplicationManager& app_mngr, + const ModuleUid& module); static std::vector<application_manager::ApplicationSharedPtr> AppsSubscribedToModuleType(application_manager::ApplicationManager& app_mngr, @@ -88,10 +93,51 @@ class RCHelpers { typedef std::map<application_manager::ApplicationSharedPtr, std::vector<std::string> > - AppsModules; - static AppsModules GetApplicationsAllowedModules( + AppsModuleTypes; + + static AppsModuleTypes GetApplicationsAllowedModuleTypes( application_manager::ApplicationManager& app_mngr); + typedef std::map<std::string, mobile_apis::ButtonName::eType> ButtonsMap; + + static const std::vector<std::string> buttons_climate(); + + static const std::vector<std::string> buttons_radio(); + + static const ButtonsMap buttons_map(); + + static std::vector<std::string> GetModuleReadOnlyParams( + const std::string& module_type); + + /** + * @brief Combines module ids and alloweds for these ids and fills vector with + * ModuleConsents + * @param module_type Module type as string + * @param module_ids Modules ids which needed consents from driver + * @param allowed Consents for modules + */ + static rc_rpc_types::ModuleIdConsentVector FillModuleConsents( + const std::string& module_type, + const std::vector<std::string>& module_ids, + const std::vector<bool> allowed); + + /** + * @brief Retrieves module ids from SmartObject. + * @param moduleIds Smartobject which contains collection of module ids + * @return Collection of module ids + */ + static std::vector<std::string> RetrieveModuleIds( + const smart_objects::SmartObject& moduleIds); + + /** + * @brief Retrieves module ids consents from SmartObject. + * @param moduleIds Smartobject which contains collection of module ids + * consents + * @return Collection of module ids consents. + */ + static std::vector<bool> RetrieveModuleConsents( + const smart_objects::SmartObject& consents); + /** * @brief RemoveRedundantGPSDataFromVIDataMsg removes redundant GPS data * params from interior vehicle data response message if one contains radio diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/rc_module_constants.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/rc_module_constants.h index b9f922a1be..5ee2e0725c 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/rc_module_constants.h +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/rc_module_constants.h @@ -46,10 +46,43 @@ const char khmiSettingsControlCapabilities[] = "hmiSettingsControlCapabilities"; const char kseatControlCapabilities[] = "seatControlCapabilities"; // RemoteControlCapabilities constants -const char kRadioControlData[] = "radioControlData"; -const char kClimateControlData[] = "climateControlData"; +const char kServiceArea[] = "serviceArea"; +const char kLocation[] = "location"; +const char kCol[] = "col"; +const char kRow[] = "row"; +const char kLevel[] = "level"; +const char kColspan[] = "colspan"; +const char kRowspan[] = "rowspan"; +const char kLevelspan[] = "levelspan"; + +// SeatLocationCapability constants +const char kCols[] = "columns"; +const char kRows[] = "rows"; +const char kLevels[] = "levels"; +const char kSeats[] = "seats"; +const char kGrid[] = "grid"; +// SeatLocationCapability constants + +const char kAllowMultipleAccess[] = "allowMultipleAccess"; + const char kSupportedLights[] = "supportedLights"; +// ClimateControlCapabilities +const char kFanSpeedAvailable[] = "fanSpeedAvailable"; +const char kCurrentTemperatureAvailable[] = "currentTemperatureAvailable"; +const char kDesiredTemperatureAvailable[] = "desiredTemperatureAvailable"; +const char kAcEnableAvailable[] = "acEnableAvailable"; +const char kCirculateAirEnableAvailable[] = "circulateAirEnableAvailable"; +const char kAutoModeEnableAvailable[] = "autoModeEnableAvailable"; +const char kDefrostZoneAvailable[] = "defrostZoneAvailable"; +const char kDualModeEnableAvailable[] = "dualModeEnableAvailable"; +const char kAcMaxEnableAvailable[] = "acMaxEnableAvailable"; +const char kVentilationModeAvailable[] = "ventilationModeAvailable"; +const char kHeatedSteeringWheelAvailable[] = "heatedSteeringWheelAvailable"; +const char kHeatedWindshieldAvailable[] = "heatedWindshieldAvailable"; +const char kHeatedMirrorsAvailable[] = "heatedMirrorsAvailable"; +const char kHeatedRearWindowAvailable[] = "heatedRearWindowAvailable"; + // LightControlCapabilities const char kName[] = "name"; const char kStatusAvailable[] = "statusAvailable"; @@ -57,7 +90,50 @@ const char kDensityAvailable[] = "densityAvailable"; const char kRGBColorSpaceAvailable[] = "rgbColorSpaceAvailable"; // RadioControlCapabilities +const char kRadioBandAvailable[] = "radioBandAvailable"; +const char kRadioFrequencyAvailable[] = "radioFrequencyAvailable"; +const char kRdsDataAvailable[] = "rdsDataAvailable"; +const char kAvailableHDsAvailable[] = "availableHDsAvailable"; +const char kHdRadioEnableAvailable[] = "hdRadioEnableAvailable"; +const char kSignalStrengthAvailable[] = "signalStrengthAvailable"; +const char kSignalChangeThresholdAvailable[] = "signalChangeThresholdAvailable"; +const char kRadioEnableAvailable[] = "radioEnableAvailable"; +const char kStateAvailable[] = "stateAvailable"; +const char kSisDataAvailable[] = "sisDataAvailable"; + const char kSiriusxmRadioAvailable[] = "siriusxmRadioAvailable"; + +// SeatControlCapabilities +const char kHeatingEnabledAvailable[] = "heatingEnabledAvailable"; +const char kCoolingEnabledAvailable[] = "coolingEnabledAvailable"; +const char kHeatingLevelAvailable[] = "heatingLevelAvailable"; +const char kCoolingLevelAvailable[] = "coolingLevelAvailable"; +const char kHorizontalPositionAvailable[] = "horizontalPositionAvailable"; +const char kVerticalPositionAvailable[] = "verticalPositionAvailable"; +const char kFrontVerticalPositionAvailable[] = "frontVerticalPositionAvailable"; +const char kBackVerticalPositionAvailable[] = "backVerticalPositionAvailable"; +const char kBackTiltAngleAvailable[] = "backTiltAngleAvailable"; +const char kHeadSupportHorizontalPositionAvailable[] = + "headSupportHorizontalPositionAvailable"; +const char kHeadSupportVerticalPositionAvailable[] = + "headSupportVerticalPositionAvailable"; +const char kMassageEnabledAvailable[] = "massageEnabledAvailable"; +const char kMassageModeAvailable[] = "massageModeAvailable"; +const char kMassageCushionFirmnessAvailable[] = + "massageCushionFirmnessAvailable"; +const char kMemoryAvailable[] = "memoryAvailable"; + +// AudioControlCapabilities +const char kSourceAvailable[] = "sourceAvailable"; +const char kKeepContextAvailable[] = "keepContextAvailable"; +const char kVolumeAvailable[] = "volumeAvailable"; +const char kEqualizerAvailable[] = "equalizerAvailable"; + +// HmiSettingsCapabilities +const char kDistanceUnitAvailable[] = "distanceUnitAvailable"; +const char kTemperatureUnitAvailable[] = "temperatureUnitAvailable"; +const char kDisplayModeUnitAvailable[] = "displayModeUnitAvailable"; + } // namespace strings namespace result_codes { @@ -106,6 +182,20 @@ namespace message_params { const char kName[] = "name"; const char kId[] = "id"; +// RCConsentManager, ResumptionCtrl, GetInteriorVehicleDataConsent request +const char kModuleId[] = "moduleId"; +const char kModuleInfo[] = "moduleInfo"; +const char kAppConsents[] = "appConsents"; +const char kAppConsentList[] = "appConsentsList"; +const char kConsent[] = "consent"; +const char kConsentDate[] = "consentDate"; +const char kModuleConsents[] = "moduleConsents"; +const char kAppId[] = "appId"; +const char kModuleIds[] = "moduleIds"; +const char kMacAddress[] = "macAddress"; +const char kApplications[] = "applications"; +// RCConsentManager, ResumptionCtrl, GetInteriorVehicleDataConsent request + // SetInteriorVehicleData request const char kModuleData[] = "moduleData"; // SetInteriorVehicleData request @@ -153,6 +243,7 @@ const char kRdsData[] = "rdsData"; const char kHdRadioEnable[] = "hdRadioEnable"; const char kAvailableHDs[] = "availableHDs"; const char kAvailableHdChannels[] = "availableHdChannels"; +const char kAvailableHdChannelsAvailable[] = "availableHdChannelsAvailable"; const char kHdChannel[] = "hdChannel"; const char kSignalStrength[] = "signalStrength"; const char kSignalChangeThreshold[] = "signalChangeThreshold"; @@ -181,6 +272,23 @@ const char kClimateEnable[] = "climateEnable"; const char kClimateEnableAvailable[] = "climateEnableAvailable"; // ClimateControlData struct +// SeatControlData +const char kHeatingEnabled[] = "heatingEnabled"; +const char kCoolingEnabled[] = "coolingEnabled"; +const char kHeatingLevele[] = "heatingLevel"; +const char kCoolingLevel[] = "coolingLevel"; +const char kHorizontalPosition[] = "horizontalPosition"; +const char kVerticalPosition[] = "verticalPosition"; +const char kFrontVerticalPosition[] = "frontVerticalPosition"; +const char kBackVerticalPosition[] = "backVerticalPosition"; +const char kBackTiltAngle[] = "backTiltAngle"; +const char kHeadSupportHorizontalPosition[] = "headSupportHorizontalPosition"; +const char kHeadSupportVerticalPosition[] = "headSupportVerticalPosition"; +const char kMassageEnabled[] = "massageEnabled"; +const char kMassageMode[] = "massageMode"; +const char kMassageCushionFirmness[] = "massageCushionFirmness"; +const char kMemory[] = "memory"; + // LightControlData const char kLightState[] = "lightState"; const char kLightStatus[] = "status"; @@ -189,10 +297,15 @@ const char kLightColor[] = "color"; // AudioControlData const char kSource[] = "source"; +const char kVolume[] = "volume"; const char kKeepContext[] = "keepContext"; const char kEqualizerSettings[] = "equalizerSettings"; const char kChannelName[] = "channelName"; +// HmiSettingsControlData +const char kDistanceUnit[] = "distanceUnit"; +const char kDisplayMode[] = "displayMode"; + // ModuleData struct const char kRadioControlData[] = "radioControlData"; const char kClimateControlData[] = "climateControlData"; @@ -206,6 +319,15 @@ const char kHMIAppID[] = "appID"; const char kHmiLevel[] = "hmiLevel"; const char kSysContext[] = "systemContext"; const char kAudioState[] = "audioStreamingState"; + +// Grid struct +const char kCol[] = "col"; +const char kRow[] = "row"; +const char kLevel[] = "level"; +const char kColspan[] = "colspan"; +const char kRowspan[] = "rowspan"; +const char kLevelspan[] = "levelspan"; + } // namespace message_params namespace enums_value { diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/rc_rpc_plugin.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/rc_rpc_plugin.h index cd15674889..1225feb67f 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/rc_rpc_plugin.h +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/rc_rpc_plugin.h @@ -39,8 +39,14 @@ #include "application_manager/plugin_manager/rpc_plugin.h" #include "rc_rpc_plugin/interior_data_cache.h" #include "rc_rpc_plugin/interior_data_manager.h" +#include "rc_rpc_plugin/rc_capabilities_manager.h" +#include "rc_rpc_plugin/rc_consent_manager.h" #include "rc_rpc_plugin/resource_allocation_manager.h" +namespace resumption { +class LastState; +} + namespace rc_rpc_plugin { namespace plugins = application_manager::plugin_manager; namespace app_mngr = application_manager; @@ -58,7 +64,8 @@ class RCRPCPlugin : public plugins::RPCPlugin { bool Init(app_mngr::ApplicationManager& app_manager, app_mngr::rpc_service::RPCService& rpc_service, app_mngr::HMICapabilities& hmi_capabilities, - policy::PolicyHandlerInterface& policy_handler) OVERRIDE; + policy::PolicyHandlerInterface& policy_handler, + resumption::LastState& last_state) OVERRIDE; /** * @param int32_t command id * @param CommandSource source @@ -101,10 +108,12 @@ class RCRPCPlugin : public plugins::RPCPlugin { private: application_manager::rpc_service::RPCService* rpc_service_; application_manager::ApplicationManager* app_mngr_; + std::unique_ptr<rc_rpc_plugin::RCConsentManager> rc_consent_manager_; std::unique_ptr<application_manager::CommandFactory> command_factory_; std::unique_ptr<ResourceAllocationManager> resource_allocation_manager_; std::unique_ptr<InteriorDataCache> interior_data_cache_; std::unique_ptr<InteriorDataManager> interior_data_manager_; + std::unique_ptr<RCCapabilitiesManager> rc_capabilities_manager_; }; } // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/rc_rpc_types.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/rc_rpc_types.h new file mode 100644 index 0000000000..3698728aa6 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/rc_rpc_types.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2019, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_INCLUDE_RC_RPC_TYPES_H +#define SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_INCLUDE_RC_RPC_TYPES_H + +#include <ctime> +#include <string> +#include <utility> +#include <vector> + +namespace resumption { +class LastState; +} // namespace resumption + +namespace application_manager { +class ApplicationManager; +} // namespace application_manager + +namespace rc_rpc_plugin { +namespace rc_rpc_types { +/** + * @brief Module resource (module_type(first) + module_id(second)) + */ +typedef std::pair<std::string, std::string> ModuleUid; + +/** + * @brief Module consent enum. + */ +enum class ModuleConsent { + NOT_EXISTS = 0, /**< Consent is absent for specified module resource */ + CONSENTED, /**< Module resource is consented */ + NOT_CONSENTED /**< Module resource isn't consented */ +}; + +enum class ModuleConsentState { + NOT_EXISTS = 0, /**< Consent is absent for specified module resource */ + EXPIRED, /**< Module resource is expired */ + ACTIVE /**< Module resource isn't expired */ +}; + +/** + * @brief Module consent + * @param module_id - Module resource for consent + * @param consent - Is module resource consented by driver + * @param date_of_consent - Date, when module resource has been consented (in + * seconds [UNIX time]) + */ +struct ModuleIdConsent { + ModuleUid module_id; + ModuleConsent consent; + std::time_t date_of_consent; +}; + +/** + * @brief ModuleIdConsent collection + */ +typedef std::vector<ModuleIdConsent> ModuleIdConsentVector; +} // namespace rc_rpc_types +} // namespace rc_rpc_plugin + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_INCLUDE_RC_RPC_TYPES_H diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/resource_allocation_manager.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/resource_allocation_manager.h index 6dfc794648..ee0bd11885 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/resource_allocation_manager.h +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/resource_allocation_manager.h @@ -69,55 +69,84 @@ enum eType { APP_REGISTRATION = 0, MODULE_ALLOCATION, RC_STATE_CHANGING }; } // namespace NotificationTrigger /** + * Defines result of releasing specified module type resource. + */ +namespace ResourceReleasedState { +/** + * NOT_ALLOCATED Module's resource is not allocated + * IS_ALLOCATED Module's resource is already allocated by + * different application + * IS_RELEASED Module's resource is released. + */ +enum eType { NOT_ALLOCATED = 0, IS_ALLOCATED, IS_RELEASED }; +} // namespace ResourceReleasedState + +/** + * @brief ModuleUid uniquely identify a module + * moduleType + moduleID + */ +typedef std::pair<std::string, std::string> ModuleUid; + +/** * @brief Resources defines list of resources */ -typedef std::vector<std::string> Resources; +typedef std::vector<ModuleUid> Resources; class ResourceAllocationManager { public: /** * @brief AcquireResource acquires resource by application * @param module_type resource to acquire + * @param module_id uuid of a resource * @param app_id application that acquire resource * @return ALLOWED if resource acquired \ * IN_USE if resource already acquired * ASK_DRIVER if driver confirmation is required */ virtual AcquireResult::eType AcquireResource(const std::string& module_type, + const std::string& module_id, const uint32_t app_id) = 0; /** * @brief SetResourceState changes resource state. Resource must be acquired * beforehand. * @param module_type Resource to change its state + * @param module_id uuid of a resource * @param app_id Application aquired resource before * @param state State to set for resource */ virtual void SetResourceState(const std::string& module_type, + const std::string& module_id, const uint32_t app_id, const ResourceState::eType state) = 0; /** * @brief IsResourceFree check resource state * @param module_type Resource name + * @param module_id uuid of a resource * @return True if free, otherwise - false */ - virtual bool IsResourceFree(const std::string& module_type) const = 0; + virtual bool IsResourceFree(const std::string& module_type, + const std::string& module_id) const = 0; /** * @brief AcquireResource forces acquiring resource by application * @param module_type resource to acquire + * @param module_id uuid of a resource * @param app_id application that acquire resource */ virtual void ForceAcquireResource(const std::string& module_type, + const std::string& module_id, const uint32_t app_id) = 0; /** * @brief OnDriverDisallowed callback for rejecting acquiring resource * @param module_type resource type + * @param module_id uuid of a resource * @param app_id application id */ virtual void OnDriverDisallowed(const std::string& module_type, + const std::string& module_id, const uint32_t app_id) = 0; /** @@ -171,6 +200,42 @@ class ResourceAllocationManager { virtual void set_rc_enabled(const bool value) = 0; + /** + * @brief ReleaseResource Releases resource acquired by application + * @param module_type Module name + * @param module_id uuid of a module + * @param application_id Application id + */ + virtual ResourceReleasedState::eType ReleaseResource( + const std::string& module_type, + const std::string& module_id, + const uint32_t application_id) = 0; + + /** + * @brief SetResourceAquired mark resourse as aquired and process logic of + * changing state of aquired resources + * @param module_type resource name + * @param module_id uuid of a resource + * @param app applicastion that aquire resource + */ + virtual void SetResourceAcquired(const std::string& module_type, + const std::string& module_id, + const uint32_t app_id) = 0; + + /** + * @brief Checks if specific resource is already aquired by specific + * application + * @param moduleUid Module resurce (module type + module ID) + * @param app_id Application ID which try to aquire resource + * @return true In case when resource is already aquired by specific + * application + * @return false In case when isn't aquired by specific + * application + */ + virtual bool IsResourceAlreadyAcquiredByApp( + const rc_rpc_plugin::ModuleUid& moduleUid, + const uint32_t app_id) const = 0; + virtual ~ResourceAllocationManager() {} }; diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/resource_allocation_manager_impl.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/resource_allocation_manager_impl.h index c0ef971235..0fd5449912 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/resource_allocation_manager_impl.h +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/resource_allocation_manager_impl.h @@ -34,6 +34,7 @@ #define SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_INCLUDE_RC_RPC_PLUGIN_RESOURCE_ALLOCATION_MANAGER_IMPL_H_ #include "application_manager/application_impl.h" #include "rc_rpc_plugin/rc_app_extension.h" +#include "rc_rpc_plugin/rc_capabilities_manager.h" #include "rc_rpc_plugin/resource_allocation_manager.h" #include "utils/lock.h" #include "utils/macro.h" @@ -46,43 +47,52 @@ class ResourceAllocationManagerImpl : public ResourceAllocationManager { public: ResourceAllocationManagerImpl( application_manager::ApplicationManager& app_mngr, - application_manager::rpc_service::RPCService& rpc_service); + application_manager::rpc_service::RPCService& rpc_service, + rc_rpc_plugin::RCCapabilitiesManager& rc_capabilities_manager); ~ResourceAllocationManagerImpl(); /** * @brief AcquireResource forces acquiring resource by application * @param module_type resource to acquire + * @param module_id uuid of a resource * @param app_id application that acquire resourc * @return result of acauiring resources */ AcquireResult::eType AcquireResource(const std::string& module_type, + const std::string& module_id, const uint32_t app_id) OVERRIDE FINAL; /** * @brief ForceAcquireResource forces acquiring resource by application * @param module_type resource to acquire + * @param module_id uuid of a resource * @param app_id application that acquire resource */ void ForceAcquireResource(const std::string& module_type, + const std::string& module_id, const uint32_t app_id) FINAL; /** * @brief SetResourceState changes resource state. Resource must be acquired * beforehand. * @param module_type Resource to change its state + * @param module_id uuid of a resource * @param app_id Application aquired resource before * @param state State to set for resource */ void SetResourceState(const std::string& module_type, + const std::string& module_id, const uint32_t app_id, const ResourceState::eType state) FINAL; /** * @brief IsResourceFree check resource state * @param module_type Resource name + * @param module_id uuid of a resource * @return True if free, otherwise - false */ - bool IsResourceFree(const std::string& module_type) const FINAL; + bool IsResourceFree(const std::string& module_type, + const std::string& module_id) const FINAL; void SetAccessMode( const hmi_apis::Common_RCAccessMode::eType access_mode) FINAL; @@ -90,6 +100,7 @@ class ResourceAllocationManagerImpl : public ResourceAllocationManager { hmi_apis::Common_RCAccessMode::eType GetAccessMode() const FINAL; void OnDriverDisallowed(const std::string& module_type, + const std::string& module_id, const uint32_t app_id) FINAL; /** @@ -118,6 +129,18 @@ class ResourceAllocationManagerImpl : public ResourceAllocationManager { void set_rc_enabled(const bool value) FINAL; + ResourceReleasedState::eType ReleaseResource( + const std::string& module_type, + const std::string& module_id, + const uint32_t application_id) FINAL; + + void SetResourceAcquired(const std::string& module_type, + const std::string& module_id, + const uint32_t app_id) FINAL; + + bool IsResourceAlreadyAcquiredByApp(const rc_rpc_plugin::ModuleUid& moduleUid, + const uint32_t app_id) const FINAL; + private: typedef std::vector<application_manager::ApplicationSharedPtr> Apps; @@ -137,20 +160,23 @@ class ResourceAllocationManagerImpl : public ResourceAllocationManager { * @brief IsModuleTypeRejected check if current resource was rejected by * driver for current application * @param module_type resource to check + * @param module_id uuid of a resource * @param app_id application id * @return true if current resource was rejected by driver for current * application, otherwise - false */ bool IsModuleTypeRejected(const std::string& module_type, + const std::string& module_id, const uint32_t app_id); /** - * @brief ReleaseResource Releases resource acquired by application + * @brief ReleaseModuleType Releases all resources related to + * the corresponding module type acquired by application * @param module_type Module name * @param application_id Application id */ - void ReleaseResource(const std::string& module_type, - const uint32_t application_id); + void ReleaseModuleType(const std::string& module_type, + const uint32_t application_id); /** * @brief GetAcquiredResources Provides resources acquired by particular @@ -161,6 +187,15 @@ class ResourceAllocationManagerImpl : public ResourceAllocationManager { Resources GetAcquiredResources(const uint32_t application_id) const; /** + * @brief GetAcquiredModuleTypes Provides module types acquired by particular + * application currently + * @param application_id Application id + * @return List of acquired module types by specific application + */ + std::set<std::string> GetAcquiredModuleTypes( + const uint32_t application_id) const; + + /** * @brief ProcessApplicationPolicyUpdate Checks if allowed modules list is * changed for registered RC applications and releases in case some modules * now out of the list @@ -175,33 +210,38 @@ class ResourceAllocationManagerImpl : public ResourceAllocationManager { void RemoveAppsSubscriptions(const Apps& apps); /** - * @brief SetResourceAquired mark resourse as aquired and process logic of + * @brief SetResourceFree mark resourse as free and process logic of * changing state of aquired resources * @param module_type resource name + * @param module_id uuid of a resource * @param app applicastion that aquire resource */ - void SetResourceAquired(const std::string& module_type, - const uint32_t app_id); + ResourceReleasedState::eType SetResourceFree(const std::string& module_type, + const std::string& module_id, + const uint32_t app_id); /** - * @brief SetResourceFree mark resourse as free and process logic of - * changing state of aquired resources - * @param module_type resource name - * @param app applicastion that aquire resource + * @brief CheckLocation checks if the user's grid is equal to or is within the + * service area of the module, or user location is driver's seat + * @param module module type + module id + * @return true if the user's grid equals to or is within module service + * area or user location is driver's seat, otherwise - false */ - void SetResourceFree(const std::string& module_type, const uint32_t app_id); + bool IsUserLocationValid(ModuleUid& module, + application_manager::ApplicationSharedPtr app); /** * @brief AllocatedResources contains link between resource and application * owning that resource */ - typedef std::map<std::string, uint32_t> AllocatedResources; + + typedef std::map<ModuleUid, uint32_t> AllocatedResources; AllocatedResources allocated_resources_; mutable sync_primitives::Lock allocated_resources_lock_; /** * @brief ResourcesState contains states of ALLOCATED resources */ - typedef std::map<std::string, ResourceState::eType> ResourcesState; + typedef std::map<ModuleUid, ResourceState::eType> ResourcesState; ResourcesState resources_state_; mutable sync_primitives::Lock resources_state_lock_; @@ -210,13 +250,14 @@ class ResourceAllocationManagerImpl : public ResourceAllocationManager { * driver for application * application_id : [vector of rejected resources] */ - typedef std::map<uint32_t, std::vector<std::string> > RejectedResources; + typedef std::map<uint32_t, std::vector<ModuleUid> > RejectedResources; RejectedResources rejected_resources_for_application_; mutable sync_primitives::Lock rejected_resources_for_application_lock_; hmi_apis::Common_RCAccessMode::eType current_access_mode_; application_manager::ApplicationManager& app_mngr_; application_manager::rpc_service::RPCService& rpc_service_; + rc_rpc_plugin::RCCapabilitiesManager& rc_capabilities_manager_; bool is_rc_enabled_; }; } // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_on_remote_control_settings_notification.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_on_remote_control_settings_notification.cc index 643e98213c..45b0d13582 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_on_remote_control_settings_notification.cc +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_on_remote_control_settings_notification.cc @@ -59,7 +59,8 @@ RCOnRemoteControlSettingsNotification::RCOnRemoteControlSettingsNotification( params.hmi_capabilities_, params.policy_handler_) , resource_allocation_manager_(params.resource_allocation_manager_) - , interior_data_manager_(params.interior_data_manager_) {} + , interior_data_manager_(params.interior_data_manager_) + , rc_consent_manager_(params.rc_consent_manager_) {} RCOnRemoteControlSettingsNotification:: ~RCOnRemoteControlSettingsNotification() {} @@ -132,6 +133,7 @@ void RCOnRemoteControlSettingsNotification::Run() { DisallowRCFunctionality(); resource_allocation_manager_.ResetAllAllocations(); resource_allocation_manager_.set_rc_enabled(false); + rc_consent_manager_.RemoveAllConsents(); } } diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_set_global_properties_request.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_set_global_properties_request.cc new file mode 100644 index 0000000000..2f203afc2d --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_set_global_properties_request.cc @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2019, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "rc_rpc_plugin/commands/hmi/rc_set_global_properties_request.h" + +namespace rc_rpc_plugin { +namespace app_mngr = application_manager; + +namespace commands { + +RCSetGlobalPropertiesRequest::RCSetGlobalPropertiesRequest( + const app_mngr::commands::MessageSharedPtr& message, + const RCCommandParams& params) + : app_mngr::commands::RequestToHMI(message, + params.application_manager_, + params.rpc_service_, + params.hmi_capabilities_, + params.policy_handler_) {} + +void RCSetGlobalPropertiesRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + SendRequest(); +} + +RCSetGlobalPropertiesRequest::~RCSetGlobalPropertiesRequest() {} + +} // namespace commands +} // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_set_global_properties_response.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_set_global_properties_response.cc new file mode 100644 index 0000000000..c31314ec21 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_set_global_properties_response.cc @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "rc_rpc_plugin/commands/hmi/rc_set_global_properties_response.h" + +namespace rc_rpc_plugin { +namespace commands { + +RCSetGlobalPropertiesResponse::RCSetGlobalPropertiesResponse( + const app_mngr::commands::MessageSharedPtr& message, + const RCCommandParams& params) + : application_manager::commands::ResponseFromHMI( + message, + params.application_manager_, + params.rpc_service_, + params.hmi_capabilities_, + params.policy_handler_) {} + +void RCSetGlobalPropertiesResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + app_mngr::event_engine::Event event( + hmi_apis::FunctionID::RC_SetGlobalProperties); + event.set_smart_object(*message_); + event.raise(application_manager_.event_dispatcher()); +} + +RCSetGlobalPropertiesResponse::~RCSetGlobalPropertiesResponse() {} +} // namespace commands +} // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/button_press_request.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/button_press_request.cc index b85f092252..3adc48dfbf 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/button_press_request.cc +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/button_press_request.cc @@ -33,6 +33,7 @@ #include "rc_rpc_plugin/commands/mobile/button_press_request.h" #include "interfaces/MOBILE_API.h" #include "json/json.h" +#include "rc_rpc_plugin/rc_helpers.h" #include "rc_rpc_plugin/rc_module_constants.h" #include "smart_objects/enum_schema_item.h" #include "utils/helpers.h" @@ -46,8 +47,6 @@ using namespace message_params; CREATE_LOGGERPTR_GLOBAL(logger_, "RemoteControlModule") -typedef std::map<std::string, mobile_apis::ButtonName::eType> ButtonsMap; - ButtonPressRequest::ButtonPressRequest( const app_mngr::commands::MessageSharedPtr& message, const RCCommandParams& params) @@ -55,147 +54,44 @@ ButtonPressRequest::ButtonPressRequest( ButtonPressRequest::~ButtonPressRequest() {} -const std::vector<std::string> buttons_climate() { - std::vector<std::string> data; - data.push_back(enums_value::kACMax); - data.push_back(enums_value::kAC); - data.push_back(enums_value::kRecirculate); - data.push_back(enums_value::kFanUp); - data.push_back(enums_value::kFanDown); - data.push_back(enums_value::kTempUp); - data.push_back(enums_value::kTempDown); - data.push_back(enums_value::kDefrostMax); - data.push_back(enums_value::kDefrost); - data.push_back(enums_value::kDefrostRear); - data.push_back(enums_value::kUpperVent); - data.push_back(enums_value::kLowerVent); - return data; -} - -const std::vector<std::string> buttons_radio() { - std::vector<std::string> data; - data.push_back(enums_value::kVolumeUp); - data.push_back(enums_value::kVolumeDown); - data.push_back(enums_value::kEject); - data.push_back(enums_value::kSource); - data.push_back(enums_value::kShuffle); - data.push_back(enums_value::kRepeat); - return data; -} - -const ButtonsMap buttons_map() { - using namespace mobile_apis; - - ButtonsMap buttons_map; - buttons_map[enums_value::kACMax] = ButtonName::AC_MAX; - buttons_map[enums_value::kAC] = ButtonName::AC; - buttons_map[enums_value::kRecirculate] = ButtonName::RECIRCULATE; - buttons_map[enums_value::kFanUp] = ButtonName::FAN_UP; - buttons_map[enums_value::kFanDown] = ButtonName::FAN_DOWN; - buttons_map[enums_value::kTempUp] = ButtonName::TEMP_UP; - buttons_map[enums_value::kTempDown] = ButtonName::TEMP_DOWN; - buttons_map[enums_value::kDefrostMax] = ButtonName::DEFROST_MAX; - buttons_map[enums_value::kDefrost] = ButtonName::DEFROST; - buttons_map[enums_value::kDefrostRear] = ButtonName::DEFROST_REAR; - buttons_map[enums_value::kUpperVent] = ButtonName::UPPER_VENT; - buttons_map[enums_value::kLowerVent] = ButtonName::LOWER_VENT; - buttons_map[enums_value::kVolumeUp] = ButtonName::VOLUME_UP; - buttons_map[enums_value::kVolumeDown] = ButtonName::VOLUME_DOWN; - buttons_map[enums_value::kEject] = ButtonName::EJECT; - buttons_map[enums_value::kSource] = ButtonName::SOURCE; - buttons_map[enums_value::kShuffle] = ButtonName::SHUFFLE; - buttons_map[enums_value::kRepeat] = ButtonName::REPEAT; - - return buttons_map; -} - -bool CheckIfButtonExistInRCCaps( - const smart_objects::SmartObject& rc_capabilities, - const mobile_apis::ButtonName::eType button) { - if (rc_capabilities.keyExists(strings::kbuttonCapabilities)) { - const smart_objects::SmartObject& button_caps = - rc_capabilities[strings::kbuttonCapabilities]; - auto it = button_caps.asArray()->begin(); - for (; it != button_caps.asArray()->end(); ++it) { - smart_objects::SmartObject& so = *it; - int64_t current_id = so[message_params::kName].asInt(); - if (-1 == current_id) { - // capabilities received from HMI contains enum values - // capabilities loaded from file contains string values - // TODO : unificate capabilities storing - const std::string& bt_name = so[message_params::kName].asString(); - static ButtonsMap btn_map = buttons_map(); - current_id = btn_map[bt_name]; - } - const mobile_apis::ButtonName::eType current_button = - static_cast<mobile_apis::ButtonName::eType>(current_id); - if (current_button == button) { - LOG4CXX_TRACE( - logger_, - "Button id " << current_button << " exist in capabilities"); - return true; - } - } - } - LOG4CXX_TRACE(logger_, - "Button id " << button << " do not exist in capabilities"); - return false; +std::string ButtonPressRequest::GetButtonName() const { + mobile_apis::ButtonName::eType button_name = + static_cast<mobile_apis::ButtonName::eType>( + (*message_)[app_mngr::strings::msg_params] + [message_params::kButtonName] + .asUInt()); + const char* str; + const bool ok = ns_smart_device_link::ns_smart_objects::EnumConversionHelper< + mobile_apis::ButtonName::eType>::EnumToCString(button_name, &str); + return ok ? str : "unknown"; } -bool CheckButtonName(const std::string& module_type, - const std::string& button_name, - const smart_objects::SmartObject* rc_capabilities) { - LOG4CXX_AUTO_TRACE(logger_); - if (rc_capabilities == NULL) { - LOG4CXX_ERROR(logger_, "No remote controll capabilities available"); - return false; - } - - if (enums_value::kRadio == module_type) { - if (!helpers::in_range(buttons_radio(), button_name)) { - LOG4CXX_WARN(logger_, - "Trying to acceess climate button with module type radio"); - return false; - } - } - - if (enums_value::kClimate == module_type) { - if (!helpers::in_range(buttons_climate(), button_name)) { - LOG4CXX_WARN(logger_, - "Trying to acceess radio button with module type climate"); - return false; - } +const mobile_apis::ButtonName::eType ButtonPressRequest::GetButtonId() const { + const auto button_name = GetButtonName(); + static RCHelpers::ButtonsMap btn_map = RCHelpers::buttons_map(); + mobile_apis::ButtonName::eType button_id = + mobile_apis::ButtonName::INVALID_ENUM; + if (btn_map.end() != btn_map.find(button_name)) { + button_id = btn_map[button_name]; } - return true; + return button_id; } void ButtonPressRequest::Execute() { LOG4CXX_AUTO_TRACE(logger_); - - const char* button_name; - ns_smart_device_link::ns_smart_objects:: - EnumConversionHelper<mobile_apis::ButtonName::eType>::EnumToCString( - static_cast<mobile_apis::ButtonName::eType>( - (*message_)[app_mngr::strings::msg_params] - [message_params::kButtonName] - .asUInt()), - &button_name); - const std::string module_type = ModuleType(); - static ButtonsMap btn_map = buttons_map(); - mobile_apis::ButtonName::eType button_id = - mobile_apis::ButtonName::INVALID_ENUM; - if (btn_map.end() != btn_map.find(button_name)) { - button_id = btn_map[button_name]; - } - const smart_objects::SmartObject* rc_capabilities = - hmi_capabilities_.rc_capability(); const bool button_name_matches_module_type = - CheckButtonName(module_type, button_name, rc_capabilities); - const bool button_id_exist_in_caps = - rc_capabilities && - CheckIfButtonExistInRCCaps(*rc_capabilities, button_id); + rc_capabilities_manager_.CheckButtonName(module_type, GetButtonName()); + + const std::string module_id = ModuleId(); + const ModuleUid module(module_type, module_id); + const bool is_module_exists = + rc_capabilities_manager_.CheckIfModuleExistsInCapabilities(module); + + const bool button_valid_by_caps = + is_module_exists && + rc_capabilities_manager_.CheckIfButtonExistInRCCaps(GetButtonId()); app_mngr::ApplicationSharedPtr app = application_manager_.application(connection_key()); @@ -203,7 +99,9 @@ void ButtonPressRequest::Execute() { (*message_)[app_mngr::strings::msg_params][app_mngr::strings::app_id] = app->app_id(); - if (button_name_matches_module_type && button_id_exist_in_caps) { + if (button_name_matches_module_type && button_valid_by_caps) { + (*message_)[app_mngr::strings::msg_params][message_params::kModuleId] = + module_id; SendHMIRequest(hmi_apis::FunctionID::Buttons_ButtonPress, &(*message_)[app_mngr::strings::msg_params], true); @@ -214,11 +112,12 @@ void ButtonPressRequest::Execute() { mobile_apis::Result::INVALID_DATA, "Request module type and button name mismatch!"); } else { - LOG4CXX_WARN(logger_, "Requested button is not exists in capabilities!"); + LOG4CXX_WARN(logger_, + "Requested button or module does not exist in capabilities!"); SetResourceState(module_type, ResourceState::FREE); SendResponse(false, mobile_apis::Result::UNSUPPORTED_RESOURCE, - "Requested button is not exists in capabilities!"); + "Requested button or module does not exist in capabilities!"); } } @@ -228,13 +127,15 @@ AcquireResult::eType ButtonPressRequest::AcquireResource( const std::string module_type = ModuleType(); app_mngr::ApplicationSharedPtr app = application_manager_.application(CommandRequestImpl::connection_key()); - return resource_allocation_manager_.AcquireResource(module_type, - app->app_id()); + + return resource_allocation_manager_.AcquireResource( + module_type, ModuleId(), app->app_id()); } -bool ButtonPressRequest::IsResourceFree(const std::string& module_type) const { +bool ButtonPressRequest::IsResourceFree(const std::string& module_type, + const std::string& module_id) const { LOG4CXX_AUTO_TRACE(logger_); - return resource_allocation_manager_.IsResourceFree(module_type); + return resource_allocation_manager_.IsResourceFree(module_type, module_id); } void ButtonPressRequest::SetResourceState(const std::string& module_type, @@ -242,8 +143,9 @@ void ButtonPressRequest::SetResourceState(const std::string& module_type, LOG4CXX_AUTO_TRACE(logger_); app_mngr::ApplicationSharedPtr app = application_manager_.application(CommandRequestImpl::connection_key()); + resource_allocation_manager_.SetResourceState( - module_type, app->app_id(), state); + module_type, ModuleId(), app->app_id(), state); } void ButtonPressRequest::on_event(const app_mngr::event_engine::Event& event) { @@ -270,13 +172,43 @@ void ButtonPressRequest::on_event(const app_mngr::event_engine::Event& event) { result = false; result_code = mobile_apis::Result::GENERIC_ERROR; } + + const std::string module_type = ModuleType(); + const std::string module_id = ModuleId(); + + const rc_rpc_types::ModuleUid resource{module_type, module_id}; + auto app = application_manager_.application(connection_key()); + + if (!app) { + LOG4CXX_ERROR(logger_, "NULL pointer."); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED, ""); + return; + } + + const auto app_id = app->app_id(); + + bool is_resource_acquired = false; + + if (result && !resource_allocation_manager_.IsResourceAlreadyAcquiredByApp( + resource, app_id)) { + resource_allocation_manager_.SetResourceAcquired( + module_type, module_id, app_id); + + is_resource_acquired = true; + } + std::string response_info; GetInfo(message, response_info); - SetResourceState(ModuleType(), ResourceState::FREE); SendResponse(result, result_code, response_info.c_str()); + + if (is_resource_acquired) { + resource_allocation_manager_.SendOnRCStatusNotifications( + NotificationTrigger::MODULE_ALLOCATION, + std::shared_ptr<application_manager::Application>()); + } } -std::string ButtonPressRequest::ModuleType() { +std::string ButtonPressRequest::ModuleType() const { mobile_apis::ModuleType::eType module_type = static_cast<mobile_apis::ModuleType::eType>( (*message_)[app_mngr::strings::msg_params] @@ -288,5 +220,16 @@ std::string ButtonPressRequest::ModuleType() { return ok ? str : "unknown"; } +std::string ButtonPressRequest::ModuleId() const { + LOG4CXX_AUTO_TRACE(logger_); + auto msg_params = (*message_)[app_mngr::strings::msg_params]; + if (msg_params.keyExists(message_params::kModuleId)) { + return msg_params[message_params::kModuleId].asString(); + } + const std::string module_id = + rc_capabilities_manager_.GetDefaultModuleIdFromCapabilities(ModuleType()); + return module_id; +} + } // namespace commands } // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/get_interior_vehicle_data_consent_request.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/get_interior_vehicle_data_consent_request.cc new file mode 100644 index 0000000000..477f04bb7c --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/get_interior_vehicle_data_consent_request.cc @@ -0,0 +1,368 @@ +/* + * Copyright (c) 2019, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <algorithm> +#include <ctime> +#include <vector> + +#include "rc_rpc_plugin/commands/mobile/get_interior_vehicle_data_consent_request.h" +#include "rc_rpc_plugin/rc_helpers.h" +#include "rc_rpc_plugin/rc_module_constants.h" +#include "rc_rpc_plugin/rc_rpc_types.h" +#include "smart_objects/enum_schema_item.h" + +namespace rc_rpc_plugin { +namespace app_mngr = application_manager; +namespace commands { + +GetInteriorVehicleDataConsentRequest::GetInteriorVehicleDataConsentRequest( + const application_manager::commands::MessageSharedPtr& message, + const RCCommandParams& params) + : RCCommandRequest(message, params) {} + +void GetInteriorVehicleDataConsentRequest::Execute() { + LOG4CXX_AUTO_TRACE(logger_); + + auto& msg_params = (*message_)[app_mngr::strings::msg_params]; + + const bool module_ids_exists = + msg_params.keyExists(message_params::kModuleIds); + if (!module_ids_exists) { + SendResponse(false, + mobile_apis::Result::INVALID_DATA, + "ModuleIds collection is absent in request message"); + return; + } + + if (msg_params[message_params::kModuleIds].empty()) { + LOG4CXX_DEBUG(logger_, + "ModuleIds collection is empty. Will be add default " + "module_id from capabilities"); + + const auto module_id = + rc_capabilities_manager_.GetDefaultModuleIdFromCapabilities( + ModuleType()); + + msg_params[message_params::kModuleIds][0] = module_id; + } + + const std::string module_type = ModuleType(); + for (const auto module_id : + *(msg_params[message_params::kModuleIds].asArray())) { + const ModuleUid module(module_type, module_id.asString()); + if (!rc_capabilities_manager_.CheckIfModuleExistsInCapabilities(module)) { + LOG4CXX_WARN(logger_, + "Accessing not supported module: " << module_type << " " + << module_id.asString()); + SetResourceState(module_type, ResourceState::FREE); + SendResponse(false, + mobile_apis::Result::UNSUPPORTED_RESOURCE, + "Accessing not supported module data"); + return; + } + } + + smart_objects::SmartObject response_params; + if (GetCalculatedVehicleDataConsent(response_params)) { + LOG4CXX_DEBUG( + logger_, + "No need to send response to HMI. Sending cached consents to mobile"); + SendResponse(true, mobile_apis::Result::SUCCESS, nullptr, &response_params); + return; + } + + (*message_)[application_manager::strings::msg_params] + [application_manager::strings::app_id] = connection_key(); + + SendHMIRequest(hmi_apis::FunctionID::RC_GetInteriorVehicleDataConsent, + (&msg_params), + true); +} + +void GetInteriorVehicleDataConsentRequest::on_event( + const app_mngr::event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + namespace app_mnrg = application_manager; + + if (event.id() != hmi_apis::FunctionID::RC_GetInteriorVehicleDataConsent) { + LOG4CXX_ERROR(logger_, "Received wrong event. FunctionID: " << event.id()); + return; + } + + const auto& hmi_response = event.smart_object(); + + std::string response_info; + const bool result_of_saving = SaveModuleIdConsents( + response_info, hmi_response[app_mngr::strings::msg_params]); + + if (!result_of_saving) { + LOG4CXX_DEBUG(logger_, "Consent saving failed"); + SendResponse( + false, mobile_apis::Result::GENERIC_ERROR, response_info.c_str()); + return; + } + + auto result_code = + GetMobileResultCode(static_cast<hmi_apis::Common_Result::eType>( + hmi_response[app_mngr::strings::params][app_mngr::hmi_response::code] + .asUInt())); + + const bool success_result = + helpers::Compare<mobile_apis::Result::eType, helpers::EQ, helpers::ONE>( + result_code, + mobile_apis::Result::SUCCESS, + mobile_apis::Result::WARNINGS); + + smart_objects::SmartObject response_params; + response_params = hmi_response[app_mngr::strings::msg_params]; + std::string info; + GetInfo(hmi_response, info); + SendResponse(success_result, + result_code, + info.c_str(), + success_result ? &response_params : nullptr); +} + +std::string GetInteriorVehicleDataConsentRequest::ModuleType() const { + mobile_apis::ModuleType::eType module_type = + static_cast<mobile_apis::ModuleType::eType>( + (*message_)[app_mngr::strings::msg_params] + [message_params::kModuleType] + .asUInt()); + + const char* str; + const bool ok = smart_objects::EnumConversionHelper< + mobile_apis::ModuleType::eType>::EnumToCString(module_type, &str); + return ok ? str : "unknown"; +} + +std::string GetInteriorVehicleDataConsentRequest::ModuleId() const { + return std::string(); +} + +GetInteriorVehicleDataConsentRequest::~GetInteriorVehicleDataConsentRequest() {} + +bool GetInteriorVehicleDataConsentRequest::GetCalculatedVehicleDataConsent( + smart_objects::SmartObject& out_response) const { + LOG4CXX_AUTO_TRACE(logger_); + + out_response = + smart_objects::SmartObject(smart_objects::SmartType::SmartType_Map); + out_response[message_params::kAllowed] = + smart_objects::SmartObject(smart_objects::SmartType::SmartType_Array); + + auto modules_consent_array = out_response[message_params::kAllowed].asArray(); + const auto module_ids = + (*message_)[app_mngr::strings::msg_params][message_params::kModuleIds] + .asArray(); + + if (!MultipleAccessAllowed((*module_ids), (*modules_consent_array))) { + return true; + } + + auto fill_auto_allow_consents = + [&module_ids](smart_objects::SmartArray& out_consents_array) { + for (uint32_t i = 0; i < module_ids->size(); ++i) { + out_consents_array.push_back(smart_objects::SmartObject(true)); + } + }; + + auto fill_auto_deny_consents = + [this, &module_ids](smart_objects::SmartArray& out_consents_array) { + const std::string module_type = ModuleType(); + auto app = application_manager_.application(connection_key()); + const uint32_t app_id = app->app_id(); + for (auto& module_id : (*module_ids)) { + const ModuleUid module_uid(module_type, module_id.asString()); + const bool is_resource_available = + (resource_allocation_manager_.AcquireResource( + module_uid.first, module_uid.second, app_id) == + AcquireResult::ALLOWED); + + out_consents_array.push_back( + smart_objects::SmartObject(is_resource_available)); + } + }; + + auto fill_ask_driver_consents = + [this, &module_ids](smart_objects::SmartArray& out_consents_array) { + auto app = application_manager_.application(connection_key()); + const std::string policy_app_id = app->policy_app_id(); + const std::string mac_address = app->mac_address(); + const std::string module_type = ModuleType(); + + for (auto& module_id : (*module_ids)) { + const ModuleUid module_uid(module_type, module_id.asString()); + auto consent = rc_consent_manager_.GetModuleConsent( + policy_app_id, mac_address, module_uid); + + if (rc_rpc_types::ModuleConsent::NOT_EXISTS == consent) { + const bool is_resource_available = + resource_allocation_manager_.AcquireResource( + module_uid.first, module_uid.second, app->app_id()) == + AcquireResult::ALLOWED; + + const bool is_resource_rejected = + resource_allocation_manager_.AcquireResource( + module_uid.first, module_uid.second, app->app_id()) == + AcquireResult::REJECTED; + + if (!is_resource_available && !is_resource_rejected) { + out_consents_array.clear(); + break; + } + + out_consents_array.push_back(smart_objects::SmartObject( + is_resource_available ? true : false)); + continue; + } + + const bool is_resource_available = + rc_rpc_types::ModuleConsent::CONSENTED == consent; + out_consents_array.push_back( + smart_objects::SmartObject(is_resource_available)); + } + }; + + const auto access_mode = resource_allocation_manager_.GetAccessMode(); + if (hmi_apis::Common_RCAccessMode::AUTO_ALLOW == access_mode) { + LOG4CXX_DEBUG(logger_, + "Current access mode is AUTO_ALLOW - returning successful " + "consents for all"); + fill_auto_allow_consents(*modules_consent_array); + return true; + } + + if (hmi_apis::Common_RCAccessMode::AUTO_DENY == access_mode) { + LOG4CXX_DEBUG(logger_, + "Current access mode is AUTO_DENY - returning true only for " + "FREE resources"); + fill_auto_deny_consents(*modules_consent_array); + return true; + } + + if (hmi_apis::Common_RCAccessMode::ASK_DRIVER == access_mode) { + LOG4CXX_DEBUG( + logger_, + "Current access mode is ASK_DRIVER - returning consents from cache"); + fill_ask_driver_consents(*modules_consent_array); + if (!modules_consent_array->empty()) { + LOG4CXX_DEBUG(logger_, "Returning consents from cache directly"); + return true; + } + } + + LOG4CXX_DEBUG( + logger_, + "Can't provide calculated consents - should send request to HMI"); + return false; +} + +bool GetInteriorVehicleDataConsentRequest::MultipleAccessAllowed( + const smart_objects::SmartArray& module_ids, + smart_objects::SmartArray& out_consents_array) const { + LOG4CXX_AUTO_TRACE(logger_); + for (auto& module_id : module_ids) { + const std::string module_type = ModuleType(); + auto app = application_manager_.application(connection_key()); + const uint32_t app_id = app->app_id(); + const ModuleUid module_uid(module_type, module_id.asString()); + const bool is_multiple_access_allowed = + rc_capabilities_manager_.IsMultipleAccessAllowed(module_uid); + if (!is_multiple_access_allowed) { + const bool is_resource_free = + (resource_allocation_manager_.AcquireResource( + module_uid.first, module_uid.second, app_id) == + AcquireResult::ALLOWED); + + out_consents_array.push_back( + smart_objects::SmartObject(is_resource_free)); + } else { + out_consents_array.clear(); + break; + } + } + + if (!out_consents_array.empty()) { + LOG4CXX_DEBUG(logger_, + "Multiple access disallowed, returning true only for " + "FREE resources"); + return false; + } + return true; +} + +bool GetInteriorVehicleDataConsentRequest::SaveModuleIdConsents( + std::string& info_out, const smart_objects::SmartObject& msg_params) { + LOG4CXX_AUTO_TRACE(logger_); + const bool is_allowed_exists = msg_params.keyExists(message_params::kAllowed); + + if (!is_allowed_exists || msg_params[message_params::kAllowed].empty()) { + info_out = "Collection of consents is absent in HMI response or empty"; + LOG4CXX_ERROR(logger_, info_out); + return false; + } + + const auto& allowed = msg_params[message_params::kAllowed]; + const auto& moduleIds = + (*message_)[app_mngr::strings::msg_params][message_params::kModuleIds]; + + if (allowed.length() != moduleIds.length()) { + info_out = + "The received module_id collection from mobile and received consent " + "collection from HMI are not equal by size."; + LOG4CXX_ERROR(logger_, info_out); + return false; + } + std::string module_type = ModuleType(); + auto module_ids = RCHelpers::RetrieveModuleIds(moduleIds); + auto module_allowed = RCHelpers::RetrieveModuleConsents(allowed); + + auto module_consents = + RCHelpers::FillModuleConsents(module_type, module_ids, module_allowed); + + auto application = application_manager_.application(connection_key()); + if (!application) { + LOG4CXX_ERROR(logger_, + "Application with connection key:" << connection_key() + << " isn't registered"); + return false; + } + std::string policy_app_id = application->policy_app_id(); + const auto mac_address = application->mac_address(); + rc_consent_manager_.SaveModuleConsents( + policy_app_id, mac_address, module_consents); + return true; +} + +} // namespace commands +} // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/get_interior_vehicle_data_consent_response.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/get_interior_vehicle_data_consent_response.cc new file mode 100644 index 0000000000..3e197fbdea --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/get_interior_vehicle_data_consent_response.cc @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2019, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "rc_rpc_plugin/commands/mobile/get_interior_vehicle_data_consent_response.h" + +namespace rc_rpc_plugin { +namespace commands { + +GetInteriorVehicleDataConsentResponse::GetInteriorVehicleDataConsentResponse( + const application_manager::commands::MessageSharedPtr& message, + const RCCommandParams& params) + : application_manager::commands::CommandResponseImpl( + message, + params.application_manager_, + params.rpc_service_, + params.hmi_capabilities_, + params.policy_handler_) {} + +void GetInteriorVehicleDataConsentResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +GetInteriorVehicleDataConsentResponse:: + ~GetInteriorVehicleDataConsentResponse() {} + +} // namespace commands +} // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/get_interior_vehicle_data_request.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/get_interior_vehicle_data_request.cc index ded96461f5..10f6303ac9 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/get_interior_vehicle_data_request.cc +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/get_interior_vehicle_data_request.cc @@ -50,36 +50,21 @@ GetInteriorVehicleDataRequest::GetInteriorVehicleDataRequest( const app_mngr::commands::MessageSharedPtr& message, const RCCommandParams& params) : RCCommandRequest(message, params) - , excessive_subscription_occured_(false) {} -bool CheckIfModuleTypeExistInCapabilities( - const smart_objects::SmartObject& rc_capabilities, - const std::string& module_type) { - LOG4CXX_AUTO_TRACE(logger_); - const auto& mapping = RCHelpers::GetModuleTypeToCapabilitiesMapping(); - const auto& module_list = RCHelpers::GetModulesList(); - bool is_module_type_valid = false; - for (const auto& module : module_list) { - if (module == module_type) { - if (rc_capabilities.keyExists(mapping(module))) { - is_module_type_valid = true; - break; - } - } - } - return is_module_type_valid; -} - bool GetInteriorVehicleDataRequest::ProcessCapabilities() { LOG4CXX_AUTO_TRACE(logger_); const smart_objects::SmartObject* rc_capabilities = hmi_capabilities_.rc_capability(); const std::string module_type = ModuleType(); + const std::string module_id = ModuleId(); + const ModuleUid module(module_type, module_id); if (rc_capabilities && - !CheckIfModuleTypeExistInCapabilities(*rc_capabilities, module_type)) { - LOG4CXX_WARN(logger_, "Accessing not supported module data"); + !rc_capabilities_manager_.CheckIfModuleExistsInCapabilities(module)) { + LOG4CXX_WARN( + logger_, + "Accessing not supported module: " << module_type << " " << module_id); SetResourceState(ModuleType(), ResourceState::FREE); SendResponse(false, mobile_apis::Result::UNSUPPORTED_RESOURCE, @@ -118,14 +103,20 @@ void GetInteriorVehicleDataRequest::ProcessResponseToMobileFromCache( app_mngr::ApplicationSharedPtr app) { LOG4CXX_AUTO_TRACE(logger_); const auto& data_mapping = RCHelpers::GetModuleTypeToDataMapping(); - auto data = interior_data_cache_.Retrieve(ModuleType()); + const std::string module_type = ModuleType(); + const std::string module_id = ModuleId(); + const ModuleUid module(module_type, module_id); + auto data = interior_data_cache_.Retrieve(module); FilterDisabledModuleData(data); auto response_msg_params = smart_objects::SmartObject(smart_objects::SmartType_Map); - response_msg_params[message_params::kModuleData][data_mapping(ModuleType())] = + response_msg_params[message_params::kModuleData][data_mapping(module_type)] = data; response_msg_params[message_params::kModuleData] - [message_params::kModuleType] = ModuleType(); + [message_params::kModuleType] = module_type; + + response_msg_params[message_params::kModuleData][message_params::kModuleId] = + module_id; const auto& request_msg_params = (*message_)[app_mngr::strings::msg_params]; LOG4CXX_DEBUG(logger_, @@ -137,7 +128,7 @@ void GetInteriorVehicleDataRequest::ProcessResponseToMobileFromCache( if (request_msg_params[message_params::kSubscribe].asBool()) { auto extension = RCHelpers::GetRCExtension(*app); DCHECK(extension); - extension->SubscribeToInteriorVehicleData(ModuleType()); + extension->SubscribeToInteriorVehicleData(module); } } SendResponse( @@ -145,13 +136,16 @@ void GetInteriorVehicleDataRequest::ProcessResponseToMobileFromCache( if (AppShouldBeUnsubscribed()) { auto extension = RCHelpers::GetRCExtension(*app); DCHECK(extension); - extension->UnsubscribeFromInteriorVehicleData(ModuleType()); + extension->UnsubscribeFromInteriorVehicleData(module); } } bool GetInteriorVehicleDataRequest::CheckRateLimits() { LOG4CXX_AUTO_TRACE(logger_); - return interior_data_manager_.CheckRequestsToHMIFrequency(ModuleType()); + const std::string module_type = ModuleType(); + const std::string module_id = ModuleId(); + const ModuleUid module(module_type, module_id); + return interior_data_manager_.CheckRequestsToHMIFrequency(module); } bool GetInteriorVehicleDataRequest::AppShouldBeUnsubscribed() { @@ -167,13 +161,16 @@ bool GetInteriorVehicleDataRequest::TheLastAppShouldBeUnsubscribed( app_mngr::ApplicationSharedPtr app) { LOG4CXX_AUTO_TRACE(logger_); if (AppShouldBeUnsubscribed()) { + const std::string module_type = ModuleType(); + const std::string module_id = ModuleId(); + const ModuleUid module(module_type, module_id); const auto subscribed_to_module_type = - RCHelpers::AppsSubscribedToModuleType(application_manager_, - ModuleType()); + RCHelpers::AppsSubscribedToModule(application_manager_, module); if (subscribed_to_module_type.size() == 1 && subscribed_to_module_type.front() == app) { LOG4CXX_DEBUG(logger_, - "The last application unsubscribes from " << ModuleType()); + "The last application unsubscribes from " + << module_type << " " << module_id); return true; } } @@ -189,9 +186,12 @@ void GetInteriorVehicleDataRequest::Execute() { app_mngr::ApplicationSharedPtr app = application_manager_.application(connection_key()); + const std::string module_type = ModuleType(); + const std::string module_id = ModuleId(); + const ModuleUid module(module_type, module_id); if (TheLastAppShouldBeUnsubscribed(app) || - !interior_data_cache_.Contains(ModuleType())) { + !interior_data_cache_.Contains(module)) { if (HasRequestExcessiveSubscription()) { excessive_subscription_occured_ = true; is_subscribed = @@ -204,7 +204,9 @@ void GetInteriorVehicleDataRequest::Execute() { SendResponse(false, mobile_apis::Result::REJECTED); return; } - interior_data_manager_.StoreRequestToHMITime(ModuleType()); + interior_data_manager_.StoreRequestToHMITime(module); + (*message_)[app_mngr::strings::msg_params][message_params::kModuleId] = + ModuleId(); SendHMIRequest(hmi_apis::FunctionID::RC_GetInteriorVehicleData, &(*message_)[app_mngr::strings::msg_params], true); @@ -242,20 +244,32 @@ void GetInteriorVehicleDataRequest::on_event( } if (result) { + if (!IsModuleIdProvided(hmi_response)) { + LOG4CXX_WARN(logger_, + "conditional mandatory parameter " + << message_params::kModuleId + << " missed in hmi response"); + result = false; + result_code = mobile_apis::Result::GENERIC_ERROR; + } app_mngr::ApplicationSharedPtr app = application_manager_.application(connection_key()); DCHECK_OR_RETURN_VOID(app); + const std::string module_type = ModuleType(); + const std::string module_id = ModuleId(); + const ModuleUid module(module_type, module_id); + if (TheLastAppShouldBeUnsubscribed(app)) { - interior_data_cache_.Remove(ModuleType()); + interior_data_cache_.Remove(module); } ProccessSubscription(hmi_response); if (is_subscribed) { const auto& data_mapping = RCHelpers::GetModuleTypeToDataMapping(); const auto module_data = hmi_response[app_mngr::strings::msg_params] - [message_params::kModuleData][data_mapping(ModuleType())]; - interior_data_cache_.Add(ModuleType(), module_data); + [message_params::kModuleData][data_mapping(module_type)]; + interior_data_cache_.Add(module, module_data); } } else { hmi_response[app_mngr::strings::msg_params].erase( @@ -301,8 +315,15 @@ void GetInteriorVehicleDataRequest::ProccessSubscription( [message_params::kModuleType] .asUInt()), &module_type); + + const std::string module_id = + hmi_response[app_mngr::strings::msg_params][message_params::kModuleData] + [message_params::kModuleId] + .asString(); + const ModuleUid module(module_type, module_id); + if (excessive_subscription_occured_) { - is_subscribed = extension->IsSubscibedToInteriorVehicleData(module_type); + is_subscribed = extension->IsSubscribedToInteriorVehicleData(module); temp_hmi_response[app_mngr::strings::msg_params] [message_params::kIsSubscribed] = is_subscribed; return; @@ -317,7 +338,7 @@ void GetInteriorVehicleDataRequest::ProccessSubscription( << message_params::kIsSubscribed << " missed in hmi response"); - is_subscribed = extension->IsSubscibedToInteriorVehicleData(module_type); + is_subscribed = extension->IsSubscribedToInteriorVehicleData(module); temp_hmi_response[app_mngr::strings::msg_params] [message_params::kIsSubscribed] = is_subscribed; return; @@ -348,16 +369,21 @@ void GetInteriorVehicleDataRequest::ProccessSubscription( LOG4CXX_TRACE(logger_, "response_subscribe = " << response_subscribe); if (request_subscribe == response_subscribe) { const std::string module_type = ModuleType(); + const std::string module_id = ModuleId(); + const ModuleUid module(module_type, module_id); + if (response_subscribe) { LOG4CXX_DEBUG(logger_, "SubscribeToInteriorVehicleData " << app->app_id() << " " - << module_type); - extension->SubscribeToInteriorVehicleData(module_type); + << module_type << " " + << module_id); + extension->SubscribeToInteriorVehicleData(module); } else { LOG4CXX_DEBUG(logger_, "UnsubscribeFromInteriorVehicleData " - << app->app_id() << " " << module_type); - extension->UnsubscribeFromInteriorVehicleData(module_type); + << app->app_id() << " " << module_type << " " + << module_id); + extension->UnsubscribeFromInteriorVehicleData(module); } } } @@ -373,8 +399,12 @@ bool GetInteriorVehicleDataRequest::HasRequestExcessiveSubscription() { application_manager_.application(CommandRequestImpl::connection_key()); const auto extension = RCHelpers::GetRCExtension(*app); + const std::string module_type = ModuleType(); + const std::string module_id = ModuleId(); + const ModuleUid module(module_type, module_id); + const bool is_app_already_subscribed = - extension->IsSubscibedToInteriorVehicleData(ModuleType()); + extension->IsSubscribedToInteriorVehicleData(module); const bool app_wants_to_subscribe = (*message_)[app_mngr::strings::msg_params][message_params::kSubscribe] .asBool(); @@ -391,7 +421,8 @@ void GetInteriorVehicleDataRequest::RemoveExcessiveSubscription() { (*message_)[app_mngr::strings::msg_params].erase(message_params::kSubscribe); } -std::string GetInteriorVehicleDataRequest::ModuleType() { +std::string GetInteriorVehicleDataRequest::ModuleType() const { + LOG4CXX_AUTO_TRACE(logger_); mobile_apis::ModuleType::eType module_type = static_cast<mobile_apis::ModuleType::eType>( (*message_)[app_mngr::strings::msg_params] @@ -403,5 +434,16 @@ std::string GetInteriorVehicleDataRequest::ModuleType() { return ok ? str : "unknown"; } +std::string GetInteriorVehicleDataRequest::ModuleId() const { + LOG4CXX_AUTO_TRACE(logger_); + auto msg_params = (*message_)[app_mngr::strings::msg_params]; + if (msg_params.keyExists(message_params::kModuleId)) { + return msg_params[message_params::kModuleId].asString(); + } + const std::string module_id = + rc_capabilities_manager_.GetDefaultModuleIdFromCapabilities(ModuleType()); + return module_id; +} + } // namespace commands } // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/on_interior_vehicle_data_notification.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/on_interior_vehicle_data_notification.cc index 06b5218bb3..91ecbe77eb 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/on_interior_vehicle_data_notification.cc +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/on_interior_vehicle_data_notification.cc @@ -50,27 +50,31 @@ OnInteriorVehicleDataNotification::OnInteriorVehicleDataNotification( params.rpc_service_, params.hmi_capabilities_, params.policy_handler_) - , interior_data_cache_(params.interior_data_cache_) {} + , interior_data_cache_(params.interior_data_cache_) + , rc_capabilities_manager_(params.rc_capabilities_manager_) {} OnInteriorVehicleDataNotification::~OnInteriorVehicleDataNotification() {} void OnInteriorVehicleDataNotification::AddDataToCache( - const std::string& module_type) { + const ModuleUid& module) { const auto& data_mapping = RCHelpers::GetModuleTypeToDataMapping(); const auto module_data = (*message_)[app_mngr::strings::msg_params][message_params::kModuleData] - [data_mapping(module_type)]; - interior_data_cache_.Add(module_type, module_data); + [data_mapping(module.first)]; + interior_data_cache_.Add(module, module_data); } void OnInteriorVehicleDataNotification::Run() { LOG4CXX_AUTO_TRACE(logger_); const std::string module_type = ModuleType(); + const std::string module_id = ModuleId(); + const ModuleUid module(module_type, module_id); + auto apps_subscribed = - RCHelpers::AppsSubscribedToModuleType(application_manager_, module_type); + RCHelpers::AppsSubscribedToModule(application_manager_, module); if (!apps_subscribed.empty()) { - AddDataToCache(module_type); + AddDataToCache(module); } typedef std::vector<application_manager::ApplicationSharedPtr> AppPtrs; AppPtrs apps = RCRPCPlugin::GetRCApplications(application_manager_); @@ -84,17 +88,36 @@ void OnInteriorVehicleDataNotification::Run() { const auto extension = RCHelpers::GetRCExtension(app); DCHECK(extension); LOG4CXX_TRACE(logger_, - "Check subscription for " - << app.app_id() << "and module type " << module_type); - if (extension->IsSubscibedToInteriorVehicleData(module_type)) { + "Check subscription for " << app.app_id() + << "and module type " << module_type + << " " << module_id); + + if (extension->IsSubscribedToInteriorVehicleData(module)) { (*message_)[app_mngr::strings::params] [app_mngr::strings::connection_key] = app.app_id(); + + (*message_)[app_mngr::strings::msg_params][message_params::kModuleData] + [message_params::kModuleId] = module_id; + SendNotification(); } } } -std::string OnInteriorVehicleDataNotification::ModuleType() { +std::string OnInteriorVehicleDataNotification::ModuleId() const { + LOG4CXX_AUTO_TRACE(logger_); + auto msg_params = (*message_)[app_mngr::strings::msg_params]; + if (msg_params[message_params::kModuleData].keyExists( + message_params::kModuleId)) { + return msg_params[message_params::kModuleData][message_params::kModuleId] + .asString(); + } + const std::string module_id = + rc_capabilities_manager_.GetDefaultModuleIdFromCapabilities(ModuleType()); + return module_id; +} + +std::string OnInteriorVehicleDataNotification::ModuleType() const { mobile_apis::ModuleType::eType module_type = static_cast<mobile_apis::ModuleType::eType>( (*message_)[app_mngr::strings::msg_params] diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/release_interior_vehicle_data_module_request.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/release_interior_vehicle_data_module_request.cc new file mode 100644 index 0000000000..e30d7869bd --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/release_interior_vehicle_data_module_request.cc @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2019, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <string> + +#include "application_manager/rpc_plugins/rc_rpc_plugin/include/rc_rpc_plugin/resource_allocation_manager.h" +#include "rc_rpc_plugin/commands/mobile/release_interior_vehicle_data_module_request.h" +#include "rc_rpc_plugin/rc_module_constants.h" +#include "smart_objects/enum_schema_item.h" + +namespace rc_rpc_plugin { +using namespace application_manager; +namespace commands { + +namespace { +struct ResponseParams { + std::string response_info; + std::string module_type; + std::string module_id; + mobile_apis::Result::eType result_code; + uint32_t app_id; + bool success_result; +}; + +void PrepareResponseResult( + ResponseParams& response_params_out, + rc_rpc_plugin::ResourceReleasedState::eType& released_result) { + std::stringstream ss; + auto info_inserter = [&ss, response_params_out](std::string info) { + ss << "Module [" << response_params_out.module_type << ":" + << response_params_out.module_id << "] " << info; + }; + switch (released_result) { + case rc_rpc_plugin::ResourceReleasedState::eType::IS_RELEASED: { + response_params_out.success_result = true; + response_params_out.result_code = mobile_apis::Result::eType::SUCCESS; + info_inserter("is released successfully."); + break; + } + case rc_rpc_plugin::ResourceReleasedState::eType::IS_ALLOCATED: { + response_params_out.success_result = false; + response_params_out.result_code = mobile_apis::Result::eType::REJECTED; + info_inserter("is allocated to a different application."); + break; + } + case rc_rpc_plugin::ResourceReleasedState::eType::NOT_ALLOCATED: { + response_params_out.success_result = false; + response_params_out.result_code = mobile_apis::Result::eType::IGNORED; + info_inserter("is not allocated to any application."); + break; + } + } + response_params_out.response_info = ss.str(); +} +} // namespace + +ReleaseInteriorVehicleDataModuleRequest:: + ReleaseInteriorVehicleDataModuleRequest( + const application_manager::commands::MessageSharedPtr& message, + const RCCommandParams& params) + : RCCommandRequest(message, params) {} + +bool ReleaseInteriorVehicleDataModuleRequest::ProcessCapabilities() { + LOG4CXX_AUTO_TRACE(logger_); + const smart_objects::SmartObject* rc_capabilities = + hmi_capabilities_.rc_capability(); + + const std::string module_type = ModuleType(); + const std::string module_id = ModuleId(); + const ModuleUid module(module_type, module_id); + if (rc_capabilities && + !rc_capabilities_manager_.CheckIfModuleExistsInCapabilities(module)) { + LOG4CXX_WARN( + logger_, + "Accessing not supported module: " << module_type << " " << module_id); + SendResponse(false, + mobile_apis::Result::UNSUPPORTED_RESOURCE, + "Accessing not supported module"); + return false; + } + return true; +} + +void ReleaseInteriorVehicleDataModuleRequest::Execute() { + LOG4CXX_AUTO_TRACE(logger_); + + if (!ProcessCapabilities()) { + return; + } + + const std::string module_type = ModuleType(); + const std::string module_id = ModuleId(); + + ApplicationSharedPtr app = application_manager_.application(connection_key()); + + if (!app) { + LOG4CXX_ERROR(logger_, "Application is not registered"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + const uint32_t app_id = app->app_id(); + + ResourceReleasedState::eType released_result = + resource_allocation_manager_.ReleaseResource( + module_type, module_id, app_id); + + bool success_result = true; + mobile_apis::Result::eType result_code = mobile_apis::Result::eType::SUCCESS; + std::string response_info; + ResponseParams response_params{response_info, + ModuleType(), + module_id, + result_code, + app_id, + success_result}; + PrepareResponseResult(response_params, released_result); + + if (response_params.success_result) { + resource_allocation_manager_.SendOnRCStatusNotifications( + NotificationTrigger::MODULE_ALLOCATION, app); + } + + LOG4CXX_DEBUG(logger_, + "Resource for module: " + << ModuleType() << " with id: " << module_id + << " was released with result " << std::boolalpha + << response_params.success_result + << " and result_code: " << response_params.result_code); + + SendResponse(response_params.success_result, + response_params.result_code, + response_params.response_info.c_str()); +} + +std::string ReleaseInteriorVehicleDataModuleRequest::ModuleType() const { + LOG4CXX_AUTO_TRACE(logger_); + mobile_apis::ModuleType::eType module_type = + static_cast<mobile_apis::ModuleType::eType>( + (*message_)[app_mngr::strings::msg_params] + [message_params::kModuleType] + .asUInt()); + + const char* str; + const bool ok = ns_smart_device_link::ns_smart_objects::EnumConversionHelper< + mobile_apis::ModuleType::eType>::EnumToCString(module_type, &str); + return ok ? str : "unknown"; +} + +std::string ReleaseInteriorVehicleDataModuleRequest::ModuleId() const { + LOG4CXX_AUTO_TRACE(logger_); + auto msg_params = (*message_)[app_mngr::strings::msg_params]; + if (msg_params.keyExists(message_params::kModuleId)) { + return msg_params[message_params::kModuleId].asString(); + } + const std::string module_id = + rc_capabilities_manager_.GetDefaultModuleIdFromCapabilities(ModuleType()); + return module_id; +} + +ReleaseInteriorVehicleDataModuleRequest:: + ~ReleaseInteriorVehicleDataModuleRequest() {} + +} // namespace commands +} // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/release_interior_vehicle_data_module_response.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/release_interior_vehicle_data_module_response.cc new file mode 100644 index 0000000000..fae792f143 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/release_interior_vehicle_data_module_response.cc @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2019, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "rc_rpc_plugin/commands/mobile/release_interior_vehicle_data_module_response.h" + +namespace rc_rpc_plugin { +namespace commands { + +ReleaseInteriorVehicleDataModuleResponse:: + ReleaseInteriorVehicleDataModuleResponse( + const application_manager::commands::MessageSharedPtr& message, + const RCCommandParams& params) + : application_manager::commands::CommandResponseImpl( + message, + params.application_manager_, + params.rpc_service_, + params.hmi_capabilities_, + params.policy_handler_) {} + +void ReleaseInteriorVehicleDataModuleResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +ReleaseInteriorVehicleDataModuleResponse:: + ~ReleaseInteriorVehicleDataModuleResponse() {} + +} // namespace commands +} // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/set_interior_vehicle_data_request.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/set_interior_vehicle_data_request.cc index 44d302276d..c3e5e807d7 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/set_interior_vehicle_data_request.cc +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/set_interior_vehicle_data_request.cc @@ -45,106 +45,6 @@ namespace commands { using namespace json_keys; using namespace message_params; - -namespace { -std::vector<std::string> GetModuleReadOnlyParams( - const std::string& module_type) { - std::vector<std::string> module_ro_params; - if (enums_value::kClimate == module_type) { - module_ro_params.push_back(kCurrentTemperature); - } else if (enums_value::kRadio == module_type) { - module_ro_params.push_back(kRdsData); - module_ro_params.push_back(kAvailableHDs); - module_ro_params.push_back(kAvailableHdChannels); - module_ro_params.push_back(kSignalStrength); - module_ro_params.push_back(kSignalChangeThreshold); - module_ro_params.push_back(kState); - module_ro_params.push_back(kSisData); - } else if (enums_value::kLight == module_type) { - module_ro_params.push_back(kLightStatus); - } - - return module_ro_params; -} - -const std::map<std::string, std::string> GetLightCapabilitiesMapping() { - std::map<std::string, std::string> mapping = { - {message_params::kId, strings::kName}, - {message_params::kLightStatus, strings::kStatusAvailable}, - {message_params::kLightDensity, strings::kDensityAvailable}, - {message_params::kLightColor, strings::kRGBColorSpaceAvailable}}; - return mapping; -} - -const std::map<std::string, std::string> GetModuleDataToCapabilitiesMapping() { - std::map<std::string, std::string> mapping; - // climate - mapping["fanSpeed"] = "fanSpeedAvailable"; - mapping["currentTemperature"] = "currentTemperatureAvailable"; - mapping["desiredTemperature"] = "desiredTemperatureAvailable"; - mapping["acEnable"] = "acEnableAvailable"; - mapping["circulateAirEnable"] = "circulateAirEnableAvailable"; - mapping["autoModeEnable"] = "autoModeEnableAvailable"; - mapping["defrostZone"] = "defrostZoneAvailable"; - mapping["dualModeEnable"] = "dualModeEnableAvailable"; - mapping["acMaxEnable"] = "acMaxEnableAvailable"; - mapping["ventilationMode"] = "ventilationModeAvailable"; - mapping["heatedSteeringWheelEnable"] = "heatedSteeringWheelAvailable"; - mapping["heatedWindshieldEnable"] = "heatedWindshieldAvailable"; - mapping["heatedMirrorsEnable"] = "heatedMirrorsAvailable"; - mapping["heatedRearWindowEnable"] = "heatedRearWindowAvailable"; - mapping["climateEnable"] = "climateEnableAvailable"; - mapping["climateEnableAvailable"] = "climateEnableAvailable"; - - // radio - mapping["band"] = "radioBandAvailable"; - mapping["frequencyInteger"] = "radioFrequencyAvailable"; - mapping["frequencyFraction"] = "radioFrequencyAvailable"; - mapping["rdsData"] = "rdsDataAvailable"; - mapping["availableHDs"] = "availableHDsAvailable"; - mapping["availableHdChannels"] = "availableHdChannelsAvailable"; - mapping["hdChannel"] = "availableHdChannelsAvailable"; - mapping["hdRadioEnable"] = "hdRadioEnableAvailable"; - mapping["signalStrength"] = "signalStrengthAvailable"; - mapping["signalChangeThreshold"] = "signalChangeThresholdAvailable"; - mapping["radioEnable"] = "radioEnableAvailable"; - mapping["state"] = "stateAvailable"; - mapping["sisData"] = "sisDataAvailable"; - - // seat - mapping["heatingEnabled"] = "heatingEnabledAvailable"; - mapping["coolingEnabled"] = "coolingEnabledAvailable"; - mapping["heatingLevel"] = "heatingLevelAvailable"; - mapping["coolingLevel"] = "coolingLevelAvailable"; - mapping["horizontalPosition"] = "horizontalPositionAvailable"; - mapping["verticalPosition"] = "verticalPositionAvailable"; - mapping["frontVerticalPosition"] = "frontVerticalPositionAvailable"; - mapping["backVerticalPosition"] = "backVerticalPositionAvailable"; - mapping["backTiltAngle"] = "backTiltAngleAvailable"; - mapping["headSupportHorizontalPosition"] = - "headSupportHorizontalPositionAvailable"; - mapping["headSupportVerticalPosition"] = - "headSupportVerticalPositionAvailable"; - mapping["massageEnabled"] = "massageEnabledAvailable"; - mapping["massageMode"] = "massageModeAvailable"; - mapping["massageCushionFirmness"] = "massageCushionFirmnessAvailable"; - mapping["memory"] = "memoryAvailable"; - - // audio - mapping["source"] = "sourceAvailable"; - mapping["keepContext"] = "keepContextAvailable"; - mapping["volume"] = "volumeAvailable"; - mapping["equalizerSettings"] = "equalizerAvailable"; - - // hmi settings - mapping["distanceUnit"] = "distanceUnitAvailable"; - mapping["temperatureUnit"] = "temperatureUnitAvailable"; - mapping["displayMode"] = "displayModeUnitAvailable"; - - return mapping; -} -} // namespace - CREATE_LOGGERPTR_GLOBAL(logger_, "RemoteControlModule") SetInteriorVehicleDataRequest::SetInteriorVehicleDataRequest( @@ -154,250 +54,6 @@ SetInteriorVehicleDataRequest::SetInteriorVehicleDataRequest( SetInteriorVehicleDataRequest::~SetInteriorVehicleDataRequest() {} -const std::string LightName(const smart_objects::SmartObject& light_name) { - const char* name; - const bool ok = ns_smart_device_link::ns_smart_objects:: - EnumConversionHelper<mobile_apis::LightName::eType>::EnumToCString( - static_cast<mobile_apis::LightName::eType>(light_name.asUInt()), - &name); - return ok ? name : "unknown"; -} - -/** - * @brief Check whether the parameter exist in capabilities - * @param smart object of capabilities - * @param mapping - map of module data and capabilities - * @param request_parameter - string - * @param switched_off_result - ref of mobile_apis::Result - * @return success if parameter exist in capabilities missedParam otherwise - */ -capabilitiesStatus GetItemCapability( - const smart_objects::SmartObject& capabilities, - const std::map<std::string, std::string>& mapping, - const std::string& request_parameter, - const mobile_apis::Result::eType& switched_off_result) { - const auto it = mapping.find(request_parameter); - - if (it == mapping.end()) { - LOG4CXX_DEBUG( - logger_, - "Parameter " << request_parameter << " doesn't exist in capabilities."); - return capabilitiesStatus::missedParam; - } - - const std::string& caps_key = it->second; - - LOG4CXX_DEBUG(logger_, - "Checking request parameter " - << request_parameter - << " with capabilities. Appropriate key is " << caps_key); - - if (!capabilities.keyExists(caps_key)) { - LOG4CXX_DEBUG(logger_, - "Capability " << caps_key - << " is missed in RemoteControl capabilities"); - return capabilitiesStatus::missedParam; - } - - if (!capabilities[caps_key].asBool()) { - LOG4CXX_DEBUG(logger_, - "Capability " - << caps_key - << " is switched off in RemoteControl capabilities"); - capabilitiesStatus status = capabilitiesStatus::missedParam; - if (mobile_apis::Result::READ_ONLY == switched_off_result) { - status = capabilitiesStatus::readOnly; - } - return status; - } - - return capabilitiesStatus::success; -} - -/** - * @brief Check whether the cpabilities for light allowed - * @param smart object of capabilities - * @param smart object of control_data - * @return pair of state and capability status - ModuleCapability - */ -ModuleCapability GetLightDataCapabilities( - const smart_objects::SmartObject& capabilities, - const smart_objects::SmartObject& control_data) { - LOG4CXX_AUTO_TRACE(logger_); - std::map<std::string, std::string> mapping = GetLightCapabilitiesMapping(); - - for (auto it = control_data.map_begin(); it != control_data.map_end(); ++it) { - const std::string& request_parameter = it->first; - - if (message_params::kId == request_parameter) { - continue; - } - - const capabilitiesStatus status_item_capability = - GetItemCapability(capabilities, - mapping, - request_parameter, - mobile_apis::Result::READ_ONLY); - - if (capabilitiesStatus::success != status_item_capability) { - return std::make_pair(message_params::kLightState, - status_item_capability); - } - } - - return std::make_pair("", capabilitiesStatus::success); -} - -/** - * @brief Check whether the light name exists in capabilities - * @param smart object of capabilities_status - * @param smart object of light_data - * @return pair of state and capability status - ModuleCapability - */ -ModuleCapability GetLightNameCapabilities( - const smart_objects::SmartObject& capabilities_status, - const smart_objects::SmartObject& light_data) { - LOG4CXX_AUTO_TRACE(logger_); - auto it = capabilities_status.asArray()->begin(); - for (; it != capabilities_status.asArray()->end(); ++it) { - const smart_objects::SmartObject& so = *it; - const int64_t current_id = so[message_params::kName].asInt(); - if (current_id == light_data[message_params::kId].asInt()) { - return GetLightDataCapabilities(so, light_data); - } - } - LOG4CXX_DEBUG(logger_, "There is no such light name in capabilities"); - return std::make_pair(message_params::kLightState, - capabilitiesStatus::missedLightName); -} - -ModuleCapability GetRadioBandByCapabilities( - const smart_objects::SmartObject& capabilities_status, - const smart_objects::SmartObject& request_parameter) { - mobile_apis::RadioBand::eType radio_band = - static_cast<mobile_apis::RadioBand::eType>(request_parameter.asUInt()); - if (mobile_apis::RadioBand::XM == radio_band) { - if (!capabilities_status.keyExists(strings::kSiriusxmRadioAvailable)) { - LOG4CXX_DEBUG(logger_, - "Capability " - << strings::kSiriusxmRadioAvailable - << " is missed in RemoteControl capabilities"); - return std::make_pair(strings::kSiriusxmRadioAvailable, - capabilitiesStatus::missedParam); - } - if (!capabilities_status[strings::kSiriusxmRadioAvailable].asBool()) { - LOG4CXX_DEBUG(logger_, - "Capability " - << strings::kSiriusxmRadioAvailable - << " is switched off in RemoteControl capabilities"); - return std::make_pair(strings::kSiriusxmRadioAvailable, - capabilitiesStatus::missedParam); - } - } - return std::make_pair("", capabilitiesStatus::success); -} - -/** - * @brief Check whether the exists light data related to correspondent - * capabilities - * @param smart object of capabilities - * @param smart object of control_data - * @return pair of state and capability status - ModuleCapability - */ -ModuleCapability GetControlDataCapabilities( - const smart_objects::SmartObject& capabilities, - const smart_objects::SmartObject& control_data) { - LOG4CXX_AUTO_TRACE(logger_); - std::map<std::string, std::string> mapping = - GetModuleDataToCapabilitiesMapping(); - - for (auto it = control_data.map_begin(); it != control_data.map_end(); ++it) { - const std::string& request_parameter = it->first; - if (message_params::kId == request_parameter) { - continue; - } - if (message_params::kLightState == request_parameter) { - auto light_data = control_data[request_parameter].asArray()->begin(); - ModuleCapability light_capability = - std::make_pair("", capabilitiesStatus::success); - - for (; light_data != control_data[request_parameter].asArray()->end(); - ++light_data) { - light_capability = GetLightNameCapabilities( - capabilities[strings::kSupportedLights], *light_data); - - if (capabilitiesStatus::success != light_capability.second) { - return light_capability; - } - } - - return light_capability; - } - if (message_params::kBand == request_parameter) { - ModuleCapability radio_capability = GetRadioBandByCapabilities( - capabilities, control_data[request_parameter]); - if (capabilitiesStatus::success != radio_capability.second) { - return radio_capability; - } - } - - const capabilitiesStatus status_item_capability = - GetItemCapability(capabilities, - mapping, - request_parameter, - mobile_apis::Result::UNSUPPORTED_RESOURCE); - - if (capabilitiesStatus::success != status_item_capability) { - return std::make_pair("", status_item_capability); - } - } - - return std::make_pair("", capabilitiesStatus::success); -} - -/** - * @brief Check whether rc module data capabilities are presented - * @param smart object of rc_capabilities - * @param smart object of module_data - * @return pair of state and capability status - ModuleCapability - */ -ModuleCapability GetModuleDataCapabilities( - const smart_objects::SmartObject& rc_capabilities, - const smart_objects::SmartObject& module_data) { - LOG4CXX_AUTO_TRACE(logger_); - - const auto& all_module_types = RCHelpers::GetModulesList(); - const auto& get_module_data_key = RCHelpers::GetModuleTypeToDataMapping(); - const auto& get_capabilities_key = - RCHelpers::GetModuleTypeToCapabilitiesMapping(); - ModuleCapability module_data_capabilities = - std::make_pair("", capabilitiesStatus::missedParam); - - for (const auto& module_type : all_module_types) { - const auto module_data_key = get_module_data_key(module_type); - const auto capabilities_key = get_capabilities_key(module_type); - if (module_data.keyExists(module_data_key)) { - if (!rc_capabilities.keyExists(capabilities_key)) { - LOG4CXX_DEBUG(logger_, module_data_key << " capabilities not present"); - return module_data_capabilities; - } - const smart_objects::SmartObject& caps = - rc_capabilities[capabilities_key]; - - if (message_params::kHmiSettingsControlData == module_data_key || - message_params::kLightControlData == module_data_key) { - module_data_capabilities = - GetControlDataCapabilities(caps, module_data[module_data_key]); - } else { - module_data_capabilities = - GetControlDataCapabilities(caps[0], module_data[module_data_key]); - } - } - } - - return module_data_capabilities; -} - /** * @brief Clears unrelated module data parameters * @param module type in request @@ -407,7 +63,7 @@ ModuleCapability GetModuleDataCapabilities( bool ClearUnrelatedModuleData(const std::string& module_type, smart_objects::SmartObject& module_data) { LOG4CXX_AUTO_TRACE(logger_); - const auto& all_module_types = RCHelpers::GetModulesList(); + const auto& all_module_types = RCHelpers::GetModuleTypesList(); const auto& data_mapping = RCHelpers::GetModuleTypeToDataMapping(); bool module_type_and_data_match = false; for (const auto& type : all_module_types) { @@ -423,7 +79,7 @@ bool ClearUnrelatedModuleData(const std::string& module_type, } mobile_apis::Result::eType PrepareResultCodeAndInfo( - const ModuleCapability module_data_capabilities, std::string& info) { + const ModuleTypeCapability module_data_capabilities, std::string& info) { mobile_apis::Result::eType result_code = mobile_apis::Result::UNSUPPORTED_RESOURCE; if (message_params::kLightState == module_data_capabilities.first) { @@ -459,25 +115,35 @@ void SetInteriorVehicleDataRequest::Execute() { const std::string module_type = ModuleType(); if (ClearUnrelatedModuleData(module_type, module_data)) { - const smart_objects::SmartObject* rc_capabilities = - hmi_capabilities_.rc_capability(); - ModuleCapability module_data_capabilities; + const std::string module_id = ModuleId(); + const ModuleUid module(module_type, module_id); + if (!rc_capabilities_manager_.CheckIfModuleExistsInCapabilities(module)) { + LOG4CXX_WARN(logger_, + "Accessing not supported module: " << module_type << " " + << module_id); + SetResourceState(ModuleType(), ResourceState::FREE); + SendResponse(false, + mobile_apis::Result::UNSUPPORTED_RESOURCE, + "Accessing not supported module data"); + return; + } - if (rc_capabilities) { - module_data_capabilities = - GetModuleDataCapabilities(*rc_capabilities, module_data); + ModuleTypeCapability module_data_capabilities; + module_data_capabilities = + rc_capabilities_manager_.GetModuleDataCapabilities(module_data, + module_id); - if (capabilitiesStatus::success != module_data_capabilities.second) { - SetResourceState(ModuleType(), ResourceState::FREE); - std::string info; - mobile_apis::Result::eType result = - PrepareResultCodeAndInfo(module_data_capabilities, info); - SendResponse(false, result, info.c_str()); - return; - } + if (capabilitiesStatus::success != module_data_capabilities.second) { + SetResourceState(ModuleType(), ResourceState::FREE); + std::string info; + mobile_apis::Result::eType result = + PrepareResultCodeAndInfo(module_data_capabilities, info); + SendResponse(false, result, info.c_str()); + return; } - if (AreAllParamsReadOnly(module_data)) { + if (rc_capabilities_manager_.AreAllParamsReadOnly(module_data, + module_type)) { LOG4CXX_WARN(logger_, "All request params in module type are READ ONLY!"); SetResourceState(ModuleType(), ResourceState::FREE); SendResponse(false, @@ -488,7 +154,8 @@ void SetInteriorVehicleDataRequest::Execute() { module_data_capabilities = std::make_pair("", capabilitiesStatus::success); - if (AreReadOnlyParamsPresent(module_data, module_data_capabilities)) { + if (rc_capabilities_manager_.AreReadOnlyParamsPresent( + module_data, module_type, module_data_capabilities)) { LOG4CXX_DEBUG(logger_, "Request module type has READ ONLY parameters"); if (enums_value::kLight == module_data_capabilities.first && @@ -535,11 +202,14 @@ void SetInteriorVehicleDataRequest::Execute() { } } + (*message_)[app_mngr::strings::msg_params][message_params::kModuleData] + [message_params::kModuleId] = module_id; SendHMIRequest(hmi_apis::FunctionID::RC_SetInteriorVehicleData, &(*message_)[app_mngr::strings::msg_params], true); } else { LOG4CXX_WARN(logger_, "Request module type & data mismatch!"); + SetResourceState(ModuleType(), ResourceState::FREE); SendResponse(false, mobile_apis::Result::INVALID_DATA, "Request module type & data mismatch!"); @@ -568,13 +238,45 @@ void SetInteriorVehicleDataRequest::on_event( mobile_apis::Result::WARNINGS); smart_objects::SmartObject response_params; + bool is_resource_acquired = false; + if (result) { + if (!IsModuleIdProvided(hmi_response)) { + LOG4CXX_WARN(logger_, + "conditional mandatory parameter " + << message_params::kModuleId + << " missed in hmi response"); + result = false; + result_code = mobile_apis::Result::GENERIC_ERROR; + } response_params = hmi_response[app_mngr::strings::msg_params]; if (enums_value::kAudio == ModuleType()) { CheckAudioSource(( *message_)[app_mngr::strings::msg_params][message_params::kModuleData] [message_params::kAudioControlData]); } + + const std::string module_type = ModuleType(); + const std::string module_id = ModuleId(); + + const rc_rpc_types::ModuleUid resource{module_type, module_id}; + auto app = application_manager_.application(connection_key()); + + if (!app) { + LOG4CXX_ERROR(logger_, "NULL pointer."); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED, ""); + return; + } + + const auto app_id = app->app_id(); + + if (!resource_allocation_manager_.IsResourceAlreadyAcquiredByApp(resource, + app_id)) { + resource_allocation_manager_.SetResourceAcquired( + module_type, module_id, app_id); + is_resource_acquired = true; + } + } else { app_mngr::ApplicationSharedPtr app = application_manager_.application(connection_key()); @@ -584,21 +286,12 @@ void SetInteriorVehicleDataRequest::on_event( GetInfo(hmi_response, info); SendResponse( result, result_code, info.c_str(), result ? &response_params : nullptr); -} - -const smart_objects::SmartObject& SetInteriorVehicleDataRequest::ControlData( - const smart_objects::SmartObject& module_data) { - const std::string module_type = ModuleType(); - const auto& all_module_types = RCHelpers::GetModulesList(); - const auto& data_mapping = RCHelpers::GetModuleTypeToDataMapping(); - for (const auto& type : all_module_types) { - if (type == module_type) { - return module_data[data_mapping(type)]; - } + if (is_resource_acquired) { + resource_allocation_manager_.SendOnRCStatusNotifications( + NotificationTrigger::MODULE_ALLOCATION, + std::shared_ptr<application_manager::Application>()); } - NOTREACHED(); - return module_data[0]; } void SetInteriorVehicleDataRequest::CheckAudioSource( @@ -610,116 +303,12 @@ void SetInteriorVehicleDataRequest::CheckAudioSource( } } -bool SetInteriorVehicleDataRequest::AreAllParamsReadOnly( - const smart_objects::SmartObject& module_data) { - LOG4CXX_AUTO_TRACE(logger_); - const smart_objects::SmartObject& module_type_params = - ControlData(module_data); - auto it = module_type_params.map_begin(); - std::vector<std::string> ro_params = GetModuleReadOnlyParams(ModuleType()); - for (; it != module_type_params.map_end(); ++it) { - if (!helpers::in_range(ro_params, it->first)) { - return false; - } - } - - LOG4CXX_DEBUG(logger_, "All params are ReadOnly"); - return true; -} - -bool CheckReadOnlyParamsForAudio( - const smart_objects::SmartObject& module_type_params) { - if (module_type_params.keyExists(message_params::kEqualizerSettings)) { - const auto& equalizer_settings = - module_type_params[message_params::kEqualizerSettings]; - auto it = equalizer_settings.asArray()->begin(); - - for (; it != equalizer_settings.asArray()->end(); ++it) { - if (it->keyExists(message_params::kChannelName)) { - LOG4CXX_DEBUG(logger_, - "READ ONLY parameter. ChannelName = " - << (*it)[message_params::kChannelName].asString()); - return true; - } - } - } - - return false; -} - -bool CheckReadOnlyParamsForLight( - const smart_objects::SmartObject& module_type_params) { - if (module_type_params.keyExists(message_params::kLightState)) { - const auto& light_state = module_type_params[message_params::kLightState]; - auto it = light_state.asArray()->begin(); - - for (; it != light_state.asArray()->end(); ++it) { - if (it->keyExists(message_params::kLightStatus)) { - const mobile_apis::LightStatus::eType light_status = - static_cast<mobile_apis::LightStatus::eType>( - (*it)[message_params::kLightStatus].asUInt()); - - if (helpers::Compare<mobile_apis::LightStatus::eType, - helpers::EQ, - helpers::ONE>(light_status, - mobile_apis::LightStatus::RAMP_UP, - mobile_apis::LightStatus::RAMP_DOWN, - mobile_apis::LightStatus::UNKNOWN, - mobile_apis::LightStatus::INVALID)) { - LOG4CXX_DEBUG(logger_, - "READ ONLY parameter. Status = " - << (*it)[message_params::kLightStatus].asInt()); - return true; - } - } - } - } - - return false; -} - -bool SetInteriorVehicleDataRequest::AreReadOnlyParamsPresent( - const smart_objects::SmartObject& module_data, - ModuleCapability& module_data_capabilities) { - LOG4CXX_AUTO_TRACE(logger_); - const smart_objects::SmartObject& module_type_params = - ControlData(module_data); - const std::string module_type = ModuleType(); - - if (enums_value::kAudio == module_type) { - return CheckReadOnlyParamsForAudio(module_type_params); - } - - if (enums_value::kLight == module_type) { - const bool result = CheckReadOnlyParamsForLight(module_type_params); - - if (result) { - module_data_capabilities = - std::make_pair(module_type, capabilitiesStatus::readOnly); - } - - return result; - } - - const std::vector<std::string> ro_params = - GetModuleReadOnlyParams(module_type); - auto it = module_type_params.map_begin(); - - for (; it != module_type_params.map_end(); ++it) { - if (helpers::in_range(ro_params, it->first)) { - return true; - } - } - - return false; -} - void SetInteriorVehicleDataRequest::CutOffReadOnlyParams( smart_objects::SmartObject& module_data) { LOG4CXX_AUTO_TRACE(logger_); - const smart_objects::SmartObject& module_type_params = - ControlData(module_data); const std::string module_type = ModuleType(); + const auto& module_type_params = + rc_capabilities_manager_.ControlDataForType(module_data, module_type); if (enums_value::kAudio == module_type) { auto& equalizer_settings = module_data[message_params::kAudioControlData] @@ -735,7 +324,8 @@ void SetInteriorVehicleDataRequest::CutOffReadOnlyParams( } } - std::vector<std::string> ro_params = GetModuleReadOnlyParams(module_type); + std::vector<std::string> ro_params = + RCHelpers::GetModuleReadOnlyParams(module_type); const auto& data_mapping = RCHelpers::GetModuleTypeToDataMapping(); for (const auto& param : ro_params) { if (module_type_params.keyExists(param)) { @@ -745,7 +335,8 @@ void SetInteriorVehicleDataRequest::CutOffReadOnlyParams( } } -std::string SetInteriorVehicleDataRequest::ModuleType() { +std::string SetInteriorVehicleDataRequest::ModuleType() const { + LOG4CXX_AUTO_TRACE(logger_); mobile_apis::ModuleType::eType module_type = static_cast<mobile_apis::ModuleType::eType>( (*message_)[app_mngr::strings::msg_params] @@ -757,19 +348,40 @@ std::string SetInteriorVehicleDataRequest::ModuleType() { return ok ? str : "unknown"; } +std::string SetInteriorVehicleDataRequest::ModuleId() const { + LOG4CXX_AUTO_TRACE(logger_); + auto msg_params = (*message_)[app_mngr::strings::msg_params]; + if (msg_params[message_params::kModuleData].keyExists( + message_params::kModuleId)) { + return msg_params[message_params::kModuleData][message_params::kModuleId] + .asString(); + } + if (enums_value::kSeat == ModuleType()) { + const auto id = static_cast<mobile_apis::SupportedSeat::eType>( + msg_params[message_params::kModuleData] + [message_params::kSeatControlData][message_params::kId] + .asUInt()); + return rc_capabilities_manager_.GetModuleIdForSeatLocation(id); + } + const std::string module_id = + rc_capabilities_manager_.GetDefaultModuleIdFromCapabilities(ModuleType()); + return module_id; +} + AcquireResult::eType SetInteriorVehicleDataRequest::AcquireResource( const app_mngr::commands::MessageSharedPtr& message) { LOG4CXX_AUTO_TRACE(logger_); const std::string module_type = ModuleType(); app_mngr::ApplicationSharedPtr app = application_manager_.application(CommandRequestImpl::connection_key()); - return resource_allocation_manager_.AcquireResource(module_type, - app->app_id()); + + return resource_allocation_manager_.AcquireResource( + module_type, ModuleId(), app->app_id()); } bool SetInteriorVehicleDataRequest::IsResourceFree( - const std::string& module_type) const { - return resource_allocation_manager_.IsResourceFree(module_type); + const std::string& module_type, const std::string& module_id) const { + return resource_allocation_manager_.IsResourceFree(module_type, module_id); } void SetInteriorVehicleDataRequest::SetResourceState( @@ -778,7 +390,7 @@ void SetInteriorVehicleDataRequest::SetResourceState( app_mngr::ApplicationSharedPtr app = application_manager_.application(CommandRequestImpl::connection_key()); resource_allocation_manager_.SetResourceState( - module_type, app->app_id(), state); + module_type, ModuleId(), app->app_id(), state); } } // namespace commands diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/rc_command_request.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/rc_command_request.cc index 4088a25ed5..885c5ac0dd 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/rc_command_request.cc +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/rc_command_request.cc @@ -31,10 +31,13 @@ */ #include "rc_rpc_plugin/commands/rc_command_request.h" +#include <sstream> #include "application_manager/hmi_interfaces.h" #include "application_manager/message_helper.h" #include "application_manager/policies/policy_handler_interface.h" +#include "rc_rpc_plugin/commands/rc_command_request.h" #include "rc_rpc_plugin/interior_data_cache.h" +#include "rc_rpc_plugin/rc_helpers.h" #include "rc_rpc_plugin/rc_module_constants.h" #include "smart_objects/enum_schema_item.h" @@ -56,7 +59,9 @@ RCCommandRequest::RCCommandRequest( , auto_allowed_(false) , resource_allocation_manager_(params.resource_allocation_manager_) , interior_data_cache_(params.interior_data_cache_) - , interior_data_manager_(params.interior_data_manager_) {} + , interior_data_manager_(params.interior_data_manager_) + , rc_capabilities_manager_(params.rc_capabilities_manager_) + , rc_consent_manager_(params.rc_consent_manager_) {} RCCommandRequest::~RCCommandRequest() {} @@ -101,6 +106,14 @@ rc_rpc_plugin::TypeAccess RCCommandRequest::CheckModule( : rc_rpc_plugin::TypeAccess::kDisallowed; } +bool RCCommandRequest::IsModuleIdProvided( + const smart_objects::SmartObject& hmi_response) const { + LOG4CXX_AUTO_TRACE(logger_); + return hmi_response[app_mngr::strings::msg_params] + [message_params::kModuleData] + .keyExists(message_params::kModuleId); +} + void RCCommandRequest::SendDisallowed(rc_rpc_plugin::TypeAccess access) { LOG4CXX_AUTO_TRACE(logger_); std::string info; @@ -144,6 +157,15 @@ void RCCommandRequest::Run() { "Remote control is disabled by user"); return; } + auto rc_capabilities = hmi_capabilities_.rc_capability(); + if (!rc_capabilities || rc_capabilities->empty()) { + LOG4CXX_WARN(logger_, "Accessing not supported module: " << ModuleType()); + SetResourceState(ModuleType(), ResourceState::FREE); + SendResponse(false, + mobile_apis::Result::UNSUPPORTED_RESOURCE, + "Accessing not supported module"); + return; + } if (CheckDriverConsent()) { if (AcquireResources()) { @@ -158,8 +180,9 @@ void RCCommandRequest::Run() { bool RCCommandRequest::AcquireResources() { LOG4CXX_AUTO_TRACE(logger_); const std::string module_type = ModuleType(); + const std::string module_id = ModuleId(); - if (!IsResourceFree(module_type)) { + if (!IsResourceFree(module_type, module_id)) { LOG4CXX_WARN(logger_, "Resource is busy."); SendResponse(false, mobile_apis::Result::IN_USE, ""); return false; @@ -176,7 +199,7 @@ bool RCCommandRequest::AcquireResources() { return false; } case AcquireResult::ASK_DRIVER: { - SendGetUserConsent(module_type); + ProcessAskDriverMode(module_type, module_id); return false; } case AcquireResult::REJECTED: { @@ -204,6 +227,7 @@ void RCCommandRequest::ProcessAccessResponse( app_mngr::ApplicationSharedPtr app = application_manager_.application(CommandRequestImpl::connection_key()); const std::string module_type = ModuleType(); + const std::string module_id = ModuleId(); if (!app) { LOG4CXX_ERROR(logger_, "NULL pointer."); SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED, ""); @@ -228,23 +252,18 @@ void RCCommandRequest::ProcessAccessResponse( if (message[app_mngr::strings::msg_params].keyExists( message_params::kAllowed)) { is_allowed = - message[app_mngr::strings::msg_params][message_params::kAllowed] + message[app_mngr::strings::msg_params][message_params::kAllowed][0] .asBool(); } - if (is_allowed) { - resource_allocation_manager_.ForceAcquireResource(module_type, - app->app_id()); - SetResourceState(module_type, ResourceState::BUSY); - Execute(); // run child's logic - } else { - resource_allocation_manager_.OnDriverDisallowed(module_type, - app->app_id()); - SendResponse( - false, - mobile_apis::Result::REJECTED, - "The resource is in use and the driver disallows this remote " - "control RPC"); - } + std::string policy_app_id = app->policy_app_id(); + const auto mac_address = app->mac_address(); + std::vector<std::string> module_ids{module_id}; + std::vector<bool> module_allowed{is_allowed}; + auto module_consents = + RCHelpers::FillModuleConsents(module_type, module_ids, module_allowed); + rc_consent_manager_.SaveModuleConsents( + policy_app_id, mac_address, module_consents); + ProcessConsentResult(is_allowed, module_type, module_id, app->app_id()); } else { std::string response_info; GetInfo(message, response_info); @@ -252,7 +271,56 @@ void RCCommandRequest::ProcessAccessResponse( } } -void RCCommandRequest::SendGetUserConsent(const std::string& module_type) { +void RCCommandRequest::ProcessConsentResult(const bool is_allowed, + const std::string& module_type, + const std::string& module_id, + const uint32_t app_id) { + LOG4CXX_AUTO_TRACE(logger_); + if (is_allowed) { + SetResourceState(module_type, ResourceState::BUSY); + Execute(); // run child's logic + } else { + resource_allocation_manager_.OnDriverDisallowed( + module_type, module_id, app_id); + + std::stringstream ss; + ss << "The resource [" << module_type << ":" << module_id + << "] is in use and the driver disallows this remote " + "control RPC"; + SendResponse(false, mobile_apis::Result::REJECTED, ss.str().c_str()); + } +} + +void RCCommandRequest::ProcessAskDriverMode(const std::string& module_type, + const std::string& module_id) { + LOG4CXX_AUTO_TRACE(logger_); + auto app = + application_manager_.application(CommandRequestImpl::connection_key()); + const std::string policy_app_id = app->policy_app_id(); + const std::string mac_address = app->mac_address(); + + auto consent = rc_consent_manager_.GetModuleConsent( + policy_app_id, mac_address, {module_type, module_id}); + switch (consent) { + case rc_rpc_types::ModuleConsent::NOT_EXISTS: { + smart_objects::SmartObject module_ids( + smart_objects::SmartType::SmartType_Array); + module_ids[0] = module_id; + SendGetUserConsent(module_type, module_ids); + break; + } + case rc_rpc_types::ModuleConsent::NOT_CONSENTED: + case rc_rpc_types::ModuleConsent::CONSENTED: { + const bool is_allowed = rc_rpc_types::ModuleConsent::CONSENTED == consent; + ProcessConsentResult(is_allowed, module_type, module_id, app->app_id()); + break; + } + }; +} + +void RCCommandRequest::SendGetUserConsent( + const std::string& module_type, + const smart_objects::SmartObject& module_ids) { LOG4CXX_AUTO_TRACE(logger_); app_mngr::ApplicationSharedPtr app = application_manager_.application(CommandRequestImpl::connection_key()); @@ -261,6 +329,8 @@ void RCCommandRequest::SendGetUserConsent(const std::string& module_type) { smart_objects::SmartObject(smart_objects::SmartType_Map); msg_params[app_mngr::strings::app_id] = app->app_id(); msg_params[message_params::kModuleType] = module_type; + msg_params[message_params::kModuleIds] = module_ids; + SendHMIRequest(hmi_apis::FunctionID::RC_GetInteriorVehicleDataConsent, &msg_params, true); diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/interior_data_cache_impl.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/interior_data_cache_impl.cc index 2c8683f84a..bcbc3ab11b 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/interior_data_cache_impl.cc +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/interior_data_cache_impl.cc @@ -135,49 +135,72 @@ smart_objects::SmartObject MergeArray(const smart_objects::SmartObject& data1, return result; } -void InteriorDataCacheImpl::Add(const std::string& module_type, +void InteriorDataCacheImpl::Add(const ModuleUid& module, const smart_objects::SmartObject& module_data) { - LOG4CXX_TRACE(logger_, "module_type : " << module_type); + LOG4CXX_TRACE( + logger_, + "module_type : " << module.first << " module_id : " << module.second); sync_primitives::AutoLock autolock(cached_data_lock_); - auto it = cached_data_.find(module_type); + auto it = cached_data_.find(module); if (cached_data_.end() == it) { - cached_data_[module_type] = module_data; + cached_data_[module] = module_data; return; } - cached_data_[module_type] = MergeModuleData(it->second, module_data); + cached_data_[module] = MergeModuleData(it->second, module_data); } smart_objects::SmartObject InteriorDataCacheImpl::Retrieve( - const std::string& module_type) const { + const ModuleUid& module) const { LOG4CXX_AUTO_TRACE(logger_); sync_primitives::AutoLock autolock(cached_data_lock_); - auto it = cached_data_.find(module_type); + auto it = cached_data_.find(module); if (it == cached_data_.end()) { LOG4CXX_WARN(logger_, - "Module type " << module_type << " was not found in cache"); + "Module with type: " << module.first + << " and id: " << module.second + << " was not found in cache"); return smart_objects::SmartObject(smart_objects::SmartType_Null); } - LOG4CXX_TRACE(logger_, "module_type : " << module_type); + LOG4CXX_TRACE( + logger_, + "module_type : " << module.first << " module_id : " << module.second); return it->second; } -bool InteriorDataCacheImpl::Contains(const std::string& module_type) const { +std::vector<ModuleUid> InteriorDataCacheImpl::GetCachedModulesByType( + const std::string& module_type) const { + std::vector<ModuleUid> modules; + for (auto& item : cached_data_) { + auto& module = item.first; + if (module_type == module.first) { + modules.push_back(module); + } + } + return modules; +} + +bool InteriorDataCacheImpl::Contains(const ModuleUid& module) const { LOG4CXX_AUTO_TRACE(logger_); sync_primitives::AutoLock autolock(cached_data_lock_); - auto it = cached_data_.find(module_type); + auto it = cached_data_.find(module); const bool contains = it != cached_data_.end(); - LOG4CXX_TRACE( - logger_, - "module_type : " << module_type << " " << (contains ? "true" : "false")); + LOG4CXX_TRACE(logger_, + "module_type : " << module.first + << " module_id : " << module.second << " " + << (contains ? "true" : "false")); return contains; } -void InteriorDataCacheImpl::Remove(const std::string& module_type) { - LOG4CXX_TRACE(logger_, "module_type : " << module_type); +void InteriorDataCacheImpl::Remove(const ModuleUid& module) { + LOG4CXX_TRACE( + logger_, + "module_type : " << module.first << " module_id : " << module.second); sync_primitives::AutoLock autolock(cached_data_lock_); - auto it = cached_data_.find(module_type); + auto it = cached_data_.find(module); if (cached_data_.end() == it) { - LOG4CXX_TRACE(logger_, "Not existing module_type : " << module_type); + LOG4CXX_TRACE( + logger_, + "Not existing module : " << module.first << " " << module.second); return; } cached_data_.erase(it); diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/interior_data_manager_impl.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/interior_data_manager_impl.cc index cb800a6081..50568de63a 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/interior_data_manager_impl.cc +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/interior_data_manager_impl.cc @@ -33,7 +33,7 @@ void InteriorDataManagerImpl::OnApplicationEvent( void InteriorDataManagerImpl::OnDisablingRC() { LOG4CXX_AUTO_TRACE(logger_); auto existing_subscription = AppsSubscribedModules(); - std::set<std::string> subscribed_modules; + std::set<ModuleUid> subscribed_modules; for (auto& pair : existing_subscription) { auto& app = pair.first; auto rc_extension = RCHelpers::GetRCExtension(*app); @@ -43,36 +43,37 @@ void InteriorDataManagerImpl::OnDisablingRC() { } } for (auto& module : subscribed_modules) { - LOG4CXX_TRACE(logger_, "unsubscribe " << module); + LOG4CXX_TRACE(logger_, + "unsubscribe from module type: " << module.first + << " id: " << module.second); UnsubscribeFromInteriorVehicleData(module); } } -void InteriorDataManagerImpl::StoreRequestToHMITime( - const std::string& module_type) { +void InteriorDataManagerImpl::StoreRequestToHMITime(const ModuleUid& module) { LOG4CXX_AUTO_TRACE(logger_); sync_primitives::AutoLock autolock(requests_to_hmi_history_lock_); - requests_to_hmi_history_[module_type].push_back(date_time::getCurrentTime()); + requests_to_hmi_history_[module].push_back(date_time::getCurrentTime()); } bool InteriorDataManagerImpl::CheckRequestsToHMIFrequency( - const std::string& module_type) { + const ModuleUid& module) { LOG4CXX_AUTO_TRACE(logger_); sync_primitives::AutoLock autolock(requests_to_hmi_history_lock_); ClearOldRequestsToHMIHistory(); - const auto& history = requests_to_hmi_history_[module_type]; + const auto& history = requests_to_hmi_history_[module]; const auto limit = app_mngr_.get_settings().get_interior_vehicle_data_frequency().first; return history.size() < limit; } void InteriorDataManagerImpl::UpdateHMISubscriptionsOnPolicyUpdated() { - auto apps_allowed_modules = - RCHelpers::GetApplicationsAllowedModules(app_mngr_); - auto apps_subscribed_modules = AppsSubscribedModules(); - InteriorDataManagerImpl::AppsModules apps_disallowed_modules; - for (auto& pair : apps_subscribed_modules) { - auto& allowed = apps_allowed_modules[pair.first]; + auto apps_allowed_module_types = + RCHelpers::GetApplicationsAllowedModuleTypes(app_mngr_); + auto apps_subscribed_module_types = AppsSubscribedModuleTypes(); + InteriorDataManagerImpl::AppsModuleTypes apps_disallowed_modules; + for (auto& pair : apps_subscribed_module_types) { + auto& allowed = apps_allowed_module_types[pair.first]; auto& subscribed = pair.second; std::vector<std::string> disallowed_modules; std::set_difference(subscribed.begin(), @@ -80,18 +81,25 @@ void InteriorDataManagerImpl::UpdateHMISubscriptionsOnPolicyUpdated() { allowed.begin(), allowed.end(), std::back_inserter(disallowed_modules)); + + std::sort(disallowed_modules.begin(), disallowed_modules.end()); + + auto unique_result = + std::unique(disallowed_modules.begin(), disallowed_modules.end()); + + disallowed_modules.erase(unique_result, disallowed_modules.end()); apps_disallowed_modules[pair.first] = disallowed_modules; } for (auto& pair : apps_disallowed_modules) { auto& app = pair.first; auto rc_extension = RCHelpers::GetRCExtension(*app); - for (const auto& module : pair.second) { - rc_extension->UnsubscribeFromInteriorVehicleData(module); + for (const auto& module_type : pair.second) { + rc_extension->UnsubscribeFromInteriorVehicleDataOfType(module_type); auto apps_subscribed = - RCHelpers::AppsSubscribedToModuleType(app_mngr_, module); + RCHelpers::AppsSubscribedToModuleType(app_mngr_, module_type); if (apps_subscribed.empty()) { - UnsubscribeFromInteriorVehicleData(module); + UnsubscribeFromInteriorVehicleDataOfType(module_type); } } } @@ -104,8 +112,7 @@ void InteriorDataManagerImpl::UpdateHMISubscriptionsOnAppUnregistered( auto subscribed_data = rc_extension->InteriorVehicleDataSubscriptions(); rc_extension->UnsubscribeFromInteriorVehicleData(); for (auto& data : subscribed_data) { - auto apps_subscribed = - RCHelpers::AppsSubscribedToModuleType(app_mngr_, data); + auto apps_subscribed = RCHelpers::AppsSubscribedToModule(app_mngr_, data); if (apps_subscribed.empty()) { UnsubscribeFromInteriorVehicleData(data); } @@ -117,14 +124,31 @@ void InteriorDataManagerImpl::UpdateHMISubscriptionsOnAppUnregistered( } void InteriorDataManagerImpl::UnsubscribeFromInteriorVehicleData( - const std::string& module_type) { - cache_.Remove(module_type); + const ModuleUid& module) { + cache_.Remove(module); auto unsubscribe_request = RCHelpers::CreateUnsubscribeRequestToHMI( - module_type, app_mngr_.GetNextHMICorrelationID()); - LOG4CXX_DEBUG(logger_, "Send Unsubscribe from " << module_type); + module, app_mngr_.GetNextHMICorrelationID()); + LOG4CXX_DEBUG(logger_, + "Send Unsubscribe from module type: " << module.first << " id: " + << module.second); rpc_service_.ManageHMICommand(unsubscribe_request); } +void InteriorDataManagerImpl::UnsubscribeFromInteriorVehicleDataOfType( + const std::string& module_type) { + const auto& modules = cache_.GetCachedModulesByType(module_type); + + for (const auto& module : modules) { + cache_.Remove(module); + auto unsubscribe_request = RCHelpers::CreateUnsubscribeRequestToHMI( + module, app_mngr_.GetNextHMICorrelationID()); + LOG4CXX_DEBUG(logger_, + "Send Unsubscribe from module type: " + << module.first << " id: " << module.second); + rpc_service_.ManageHMICommand(unsubscribe_request); + } +} + void InteriorDataManagerImpl::ClearOldRequestsToHMIHistory() { auto limit = app_mngr_.get_settings().get_interior_vehicle_data_frequency().second; @@ -148,11 +172,30 @@ InteriorDataManagerImpl::AppsSubscribedModules() { for (auto& app_ptr : apps_list) { const auto rc_extension = RCHelpers::GetRCExtension(*app_ptr); auto app_subscriptions = rc_extension->InteriorVehicleDataSubscriptions(); - result[app_ptr] = std::vector<std::string>(app_subscriptions.size()); + result[app_ptr] = std::vector<ModuleUid>(app_subscriptions.size()); std::copy(app_subscriptions.begin(), app_subscriptions.end(), result[app_ptr].begin()); } return result; } + +InteriorDataManagerImpl::AppsModuleTypes +InteriorDataManagerImpl::AppsSubscribedModuleTypes() { + auto apps_list = RCRPCPlugin::GetRCApplications(app_mngr_); + RCHelpers::AppsModuleTypes result; + for (auto& app_ptr : apps_list) { + const auto rc_extension = RCHelpers::GetRCExtension(*app_ptr); + auto app_subscriptions = rc_extension->InteriorVehicleDataSubscriptions(); + std::vector<std::string> app_module_types; + + for (auto& app_subscription : app_subscriptions) { + app_module_types.push_back(app_subscription.first); + } + + std::sort(app_module_types.begin(), app_module_types.end()); + result[app_ptr] = app_module_types; + } + return result; +} } // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_app_extension.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_app_extension.cc index 5282da8d83..ea9c13113c 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_app_extension.cc +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_app_extension.cc @@ -31,29 +31,51 @@ */ #include "rc_rpc_plugin/rc_app_extension.h" +#include <algorithm> +#include "rc_rpc_plugin/rc_module_constants.h" +#include "smart_objects/smart_object.h" namespace rc_rpc_plugin { RCAppExtension::RCAppExtension(application_manager::AppExtensionUID uid) : AppExtension(uid) {} -void RCAppExtension::SubscribeToInteriorVehicleData( - const std::string& module_type) { - subscribed_interior_vehicle_data_.insert(module_type); +void RCAppExtension::SubscribeToInteriorVehicleData(const ModuleUid& module) { + subscribed_interior_vehicle_data_.insert(module); } void RCAppExtension::UnsubscribeFromInteriorVehicleData( + const ModuleUid& module) { + subscribed_interior_vehicle_data_.erase(module); +} + +void RCAppExtension::UnsubscribeFromInteriorVehicleDataOfType( const std::string& module_type) { - subscribed_interior_vehicle_data_.erase(module_type); + for (auto& item : subscribed_interior_vehicle_data_) { + if (module_type == item.first) { + subscribed_interior_vehicle_data_.erase(item); + } + } } void RCAppExtension::UnsubscribeFromInteriorVehicleData() { subscribed_interior_vehicle_data_.clear(); } -bool RCAppExtension::IsSubscibedToInteriorVehicleData( +bool RCAppExtension::IsSubscribedToInteriorVehicleDataOfType( const std::string& module_type) { - std::set<std::string>::iterator it = - subscribed_interior_vehicle_data_.find(module_type); + auto it = std::find_if(subscribed_interior_vehicle_data_.begin(), + subscribed_interior_vehicle_data_.end(), + [&module_type](ModuleUid module) -> bool { + return module_type == module.first; + }); + + return (it != subscribed_interior_vehicle_data_.end()); +} + +bool RCAppExtension::IsSubscribedToInteriorVehicleData( + const ModuleUid& module) { + std::set<ModuleUid>::iterator it = + subscribed_interior_vehicle_data_.find(module); return (it != subscribed_interior_vehicle_data_.end()); } @@ -65,9 +87,29 @@ void RCAppExtension::ProcessResumption( const ns_smart_device_link::ns_smart_objects::SmartObject& resumption_data) {} -std::set<std::string> RCAppExtension::InteriorVehicleDataSubscriptions() const { +std::set<ModuleUid> RCAppExtension::InteriorVehicleDataSubscriptions() const { return subscribed_interior_vehicle_data_; } +Grid RCAppExtension::GetUserLocation() const { + return user_location_; +} + +void RCAppExtension::SetUserLocation( + const ns_smart_device_link::ns_smart_objects::SmartObject& user_location) { + const auto grid = user_location[strings::kGrid]; + const int32_t col = grid[strings::kCol].asInt(); + const int32_t row = grid[strings::kRow].asInt(); + const int32_t level = grid[strings::kLevel].asInt(); + const int32_t colspan = grid[strings::kColspan].asInt(); + const int32_t rowspan = grid[strings::kRowspan].asInt(); + const int32_t levelspan = grid[strings::kLevelspan].asInt(); + user_location_ = Grid(col, row, level, colspan, rowspan, levelspan); +} + +void RCAppExtension::SetUserLocation(const Grid& grid) { + user_location_ = grid; +} + RCAppExtension::~RCAppExtension() {} } // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_capabilities_manager_impl.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_capabilities_manager_impl.cc new file mode 100644 index 0000000000..dbedd0167f --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_capabilities_manager_impl.cc @@ -0,0 +1,925 @@ +/* + Copyright (c) 2019, Ford Motor Company + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following + disclaimer in the documentation and/or other materials provided with the + distribution. + + Neither the name of the copyright holders nor the names of their contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ + +#include "rc_rpc_plugin/rc_capabilities_manager_impl.h" +#include "rc_rpc_plugin/rc_helpers.h" +#include "rc_rpc_plugin/rc_module_constants.h" + +namespace rc_rpc_plugin { +CREATE_LOGGERPTR_GLOBAL(logger_, "RemoteControlModule") + +RCCapabilitiesManagerImpl::RCCapabilitiesManagerImpl( + application_manager::HMICapabilities& hmi_capabilities) + : hmi_capabilities_(hmi_capabilities) {} + +const std::string +RCCapabilitiesManagerImpl::GetDefaultModuleIdFromCapabilitiesStructure( + const smart_objects::SmartObject& control_capabilities, + const std::string& module_type) const { + LOG4CXX_AUTO_TRACE(logger_); + if (control_capabilities.keyExists(message_params::kModuleInfo)) { + // moduleId - mandatory param for ModuleInfo structure + const auto module_id = control_capabilities[message_params::kModuleInfo] + [message_params::kModuleId] + .asString(); + LOG4CXX_WARN(logger_, + "Use default moduleId from hmi capabilities: " + << module_id + << " for requested moduleType: " << module_type); + return module_id; + } + LOG4CXX_WARN(logger_, + "There are no moduleInfo in hmi capabilities for requested " + "moduleType " + << module_type); + return ""; +} + +const std::string +RCCapabilitiesManagerImpl::GetDefaultModuleIdFromCapabilitiesArray( + const smart_objects::SmartObject& control_capabilities, + const std::string& module_type) const { + LOG4CXX_AUTO_TRACE(logger_); + for (auto& cap_item : *(control_capabilities.asArray())) { + if (cap_item.keyExists(message_params::kModuleInfo)) { + // moduleId - mandatory param for ModuleInfo structure + const auto module_id = + cap_item[message_params::kModuleInfo][message_params::kModuleId] + .asString(); + LOG4CXX_WARN(logger_, + "Use default moduleId from hmi capabilities: " + << module_id + << " for requested moduleType: " << module_type); + return module_id; + } + } + LOG4CXX_WARN(logger_, + "There are no moduleInfo in hmi capabilities for requested " + "moduleType " + << module_type); + return ""; +} + +const std::string RCCapabilitiesManagerImpl::GetDefaultModuleIdFromCapabilities( + const std::string& module_type) const { + LOG4CXX_AUTO_TRACE(logger_); + auto rc_capabilities = *(hmi_capabilities_.rc_capability()); + const auto& mapping = RCHelpers::GetModuleTypeToCapabilitiesMapping(); + if (!rc_capabilities.keyExists(mapping(module_type))) { + LOG4CXX_WARN( + logger_, + "There is no RC capability for requested module_type " << module_type); + return ""; + } + if (enums_value::kHmiSettings == module_type || + enums_value::kLight == module_type) { + return GetDefaultModuleIdFromCapabilitiesStructure( + rc_capabilities[mapping(module_type)], module_type); + } + return GetDefaultModuleIdFromCapabilitiesArray( + rc_capabilities[mapping(module_type)], module_type); +} + +const bool RCCapabilitiesManagerImpl::CheckModuleIdWithCapabilitiesStructure( + const smart_objects::SmartObject& control_capabilities, + const std::string& module_id) const { + LOG4CXX_AUTO_TRACE(logger_); + if (control_capabilities.keyExists(message_params::kModuleInfo) && + (module_id == control_capabilities[message_params::kModuleInfo] + [message_params::kModuleId] + .asString())) { + return true; + } + LOG4CXX_WARN(logger_, + "There are no moduleInfo in hmi capabilities for requested " + "moduleId " + << module_id); + return false; +} + +const bool RCCapabilitiesManagerImpl::CheckModuleIdWithCapabilitiesArrays( + const smart_objects::SmartObject& control_capabilities, + const std::string& module_id) const { + LOG4CXX_AUTO_TRACE(logger_); + for (auto& cap_item : *(control_capabilities.asArray())) { + if (cap_item.keyExists(message_params::kModuleInfo) && + (module_id == + cap_item[message_params::kModuleInfo][message_params::kModuleId] + .asString())) { + return true; + } + } + LOG4CXX_WARN(logger_, + "There are no moduleInfo in hmi capabilities for requested " + "moduleId " + << module_id); + return false; +} + +const bool RCCapabilitiesManagerImpl::CheckModuleIdWithCapabilities( + const smart_objects::SmartObject& rc_capabilities, + const ModuleUid& module) const { + LOG4CXX_AUTO_TRACE(logger_); + if (module.second.empty()) { + return true; + } + const auto& mapping = RCHelpers::GetModuleTypeToCapabilitiesMapping(); + if (enums_value::kHmiSettings == module.first || + enums_value::kLight == module.first) { + return CheckModuleIdWithCapabilitiesStructure( + rc_capabilities[mapping(module.first)], module.second); + } + return CheckModuleIdWithCapabilitiesArrays( + rc_capabilities[mapping(module.first)], module.second); +} + +bool RCCapabilitiesManagerImpl::CheckIfModuleExistsInCapabilities( + const ModuleUid& module) const { + LOG4CXX_AUTO_TRACE(logger_); + auto rc_capabilities = *(hmi_capabilities_.rc_capability()); + const auto& mapping = RCHelpers::GetModuleTypeToCapabilitiesMapping(); + const auto& resource_list = GetResources(); + bool is_module_type_valid = false; + for (const auto& resource : resource_list) { + if (resource.first == module.first) { + if (rc_capabilities.keyExists(mapping(module.first)) && + CheckModuleIdWithCapabilities(rc_capabilities, module)) { + is_module_type_valid = true; + break; + } + } + } + return is_module_type_valid; +} + +const std::vector<std::string> RCCapabilitiesManagerImpl::GetCapabilitiesList() + const { + using namespace enums_value; + return {strings::kclimateControlCapabilities, + strings::kradioControlCapabilities, + strings::kseatControlCapabilities, + strings::kaudioControlCapabilities, + strings::klightControlCapabilities, + strings::khmiSettingsControlCapabilities}; +} + +const std::function<std::string(const std::string& control_cap)> +RCCapabilitiesManagerImpl::GetCapabilitiesToModuleTypeMapping() const { + auto mapping_lambda = [](const std::string& control_cap) -> std::string { + static std::map<std::string, std::string> mapping = { + {strings::kclimateControlCapabilities, enums_value::kClimate}, + {strings::kradioControlCapabilities, enums_value::kRadio}, + {strings::kseatControlCapabilities, enums_value::kSeat}, + {strings::kaudioControlCapabilities, enums_value::kAudio}, + {strings::klightControlCapabilities, enums_value::kLight}, + {strings::khmiSettingsControlCapabilities, enums_value::kHmiSettings}}; + auto it = mapping.find(control_cap); + if (mapping.end() == it) { + LOG4CXX_ERROR(logger_, "Unknown control capability " << control_cap); + return std::string(); + } + return it->second; + }; + + return mapping_lambda; +} + +void RCCapabilitiesManagerImpl::GetResourcesFromCapabilitiesStructure( + const smart_objects::SmartObject& control_capabilities, + const std::string& capability_key, + std::vector<ModuleUid>& out_resources) const { + const auto& mapping = GetCapabilitiesToModuleTypeMapping(); + if (control_capabilities.keyExists(message_params::kModuleInfo)) { + std::string module_id = control_capabilities[message_params::kModuleInfo] + [message_params::kModuleId] + .asString(); + out_resources.push_back(std::make_pair(mapping(capability_key), module_id)); + } else { + LOG4CXX_WARN(logger_, "There are no moduleId in " << capability_key); + out_resources.push_back(std::make_pair(mapping(capability_key), "")); + } +} + +void RCCapabilitiesManagerImpl::GetResourcesFromCapabilitiesArray( + const smart_objects::SmartObject& control_capabilities, + const std::string& capability_key, + std::vector<ModuleUid>& out_resources) const { + const auto& mapping = GetCapabilitiesToModuleTypeMapping(); + for (auto cap_item : *(control_capabilities.asArray())) { + if (cap_item.keyExists(message_params::kModuleInfo)) { + std::string module_id = + cap_item[message_params::kModuleInfo][message_params::kModuleId] + .asString(); + out_resources.push_back( + std::make_pair(mapping(capability_key), module_id)); + } else { + LOG4CXX_WARN(logger_, + "There are no moduleId for item from " << capability_key); + out_resources.push_back(std::make_pair(mapping(capability_key), "")); + } + } +} + +const std::vector<ModuleUid> RCCapabilitiesManagerImpl::GetResources() const { + LOG4CXX_AUTO_TRACE(logger_); + std::vector<ModuleUid> resources; + auto rc_capabilities = *(hmi_capabilities_.rc_capability()); + const auto& control_caps_list = GetCapabilitiesList(); + for (const auto& capability_key : control_caps_list) { + if (rc_capabilities.keyExists(capability_key)) { + if (strings::khmiSettingsControlCapabilities == capability_key || + strings::klightControlCapabilities == capability_key) { + GetResourcesFromCapabilitiesStructure( + rc_capabilities[capability_key], capability_key, resources); + } else { + GetResourcesFromCapabilitiesArray( + rc_capabilities[capability_key], capability_key, resources); + } + } + } + return resources; +} + +const std::string RCCapabilitiesManagerImpl::GetModuleIdForSeatLocation( + const mobile_apis::SupportedSeat::eType id) const { + LOG4CXX_AUTO_TRACE(logger_); + auto rc_capabilities = *(hmi_capabilities_.rc_capability()); + const auto seat_capabilities = + rc_capabilities[strings::kseatControlCapabilities]; + if (seat_capabilities.length() > 0) { + if (mobile_apis::SupportedSeat::DRIVER == id) { + return seat_capabilities[0][message_params::kModuleInfo] + [message_params::kModuleId] + .asString(); + } + if ((seat_capabilities.length() > 1) && + mobile_apis::SupportedSeat::FRONT_PASSENGER == id) { + return seat_capabilities[1][message_params::kModuleInfo] + [message_params::kModuleId] + .asString(); + } + } + LOG4CXX_DEBUG(logger_, "There are no capabitities for requested id: " << id); + return ""; +} + +bool RCCapabilitiesManagerImpl::CheckIfButtonExistInRCCaps( + const mobile_apis::ButtonName::eType button) const { + auto rc_capabilities = *(hmi_capabilities_.rc_capability()); + if (rc_capabilities.keyExists(strings::kbuttonCapabilities)) { + const smart_objects::SmartObject& button_caps = + rc_capabilities[strings::kbuttonCapabilities]; + for (auto& button_cap : *(button_caps.asArray())) { + int64_t current_id = button_cap[message_params::kName].asInt(); + if (-1 == current_id) { + // capabilities received from HMI contains enum values + // capabilities loaded from file contains string values + // TODO : unificate capabilities storing + const std::string& bt_name = + button_cap[message_params::kName].asString(); + static RCHelpers::ButtonsMap btn_map = RCHelpers::buttons_map(); + current_id = btn_map[bt_name]; + } + const mobile_apis::ButtonName::eType current_button = + static_cast<mobile_apis::ButtonName::eType>(current_id); + if (current_button == button) { + LOG4CXX_TRACE( + logger_, + "Button id " << current_button << " exist in capabilities"); + return true; + } + } + } + LOG4CXX_TRACE(logger_, + "Button id " << button << " do not exist in capabilities"); + return false; +} + +smart_objects::SmartObject +RCCapabilitiesManagerImpl::GetCapabilitiesByModuleIdFromArray( + const smart_objects::SmartObject& module_data_capabilities, + const std::string& module_id) const { + for (auto& cap_item : *(module_data_capabilities.asArray())) { + std::string current_id = + cap_item[message_params::kModuleInfo][message_params::kModuleId] + .asString(); + if (module_id == current_id) { + return cap_item; + } + } + LOG4CXX_WARN(logger_, + "Capabilities for moduleId " << module_id + << " do not exist in capabilities"); + return smart_objects::SmartObject(smart_objects::SmartType_Null); +} + +bool RCCapabilitiesManagerImpl::CheckButtonName( + const std::string& module_type, const std::string& button_name) const { + LOG4CXX_AUTO_TRACE(logger_); + auto rc_capabilities = hmi_capabilities_.rc_capability(); + if (!rc_capabilities) { + LOG4CXX_ERROR(logger_, "No remote controll capabilities available"); + return false; + } + + if (enums_value::kRadio == module_type) { + if (!helpers::in_range(RCHelpers::buttons_radio(), button_name)) { + LOG4CXX_WARN(logger_, + "Trying to acceess climate button with module type radio"); + return false; + } + } + + if (enums_value::kClimate == module_type) { + if (!helpers::in_range(RCHelpers::buttons_climate(), button_name)) { + LOG4CXX_WARN(logger_, + "Trying to acceess radio button with module type climate"); + return false; + } + } + return true; +} + +const std::map<std::string, std::string> +RCCapabilitiesManagerImpl::GetLightCapabilitiesMapping() const { + std::map<std::string, std::string> mapping = { + {message_params::kId, strings::kName}, + {message_params::kLightStatus, strings::kStatusAvailable}, + {message_params::kLightDensity, strings::kDensityAvailable}, + {message_params::kLightColor, strings::kRGBColorSpaceAvailable}}; + return mapping; +} + +const std::map<std::string, std::string> +RCCapabilitiesManagerImpl::GetModuleDataToCapabilitiesMapping() const { + std::map<std::string, std::string> mapping; + using namespace message_params; + using namespace rc_rpc_plugin::strings; + // climate + mapping[kFanSpeed] = kFanSpeedAvailable; + mapping[kCurrentTemperature] = kCurrentTemperatureAvailable; + mapping[kDesiredTemperature] = kDesiredTemperatureAvailable; + mapping[kACEnable] = kAcEnableAvailable; + mapping[kCirculateAirEnable] = kCirculateAirEnableAvailable; + mapping[kAutoModeEnable] = kAutoModeEnableAvailable; + mapping[kDefrostZone] = kDefrostZoneAvailable; + mapping[kDualModeEnable] = kDualModeEnableAvailable; + mapping[kACMaxEnable] = kAcMaxEnableAvailable; + mapping[kVentilationMode] = kVentilationModeAvailable; + mapping[kHeatedSteeringWheelEnable] = kHeatedSteeringWheelAvailable; + mapping[kHeatedWindshieldEnable] = kHeatedWindshieldAvailable; + mapping[kHeatedMirrorsEnable] = kHeatedMirrorsAvailable; + mapping[kHeatedRearWindowEnable] = kHeatedRearWindowAvailable; + mapping[kClimateEnable] = kClimateEnableAvailable; + mapping[kClimateEnableAvailable] = kClimateEnableAvailable; + + // radio + mapping[kBand] = kRadioBandAvailable; + mapping[kFrequencyInteger] = kRadioFrequencyAvailable; + mapping[kFrequencyFraction] = kRadioFrequencyAvailable; + mapping[kRdsData] = kRdsDataAvailable; + mapping[kAvailableHDs] = kAvailableHDsAvailable; + mapping[kAvailableHdChannels] = kAvailableHdChannelsAvailable; + mapping[kHdChannel] = kAvailableHdChannelsAvailable; + mapping[kHdRadioEnable] = kHdRadioEnableAvailable; + mapping[kSignalStrength] = kSignalStrengthAvailable; + mapping[kSignalChangeThreshold] = kSignalChangeThresholdAvailable; + mapping[kRadioEnable] = kRadioEnableAvailable; + mapping[kState] = kStateAvailable; + mapping[kSisData] = kSisDataAvailable; + + // seat + mapping[kHeatingEnabled] = kHeatingEnabledAvailable; + mapping[kCoolingEnabled] = kCoolingEnabledAvailable; + mapping[kHeatingLevele] = kHeatingLevelAvailable; + mapping[kCoolingLevel] = kCoolingLevelAvailable; + mapping[kHorizontalPosition] = kHorizontalPositionAvailable; + mapping[kVerticalPosition] = kVerticalPositionAvailable; + mapping[kFrontVerticalPosition] = kFrontVerticalPositionAvailable; + mapping[kBackVerticalPosition] = kBackVerticalPositionAvailable; + mapping[kBackTiltAngle] = kBackTiltAngleAvailable; + mapping[kHeadSupportHorizontalPosition] = + kHeadSupportHorizontalPositionAvailable; + mapping[kHeadSupportVerticalPosition] = kHeadSupportVerticalPositionAvailable; + mapping[kMassageEnabled] = kMassageEnabledAvailable; + mapping[kMassageMode] = kMassageModeAvailable; + mapping[kMassageCushionFirmness] = kMassageCushionFirmnessAvailable; + mapping[kMemory] = kMemoryAvailable; + + // audio + mapping[kSource] = kSourceAvailable; + mapping[kKeepContext] = kKeepContextAvailable; + mapping[kVolume] = kVolumeAvailable; + mapping[kEqualizerSettings] = kEqualizerAvailable; + + // hmi settings + mapping[kDistanceUnit] = kDistanceUnitAvailable; + mapping[kTemperatureUnit] = kTemperatureUnitAvailable; + mapping[kDisplayMode] = kDisplayModeUnitAvailable; + + return mapping; +} + +ModuleTypeCapability RCCapabilitiesManagerImpl::GetModuleDataCapabilities( + const smart_objects::SmartObject& module_data, + const std::string& module_id) const { + LOG4CXX_AUTO_TRACE(logger_); + auto rc_capabilities = *(hmi_capabilities_.rc_capability()); + + const auto& all_module_types = RCHelpers::GetModuleTypesList(); + const auto& get_module_data_key = RCHelpers::GetModuleTypeToDataMapping(); + const auto& get_capabilities_key = + RCHelpers::GetModuleTypeToCapabilitiesMapping(); + ModuleTypeCapability module_data_capabilities = + std::make_pair("", capabilitiesStatus::missedParam); + + for (const auto& module_type : all_module_types) { + const auto module_data_key = get_module_data_key(module_type); + const auto capabilities_key = get_capabilities_key(module_type); + if (module_data.keyExists(module_data_key)) { + if (!rc_capabilities.keyExists(capabilities_key)) { + LOG4CXX_DEBUG(logger_, module_data_key << " capabilities not present"); + return module_data_capabilities; + } + const auto& caps = rc_capabilities[capabilities_key]; + + if (message_params::kHmiSettingsControlData == module_data_key || + message_params::kLightControlData == module_data_key) { + module_data_capabilities = + GetControlDataCapabilities(caps, module_data[module_data_key]); + } else { + module_data_capabilities = GetControlDataCapabilities( + GetCapabilitiesByModuleIdFromArray(caps, module_id), + module_data[module_data_key]); + } + } + } + + return module_data_capabilities; +} + +ModuleTypeCapability RCCapabilitiesManagerImpl::GetControlDataCapabilities( + const smart_objects::SmartObject& capabilities, + const smart_objects::SmartObject& control_data) const { + LOG4CXX_AUTO_TRACE(logger_); + std::map<std::string, std::string> mapping = + GetModuleDataToCapabilitiesMapping(); + + for (auto it = control_data.map_begin(); it != control_data.map_end(); ++it) { + const std::string& request_parameter = it->first; + if (message_params::kId == request_parameter) { + continue; + } + if (message_params::kLightState == request_parameter) { + ModuleTypeCapability light_capability = + std::make_pair("", capabilitiesStatus::success); + + for (auto& light_data : *(control_data[request_parameter].asArray())) { + light_capability = GetLightNameCapabilities( + capabilities[strings::kSupportedLights], light_data); + + if (capabilitiesStatus::success != light_capability.second) { + return light_capability; + } + } + + return light_capability; + } + if (message_params::kBand == request_parameter) { + ModuleTypeCapability radio_capability = GetRadioBandByCapabilities( + capabilities, control_data[request_parameter]); + if (capabilitiesStatus::success != radio_capability.second) { + return radio_capability; + } + } + + const capabilitiesStatus status_item_capability = + GetItemCapability(capabilities, + mapping, + request_parameter, + mobile_apis::Result::UNSUPPORTED_RESOURCE); + + if (capabilitiesStatus::success != status_item_capability) { + return std::make_pair("", status_item_capability); + } + } + + return std::make_pair("", capabilitiesStatus::success); +} + +capabilitiesStatus RCCapabilitiesManagerImpl::GetItemCapability( + const smart_objects::SmartObject& capabilities, + const std::map<std::string, std::string>& mapping, + const std::string& request_parameter, + const mobile_apis::Result::eType& switched_off_result) const { + const auto it = mapping.find(request_parameter); + + if (it == mapping.end()) { + LOG4CXX_DEBUG( + logger_, + "Parameter " << request_parameter << " doesn't exist in capabilities."); + return capabilitiesStatus::missedParam; + } + + const std::string& caps_key = it->second; + + LOG4CXX_DEBUG(logger_, + "Checking request parameter " + << request_parameter + << " with capabilities. Appropriate key is " << caps_key); + + if (!capabilities.keyExists(caps_key)) { + LOG4CXX_DEBUG(logger_, + "Capability " << caps_key + << " is missed in RemoteControl capabilities"); + return capabilitiesStatus::missedParam; + } + + if (!capabilities[caps_key].asBool()) { + LOG4CXX_DEBUG(logger_, + "Capability " + << caps_key + << " is switched off in RemoteControl capabilities"); + capabilitiesStatus status = capabilitiesStatus::missedParam; + if (mobile_apis::Result::READ_ONLY == switched_off_result) { + status = capabilitiesStatus::readOnly; + } + return status; + } + + return capabilitiesStatus::success; +} + +ModuleTypeCapability RCCapabilitiesManagerImpl::GetLightDataCapabilities( + const smart_objects::SmartObject& capabilities, + const smart_objects::SmartObject& control_data) const { + LOG4CXX_AUTO_TRACE(logger_); + std::map<std::string, std::string> mapping = GetLightCapabilitiesMapping(); + + for (auto it = control_data.map_begin(); it != control_data.map_end(); ++it) { + const std::string& request_parameter = it->first; + + if (message_params::kId == request_parameter) { + continue; + } + + const capabilitiesStatus status_item_capability = + GetItemCapability(capabilities, + mapping, + request_parameter, + mobile_apis::Result::READ_ONLY); + + if (capabilitiesStatus::success != status_item_capability) { + return std::make_pair(message_params::kLightState, + status_item_capability); + } + } + + return std::make_pair("", capabilitiesStatus::success); +} + +ModuleTypeCapability RCCapabilitiesManagerImpl::GetLightNameCapabilities( + const smart_objects::SmartObject& capabilities_status, + const smart_objects::SmartObject& light_data) const { + LOG4CXX_AUTO_TRACE(logger_); + for (auto& so : *(capabilities_status.asArray())) { + const int64_t current_id = so[message_params::kName].asInt(); + if (current_id == light_data[message_params::kId].asInt()) { + return GetLightDataCapabilities(so, light_data); + } + } + LOG4CXX_DEBUG(logger_, "There is no such light name in capabilities"); + return std::make_pair(message_params::kLightState, + capabilitiesStatus::missedLightName); +} + +ModuleTypeCapability RCCapabilitiesManagerImpl::GetRadioBandByCapabilities( + const smart_objects::SmartObject& capabilities_status, + const smart_objects::SmartObject& request_parameter) const { + mobile_apis::RadioBand::eType radio_band = + static_cast<mobile_apis::RadioBand::eType>(request_parameter.asUInt()); + if (mobile_apis::RadioBand::XM == radio_band) { + if (!capabilities_status.keyExists(strings::kSiriusxmRadioAvailable)) { + LOG4CXX_DEBUG(logger_, + "Capability " + << strings::kSiriusxmRadioAvailable + << " is missed in RemoteControl capabilities"); + return std::make_pair(strings::kSiriusxmRadioAvailable, + capabilitiesStatus::missedParam); + } + if (!capabilities_status[strings::kSiriusxmRadioAvailable].asBool()) { + LOG4CXX_DEBUG(logger_, + "Capability " + << strings::kSiriusxmRadioAvailable + << " is switched off in RemoteControl capabilities"); + return std::make_pair(strings::kSiriusxmRadioAvailable, + capabilitiesStatus::missedParam); + } + } + return std::make_pair("", capabilitiesStatus::success); +} + +const smart_objects::SmartObject& RCCapabilitiesManagerImpl::ControlDataForType( + const smart_objects::SmartObject& module_data, + const std::string& module_type) const { + const auto& all_module_types = RCHelpers::GetModuleTypesList(); + const auto& data_mapping = RCHelpers::GetModuleTypeToDataMapping(); + for (const auto& type : all_module_types) { + if (type == module_type) { + return module_data[data_mapping(type)]; + } + } + NOTREACHED(); + return module_data[0]; +} + +bool RCCapabilitiesManagerImpl::CheckReadOnlyParamsForAudio( + const smart_objects::SmartObject& module_type_params) const { + if (module_type_params.keyExists(message_params::kEqualizerSettings)) { + const auto& equalizer_settings = + module_type_params[message_params::kEqualizerSettings]; + + for (auto& so : *(equalizer_settings.asArray())) { + if (so.keyExists(message_params::kChannelName)) { + LOG4CXX_DEBUG(logger_, + "READ ONLY parameter. ChannelName = " + << so[message_params::kChannelName].asString()); + return true; + } + } + } + + return false; +} + +bool RCCapabilitiesManagerImpl::CheckReadOnlyParamsForLight( + const smart_objects::SmartObject& module_type_params) const { + if (module_type_params.keyExists(message_params::kLightState)) { + const auto& light_state = module_type_params[message_params::kLightState]; + + for (auto& light_data : *(light_state.asArray())) { + if (light_data.keyExists(message_params::kLightStatus)) { + const mobile_apis::LightStatus::eType light_status = + static_cast<mobile_apis::LightStatus::eType>( + light_data[message_params::kLightStatus].asUInt()); + + if (helpers::Compare<mobile_apis::LightStatus::eType, + helpers::EQ, + helpers::ONE>(light_status, + mobile_apis::LightStatus::RAMP_UP, + mobile_apis::LightStatus::RAMP_DOWN, + mobile_apis::LightStatus::UNKNOWN, + mobile_apis::LightStatus::INVALID)) { + LOG4CXX_DEBUG( + logger_, + "READ ONLY parameter. Status = " + << light_data[message_params::kLightStatus].asInt()); + return true; + } + } + } + } + + return false; +} + +bool RCCapabilitiesManagerImpl::AreReadOnlyParamsPresent( + const smart_objects::SmartObject& module_data, + const std::string& module_type, + ModuleTypeCapability& module_data_capabilities) const { + LOG4CXX_AUTO_TRACE(logger_); + const smart_objects::SmartObject& module_type_params = + ControlDataForType(module_data, module_type); + + if (enums_value::kAudio == module_type) { + return CheckReadOnlyParamsForAudio(module_type_params); + } + + if (enums_value::kLight == module_type) { + const bool result = CheckReadOnlyParamsForLight(module_type_params); + + if (result) { + module_data_capabilities = + std::make_pair(module_type, capabilitiesStatus::readOnly); + } + return result; + } + + const std::vector<std::string> ro_params = + RCHelpers::GetModuleReadOnlyParams(module_type); + auto it = module_type_params.map_begin(); + + for (; it != module_type_params.map_end(); ++it) { + if (helpers::in_range(ro_params, it->first)) { + return true; + } + } + return false; +} + +bool RCCapabilitiesManagerImpl::AreAllParamsReadOnly( + const smart_objects::SmartObject& module_data, + const std::string& module_type) const { + LOG4CXX_AUTO_TRACE(logger_); + const smart_objects::SmartObject& module_type_params = + ControlDataForType(module_data, module_type); + auto it = module_type_params.map_begin(); + std::vector<std::string> ro_params = + RCHelpers::GetModuleReadOnlyParams(module_type); + for (; it != module_type_params.map_end(); ++it) { + if (!helpers::in_range(ro_params, it->first)) { + return false; + } + } + + LOG4CXX_DEBUG(logger_, "All params are ReadOnly"); + return true; +} + +bool RCCapabilitiesManagerImpl::IsSeatLocationCapabilityProvided() const { + LOG4CXX_AUTO_TRACE(logger_); + auto seat_location_capability = hmi_capabilities_.seat_location_capability(); + if (!seat_location_capability || seat_location_capability->empty()) { + LOG4CXX_DEBUG(logger_, "Seat Location capability is not provided by HMI"); + return false; + } + + if (seat_location_capability->keyExists(strings::kRows) && + seat_location_capability->keyExists(strings::kCols) && + seat_location_capability->keyExists(strings::kLevels) && + seat_location_capability->keyExists(strings::kSeats)) { + const auto* seats = (*seat_location_capability)[strings::kSeats].asArray(); + if (!seats->empty()) { + return true; + } + } + + LOG4CXX_DEBUG( + logger_, + "Seat Location capability doesn't contain all necessary parameters"); + return false; +} + +const Grid +RCCapabilitiesManagerImpl::GetDriverLocationFromSeatLocationCapability() const { + LOG4CXX_AUTO_TRACE(logger_); + Grid grid; + if (IsSeatLocationCapabilityProvided()) { + auto seat_location_capability = + hmi_capabilities_.seat_location_capability(); + const auto* seats = (*seat_location_capability)[strings::kSeats].asArray(); + const auto& driver_seat = (*seats)[0]; + if (driver_seat.keyExists(strings::kGrid)) { + const auto& driver_location = driver_seat[strings::kGrid]; + grid = Grid(driver_location[strings::kCol].asInt(), + driver_location[strings::kRow].asInt(), + driver_location[strings::kLevel].asInt(), + driver_location[strings::kColspan].asInt(), + driver_location[strings::kRowspan].asInt(), + driver_location[strings::kLevelspan].asInt()); + } else { + LOG4CXX_DEBUG(logger_, "Driver's location doesn't provided"); + } + } + return grid; +} + +Grid RCCapabilitiesManagerImpl::GetWholeVehicleArea() const { + auto seat_location_capability = + *(hmi_capabilities_.seat_location_capability()); + int32_t colspan = seat_location_capability.keyExists(strings::kCols) + ? seat_location_capability[strings::kCols].asInt() + : 0; + + int32_t rowspan = seat_location_capability.keyExists(strings::kRows) + ? seat_location_capability[strings::kRows].asInt() + : 0; + + int32_t levelspan = seat_location_capability.keyExists(strings::kLevels) + ? seat_location_capability[strings::kLevels].asInt() + : 0; + return Grid(0, 0, 0, colspan, rowspan, levelspan); +} + +Grid RCCapabilitiesManagerImpl::GetModuleLocationFromControlCapability( + const smart_objects::SmartObject& control_capabilities) const { + if (control_capabilities[message_params::kModuleInfo].keyExists( + strings::kLocation)) { + const auto& location = + control_capabilities[message_params::kModuleInfo][strings::kLocation]; + + return Grid(location[strings::kCol].asInt(), + location[strings::kRow].asInt(), + location[strings::kLevel].asInt(), + location[strings::kColspan].asInt(), + location[strings::kRowspan].asInt(), + location[strings::kLevelspan].asInt()); + } + return GetWholeVehicleArea(); +} + +Grid RCCapabilitiesManagerImpl::GetModuleServiceAreaFromControlCapability( + const smart_objects::SmartObject& control_capabilities) const { + if (control_capabilities.keyExists(message_params::kModuleInfo)) { + if (control_capabilities[message_params::kModuleInfo].keyExists( + strings::kServiceArea)) { + const auto& serviceArea = + control_capabilities[message_params::kModuleInfo] + [strings::kServiceArea]; + + return Grid(serviceArea[strings::kCol].asInt(), + serviceArea[strings::kRow].asInt(), + serviceArea[strings::kLevel].asInt(), + serviceArea[strings::kColspan].asInt(), + serviceArea[strings::kRowspan].asInt(), + serviceArea[strings::kLevelspan].asInt()); + } + } + return GetModuleLocationFromControlCapability(control_capabilities); +} + +Grid RCCapabilitiesManagerImpl::GetModuleServiceArea( + const ModuleUid& module) const { + auto rc_capabilities = *(hmi_capabilities_.rc_capability()); + const auto& mapping = RCHelpers::GetModuleTypeToCapabilitiesMapping(); + const auto& module_type = module.first; + const auto& capabilities_key = mapping(module_type); + if (!rc_capabilities.keyExists(capabilities_key)) { + LOG4CXX_DEBUG(logger_, module_type << "control capabilities not present"); + return Grid(); + } + const auto& caps = rc_capabilities[capabilities_key]; + + if (strings::khmiSettingsControlCapabilities == capabilities_key || + strings::klightControlCapabilities == capabilities_key) { + return GetModuleServiceAreaFromControlCapability(caps); + } else { + const auto& capability_item = + GetCapabilitiesByModuleIdFromArray(caps, module.second); + return GetModuleServiceAreaFromControlCapability(capability_item); + } +} + +bool RCCapabilitiesManagerImpl::IsMultipleAccessAllowedInControlCaps( + const smart_objects::SmartObject& control_capabilities) const { + if (control_capabilities.keyExists(message_params::kModuleInfo) && + control_capabilities[message_params::kModuleInfo].keyExists( + strings::kAllowMultipleAccess)) { + return control_capabilities[message_params::kModuleInfo] + [strings::kAllowMultipleAccess] + .asBool(); + } + return true; +} + +bool RCCapabilitiesManagerImpl::IsMultipleAccessAllowed( + const ModuleUid& module) const { + auto rc_capabilities = *(hmi_capabilities_.rc_capability()); + const auto& mapping = RCHelpers::GetModuleTypeToCapabilitiesMapping(); + const auto& module_type = module.first; + const auto& capabilities_key = mapping(module_type); + if (!rc_capabilities.keyExists(capabilities_key)) { + LOG4CXX_DEBUG(logger_, module_type << "control capabilities not present"); + return false; + } + const auto& caps = rc_capabilities[capabilities_key]; + + if (strings::khmiSettingsControlCapabilities == capabilities_key || + strings::klightControlCapabilities == capabilities_key) { + return IsMultipleAccessAllowedInControlCaps(caps); + } else { + return IsMultipleAccessAllowedInControlCaps( + GetCapabilitiesByModuleIdFromArray(caps, module.second)); + } +} + +} // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_command_factory.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_command_factory.cc index 93c230dfc3..4ca2cf5182 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_command_factory.cc +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_command_factory.cc @@ -39,13 +39,19 @@ #include "rc_rpc_plugin/commands/hmi/rc_get_interior_vehicle_data_response.h" #include "rc_rpc_plugin/commands/hmi/rc_on_interior_vehicle_data_notification.h" #include "rc_rpc_plugin/commands/hmi/rc_on_remote_control_settings_notification.h" +#include "rc_rpc_plugin/commands/hmi/rc_set_global_properties_request.h" +#include "rc_rpc_plugin/commands/hmi/rc_set_global_properties_response.h" #include "rc_rpc_plugin/commands/hmi/rc_set_interior_vehicle_data_request.h" #include "rc_rpc_plugin/commands/hmi/rc_set_interior_vehicle_data_response.h" #include "rc_rpc_plugin/commands/mobile/button_press_request.h" #include "rc_rpc_plugin/commands/mobile/button_press_response.h" +#include "rc_rpc_plugin/commands/mobile/get_interior_vehicle_data_consent_request.h" +#include "rc_rpc_plugin/commands/mobile/get_interior_vehicle_data_consent_response.h" #include "rc_rpc_plugin/commands/mobile/get_interior_vehicle_data_request.h" #include "rc_rpc_plugin/commands/mobile/get_interior_vehicle_data_response.h" #include "rc_rpc_plugin/commands/mobile/on_interior_vehicle_data_notification.h" +#include "rc_rpc_plugin/commands/mobile/release_interior_vehicle_data_module_request.h" +#include "rc_rpc_plugin/commands/mobile/release_interior_vehicle_data_module_response.h" #include "rc_rpc_plugin/commands/mobile/set_interior_vehicle_data_request.h" #include "rc_rpc_plugin/commands/mobile/set_interior_vehicle_data_response.h" #include "rc_rpc_plugin/rc_command_factory.h" @@ -196,6 +202,20 @@ CommandCreator& RCCommandFactory::get_mobile_command_creator( : rc_factory .GetCreator<commands::SetInteriorVehicleDataResponse>(); } + case mobile_apis::FunctionID::ReleaseInteriorVehicleDataModuleID: { + return mobile_apis::messageType::request == message_type + ? rc_factory.GetCreator< + commands::ReleaseInteriorVehicleDataModuleRequest>() + : rc_factory.GetCreator< + commands::ReleaseInteriorVehicleDataModuleResponse>(); + } + case mobile_apis::FunctionID::GetInteriorVehicleDataConsentID: { + return mobile_apis::messageType::request == message_type + ? rc_factory.GetCreator< + commands::GetInteriorVehicleDataConsentRequest>() + : rc_factory.GetCreator< + commands::GetInteriorVehicleDataConsentResponse>(); + } default: {} } return rc_factory.GetCreator<RCInvalidCommand>(); @@ -287,6 +307,13 @@ CommandCreator& RCCommandFactory::get_hmi_creator_factory( return rc_factory .GetCreator<commands::RCOnRemoteControlSettingsNotification>(); } + case hmi_apis::FunctionID::RC_SetGlobalProperties: { + return hmi_apis::messageType::request == message_type + ? rc_factory + .GetCreator<commands::RCSetGlobalPropertiesRequest>() + : rc_factory + .GetCreator<commands::RCSetGlobalPropertiesResponse>(); + } default: { return rc_factory.GetCreator<RCInvalidCommand>(); } } } diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_consent_manager_impl.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_consent_manager_impl.cc new file mode 100644 index 0000000000..acaa6ce86c --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_consent_manager_impl.cc @@ -0,0 +1,388 @@ +/* + Copyright (c) 2019, Ford Motor Company + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following + disclaimer in the documentation and/or other materials provided with the + distribution. + + Neither the name of the Ford Motor Company nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ + +#include <algorithm> + +#include "application_manager/application_manager.h" +#include "application_manager/smart_object_keys.h" +#include "json/json.h" +#include "rc_rpc_plugin/rc_consent_manager_impl.h" +#include "rc_rpc_plugin/rc_module_constants.h" +#include "resumption/last_state.h" +#include "smart_objects/smart_object.h" +#include "utils/date_time.h" +#include "utils/logger.h" + +namespace rc_rpc_plugin { +namespace app_mngr = application_manager; + +CREATE_LOGGERPTR_GLOBAL(logger_, "RCConsentManager") + +RCConsentManagerImpl::RCConsentManagerImpl( + resumption::LastState& last_state, + application_manager::ApplicationManager& application_manager, + const uint32_t period_of_consent_expired) + : app_manager_(application_manager) + , last_state_(last_state) + , period_of_consent_expired_(period_of_consent_expired) {} + +void RCConsentManagerImpl::SaveModuleConsents( + const std::string& policy_app_id, + const std::string& mac_address, + const rc_rpc_types::ModuleIdConsentVector& module_consents) { + LOG4CXX_AUTO_TRACE(logger_); + + for (const auto& consent : module_consents) { + std::string module_type = consent.module_id.first; + + auto& app_module_consents = + GetModuleTypeConsentsOrAppend(policy_app_id, mac_address, module_type); + SaveAppModuleConsent(app_module_consents, consent); + } +} + +rc_rpc_types::ModuleConsent RCConsentManagerImpl::GetModuleConsent( + const std::string& app_id, + const std::string& mac_address, + const rc_rpc_types::ModuleUid& module_id) const { + sync_primitives::AutoLock autolock(module_consents_lock_); + + auto& module_consents = + GetModuleTypeConsentsOrAppend(app_id, mac_address, module_id.first); + if (module_consents.empty()) { + LOG4CXX_DEBUG( + logger_, + "For app: " << app_id << " module type doesn't have any consents"); + return rc_rpc_types::ModuleConsent::NOT_EXISTS; + } + + for (const auto& conset_item : module_consents) { + if (conset_item[message_params::kModuleId].asString() == module_id.second) { + return static_cast<rc_rpc_types::ModuleConsent>( + conset_item[message_params::kConsent].asUInt()); + } + } + + LOG4CXX_DEBUG(logger_, + "For app: " << app_id << " and module resource [" + << module_id.first << ":" << module_id.second + << "] consent is absent"); + + return rc_rpc_types::ModuleConsent::NOT_EXISTS; +} + +void RCConsentManagerImpl::RemoveExpiredConsents() { + LOG4CXX_AUTO_TRACE(logger_); + auto& remote_control = GetRemoteControlDataOrAppend(); + if (remote_control.empty()) { + return; + } + + auto& devices = GetAppsConsentsOrAppend(); + + sync_primitives::AutoLock autolock(device_applications_lock_); + + for (auto& device_item : devices) { + RemoveDeviceExpiredConsents(device_item); + } +} + +void RCConsentManagerImpl::RemoveAllConsents() { + auto& remote_control = GetRemoteControlDataOrAppend(); + remote_control.removeMember(message_params::kAppConsents); +} + +rc_rpc_types::ModuleConsentState RCConsentManagerImpl::CheckModuleConsentState( + const Json::Value& module_consent) const { + if (!module_consent.isMember(message_params::kConsentDate)) { + LOG4CXX_DEBUG(logger_, "Date of consent is absent"); + return rc_rpc_types::ModuleConsentState::NOT_EXISTS; + } + + const uint32_t period_for_expiring = + app_manager_.get_settings().period_for_consent_expiration(); + + const time_t consent_date = static_cast<time_t>( + module_consent[message_params::kConsentDate].asUInt()); + + const auto past_period_in_days = + date_time::calculateAmountDaysFromDate(consent_date); + + LOG4CXX_DEBUG( + logger_, + "Keeping time of consent is: " << past_period_in_days << " days"); + LOG4CXX_DEBUG(logger_, "Period for expired: " << period_for_expiring); + + return (past_period_in_days >= period_for_expiring) + ? rc_rpc_types::ModuleConsentState::EXPIRED + : rc_rpc_types::ModuleConsentState::ACTIVE; +} + +void RCConsentManagerImpl::RemoveDeviceExpiredConsents(Json::Value& device) { + sync_primitives::AutoLock autolock(applications_lock_); + + if (device.isMember(message_params::kApplications)) { + auto& applications = device[message_params::kApplications]; + + for (auto& app : applications) { + if (app.isMember(message_params::kAppConsentList)) { + RemoveAppExpiredConsents(app[message_params::kAppConsentList]); + } + } + } +} + +void RCConsentManagerImpl::RemoveAppExpiredConsents(Json::Value& app_consents) { + for (auto& module : app_consents) { + if (module.isMember(message_params::kModuleConsents)) { + auto& module_consents = module[message_params::kModuleConsents]; + RemoveModuleExpiredConsents(module_consents); + } + } +} + +void RCConsentManagerImpl::RemoveModuleExpiredConsents( + Json::Value& module_consents) { + sync_primitives::AutoLock autolock(module_consents_lock_); + Json::Value temp_consents; + + for (auto& consent : module_consents) { + const bool is_module_id_exists = + consent.isMember(message_params::kModuleId); + + const bool is_expired = rc_rpc_types::ModuleConsentState::EXPIRED == + CheckModuleConsentState(consent); + if (is_expired) { + LOG4CXX_DEBUG(logger_, + "Consent for module resource [" + << consent[message_params::kModuleId].asString() + << "] is expired and will be removed"); + } + + if (is_module_id_exists && !is_expired) { + LOG4CXX_DEBUG(logger_, + "Consent for module resource [" + << consent[message_params::kModuleId].asString() + << "] is actual."); + temp_consents.append(consent); + } + } + + module_consents.clear(); + if (!temp_consents.empty()) { + std::swap(module_consents, temp_consents); + } +} + +Json::Value& RCConsentManagerImpl::GetRemoteControlDataOrAppend() const { + Json::Value& dictionary = last_state_.get_dictionary(); + + sync_primitives::AutoLock autolock(dictionary_control_lock_); + if (!dictionary.isMember(app_mngr::strings::remote_control)) { + dictionary[app_mngr::strings::remote_control] = + Json::Value(Json::objectValue); + LOG4CXX_DEBUG(logger_, "remote_control section is missed"); + } + + Json::Value& remote_control = dictionary[app_mngr::strings::remote_control]; + + if (!remote_control.isObject()) { + LOG4CXX_ERROR(logger_, "remote_control type INVALID rewrite"); + remote_control = Json::Value(Json::objectValue); + } + return remote_control; +} + +Json::Value& RCConsentManagerImpl::GetDeviceApplicationsOrAppend( + const std::string& mac_address) const { + sync_primitives::AutoLock autolock(device_applications_lock_); + + auto& apps_consents = GetAppsConsentsOrAppend(); + + if (!apps_consents.isArray()) { + LOG4CXX_DEBUG(logger_, "applications_consents type INVALID rewrite"); + apps_consents = Json::Value(Json::arrayValue); + } + + for (auto& device_applications_item : apps_consents) { + const bool is_device_section_exists = + device_applications_item.isMember(message_params::kMacAddress); + + if (is_device_section_exists) { + auto saved_mac_adress = + device_applications_item[message_params::kMacAddress].asString(); + + if (saved_mac_adress == mac_address) { + return device_applications_item[message_params::kApplications]; + } + } + } + + auto device_applications = Json::Value(Json::objectValue); + device_applications[message_params::kMacAddress] = Json::Value(mac_address); + device_applications[message_params::kApplications] = + Json::Value(Json::arrayValue); + + apps_consents.append(device_applications); + return apps_consents[apps_consents.size() - 1][message_params::kApplications]; +} + +Json::Value& RCConsentManagerImpl::GetAppConsentsListOrAppend( + const std::string& policy_app_id, const std::string& mac_address) const { + auto& device_applications = GetDeviceApplicationsOrAppend(mac_address); + + sync_primitives::AutoLock autolock(applications_lock_); + if (!device_applications.isArray()) { + LOG4CXX_DEBUG(logger_, "applications_consents type INVALID rewrite"); + device_applications = Json::Value(Json::arrayValue); + } + + for (auto& application : device_applications) { + const bool is_app_id_section_exists = + application.isMember(message_params::kAppId); + + if (is_app_id_section_exists) { + auto saved_app_id = application[message_params::kAppId].asString(); + + if (saved_app_id == policy_app_id) { + return application[message_params::kAppConsentList]; + } + } + } + + // In case when specified application section is absent in json file, + // will be created new section and added to dictionary. + auto application = Json::Value(Json::objectValue); + application[message_params::kAppId] = Json::Value(policy_app_id); + application[message_params::kAppConsentList] = Json::Value(Json::arrayValue); + device_applications.append(application); + + // Returns last appended object + return device_applications[device_applications.size() - 1] + [message_params::kAppConsentList]; +} + +Json::Value& RCConsentManagerImpl::GetAppsConsentsOrAppend() const { + Json::Value& remote_control = GetRemoteControlDataOrAppend(); + sync_primitives::AutoLock autolock(remote_control_lock_); + + if (!remote_control.isMember(message_params::kAppConsents)) { + LOG4CXX_DEBUG(logger_, "app_consents section is missed"); + remote_control[message_params::kAppConsents] = + Json::Value(Json::arrayValue); + } + + auto& app_consents = remote_control[message_params::kAppConsents]; + if (!app_consents.isArray()) { + LOG4CXX_DEBUG(logger_, "applications_consents type INVALID rewrite"); + app_consents = Json::Value(Json::arrayValue); + } + return app_consents; +} + +Json::Value& RCConsentManagerImpl::GetModuleTypeConsentsOrAppend( + const std::string& policy_app_id, + const std::string& mac_address, + const std::string& module_type) const { + auto& app_consnets_list = + GetAppConsentsListOrAppend(policy_app_id, mac_address); + + sync_primitives::AutoLock autolock(app_consents_lock_); + for (auto& module_consents : app_consnets_list) { + const bool module_exists = + module_consents.isMember(message_params::kModuleType); + + if (module_exists && + (module_consents[message_params::kModuleType].asString() == + module_type)) { + return module_consents[message_params::kModuleConsents]; + } + } + + // In case of absent specified module_type in section of specified + // application, will be added empty section with this module type. + LOG4CXX_DEBUG( + logger_, + "Section module_type: " << module_type + << " is missed for app_id:" << policy_app_id); + auto consent_item = Json::Value(Json::objectValue); + consent_item[message_params::kModuleType] = module_type; + consent_item[message_params::kModuleConsents] = Json::Value(Json::arrayValue); + + app_consnets_list.append(consent_item); + + // Returns last (appended) object + return app_consnets_list[app_consnets_list.size() - 1] + [message_params::kModuleConsents]; +} + +RCConsentManagerImpl::~RCConsentManagerImpl() {} + +void RCConsentManagerImpl::SaveAppModuleConsent( + Json::Value& app_module_consents, + const rc_rpc_types::ModuleIdConsent& consent_to_save) { + bool is_found = false; + + sync_primitives::AutoLock autolock(app_consents_lock_); + for (auto& consent : app_module_consents) { + const bool is_module_id_exists = + consent.isMember(message_params::kModuleId); + + // In case existing consent of specified ModuelResource (module_type + + // module_id), old value will be rewritten by new value. + + if (is_module_id_exists && (consent[message_params::kModuleId].asString() == + consent_to_save.module_id.second)) { + is_found = true; + consent[message_params::kConsent] = + Json::Value(static_cast<uint32_t>(consent_to_save.consent)); + consent[message_params::kConsentDate] = Json::Value( + static_cast<Json::UInt64>(consent_to_save.date_of_consent)); + } + } + + // Otherwise, new item will be added to the "consents" collection + + if (!is_found) { + auto new_consent = Json::Value(Json::objectValue); + new_consent[message_params::kModuleId] = + Json::Value(consent_to_save.module_id.second); + new_consent[message_params::kConsent] = + Json::Value(static_cast<uint32_t>(consent_to_save.consent)); + new_consent[message_params::kConsentDate] = + Json::Value(static_cast<Json::UInt64>(consent_to_save.date_of_consent)); + + app_module_consents.append(new_consent); + } +} + +} // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_helpers.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_helpers.cc index 5785e58e5b..e9e6620e25 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_helpers.cc +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_helpers.cc @@ -8,6 +8,124 @@ namespace rc_rpc_plugin { CREATE_LOGGERPTR_GLOBAL(logger_, "RemoteControlModule"); +const std::vector<std::string> RCHelpers::buttons_climate() { + std::vector<std::string> data; + data.push_back(enums_value::kACMax); + data.push_back(enums_value::kAC); + data.push_back(enums_value::kRecirculate); + data.push_back(enums_value::kFanUp); + data.push_back(enums_value::kFanDown); + data.push_back(enums_value::kTempUp); + data.push_back(enums_value::kTempDown); + data.push_back(enums_value::kDefrostMax); + data.push_back(enums_value::kDefrost); + data.push_back(enums_value::kDefrostRear); + data.push_back(enums_value::kUpperVent); + data.push_back(enums_value::kLowerVent); + return data; +} + +const std::vector<std::string> RCHelpers::buttons_radio() { + std::vector<std::string> data; + data.push_back(enums_value::kVolumeUp); + data.push_back(enums_value::kVolumeDown); + data.push_back(enums_value::kEject); + data.push_back(enums_value::kSource); + data.push_back(enums_value::kShuffle); + data.push_back(enums_value::kRepeat); + return data; +} + +const RCHelpers::ButtonsMap RCHelpers::buttons_map() { + using namespace mobile_apis; + + ButtonsMap buttons_map; + buttons_map[enums_value::kACMax] = ButtonName::AC_MAX; + buttons_map[enums_value::kAC] = ButtonName::AC; + buttons_map[enums_value::kRecirculate] = ButtonName::RECIRCULATE; + buttons_map[enums_value::kFanUp] = ButtonName::FAN_UP; + buttons_map[enums_value::kFanDown] = ButtonName::FAN_DOWN; + buttons_map[enums_value::kTempUp] = ButtonName::TEMP_UP; + buttons_map[enums_value::kTempDown] = ButtonName::TEMP_DOWN; + buttons_map[enums_value::kDefrostMax] = ButtonName::DEFROST_MAX; + buttons_map[enums_value::kDefrost] = ButtonName::DEFROST; + buttons_map[enums_value::kDefrostRear] = ButtonName::DEFROST_REAR; + buttons_map[enums_value::kUpperVent] = ButtonName::UPPER_VENT; + buttons_map[enums_value::kLowerVent] = ButtonName::LOWER_VENT; + buttons_map[enums_value::kVolumeUp] = ButtonName::VOLUME_UP; + buttons_map[enums_value::kVolumeDown] = ButtonName::VOLUME_DOWN; + buttons_map[enums_value::kEject] = ButtonName::EJECT; + buttons_map[enums_value::kSource] = ButtonName::SOURCE; + buttons_map[enums_value::kShuffle] = ButtonName::SHUFFLE; + buttons_map[enums_value::kRepeat] = ButtonName::REPEAT; + + return buttons_map; +} + +std::vector<std::string> RCHelpers::GetModuleReadOnlyParams( + const std::string& module_type) { + using namespace message_params; + std::vector<std::string> module_ro_params; + if (enums_value::kClimate == module_type) { + module_ro_params.push_back(kCurrentTemperature); + } else if (enums_value::kRadio == module_type) { + module_ro_params.push_back(kRdsData); + module_ro_params.push_back(kAvailableHDs); + module_ro_params.push_back(kAvailableHdChannels); + module_ro_params.push_back(kSignalStrength); + module_ro_params.push_back(kSignalChangeThreshold); + module_ro_params.push_back(kState); + module_ro_params.push_back(kSisData); + } else if (enums_value::kLight == module_type) { + module_ro_params.push_back(kLightStatus); + } + + return module_ro_params; +} + +rc_rpc_types::ModuleIdConsentVector RCHelpers::FillModuleConsents( + const std::string& module_type, + const std::vector<std::string>& module_ids, + const std::vector<bool> allowed) { + using namespace rc_rpc_types; + if (module_ids.size() != allowed.size()) { + return rc_rpc_types::ModuleIdConsentVector(); + } + + rc_rpc_types::ModuleIdConsentVector module_consents; + std::time_t current_date = std::time(0); + size_t array_size = module_ids.size(); + + for (size_t i = 0; i < array_size; ++i) { + rc_rpc_types::ModuleIdConsent module_consent; + module_consent.module_id = {module_type, module_ids[i]}; + module_consent.consent = + allowed[i] ? ModuleConsent::CONSENTED : ModuleConsent::NOT_CONSENTED; + module_consent.date_of_consent = current_date; + + module_consents.push_back(module_consent); + } + return module_consents; +} + +std::vector<std::string> RCHelpers::RetrieveModuleIds( + const ns_smart_device_link::ns_smart_objects::SmartObject& moduleIds) { + std::vector<std::string> module_ids; + for (const auto& module_id : (*moduleIds.asArray())) { + module_ids.push_back(module_id.asString()); + } + return module_ids; +} + +std::vector<bool> RCHelpers::RetrieveModuleConsents( + const ns_smart_device_link::ns_smart_objects::SmartObject& consents) { + std::vector<bool> module_consents; + for (const auto& allowed_item : (*consents.asArray())) { + module_consents.push_back(allowed_item.asBool()); + } + return module_consents; +} + const std::function<std::string(const std::string& module_type)> RCHelpers::GetModuleTypeToDataMapping() { auto mapping_lambda = [](const std::string& module_type) -> std::string { @@ -50,7 +168,7 @@ RCHelpers::GetModuleTypeToCapabilitiesMapping() { return mapping_lambda; } -const std::vector<std::string> RCHelpers::GetModulesList() { +const std::vector<std::string> RCHelpers::GetModuleTypesList() { using namespace enums_value; return {kClimate, kRadio, kSeat, kAudio, kLight, kHmiSettings}; } @@ -64,7 +182,7 @@ RCAppExtensionPtr RCHelpers::GetRCExtension( } smart_objects::SmartObjectSPtr RCHelpers::CreateUnsubscribeRequestToHMI( - const std::string& module_type, const uint32_t correlation_id) { + const ModuleUid& module, const uint32_t correlation_id) { using namespace smart_objects; namespace commands = application_manager::commands; namespace am_strings = application_manager::strings; @@ -82,11 +200,28 @@ smart_objects::SmartObjectSPtr RCHelpers::CreateUnsubscribeRequestToHMI( params[am_strings::function_id] = hmi_apis::FunctionID::RC_GetInteriorVehicleData; msg_params[message_params::kSubscribe] = false; - msg_params[message_params::kModuleType] = module_type; + msg_params[message_params::kModuleType] = module.first; + msg_params[message_params::kModuleId] = module.second; return message; } std::vector<application_manager::ApplicationSharedPtr> +RCHelpers::AppsSubscribedToModule( + application_manager::ApplicationManager& app_mngr, + const ModuleUid& module) { + std::vector<application_manager::ApplicationSharedPtr> result; + auto rc_apps = RCRPCPlugin::GetRCApplications(app_mngr); + for (auto& app : rc_apps) { + auto rc_ext = RCHelpers::GetRCExtension(*app); + DCHECK_OR_RETURN(rc_ext, result); + if (rc_ext->IsSubscribedToInteriorVehicleData(module)) { + result.push_back(app); + } + } + return result; +} + +std::vector<application_manager::ApplicationSharedPtr> RCHelpers::AppsSubscribedToModuleType( application_manager::ApplicationManager& app_mngr, const std::string& module_type) { @@ -95,17 +230,17 @@ RCHelpers::AppsSubscribedToModuleType( for (auto& app : rc_apps) { auto rc_ext = RCHelpers::GetRCExtension(*app); DCHECK_OR_RETURN(rc_ext, result); - if (rc_ext->IsSubscibedToInteriorVehicleData(module_type)) { + if (rc_ext->IsSubscribedToInteriorVehicleDataOfType(module_type)) { result.push_back(app); } } return result; } -RCHelpers::AppsModules RCHelpers::GetApplicationsAllowedModules( +RCHelpers::AppsModuleTypes RCHelpers::GetApplicationsAllowedModuleTypes( app_mngr::ApplicationManager& app_mngr) { auto apps_list = RCRPCPlugin::GetRCApplications(app_mngr); - RCHelpers::AppsModules result; + RCHelpers::AppsModuleTypes result; for (auto& app_ptr : apps_list) { std::vector<std::string> allowed_modules; app_mngr.GetPolicyHandler().GetModuleTypes(app_ptr->policy_app_id(), diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_rpc_plugin.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_rpc_plugin.cc index 0c4a5a4e53..ed6b863e20 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_rpc_plugin.cc +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_rpc_plugin.cc @@ -35,7 +35,9 @@ #include "rc_rpc_plugin/interior_data_cache_impl.h" #include "rc_rpc_plugin/interior_data_manager_impl.h" #include "rc_rpc_plugin/rc_app_extension.h" +#include "rc_rpc_plugin/rc_capabilities_manager_impl.h" #include "rc_rpc_plugin/rc_command_factory.h" +#include "rc_rpc_plugin/rc_consent_manager_impl.h" #include "rc_rpc_plugin/rc_helpers.h" #include "rc_rpc_plugin/resource_allocation_manager_impl.h" #include "utils/helpers.h" @@ -49,23 +51,35 @@ bool RCRPCPlugin::Init( application_manager::ApplicationManager& app_manager, application_manager::rpc_service::RPCService& rpc_service, application_manager::HMICapabilities& hmi_capabilities, - policy::PolicyHandlerInterface& policy_handler) { + policy::PolicyHandlerInterface& policy_handler, + resumption::LastState& last_state) { + rc_consent_manager_.reset(new rc_rpc_plugin::RCConsentManagerImpl( + last_state, + app_manager, + app_manager.get_settings().period_for_consent_expiration())); interior_data_cache_.reset(new InteriorDataCacheImpl()); interior_data_manager_.reset(new InteriorDataManagerImpl( *this, *interior_data_cache_, app_manager, rpc_service)); - - resource_allocation_manager_.reset( - new ResourceAllocationManagerImpl(app_manager, rpc_service)); + rc_capabilities_manager_.reset( + new RCCapabilitiesManagerImpl(hmi_capabilities)); + resource_allocation_manager_.reset(new ResourceAllocationManagerImpl( + app_manager, rpc_service, *(rc_capabilities_manager_.get()))); RCCommandParams params{app_manager, rpc_service, hmi_capabilities, policy_handler, *(resource_allocation_manager_.get()), *(interior_data_cache_.get()), - *(interior_data_manager_.get())}; + *(interior_data_manager_.get()), + *(rc_capabilities_manager_.get()), + *(rc_consent_manager_.get())}; command_factory_.reset(new rc_rpc_plugin::RCCommandFactory(params)); rpc_service_ = &rpc_service; app_mngr_ = &app_manager; + + // Check all saved consents and remove expired + rc_consent_manager_->RemoveExpiredConsents(); + return true; } @@ -98,8 +112,13 @@ void RCRPCPlugin::OnApplicationEvent( } switch (event) { case plugins::kApplicationRegistered: { - application->AddExtension( - std::shared_ptr<RCAppExtension>(new RCAppExtension(kRCPluginID))); + auto extension = + std::shared_ptr<RCAppExtension>(new RCAppExtension(kRCPluginID)); + application->AddExtension(extension); + const auto driver_location = + rc_capabilities_manager_ + ->GetDriverLocationFromSeatLocationCapability(); + extension->SetUserLocation(driver_location); resource_allocation_manager_->SendOnRCStatusNotifications( NotificationTrigger::APP_REGISTRATION, application); break; @@ -114,6 +133,12 @@ void RCRPCPlugin::OnApplicationEvent( interior_data_manager_->OnApplicationEvent(event, application); break; } + case plugins::kGlobalPropertiesUpdated: { + const auto user_location = application->get_user_location(); + auto extension = RCHelpers::GetRCExtension(*application); + extension->SetUserLocation(user_location); + break; + } default: break; } diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/resource_allocation_manager_impl.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/resource_allocation_manager_impl.cc index 0a512b2839..97ff2b23da 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/resource_allocation_manager_impl.cc +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/resource_allocation_manager_impl.cc @@ -49,16 +49,20 @@ CREATE_LOGGERPTR_GLOBAL(logger_, "RemoteControlModule") ResourceAllocationManagerImpl::ResourceAllocationManagerImpl( application_manager::ApplicationManager& app_mngr, - application_manager::rpc_service::RPCService& rpc_service) + application_manager::rpc_service::RPCService& rpc_service, + RCCapabilitiesManager& rc_capabilities_manager) : current_access_mode_(hmi_apis::Common_RCAccessMode::AUTO_ALLOW) , app_mngr_(app_mngr) , rpc_service_(rpc_service) + , rc_capabilities_manager_(rc_capabilities_manager) , is_rc_enabled_(true) {} ResourceAllocationManagerImpl::~ResourceAllocationManagerImpl() {} AcquireResult::eType ResourceAllocationManagerImpl::AcquireResource( - const std::string& module_type, const uint32_t app_id) { + const std::string& module_type, + const std::string& module_id, + const uint32_t app_id) { LOG4CXX_AUTO_TRACE(logger_); const application_manager::ApplicationSharedPtr acquiring_app = app_mngr_.application(app_id); @@ -67,29 +71,38 @@ AcquireResult::eType ResourceAllocationManagerImpl::AcquireResource( return AcquireResult::IN_USE; } + ModuleUid module(module_type, module_id); + + if (rc_capabilities_manager_.IsSeatLocationCapabilityProvided() && + !IsUserLocationValid(module, acquiring_app)) { + LOG4CXX_WARN(logger_, + "Resource acquisition is not allowed " + "according to location verification."); + return AcquireResult::REJECTED; + } + sync_primitives::AutoLock lock(allocated_resources_lock_); const AllocatedResources::const_iterator allocated_it = - allocated_resources_.find(module_type); + allocated_resources_.find(module); if (allocated_resources_.end() == allocated_it) { - SetResourceAquired(module_type, app_id); LOG4CXX_DEBUG(logger_, "Resource is not acquired yet. " << "App: " << app_id << " is allowed to acquire " - << module_type); + << module_type << " " << module_id); return AcquireResult::ALLOWED; } - if (app_id == allocated_resources_[module_type]) { - LOG4CXX_DEBUG( - logger_, - "App: " << app_id << " is already acquired resource " << module_type); + if (app_id == allocated_resources_[module]) { + LOG4CXX_DEBUG(logger_, + "App: " << app_id << " is already acquired resource " + << module_type << " " << module_id); return AcquireResult::ALLOWED; } - if (IsModuleTypeRejected(module_type, app_id)) { - LOG4CXX_DEBUG( - logger_, - "Driver disallowed app: " << app_id << " to acquire " << module_type); + if (IsModuleTypeRejected(module_type, module_id, app_id)) { + LOG4CXX_DEBUG(logger_, + "Driver disallowed app: " << app_id << " to acquire " + << module_type << " " << module_id); return AcquireResult::REJECTED; } @@ -100,7 +113,15 @@ AcquireResult::eType ResourceAllocationManagerImpl::AcquireResource( LOG4CXX_DEBUG(logger_, "Aquiring resources is not allowed in HMI level: " << acquiring_app_hmi_level << ". App: " << app_id - << " is disallowed to acquire " << module_type); + << " is disallowed to acquire " << module_type << " " + << module_id); + return AcquireResult::REJECTED; + } + + if (!rc_capabilities_manager_.IsMultipleAccessAllowed(module)) { + LOG4CXX_DEBUG(logger_, + "Multiple access for the: " << module_type << " " << module_id + << " isn't allowed"); return AcquireResult::REJECTED; } @@ -109,34 +130,57 @@ AcquireResult::eType ResourceAllocationManagerImpl::AcquireResource( LOG4CXX_DEBUG(logger_, "Current access_mode is AUTO_DENY. " << "App: " << app_id << " is disallowed to acquire " - << module_type); + << module_type << " " << module_id); return AcquireResult::IN_USE; } case hmi_apis::Common_RCAccessMode::ASK_DRIVER: { LOG4CXX_DEBUG(logger_, "Current access_mode is ASK_DRIVER. " "Driver confirmation is required for app: " - << app_id << " to acquire " << module_type); + << app_id << " to acquire " << module_type << " " + << module_id); return AcquireResult::ASK_DRIVER; } case hmi_apis::Common_RCAccessMode::AUTO_ALLOW: { LOG4CXX_DEBUG(logger_, "Current access_mode is AUTO_ALLOW. " << "App: " << app_id << " is allowed to acquire " - << module_type); - - SetResourceAquired(module_type, app_id); + << module_type << " " << module_id); return AcquireResult::ALLOWED; } default: { DCHECK_OR_RETURN(false, AcquireResult::IN_USE); } } } -void ResourceAllocationManagerImpl::ReleaseResource( +bool ResourceAllocationManagerImpl::IsUserLocationValid( + ModuleUid& module, application_manager::ApplicationSharedPtr app) { + LOG4CXX_AUTO_TRACE(logger_); + const auto extension = RCHelpers::GetRCExtension(*app); + const auto user_location = extension->GetUserLocation(); + const auto module_service_area = + rc_capabilities_manager_.GetModuleServiceArea(module); + const auto driver = + rc_capabilities_manager_.GetDriverLocationFromSeatLocationCapability(); + const bool is_driver = user_location == driver; + if (is_driver || user_location.IntersectionExists(module_service_area)) { + return true; + } + LOG4CXX_DEBUG(logger_, "User location is not valid"); + return false; +} + +void ResourceAllocationManagerImpl::ReleaseModuleType( const std::string& module_type, const uint32_t application_id) { LOG4CXX_AUTO_TRACE(logger_); - LOG4CXX_DEBUG(logger_, "Release " << module_type << " by " << application_id); - SetResourceFree(module_type, application_id); + LOG4CXX_DEBUG(logger_, + "Release " << module_type << " " + << " by " << application_id); + Resources allocated_resources = GetAcquiredResources(application_id); + for (const auto& resource : allocated_resources) { + if (module_type == resource.first) { + SetResourceFree(module_type, resource.second, application_id); + } + } } void ResourceAllocationManagerImpl::ProcessApplicationPolicyUpdate() { @@ -147,10 +191,10 @@ void ResourceAllocationManagerImpl::ProcessApplicationPolicyUpdate() { for (; app_list.end() != app; ++app) { application_manager::ApplicationSharedPtr app_ptr = *app; const uint32_t application_id = app_ptr->app_id(); - Resources acquired_modules = GetAcquiredResources(application_id); - std::sort(acquired_modules.begin(), acquired_modules.end()); + std::set<std::string> acquired_modules = + GetAcquiredModuleTypes(application_id); - Resources allowed_modules; + std::vector<std::string> allowed_modules; app_mngr_.GetPolicyHandler().GetModuleTypes((*app)->policy_app_id(), &allowed_modules); std::sort(allowed_modules.begin(), allowed_modules.end()); @@ -160,17 +204,16 @@ void ResourceAllocationManagerImpl::ProcessApplicationPolicyUpdate() { << " , allowed modules: " << allowed_modules.size()); - Resources disallowed_modules; + std::vector<std::string> disallowed_modules; std::set_difference(acquired_modules.begin(), acquired_modules.end(), allowed_modules.begin(), allowed_modules.end(), std::back_inserter(disallowed_modules)); - auto rc_extention = RCHelpers::GetRCExtension(**app); - Resources::const_iterator module = disallowed_modules.begin(); + auto module = disallowed_modules.begin(); for (; disallowed_modules.end() != module; ++module) { - ReleaseResource(*module, application_id); + ReleaseModuleType(*module, application_id); } if (!disallowed_modules.empty()) { SendOnRCStatusNotifications( @@ -190,8 +233,8 @@ EnumType StringToEnum(const std::string& str) { void ConstructOnRCStatusNotificationParams( smart_objects::SmartObject& msg_params, - const std::map<std::string, uint32_t>& allocated_resources, - const std::vector<std::string>& supported_resources, + const std::map<ModuleUid, uint32_t>& allocated_resources, + const std::vector<ModuleUid>& supported_resources, const uint32_t app_id) { namespace strings = application_manager::strings; namespace message_params = rc_rpc_plugin::message_params; @@ -201,12 +244,13 @@ void ConstructOnRCStatusNotificationParams( LOG4CXX_AUTO_TRACE(logger_); auto modules_inserter = [](SmartObject& result_modules) { - return [&result_modules](const std::string& module_name) { + return [&result_modules](const ModuleUid& module) { smart_objects::SmartObject module_data = SmartObject(smart_objects::SmartType_Map); auto module_type = - StringToEnum<mobile_apis::ModuleType::eType>(module_name); + StringToEnum<mobile_apis::ModuleType::eType>(module.first); module_data[message_params::kModuleType] = module_type; + module_data[message_params::kModuleId] = module.second; result_modules.asArray()->push_back(module_data); }; }; @@ -236,10 +280,11 @@ ResourceAllocationManagerImpl::CreateOnRCStatusNotificationToMobile( mobile_apis::FunctionID::OnRCStatusID, app->app_id()); auto& msg_params = (*msg_to_mobile)[application_manager::strings::msg_params]; if (is_rc_enabled()) { - ConstructOnRCStatusNotificationParams(msg_params, - allocated_resources_, - RCHelpers::GetModulesList(), - app->app_id()); + ConstructOnRCStatusNotificationParams( + msg_params, + allocated_resources_, + rc_capabilities_manager_.GetResources(), + app->app_id()); } else { msg_params[message_params::kAllocatedModules] = smart_objects::SmartObject(smart_objects::SmartType_Array); @@ -259,21 +304,12 @@ ResourceAllocationManagerImpl::CreateOnRCStatusNotificationToHmi( auto& msg_params = (*msg_to_hmi)[application_manager::strings::msg_params]; ConstructOnRCStatusNotificationParams(msg_params, allocated_resources_, - RCHelpers::GetModulesList(), + rc_capabilities_manager_.GetResources(), app->app_id()); msg_params[application_manager::strings::app_id] = app->hmi_app_id(); return msg_to_hmi; } -void ResourceAllocationManagerImpl::SetResourceAquired( - const std::string& module_type, const uint32_t app_id) { - LOG4CXX_AUTO_TRACE(logger_); - allocated_resources_[module_type] = app_id; - SendOnRCStatusNotifications( - NotificationTrigger::MODULE_ALLOCATION, - std::shared_ptr<application_manager::Application>()); -} - void ResourceAllocationManagerImpl::SendOnRCStatusNotifications( NotificationTrigger::eType event, application_manager::ApplicationSharedPtr application) { @@ -310,25 +346,81 @@ void ResourceAllocationManagerImpl::set_rc_enabled(const bool value) { std::shared_ptr<application_manager::Application>()); } -void ResourceAllocationManagerImpl::SetResourceFree( - const std::string& module_type, const uint32_t app_id) { +ResourceReleasedState::eType ResourceAllocationManagerImpl::ReleaseResource( + const std::string& module_type, + const std::string& module_id, + const uint32_t application_id) { + LOG4CXX_AUTO_TRACE(logger_); + LOG4CXX_DEBUG(logger_, + "Release " << module_type << " " << module_id << " by " + << application_id); + return SetResourceFree(module_type, module_id, application_id); +} + +void ResourceAllocationManagerImpl::SetResourceAcquired( + const std::string& module_type, + const std::string& module_id, + const uint32_t app_id) { + LOG4CXX_AUTO_TRACE(logger_); + ModuleUid module(module_type, module_id); + allocated_resources_[module] = app_id; +} + +bool ResourceAllocationManagerImpl::IsResourceAlreadyAcquiredByApp( + const ModuleUid& moduleUid, const uint32_t app_id) const { + LOG4CXX_AUTO_TRACE(logger_); + + auto allocation = allocated_resources_.find(moduleUid); + + if (allocated_resources_.end() == allocation) { + LOG4CXX_DEBUG(logger_, + "Resource " << moduleUid.first + << " is not allocated for any application."); + return false; + } + + if (allocation->second != app_id) { + LOG4CXX_DEBUG(logger_, + "Resource " + << moduleUid.first + << " is already allocated by app:" << allocation->second + << ". Asquire has been asked for app:" << app_id); + return false; + } + + LOG4CXX_DEBUG(logger_, + "Resource " << moduleUid.first + << " is allocated by app:" << allocation->second); + + return true; +} + +ResourceReleasedState::eType ResourceAllocationManagerImpl::SetResourceFree( + const std::string& module_type, + const std::string& module_id, + const uint32_t app_id) { + ModuleUid module(module_type, module_id); AllocatedResources::const_iterator allocation = - allocated_resources_.find(module_type); + allocated_resources_.find(module); if (allocated_resources_.end() == allocation) { LOG4CXX_DEBUG(logger_, "Resource " << module_type << " is not allocated."); - return; + return ResourceReleasedState::NOT_ALLOCATED; } if (app_id != allocation->second) { LOG4CXX_ERROR(logger_, "Resource " << module_type << " is allocated by different application " << allocation->second); + return ResourceReleasedState::IS_ALLOCATED; } allocated_resources_.erase(allocation); - LOG4CXX_DEBUG(logger_, "Resource " << module_type << " is released."); + LOG4CXX_DEBUG( + logger_, + "Resource " << module_type << ":" << module_id << " is released."); + return ResourceReleasedState::IS_RELEASED; } -std::vector<std::string> ResourceAllocationManagerImpl::GetAcquiredResources( +std::vector<ModuleUid> ResourceAllocationManagerImpl::GetAcquiredResources( const uint32_t application_id) const { LOG4CXX_AUTO_TRACE(logger_); Resources allocated_resources; @@ -347,18 +439,37 @@ std::vector<std::string> ResourceAllocationManagerImpl::GetAcquiredResources( return allocated_resources; } +std::set<std::string> ResourceAllocationManagerImpl::GetAcquiredModuleTypes( + const uint32_t application_id) const { + LOG4CXX_AUTO_TRACE(logger_); + Resources allocated_resources = GetAcquiredResources(application_id); + std::set<std::string> acquired_module_types; + for (const auto& resource : allocated_resources) { + acquired_module_types.insert(resource.first); + } + + LOG4CXX_DEBUG(logger_, + "Application " << application_id << " acquired " + << acquired_module_types.size() + << " module type(s)."); + + return acquired_module_types; +} + void ResourceAllocationManagerImpl::SetResourceState( const std::string& module_type, + const std::string& module_id, const uint32_t app_id, const ResourceState::eType state) { LOG4CXX_AUTO_TRACE(logger_); LOG4CXX_DEBUG(logger_, "Setting state for " << module_type << " by app_id " << app_id << " to state " << state); + ModuleUid module(module_type, module_id); { sync_primitives::AutoLock lock(allocated_resources_lock_); const AllocatedResources::const_iterator allocated_it = - allocated_resources_.find(module_type); + allocated_resources_.find(module); const bool acquired = allocated_resources_.end() != allocated_it; if (acquired) { @@ -374,16 +485,16 @@ void ResourceAllocationManagerImpl::SetResourceState( } sync_primitives::AutoLock lock(resources_state_lock_); - resources_state_[module_type] = state; + resources_state_[module] = state; LOG4CXX_DEBUG(logger_, "Resource " << module_type << " got state " << state); } bool ResourceAllocationManagerImpl::IsResourceFree( - const std::string& module_type) const { + const std::string& module_type, const std::string& module_id) const { LOG4CXX_AUTO_TRACE(logger_); + ModuleUid module(module_type, module_id); sync_primitives::AutoLock lock(resources_state_lock_); - const ResourcesState::const_iterator resource = - resources_state_.find(module_type); + const ResourcesState::const_iterator resource = resources_state_.find(module); if (resources_state_.end() == resource) { LOG4CXX_DEBUG(logger_, "Resource " << module_type << " is free."); @@ -411,15 +522,20 @@ ResourceAllocationManagerImpl::GetAccessMode() const { } void ResourceAllocationManagerImpl::ForceAcquireResource( - const std::string& module_type, const uint32_t app_id) { + const std::string& module_type, + const std::string& module_id, + const uint32_t app_id) { LOG4CXX_DEBUG(logger_, "Force " << app_id << " acquiring " << module_type); sync_primitives::AutoLock lock(allocated_resources_lock_); - SetResourceAquired(module_type, app_id); + SetResourceAcquired(module_type, module_id, app_id); } bool ResourceAllocationManagerImpl::IsModuleTypeRejected( - const std::string& module_type, const uint32_t app_id) { + const std::string& module_type, + const std::string& module_id, + const uint32_t app_id) { LOG4CXX_AUTO_TRACE(logger_); + ModuleUid module(module_type, module_id); sync_primitives::AutoLock lock(rejected_resources_for_application_lock_); RejectedResources::iterator it = rejected_resources_for_application_.find(app_id); @@ -428,24 +544,27 @@ bool ResourceAllocationManagerImpl::IsModuleTypeRejected( return false; } - const std::vector<std::string>& list_of_rejected_resources = + const std::vector<ModuleUid>& list_of_rejected_resources = rejected_resources_for_application_[app_id]; - return helpers::in_range(list_of_rejected_resources, module_type); + return helpers::in_range(list_of_rejected_resources, module); } void ResourceAllocationManagerImpl::OnDriverDisallowed( - const std::string& module_type, const uint32_t app_id) { + const std::string& module_type, + const std::string& module_id, + const uint32_t app_id) { LOG4CXX_AUTO_TRACE(logger_); + ModuleUid module(module_type, module_id); sync_primitives::AutoLock lock(rejected_resources_for_application_lock_); auto it = rejected_resources_for_application_.find(app_id); if (rejected_resources_for_application_.end() == it) { - rejected_resources_for_application_[app_id] = std::vector<std::string>(); + rejected_resources_for_application_[app_id] = std::vector<ModuleUid>(); } - std::vector<std::string>& list_of_rejected_resources = + std::vector<ModuleUid>& list_of_rejected_resources = rejected_resources_for_application_[app_id]; - list_of_rejected_resources.push_back(module_type); + list_of_rejected_resources.push_back(module); } void ResourceAllocationManagerImpl::OnApplicationEvent( @@ -458,10 +577,10 @@ void ResourceAllocationManagerImpl::OnApplicationEvent( if (ApplicationEvent::kApplicationExit == event || ApplicationEvent::kApplicationUnregistered == event) { - Resources acquired_modules = GetAcquiredResources(application->app_id()); - Resources::const_iterator module = acquired_modules.begin(); + auto acquired_modules = GetAcquiredModuleTypes(application->app_id()); + auto module = acquired_modules.begin(); for (; acquired_modules.end() != module; ++module) { - ReleaseResource(*module, application->app_id()); + ReleaseModuleType(*module, application->app_id()); } if (!acquired_modules.empty()) { SendOnRCStatusNotifications( diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/CMakeLists.txt b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/CMakeLists.txt index c5a191650e..00ddcd7379 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/CMakeLists.txt +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/CMakeLists.txt @@ -37,11 +37,15 @@ include_directories ( ${COMPONENTS_DIR}/application_manager/rpc_plugins/rc_rpc_plugin/test/include/ ${COMPONENTS_DIR}/include/test/application_manager/ ${COMPONENTS_DIR}/rc_rpc_plugin/test/include + ${COMPONENTS_DIR}/resumption/include ) set (RC_TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/resource_allocation_manager_impl_test.cc ${CMAKE_CURRENT_SOURCE_DIR}/interior_data_cache_test.cc +${CMAKE_CURRENT_SOURCE_DIR}/rc_consent_manager_impl_test.cc +${CMAKE_CURRENT_SOURCE_DIR}/grid_test.cc +${CMAKE_CURRENT_SOURCE_DIR}/mock_rc_helpers.cc ) set(RC_COMMANDS_TEST_DIR ${CMAKE_CURRENT_SOURCE_DIR}/commands) @@ -53,6 +57,7 @@ file(GLOB SOURCES set(LIBRARIES rc_rpc_plugin_static + Resumption gmock_main ) diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/button_press_request_test.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/button_press_request_test.cc index f2b86f43da..fb8de0bb9c 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/button_press_request_test.cc +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/button_press_request_test.cc @@ -40,6 +40,8 @@ #include "interfaces/MOBILE_API.h" #include "rc_rpc_plugin/mock/mock_interior_data_cache.h" #include "rc_rpc_plugin/mock/mock_interior_data_manager.h" +#include "rc_rpc_plugin/mock/mock_rc_capabilities_manager.h" +#include "rc_rpc_plugin/mock/mock_rc_consent_manager.h" #include "rc_rpc_plugin/mock/mock_resource_allocation_manager.h" #include "rc_rpc_plugin/rc_app_extension.h" #include "rc_rpc_plugin/rc_command_factory.h" @@ -82,40 +84,9 @@ class ButtonPressRequestTest , rc_app_extention_( std::make_shared<rc_rpc_plugin::RCAppExtension>(kModuleId)) {} - smart_objects::SmartObject ButtonCapability( - const mobile_apis::ButtonName::eType button_name) { - smart_objects::SmartObject button(smart_objects::SmartType_Map); - button["name"] = button_name; - return button; - } - void SetUp() OVERRIDE { - using namespace mobile_apis; - - std::vector<ButtonName::eType> button_names = {ButtonName::AC_MAX, - ButtonName::AC, - ButtonName::RECIRCULATE, - ButtonName::FAN_UP, - ButtonName::FAN_DOWN, - ButtonName::TEMP_UP, - ButtonName::TEMP_DOWN, - ButtonName::DEFROST_MAX, - ButtonName::DEFROST, - ButtonName::DEFROST_REAR, - ButtonName::UPPER_VENT, - ButtonName::LOWER_VENT, - ButtonName::VOLUME_UP, - ButtonName::VOLUME_DOWN, - ButtonName::EJECT, - ButtonName::SOURCE, - ButtonName::SHUFFLE, - ButtonName::REPEAT}; - - smart_objects::SmartObject button_caps(smart_objects::SmartType_Array); - for (size_t i = 0; i < button_names.size(); i++) { - button_caps[i] = ButtonCapability(button_names[i]); - } - rc_capabilities_[strings::kbuttonCapabilities] = button_caps; + smart_objects::SmartObject control_caps((smart_objects::SmartType_Array)); + rc_capabilities_[strings::kradioControlCapabilities] = control_caps; ON_CALL(app_mngr_, application(_)).WillByDefault(Return(mock_app_)); ON_CALL(*mock_app_, QueryInterface(RCRPCPlugin::kRCPluginID)) .WillByDefault(Return(rc_app_extention_)); @@ -133,6 +104,12 @@ class ButtonPressRequestTest .WillByDefault(Return(true)); ON_CALL(mock_allocation_manager_, is_rc_enabled()) .WillByDefault(Return(true)); + ON_CALL(mock_rc_capabilities_manager_, CheckButtonName(_, _)) + .WillByDefault(Return(true)); + ON_CALL(mock_rc_capabilities_manager_, CheckIfModuleExistsInCapabilities(_)) + .WillByDefault(Return(true)); + ON_CALL(mock_rc_capabilities_manager_, CheckIfButtonExistInRCCaps(_)) + .WillByDefault(Return(true)); } MessageSharedPtr CreateBasicMessage() { @@ -156,7 +133,9 @@ class ButtonPressRequestTest mock_policy_handler_, mock_allocation_manager_, mock_interior_data_cache_, - mock_interior_data_manager_}; + mock_interior_data_manager_, + mock_rc_capabilities_manager_, + mock_rc_consent_manger_}; return std::make_shared<Command>(msg ? msg : msg = CreateMessage(), params); } @@ -172,29 +151,36 @@ class ButtonPressRequestTest mock_interior_data_cache_; testing::NiceMock<rc_rpc_plugin_test::MockInteriorDataManager> mock_interior_data_manager_; + testing::NiceMock<rc_rpc_plugin_test::MockRCCapabilitiesManager> + mock_rc_capabilities_manager_; + testing::NiceMock<MockRCConsentManager> mock_rc_consent_manger_; }; TEST_F(ButtonPressRequestTest, Execute_ButtonNameMatchesModuleType_ExpectCorrectMessageSentToHMI) { // Arrange + const std::string resource = "CLIMATE"; + const std::string resource_id = "id1"; MessageSharedPtr mobile_message = CreateBasicMessage(); ns_smart_device_link::ns_smart_objects::SmartObject& msg_params = (*mobile_message)[application_manager::strings::msg_params]; msg_params[message_params::kModuleType] = mobile_apis::ModuleType::CLIMATE; + msg_params[message_params::kModuleId] = resource_id; msg_params[message_params::kButtonName] = mobile_apis::ButtonName::AC; msg_params[message_params::kButtonPressMode] = mobile_apis::ButtonPressMode::SHORT; // Expectations - const std::string resource = "CLIMATE"; ON_CALL(mock_policy_handler_, CheckModule(_, _)).WillByDefault(Return(true)); - EXPECT_CALL(mock_allocation_manager_, IsResourceFree(resource)) + + EXPECT_CALL(mock_allocation_manager_, IsResourceFree(resource, resource_id)) .WillOnce(Return(true)); - EXPECT_CALL(mock_allocation_manager_, AcquireResource(resource, _)) + EXPECT_CALL(mock_allocation_manager_, AcquireResource(resource, _, _)) .WillOnce(Return(rc_rpc_plugin::AcquireResult::ALLOWED)); EXPECT_CALL( mock_allocation_manager_, - SetResourceState(resource, kAppId, rc_rpc_plugin::ResourceState::BUSY)); + SetResourceState( + resource, resource_id, kAppId, rc_rpc_plugin::ResourceState::BUSY)); EXPECT_CALL( mock_rpc_service_, ManageHMICommand( @@ -213,22 +199,27 @@ TEST_F( ButtonPressRequestTest, Execute_ButtonNameDoesNotMatchModuleType_ExpectMessageNotSentToHMI_AndFalseSentToMobile) { // Arrange + const std::string resource = "RADIO"; + const std::string resource_id = "id1"; MessageSharedPtr mobile_message = CreateBasicMessage(); ns_smart_device_link::ns_smart_objects::SmartObject& msg_params = (*mobile_message)[application_manager::strings::msg_params]; msg_params[message_params::kModuleType] = mobile_apis::ModuleType::RADIO; + msg_params[message_params::kModuleId] = resource_id; msg_params[message_params::kButtonName] = mobile_apis::ButtonName::AC; msg_params[message_params::kButtonPressMode] = mobile_apis::ButtonPressMode::SHORT; // Expectations - const std::string resource = "RADIO"; + EXPECT_CALL(mock_rc_capabilities_manager_, CheckButtonName(_, _)) + .WillOnce(Return(false)); ON_CALL(mock_policy_handler_, CheckModule(_, _)).WillByDefault(Return(true)); - EXPECT_CALL(mock_allocation_manager_, IsResourceFree(resource)) + EXPECT_CALL(mock_allocation_manager_, IsResourceFree(resource, resource_id)) .WillOnce(Return(true)); - EXPECT_CALL(mock_allocation_manager_, AcquireResource(resource, _)) + EXPECT_CALL(mock_allocation_manager_, AcquireResource(resource, _, _)) .WillOnce(Return(rc_rpc_plugin::AcquireResult::ALLOWED)); - EXPECT_CALL(mock_allocation_manager_, SetResourceState(resource, kAppId, _)) + EXPECT_CALL(mock_allocation_manager_, + SetResourceState(resource, resource_id, kAppId, _)) .Times(2); EXPECT_CALL( @@ -269,9 +260,10 @@ TEST_F(ButtonPressRequestTest, OnEvent_ExpectSuccessfullResponseSentToMobile) { hmi_msg_params[application_manager::strings::connection_key] = kConnectionKey; // Expectations - EXPECT_CALL(mock_allocation_manager_, - SetResourceState(_, kAppId, rc_rpc_plugin::ResourceState::FREE)) - .Times(2); + EXPECT_CALL( + mock_allocation_manager_, + SetResourceState(_, _, kAppId, rc_rpc_plugin::ResourceState::FREE)) + .Times(1); EXPECT_CALL( mock_rpc_service_, @@ -308,9 +300,10 @@ TEST_F(ButtonPressRequestTest, hmi_msg_params[application_manager::strings::connection_key] = kConnectionKey; // Expectations - EXPECT_CALL(mock_allocation_manager_, - SetResourceState(_, kAppId, rc_rpc_plugin::ResourceState::FREE)) - .Times(2); + EXPECT_CALL( + mock_allocation_manager_, + SetResourceState(_, _, kAppId, rc_rpc_plugin::ResourceState::FREE)) + .Times(1); EXPECT_CALL(mock_rpc_service_, ManageMobileCommand( diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/get_interior_vehicle_data_consent_request_test.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/get_interior_vehicle_data_consent_request_test.cc new file mode 100644 index 0000000000..29708d05bd --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/get_interior_vehicle_data_consent_request_test.cc @@ -0,0 +1,402 @@ +/* + * Copyright (c) 2019, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <memory> +#include <string> + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#include "rc_rpc_plugin/commands/mobile/get_interior_vehicle_data_consent_request.h" + +#include "application_manager/commands/command_request_test.h" +#include "application_manager/mock_application.h" +#include "rc_rpc_plugin/mock/mock_interior_data_cache.h" +#include "rc_rpc_plugin/mock/mock_interior_data_manager.h" +#include "rc_rpc_plugin/mock/mock_rc_capabilities_manager.h" +#include "rc_rpc_plugin/mock/mock_rc_consent_manager.h" +#include "rc_rpc_plugin/mock/mock_resource_allocation_manager.h" +#include "rc_rpc_plugin/rc_module_constants.h" + +using application_manager::commands::MessageSharedPtr; +using rc_rpc_plugin_test::MockInteriorDataCache; +using rc_rpc_plugin_test::MockInteriorDataManager; +using rc_rpc_plugin_test::MockRCCapabilitiesManager; +using rc_rpc_plugin_test::MockRCConsentManager; +using rc_rpc_plugin_test::MockResourceAllocationManager; +using test::components::application_manager_test::MockApplication; +using test::components::commands_test::CommandRequestTest; +using test::components::commands_test::CommandsTestMocks; + +using ::testing::_; +using ::testing::DoAll; +using ::testing::NiceMock; +using ::testing::Return; +using ::testing::ReturnRef; +using ::testing::SaveArg; + +typedef std::shared_ptr< + rc_rpc_plugin::commands::GetInteriorVehicleDataConsentRequest> + GIVDConsentPtr; + +namespace { +const uint32_t kConnectionKey = 1u; +const uint32_t kAppId = 2u; +const std::string kPolicyAppId = "policy_app_id"; +const std::string kMacAddress = "device1"; +const std::string kModuleId_1 = "34045662-a9dc-4823-8435-91056d4c26cb"; +const std::string kModuleId_2 = "eb7739ea-b263-4fe1-af9c-9311d1acac2d"; +const std::string kModuleId_3 = "06cdec22-920e-4865-bf2e-9518463edc68"; +const mobile_apis::ModuleType::eType kModule_Type = + mobile_apis::ModuleType::eType::RADIO; +} // namespace + +namespace rc_rpc_plugin_test { +namespace get_interior_vehicle_data_consent_request_test { +using namespace rc_rpc_plugin; + +class GetInteriorVehicleDataConsentRequestTest + : public CommandRequestTest<CommandsTestMocks::kIsNice> { + public: + GetInteriorVehicleDataConsentRequestTest() : mock_app_(CreateMockApp()) {} + + void SetUp() OVERRIDE { + TestPrecondition(); + } + + void TestPrecondition() { + message_ = CreateBasicMessage(); + ON_CALL(mock_rc_capabilities_manager_, CheckIfModuleExistsInCapabilities(_)) + .WillByDefault(Return(true)); + ON_CALL(mock_rc_capabilities_manager_, IsMultipleAccessAllowed(_)) + .WillByDefault(Return(true)); + } + + void PrepareNoConsentExistInCache() { + ON_CALL(mock_allocation_manager_, GetAccessMode()) + .WillByDefault(Return(hmi_apis::Common_RCAccessMode::ASK_DRIVER)); + ON_CALL(app_mngr_, application(_)).WillByDefault(Return(mock_app_)); + ON_CALL(*mock_app_, app_id()).WillByDefault(Return(kAppId)); + ON_CALL(*mock_app_, policy_app_id()).WillByDefault(Return(kPolicyAppId)); + ON_CALL(*mock_app_, mac_address()).WillByDefault(ReturnRef(kMacAddress)); + ON_CALL(mock_rc_consent_manger_, + GetModuleConsent(kPolicyAppId, kMacAddress, _)) + .WillByDefault(Return(rc_rpc_types::ModuleConsent::NOT_EXISTS)); + ON_CALL(mock_allocation_manager_, + AcquireResource(_, _, mock_app_->app_id())) + .WillByDefault(Return(AcquireResult::IN_USE)); + } + + void PrepareMobileMessage() { + auto& msg_params = (*message_)[application_manager::strings::msg_params]; + msg_params[message_params::kModuleType] = kModule_Type; + + msg_params[message_params::kModuleIds][0] = kModuleId_1; + msg_params[message_params::kModuleIds][1] = kModuleId_2; + msg_params[message_params::kModuleIds][2] = kModuleId_3; + } + + /** + * @brief CreateBasicMessage creates message for + * GetInteriorVehicleData request for app1 + * @return message shared ptr + */ + MessageSharedPtr CreateBasicMessage() { + MessageSharedPtr message = CreateMessage(); + (*message)[application_manager::strings::params] + [application_manager::strings::function_id] = + mobile_apis::FunctionID::GetInteriorVehicleDataID; + (*message)[application_manager::strings::params] + [application_manager::strings::connection_key] = kConnectionKey; + (*message)[application_manager::strings::params] + [application_manager::strings::app_id] = kAppId; + return message; + } + + template <class Command> + std::shared_ptr<Command> CreateRCCommand(MessageSharedPtr& msg) { + InitCommand(kDefaultTimeout_); + RCCommandParams params{app_mngr_, + mock_rpc_service_, + mock_hmi_capabilities_, + mock_policy_handler_, + mock_allocation_manager_, + mock_interior_data_cache_, + mock_interior_data_manager_, + mock_rc_capabilities_manager_, + mock_rc_consent_manger_}; + return std::make_shared<Command>(msg ? msg : msg = CreateMessage(), params); + } + + protected: + GIVDConsentPtr command_; + MessageSharedPtr message_; + + MockAppPtr mock_app_; + NiceMock<MockResourceAllocationManager> mock_allocation_manager_; + NiceMock<MockInteriorDataCache> mock_interior_data_cache_; + NiceMock<MockInteriorDataManager> mock_interior_data_manager_; + NiceMock<MockRCCapabilitiesManager> mock_rc_capabilities_manager_; + NiceMock<MockRCConsentManager> mock_rc_consent_manger_; +}; + +TEST_F(GetInteriorVehicleDataConsentRequestTest, + ModuleIDReturnsEmptyString_SUCCESS) { + std::string empty_str; + command_ = + CreateRCCommand<commands::GetInteriorVehicleDataConsentRequest>(message_); + + EXPECT_EQ(empty_str, command_->ModuleId()); +} + +TEST_F(GetInteriorVehicleDataConsentRequestTest, + Execute_ModuleIdsIsAbsentInMessage_Response_INVALID_DATA) { + command_ = + CreateRCCommand<commands::GetInteriorVehicleDataConsentRequest>(message_); + + auto response_to_mobile = CreateMessage(); + + EXPECT_CALL(mock_rpc_service_, ManageHMICommand(_, _)).Times(0); + + EXPECT_CALL(mock_rpc_service_, ManageMobileCommand(_, _)) + .WillOnce(DoAll(SaveArg<0>(&response_to_mobile), Return(true))); + + command_->Execute(); + + const bool result = + (*response_to_mobile)[application_manager::strings::msg_params] + [application_manager::strings::success] + .asBool(); + const auto result_code = static_cast<mobile_apis::Result::eType>( + (*response_to_mobile)[application_manager::strings::msg_params] + [application_manager::strings::result_code] + .asUInt()); + EXPECT_FALSE(result); + EXPECT_EQ(mobile_apis::Result::INVALID_DATA, result_code); +} + +TEST_F(GetInteriorVehicleDataConsentRequestTest, + Execute_ModuleIdsIsEmpty_AddDefaultModuleID) { + (*message_)[application_manager::strings::msg_params] + [message_params::kModuleIds] = smart_objects::SmartObject( + smart_objects::SmartType::SmartType_Array); + (*message_)[application_manager::strings::msg_params] + [message_params::kModuleType] = kModule_Type; + command_ = + CreateRCCommand<commands::GetInteriorVehicleDataConsentRequest>(message_); + + auto message_to_hmi = CreateMessage(); + + const std::string module_type = "RADIO"; + const std::string default_module_id = "34045662-a9dc-4823-8435-91056d4c26cb"; + ON_CALL(mock_rc_capabilities_manager_, + GetDefaultModuleIdFromCapabilities(module_type)) + .WillByDefault(Return(default_module_id)); + + PrepareNoConsentExistInCache(); + + EXPECT_CALL(mock_rpc_service_, ManageHMICommand(_, _)) + .WillOnce(DoAll(SaveArg<0>(&message_to_hmi), Return(true))); + + command_->Execute(); + + ASSERT_FALSE((*message_to_hmi)[application_manager::strings::msg_params] + [message_params::kModuleIds] + .empty()); + const auto sent_module_id = + (*message_to_hmi)[application_manager::strings::msg_params] + [message_params::kModuleIds][0] + .asString(); + EXPECT_EQ(sent_module_id, default_module_id); +} + +TEST_F(GetInteriorVehicleDataConsentRequestTest, + Execute_SDLForwardsMobileMessageToHMI_SUCCESS) { + auto message_to_hmi = CreateMessage(); + + PrepareMobileMessage(); + PrepareNoConsentExistInCache(); + + command_ = + CreateRCCommand<commands::GetInteriorVehicleDataConsentRequest>(message_); + + EXPECT_CALL(mock_rpc_service_, ManageHMICommand(_, _)) + .WillOnce(DoAll(SaveArg<0>(&message_to_hmi), Return(true))); + + command_->Execute(); + + auto outgoing_msg_params = + (*message_to_hmi)[application_manager::strings::msg_params]; + + auto module_type = static_cast<mobile_apis::ModuleType::eType>( + outgoing_msg_params[message_params::kModuleType].asUInt()); + + EXPECT_EQ(kModule_Type, module_type); + EXPECT_EQ(kModuleId_1, + outgoing_msg_params[message_params::kModuleIds][0].asString()); + EXPECT_EQ(kModuleId_2, + outgoing_msg_params[message_params::kModuleIds][1].asString()); + EXPECT_EQ(kModuleId_3, + outgoing_msg_params[message_params::kModuleIds][2].asString()); +} + +TEST_F(GetInteriorVehicleDataConsentRequestTest, + On_Event_ConsentCollectionIsAbsentOrEmpty_Response_GENERIC_ERROR) { + PrepareMobileMessage(); + + command_ = + CreateRCCommand<commands::GetInteriorVehicleDataConsentRequest>(message_); + + // Consent collection in HMI response is absent + auto event_message = CreateMessage(); + application_manager::event_engine::Event event_collection_is_absent( + hmi_apis::FunctionID::RC_GetInteriorVehicleDataConsent); + event_collection_is_absent.set_smart_object(*event_message); + + auto response_to_mobile = CreateMessage(); + + EXPECT_CALL(mock_rpc_service_, ManageMobileCommand(_, _)) + .WillOnce(DoAll(SaveArg<0>(&response_to_mobile), Return(true))); + + command_->on_event(event_collection_is_absent); + + const auto result_code_is_absent = static_cast<mobile_apis::Result::eType>( + (*response_to_mobile)[application_manager::strings::msg_params] + [application_manager::strings::result_code] + .asUInt()); + EXPECT_EQ(mobile_apis::Result::GENERIC_ERROR, result_code_is_absent); + + // Consent coolection in HMI response isn't absent but is empty + event_message = CreateMessage(); + application_manager::event_engine::MobileEvent event_collection_is_empty( + mobile_apis::FunctionID::GetInteriorVehicleDataConsentID); + (*event_message)[application_manager::strings::msg_params] + [message_params::kAllowed] = smart_objects::SmartObject( + smart_objects::SmartType::SmartType_Array); + event_collection_is_empty.set_smart_object(*event_message); + + response_to_mobile = CreateMessage(); + + EXPECT_CALL(mock_rpc_service_, ManageMobileCommand(_, _)) + .WillOnce(DoAll(SaveArg<0>(&response_to_mobile), Return(true))); + + command_->on_event(event_collection_is_absent); + + const auto result_code_is_empty = static_cast<mobile_apis::Result::eType>( + (*response_to_mobile)[application_manager::strings::msg_params] + [application_manager::strings::result_code] + .asUInt()); + EXPECT_EQ(mobile_apis::Result::GENERIC_ERROR, result_code_is_empty); +} + +TEST_F(GetInteriorVehicleDataConsentRequestTest, + On_Event_ConsentsSizeIsNotEqualModuleIdsSize_Response_GENERIC_ERROR) { + PrepareMobileMessage(); + PrepareNoConsentExistInCache(); + + // ModuleIds collection will be saved + command_ = + CreateRCCommand<commands::GetInteriorVehicleDataConsentRequest>(message_); + command_->Execute(); + + auto event_message = CreateMessage(); + (*event_message)[application_manager::strings::msg_params] + [message_params::kAllowed] = smart_objects::SmartObject( + smart_objects::SmartType::SmartType_Array); + + // Consent collection will contain only two items in collection + (*event_message)[application_manager::strings::msg_params] + [message_params::kAllowed][0] = true; + (*event_message)[application_manager::strings::msg_params] + [message_params::kAllowed][1] = false; + + application_manager::event_engine::Event event( + hmi_apis::FunctionID::RC_GetInteriorVehicleDataConsent); + event.set_smart_object(*event_message); + + auto response_to_mobile = CreateMessage(); + EXPECT_CALL(mock_rpc_service_, ManageMobileCommand(_, _)) + .WillOnce(DoAll(SaveArg<0>(&response_to_mobile), Return(true))); + + command_->on_event(event); + + const auto result_code_is_empty = static_cast<mobile_apis::Result::eType>( + (*response_to_mobile)[application_manager::strings::msg_params] + [application_manager::strings::result_code] + .asUInt()); + EXPECT_EQ(mobile_apis::Result::GENERIC_ERROR, result_code_is_empty); +} + +TEST_F(GetInteriorVehicleDataConsentRequestTest, + On_Event_SaveModuleConsentsToLastState_Response_SUCCESS) { + PrepareMobileMessage(); + PrepareNoConsentExistInCache(); + + // ModuleIds collection will be saved + command_ = + CreateRCCommand<commands::GetInteriorVehicleDataConsentRequest>(message_); + command_->Execute(); + + // Consent collection will have same size as moduelIds collection + auto event_message = CreateMessage(); + (*event_message)[application_manager::strings::msg_params] + [message_params::kAllowed][0] = true; + (*event_message)[application_manager::strings::msg_params] + [message_params::kAllowed][1] = false; + (*event_message)[application_manager::strings::msg_params] + [message_params::kAllowed][2] = false; + + application_manager::event_engine::Event event( + hmi_apis::FunctionID::RC_GetInteriorVehicleDataConsent); + event.set_smart_object(*event_message); + + ON_CALL(app_mngr_, application(_)).WillByDefault(Return(mock_app_)); + ON_CALL(*mock_app_, policy_app_id()).WillByDefault(Return(kPolicyAppId)); + ON_CALL(*mock_app_, mac_address()).WillByDefault(ReturnRef(kMacAddress)); + + EXPECT_CALL(mock_rc_consent_manger_, SaveModuleConsents(kPolicyAppId, _, _)); + + auto response_to_mobile = CreateMessage(); + EXPECT_CALL(mock_rpc_service_, ManageMobileCommand(_, _)) + .WillOnce(DoAll(SaveArg<0>(&response_to_mobile), Return(true))); + + command_->on_event(event); + + const auto result_code_is_empty = static_cast<mobile_apis::Result::eType>( + (*response_to_mobile)[application_manager::strings::msg_params] + [application_manager::strings::result_code] + .asUInt()); + EXPECT_EQ(mobile_apis::Result::SUCCESS, result_code_is_empty); +} + +} // namespace get_interior_vehicle_data_consent_request_test +} // namespace rc_rpc_plugin_test diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/get_interior_vehicle_data_request_test.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/get_interior_vehicle_data_request_test.cc index 123c22b944..532a62df3b 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/get_interior_vehicle_data_request_test.cc +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/get_interior_vehicle_data_request_test.cc @@ -38,6 +38,8 @@ #include "gtest/gtest.h" #include "rc_rpc_plugin/mock/mock_interior_data_cache.h" #include "rc_rpc_plugin/mock/mock_interior_data_manager.h" +#include "rc_rpc_plugin/mock/mock_rc_capabilities_manager.h" +#include "rc_rpc_plugin/mock/mock_rc_consent_manager.h" #include "rc_rpc_plugin/mock/mock_resource_allocation_manager.h" #include "rc_rpc_plugin/rc_app_extension.h" #include "rc_rpc_plugin/rc_command_factory.h" @@ -74,7 +76,9 @@ const int32_t kConnectionKey = 5u; const uint32_t kAppId = 0u; const uint32_t kAppId2 = 1u; const int kModuleId = 153u; -const auto module_type = mobile_apis::ModuleType::RADIO; +const auto module_eType = mobile_apis::ModuleType::RADIO; +const auto module_type = "RADIO"; +const auto module_id = "eb7739ea-b263-4fe1-af9c-9311d1acac2d"; const int32_t time_frame_of_allowed_requests = 1; const uint32_t max_request_in_time_frame = 5u; } // namespace @@ -91,7 +95,8 @@ class GetInteriorVehicleDataRequestTest , rc_app_extention_(std::make_shared<RCAppExtension>(kModuleId)) , rc_app_extention2_(std::make_shared<RCAppExtension>(kModuleId)) , apps_lock_(std::make_shared<sync_primitives::Lock>()) - , apps_da_(apps_, apps_lock_) { + , apps_da_(apps_, apps_lock_) + , rc_capabilities_(smart_objects::SmartType::SmartType_Array) { ON_CALL(*mock_app_, app_id()).WillByDefault(Return(kAppId)); ON_CALL(*mock_app2_, app_id()).WillByDefault(Return(kAppId2)); ON_CALL(*mock_app_, is_remote_control_supported()) @@ -125,6 +130,8 @@ class GetInteriorVehicleDataRequestTest std::pair<uint32_t, int32_t> frequency; frequency.first = max_request_in_time_frame; frequency.second = time_frame_of_allowed_requests; + smart_objects::SmartObject control_caps((smart_objects::SmartType_Array)); + rc_capabilities_[strings::kradioControlCapabilities] = control_caps; ON_CALL(app_mngr_, get_settings()) .WillByDefault(ReturnRef(app_mngr_settings_)); ON_CALL(app_mngr_settings_, get_interior_vehicle_data_frequency()) @@ -144,7 +151,7 @@ class GetInteriorVehicleDataRequestTest ON_CALL(app_mngr_, hmi_capabilities()) .WillByDefault(ReturnRef(mock_hmi_capabilities_)); ON_CALL(mock_hmi_capabilities_, rc_capability()) - .WillByDefault(Return(nullptr)); + .WillByDefault(Return(&rc_capabilities_)); ON_CALL(mock_policy_handler_, CheckHMIType( _, mobile_apis::AppHMIType::eType::REMOTE_CONTROL, nullptr)) @@ -153,6 +160,8 @@ class GetInteriorVehicleDataRequestTest .WillByDefault(Return(true)); ON_CALL(mock_allocation_manager_, is_rc_enabled()) .WillByDefault(Return(true)); + ON_CALL(mock_rc_capabilities_manager_, CheckIfModuleExistsInCapabilities(_)) + .WillByDefault(Return(true)); } template <class Command> @@ -164,7 +173,9 @@ class GetInteriorVehicleDataRequestTest mock_policy_handler_, mock_allocation_manager_, mock_interior_data_cache_, - mock_interior_data_manager_}; + mock_interior_data_manager_, + mock_rc_capabilities_manager_, + mock_rc_consent_manger_}; return std::make_shared<Command>(msg ? msg : msg = CreateMessage(), params); } @@ -182,6 +193,10 @@ class GetInteriorVehicleDataRequestTest application_manager::ApplicationSet apps_; const std::shared_ptr<sync_primitives::Lock> apps_lock_; DataAccessor<application_manager::ApplicationSet> apps_da_; + testing::NiceMock<rc_rpc_plugin_test::MockRCCapabilitiesManager> + mock_rc_capabilities_manager_; + smart_objects::SmartObject rc_capabilities_; + testing::NiceMock<MockRCConsentManager> mock_rc_consent_manger_; }; TEST_F(GetInteriorVehicleDataRequestTest, @@ -189,14 +204,16 @@ TEST_F(GetInteriorVehicleDataRequestTest, // Arrange MessageSharedPtr mobile_message = CreateBasicMessage(); (*mobile_message)[application_manager::strings::msg_params] - [message_params::kModuleType] = module_type; - ON_CALL(mock_interior_data_cache_, Contains(enums_value::kRadio)) + [message_params::kModuleType] = module_eType; + (*mobile_message)[application_manager::strings::msg_params] + [message_params::kModuleType] = module_id; + const ModuleUid module(module_type, module_id); + ON_CALL(mock_interior_data_cache_, Contains(module)) .WillByDefault(Return(false)); ON_CALL(mock_interior_data_manager_, CheckRequestsToHMIFrequency(_)) .WillByDefault(Return(true)); - std::shared_ptr<rc_rpc_plugin::commands::GetInteriorVehicleDataRequest> - command = CreateRCCommand< - rc_rpc_plugin::commands::GetInteriorVehicleDataRequest>( + auto command = + CreateRCCommand<rc_rpc_plugin::commands::GetInteriorVehicleDataRequest>( mobile_message); // Expectations @@ -216,16 +233,18 @@ TEST_F(GetInteriorVehicleDataRequestTest, // Arrange MessageSharedPtr mobile_message = CreateBasicMessage(); (*mobile_message)[application_manager::strings::msg_params] - [message_params::kModuleType] = module_type; + [message_params::kModuleType] = module_eType; + (*mobile_message)[application_manager::strings::msg_params] + [message_params::kModuleId] = module_id; (*mobile_message)[application_manager::strings::msg_params] [message_params::kSubscribe] = true; - ON_CALL(mock_interior_data_cache_, Contains(enums_value::kRadio)) + const ModuleUid module(module_type, module_id); + ON_CALL(mock_interior_data_cache_, Contains(module)) .WillByDefault(Return(false)); ON_CALL(mock_interior_data_manager_, CheckRequestsToHMIFrequency(_)) .WillByDefault(Return(true)); - std::shared_ptr<rc_rpc_plugin::commands::GetInteriorVehicleDataRequest> - command = CreateRCCommand< - rc_rpc_plugin::commands::GetInteriorVehicleDataRequest>( + auto command = + CreateRCCommand<rc_rpc_plugin::commands::GetInteriorVehicleDataRequest>( mobile_message); // Expectations @@ -243,10 +262,13 @@ TEST_F( GetInteriorVehicleDataRequestTest, Execute_ExpectMessageNotSentToHMI_SuccessSentToMobile_AppSubscribed_DataFromCache) { // Arrange - rc_app_extention_->SubscribeToInteriorVehicleData(enums_value::kRadio); + const ModuleUid module(module_type, module_id); + rc_app_extention_->SubscribeToInteriorVehicleData(module); MessageSharedPtr mobile_message = CreateBasicMessage(); (*mobile_message)[application_manager::strings::msg_params] - [message_params::kModuleType] = module_type; + [message_params::kModuleType] = module_eType; + (*mobile_message)[application_manager::strings::msg_params] + [message_params::kModuleId] = module_id; smart_objects::SmartObject radio_data; smart_objects::SmartObject sis_data; smart_objects::SmartObject gps_data; @@ -261,15 +283,14 @@ TEST_F( radio_data[message_params::kBand] = enums_value::kAM; radio_data[message_params::kSisData] = sis_data; - std::shared_ptr<rc_rpc_plugin::commands::GetInteriorVehicleDataRequest> - command = CreateRCCommand< - rc_rpc_plugin::commands::GetInteriorVehicleDataRequest>( + auto command = + CreateRCCommand<rc_rpc_plugin::commands::GetInteriorVehicleDataRequest>( mobile_message); // Expectations - EXPECT_CALL(mock_interior_data_cache_, Contains(enums_value::kRadio)) + EXPECT_CALL(mock_interior_data_cache_, Contains(module)) .WillOnce(Return(true)); - EXPECT_CALL(mock_interior_data_cache_, Retrieve(enums_value::kRadio)) + EXPECT_CALL(mock_interior_data_cache_, Retrieve(module)) .WillOnce(Return(radio_data)); EXPECT_CALL(mock_rpc_service_, ManageHMICommand(_, _)).Times(0); MessageSharedPtr command_result; @@ -291,13 +312,16 @@ TEST_F( TEST_F( GetInteriorVehicleDataRequestTest, - Execute_ExpectCorrectMessageSentToHMI_LastAppSubscribedUnsubscibe_ClearCache) { + Execute_ExpectCorrectMessageSentToHMI_LastAppSubscribedUnsubscribe_ClearCache) { // Arrange MessageSharedPtr mobile_message = CreateBasicMessage(); (*mobile_message)[application_manager::strings::msg_params] - [message_params::kModuleType] = module_type; + [message_params::kModuleType] = module_eType; (*mobile_message)[application_manager::strings::msg_params] [message_params::kSubscribe] = false; + (*mobile_message)[application_manager::strings::msg_params] + [message_params::kModuleId] = module_id; + const ModuleUid module(module_type, module_id); MessageSharedPtr hmi_response = CreateBasicMessage(); ns_smart_device_link::ns_smart_objects::SmartObject& hmi_msg_params = @@ -306,9 +330,11 @@ TEST_F( hmi_apis::Common_Result::SUCCESS; hmi_msg_params[application_manager::hmi_response::code] = response_code; hmi_msg_params[application_manager::strings::connection_key] = kConnectionKey; + hmi_msg_params[message_params::kModuleData][message_params::kModuleId] = + module_id; apps_.insert(mock_app_); - rc_app_extention_->SubscribeToInteriorVehicleData(enums_value::kRadio); + rc_app_extention_->SubscribeToInteriorVehicleData(module); ON_CALL(app_mngr_, applications()).WillByDefault(Return(apps_da_)); ON_CALL(mock_interior_data_manager_, CheckRequestsToHMIFrequency(_)) .WillByDefault(Return(true)); @@ -324,12 +350,11 @@ TEST_F( ManageMobileCommand(MobileResultCodeIs(mobile_apis::Result::SUCCESS), _)) .WillOnce(Return(true)); - EXPECT_CALL(mock_interior_data_cache_, Remove(enums_value::kRadio)); + EXPECT_CALL(mock_interior_data_cache_, Remove(module)); // Act - std::shared_ptr<rc_rpc_plugin::commands::GetInteriorVehicleDataRequest> - command = CreateRCCommand< - rc_rpc_plugin::commands::GetInteriorVehicleDataRequest>( + auto command = + CreateRCCommand<rc_rpc_plugin::commands::GetInteriorVehicleDataRequest>( mobile_message); ASSERT_TRUE(command->Init()); command->Run(); @@ -344,28 +369,30 @@ TEST_F(GetInteriorVehicleDataRequestTest, // Arrange MessageSharedPtr mobile_message = CreateBasicMessage(); (*mobile_message)[application_manager::strings::msg_params] - [message_params::kModuleType] = module_type; + [message_params::kModuleType] = module_eType; (*mobile_message)[application_manager::strings::msg_params] [message_params::kSubscribe] = false; + (*mobile_message)[application_manager::strings::msg_params] + [message_params::kModuleId] = module_id; + const ModuleUid module(module_type, module_id); apps_.insert(mock_app_); apps_.insert(mock_app2_); - rc_app_extention_->SubscribeToInteriorVehicleData(enums_value::kRadio); - rc_app_extention2_->SubscribeToInteriorVehicleData(enums_value::kRadio); + rc_app_extention_->SubscribeToInteriorVehicleData(module); + rc_app_extention2_->SubscribeToInteriorVehicleData(module); smart_objects::SmartObject radio_data; radio_data[message_params::kBand] = enums_value::kAM; ON_CALL(app_mngr_, applications()).WillByDefault(Return(apps_da_)); - std::shared_ptr<rc_rpc_plugin::commands::GetInteriorVehicleDataRequest> - command = CreateRCCommand< - rc_rpc_plugin::commands::GetInteriorVehicleDataRequest>( + auto command = + CreateRCCommand<rc_rpc_plugin::commands::GetInteriorVehicleDataRequest>( mobile_message); // Expectations - EXPECT_CALL(mock_interior_data_cache_, Contains(enums_value::kRadio)) + EXPECT_CALL(mock_interior_data_cache_, Contains(module)) .WillOnce(Return(true)); - EXPECT_CALL(mock_interior_data_cache_, Retrieve(enums_value::kRadio)) + EXPECT_CALL(mock_interior_data_cache_, Retrieve(module)) .WillOnce(Return(radio_data)); EXPECT_CALL(mock_rpc_service_, ManageHMICommand(_, _)).Times(0); @@ -380,8 +407,8 @@ TEST_F(GetInteriorVehicleDataRequestTest, command->Run(); // Assert - EXPECT_FALSE( - rc_app_extention_->IsSubscibedToInteriorVehicleData(enums_value::kRadio)); + EXPECT_FALSE(rc_app_extention_->IsSubscribedToInteriorVehicleDataOfType( + enums_value::kRadio)); EXPECT_EQ((*command_result)[application_manager::strings::msg_params] [message_params::kModuleData] [message_params::kRadioControlData], @@ -395,14 +422,12 @@ TEST_F( MessageSharedPtr mobile_message = CreateBasicMessage(); ns_smart_device_link::ns_smart_objects::SmartObject& msg_params = (*mobile_message)[application_manager::strings::msg_params]; - msg_params[message_params::kModuleType] = mobile_apis::ModuleType::RADIO; - std::shared_ptr<rc_rpc_plugin::commands::GetInteriorVehicleDataRequest> - command = CreateRCCommand< - rc_rpc_plugin::commands::GetInteriorVehicleDataRequest>( + msg_params[message_params::kModuleType] = module_eType; + auto command = + CreateRCCommand<rc_rpc_plugin::commands::GetInteriorVehicleDataRequest>( mobile_message); - smart_objects::SmartObject rc_capabilities; ON_CALL(mock_hmi_capabilities_, rc_capability()) - .WillByDefault(Return(&rc_capabilities)); + .WillByDefault(Return(nullptr)); // Expectations EXPECT_CALL(mock_rpc_service_, ManageHMICommand(_, _)).Times(0); @@ -423,10 +448,9 @@ TEST_F( MessageSharedPtr mobile_message = CreateBasicMessage(); ns_smart_device_link::ns_smart_objects::SmartObject& msg_params = (*mobile_message)[application_manager::strings::msg_params]; - msg_params[message_params::kModuleType] = mobile_apis::ModuleType::RADIO; - std::shared_ptr<rc_rpc_plugin::commands::GetInteriorVehicleDataRequest> - command = CreateRCCommand< - rc_rpc_plugin::commands::GetInteriorVehicleDataRequest>( + msg_params[message_params::kModuleType] = module_eType; + auto command = + CreateRCCommand<rc_rpc_plugin::commands::GetInteriorVehicleDataRequest>( mobile_message); ON_CALL(mock_policy_handler_, CheckModule(_, _)).WillByDefault(Return(false)); @@ -451,12 +475,14 @@ TEST_F(GetInteriorVehicleDataRequestTest, // Arrange MessageSharedPtr mobile_message = CreateBasicMessage(); auto& msg_params = (*mobile_message)[strings::msg_params]; - msg_params[message_params::kModuleType] = module_type; + msg_params[message_params::kModuleType] = module_eType; MessageSharedPtr hmi_response_message = CreateBasicMessage(); auto& hmi_response_params = (*hmi_response_message)[strings::msg_params]; hmi_response_params[hmi_response::code] = hmi_apis::Common_Result::SUCCESS; hmi_response_params[strings::connection_key] = kConnectionKey; + hmi_response_params[message_params::kModuleData][message_params::kModuleId] = + module_id; ON_CALL(mock_interior_data_cache_, Contains(_)).WillByDefault(Return(false)); ON_CALL(mock_interior_data_manager_, CheckRequestsToHMIFrequency(_)) @@ -494,7 +520,7 @@ TEST_F(GetInteriorVehicleDataRequestTest, MessageSharedPtr mobile_message = CreateBasicMessage(); auto& msg_params = (*mobile_message)[application_manager::strings::msg_params]; - msg_params[message_params::kModuleType] = module_type; + msg_params[message_params::kModuleType] = module_eType; MessageSharedPtr hmi_message = CreateBasicMessage(); auto& hmi_msg_params = (*hmi_message)[strings::params]; @@ -526,14 +552,16 @@ TEST_F(GetInteriorVehicleDataRequestTest, } TEST_F(GetInteriorVehicleDataRequestTest, - OnEvent_InvalidHmiResponse_DontUnsubscibeLastApp_NoClearCache) { + OnEvent_InvalidHmiResponse_DontUnsubscribeLastApp_NoClearCache) { // Arrange MessageSharedPtr mobile_message = CreateBasicMessage(); (*mobile_message)[application_manager::strings::msg_params] - [message_params::kModuleType] = module_type; + [message_params::kModuleType] = module_eType; + (*mobile_message)[application_manager::strings::msg_params] + [message_params::kModuleId] = module_id; (*mobile_message)[application_manager::strings::msg_params] [message_params::kSubscribe] = false; - + const ModuleUid module(module_type, module_id); MessageSharedPtr hmi_response = CreateBasicMessage(); ns_smart_device_link::ns_smart_objects::SmartObject& hmi_msg_params = (*hmi_response)[application_manager::strings::params]; @@ -542,7 +570,7 @@ TEST_F(GetInteriorVehicleDataRequestTest, hmi_msg_params[application_manager::strings::connection_key] = kConnectionKey; apps_.insert(mock_app_); - rc_app_extention_->SubscribeToInteriorVehicleData(enums_value::kRadio); + rc_app_extention_->SubscribeToInteriorVehicleData(module); ON_CALL(app_mngr_, applications()).WillByDefault(Return(apps_da_)); ON_CALL(mock_interior_data_manager_, CheckRequestsToHMIFrequency(_)) .WillByDefault(Return(true)); @@ -561,9 +589,8 @@ TEST_F(GetInteriorVehicleDataRequestTest, EXPECT_CALL(mock_interior_data_cache_, Clear()).Times(0); // Act - std::shared_ptr<rc_rpc_plugin::commands::GetInteriorVehicleDataRequest> - command = CreateRCCommand< - rc_rpc_plugin::commands::GetInteriorVehicleDataRequest>( + auto command = + CreateRCCommand<rc_rpc_plugin::commands::GetInteriorVehicleDataRequest>( mobile_message); ASSERT_TRUE(command->Init()); command->Run(); @@ -573,32 +600,33 @@ TEST_F(GetInteriorVehicleDataRequestTest, command->on_event(event); // Assert - EXPECT_TRUE( - rc_app_extention_->IsSubscibedToInteriorVehicleData(enums_value::kRadio)); + EXPECT_TRUE(rc_app_extention_->IsSubscribedToInteriorVehicleData(module)); } TEST_F(GetInteriorVehicleDataRequestTest, Execute_ExpectRejectDuToRequestLimitation_NoCahce) { // Arrange - rc_app_extention_->UnsubscribeFromInteriorVehicleData(enums_value::kRadio); + rc_app_extention_->UnsubscribeFromInteriorVehicleDataOfType( + enums_value::kRadio); MessageSharedPtr mobile_message = CreateBasicMessage(); (*mobile_message)[application_manager::strings::msg_params] - [message_params::kModuleType] = module_type; + [message_params::kModuleType] = module_eType; + (*mobile_message)[application_manager::strings::msg_params] + [message_params::kModuleId] = module_id; smart_objects::SmartObject radio_data; radio_data[message_params::kBand] = enums_value::kAM; - std::shared_ptr<rc_rpc_plugin::commands::GetInteriorVehicleDataRequest> - command = CreateRCCommand< - rc_rpc_plugin::commands::GetInteriorVehicleDataRequest>( + auto command = + CreateRCCommand<rc_rpc_plugin::commands::GetInteriorVehicleDataRequest>( mobile_message); + const ModuleUid module(module_type, module_id); size_t i = 0; for (; i <= max_request_in_time_frame; ++i) { // Expectations EXPECT_CALL(mock_interior_data_manager_, - CheckRequestsToHMIFrequency(enums_value::kRadio)) + CheckRequestsToHMIFrequency(module)) .WillOnce(Return(true)); - EXPECT_CALL(mock_interior_data_manager_, - StoreRequestToHMITime(enums_value::kRadio)); - EXPECT_CALL(mock_interior_data_cache_, Contains(enums_value::kRadio)) + EXPECT_CALL(mock_interior_data_manager_, StoreRequestToHMITime(module)); + EXPECT_CALL(mock_interior_data_cache_, Contains(module)) .WillRepeatedly(Return(false)); EXPECT_CALL( mock_rpc_service_, @@ -612,8 +640,7 @@ TEST_F(GetInteriorVehicleDataRequestTest, } // Expectations - EXPECT_CALL(mock_interior_data_manager_, - CheckRequestsToHMIFrequency(enums_value::kRadio)) + EXPECT_CALL(mock_interior_data_manager_, CheckRequestsToHMIFrequency(module)) .WillOnce(Return(false)); EXPECT_CALL( mock_rpc_service_, diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/on_interior_vehicle_data_notification_test.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/on_interior_vehicle_data_notification_test.cc index dcf36a34a0..d6771c534d 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/on_interior_vehicle_data_notification_test.cc +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/on_interior_vehicle_data_notification_test.cc @@ -38,6 +38,8 @@ #include "interfaces/MOBILE_API.h" #include "rc_rpc_plugin/mock/mock_interior_data_cache.h" #include "rc_rpc_plugin/mock/mock_interior_data_manager.h" +#include "rc_rpc_plugin/mock/mock_rc_capabilities_manager.h" +#include "rc_rpc_plugin/mock/mock_rc_consent_manager.h" #include "rc_rpc_plugin/mock/mock_resource_allocation_manager.h" #include "rc_rpc_plugin/rc_module_constants.h" #include "rc_rpc_plugin/rc_rpc_plugin.h" @@ -58,6 +60,8 @@ namespace { const uint32_t kAppId = 0u; const uint32_t kConnectionKey = 1u; const std::string kPolicyAppId = "Test"; +const std::string module_type = "CLIMATE"; +const std::string module_id = "34045662-a9dc-4823-8435-91056d4c26cb"; const int kModuleId = 153u; } // namespace @@ -93,6 +97,8 @@ class OnInteriorVehicleDataNotificationTest (*message)[application_manager::strings::msg_params]; msg_param[message_params::kModuleData][message_params::kModuleType] = mobile_apis::ModuleType::CLIMATE; + msg_param[message_params::kModuleData][message_params::kModuleId] = + module_id; return message; } @@ -105,7 +111,9 @@ class OnInteriorVehicleDataNotificationTest mock_policy_handler_, mock_allocation_manager_, mock_interior_data_cache_, - mock_interior_data_manager_}; + mock_interior_data_manager_, + mock_rc_capabilities_manager_, + mock_rc_consent_manger_}; return ::std::make_shared<Command>(msg ? msg : msg = CreateMessage(), params); } @@ -122,6 +130,9 @@ class OnInteriorVehicleDataNotificationTest application_manager::ApplicationSet apps_; const std::shared_ptr<sync_primitives::Lock> apps_lock_; DataAccessor<application_manager::ApplicationSet> apps_da_; + testing::NiceMock<rc_rpc_plugin_test::MockRCCapabilitiesManager> + mock_rc_capabilities_manager_; + testing::NiceMock<MockRCConsentManager> mock_rc_consent_manger_; }; TEST_F(OnInteriorVehicleDataNotificationTest, @@ -129,11 +140,12 @@ TEST_F(OnInteriorVehicleDataNotificationTest, // Arrange MessageSharedPtr mobile_message = CreateBasicMessage(); apps_.insert(mock_app_); - rc_app_extention_->SubscribeToInteriorVehicleData(enums_value::kClimate); + const ModuleUid module(module_type, module_id); + rc_app_extention_->SubscribeToInteriorVehicleData(module); ON_CALL(app_mngr_, applications()).WillByDefault(Return(apps_da_)); // Expectations - EXPECT_CALL(mock_interior_data_cache_, Add(enums_value::kClimate, _)); + EXPECT_CALL(mock_interior_data_cache_, Add(module, _)); MessageSharedPtr message; EXPECT_CALL(mock_rpc_service_, SendMessageToMobile(_, false)) .WillOnce(SaveArg<0>(&message)); diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/on_remote_control_settings_test.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/on_remote_control_settings_test.cc index 6fbff118a4..62b726ac60 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/on_remote_control_settings_test.cc +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/on_remote_control_settings_test.cc @@ -39,6 +39,8 @@ #include "rc_rpc_plugin/commands/hmi/rc_on_remote_control_settings_notification.h" #include "rc_rpc_plugin/mock/mock_interior_data_cache.h" #include "rc_rpc_plugin/mock/mock_interior_data_manager.h" +#include "rc_rpc_plugin/mock/mock_rc_capabilities_manager.h" +#include "rc_rpc_plugin/mock/mock_rc_consent_manager.h" #include "rc_rpc_plugin/mock/mock_resource_allocation_manager.h" #include "rc_rpc_plugin/rc_module_constants.h" #include "rc_rpc_plugin/rc_rpc_plugin.h" @@ -95,7 +97,9 @@ class RCOnRemoteControlSettingsNotificationTest mock_policy_handler_, mock_allocation_manager_, mock_interior_data_cache_, - mock_interior_data_manager_}; + mock_interior_data_manager_, + mock_rc_capabilities_manager_, + mock_rc_consent_manger_}; return std::make_shared<Command>(msg ? msg : msg = CreateMessage(), params); } @@ -107,6 +111,9 @@ class RCOnRemoteControlSettingsNotificationTest mock_interior_data_cache_; testing::NiceMock<rc_rpc_plugin_test::MockInteriorDataManager> mock_interior_data_manager_; + testing::NiceMock<rc_rpc_plugin_test::MockRCCapabilitiesManager> + mock_rc_capabilities_manager_; + testing::NiceMock<MockRCConsentManager> mock_rc_consent_manger_; }; TEST_F(RCOnRemoteControlSettingsNotificationTest, @@ -141,6 +148,7 @@ TEST_F(RCOnRemoteControlSettingsNotificationTest, EXPECT_CALL(mock_allocation_manager_, ResetAllAllocations()); EXPECT_CALL(mock_interior_data_manager_, OnDisablingRC()); + EXPECT_CALL(mock_rc_consent_manger_, RemoveAllConsents()); // Act std::shared_ptr< diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/rc_get_interior_vehicle_data_consent_test.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/rc_get_interior_vehicle_data_consent_test.cc index 6e9502f5a3..d44265a1d5 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/rc_get_interior_vehicle_data_consent_test.cc +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/rc_get_interior_vehicle_data_consent_test.cc @@ -52,6 +52,8 @@ #include "rc_rpc_plugin/commands/mobile/button_press_request.h" #include "rc_rpc_plugin/mock/mock_interior_data_cache.h" #include "rc_rpc_plugin/mock/mock_interior_data_manager.h" +#include "rc_rpc_plugin/mock/mock_rc_capabilities_manager.h" +#include "rc_rpc_plugin/mock/mock_rc_consent_manager.h" #include "rc_rpc_plugin/mock/mock_resource_allocation_manager.h" #include "rc_rpc_plugin/rc_module_constants.h" #include "rc_rpc_plugin/rc_rpc_plugin.h" @@ -92,6 +94,9 @@ namespace { const uint32_t kConnectionKey = 2u; const uint32_t kAppId = 5u; const std::string kResource = "CLIMATE"; +const std::string kResourceId = "34045662-a9dc-4823-8435-91056d4c26cb"; +const std::string kPolicyAppId = "policy_app_id"; +const std::string kMacAddress = "device1"; const uint32_t kPluginID = RCRPCPlugin::kRCPluginID; } // namespace @@ -101,6 +106,7 @@ class RCGetInteriorVehicleDataConsentTest RCGetInteriorVehicleDataConsentTest() : mock_app_(std::make_shared<NiceMock<MockApplication> >()) , command_holder(app_mngr_) + , rc_capabilities_(smart_objects::SmartType::SmartType_Array) , request_controller(mock_request_controler) , rpc_protection_manager_( std::make_shared<application_manager::MockRPCProtectionManager>()) @@ -117,6 +123,8 @@ class RCGetInteriorVehicleDataConsentTest std::make_shared<NiceMock<MockRPCPluginManager> >()) , rpc_plugin(mock_rpc_plugin) , optional_mock_rpc_plugin(mock_rpc_plugin) { + smart_objects::SmartObject control_caps((smart_objects::SmartType_Array)); + rc_capabilities_[strings::kradioControlCapabilities] = control_caps; ON_CALL(*mock_app_, app_id()).WillByDefault(Return(kAppId)); ON_CALL(app_mngr_, hmi_interfaces()) .WillByDefault(ReturnRef(mock_hmi_interfaces_)); @@ -146,7 +154,7 @@ class RCGetInteriorVehicleDataConsentTest .WillByDefault(ReturnRef(*mock_rpc_plugin_manager)); ON_CALL(*mock_rpc_plugin_manager, FindPluginToProcess(_, _)) .WillByDefault(Return(rpc_plugin)); - ON_CALL(mock_allocation_manager_, IsResourceFree(kResource)) + ON_CALL(mock_allocation_manager_, IsResourceFree(kResource, kResourceId)) .WillByDefault(Return(true)); ON_CALL(mock_allocation_manager_, is_rc_enabled()) .WillByDefault(Return(true)); @@ -154,6 +162,8 @@ class RCGetInteriorVehicleDataConsentTest .WillByDefault(Return(false)); ON_CALL(*rpc_protection_manager_, CheckPolicyEncryptionFlag(_, _, _)) .WillByDefault(Return(false)); + ON_CALL(mock_rc_capabilities_manager_, CheckIfModuleExistsInCapabilities(_)) + .WillByDefault(Return(true)); } template <class Command> @@ -165,7 +175,9 @@ class RCGetInteriorVehicleDataConsentTest mock_policy_handler_, mock_allocation_manager_, mock_interior_data_cache_, - mock_interior_data_manager_}; + mock_interior_data_manager_, + mock_rc_capabilities_manager_, + mock_rc_consent_manger_}; return std::make_shared<Command>(msg ? msg : msg = CreateMessage(), params); } @@ -178,6 +190,10 @@ class RCGetInteriorVehicleDataConsentTest [application_manager::strings::connection_key] = kConnectionKey; (*message)[application_manager::strings::params] [application_manager::strings::connection_key] = kAppId; + ns_smart_device_link::ns_smart_objects::SmartObject& msg_params = + (*message)[application_manager::strings::msg_params]; + msg_params[message_params::kModuleType] = kResource; + msg_params[message_params::kModuleId] = kResourceId; return message; } @@ -207,6 +223,9 @@ class RCGetInteriorVehicleDataConsentTest utils::Optional<MockRPCPlugin> optional_mock_rpc_plugin; hmi_apis::HMI_API hmi_so_factory_; mobile_apis::MOBILE_API mobile_so_factoy_; + testing::NiceMock<rc_rpc_plugin_test::MockRCCapabilitiesManager> + mock_rc_capabilities_manager_; + testing::NiceMock<MockRCConsentManager> mock_rc_consent_manger_; }; TEST_F(RCGetInteriorVehicleDataConsentTest, @@ -215,8 +234,17 @@ TEST_F(RCGetInteriorVehicleDataConsentTest, auto mobile_message = CreateBasicMessage(); // Expectations - EXPECT_CALL(mock_allocation_manager_, AcquireResource(_, _)) + EXPECT_CALL(mock_allocation_manager_, AcquireResource(_, _, _)) .WillOnce(Return(rc_rpc_plugin::AcquireResult::ASK_DRIVER)); + ON_CALL(*mock_app_, app_id()).WillByDefault(Return(kAppId)); + ON_CALL(*mock_app_, policy_app_id()).WillByDefault(Return(kPolicyAppId)); + ON_CALL(*mock_app_, mac_address()).WillByDefault(ReturnRef(kMacAddress)); + + rc_rpc_types::ModuleUid moduleUid{kResource, kResourceId}; + EXPECT_CALL(mock_rc_consent_manger_, + GetModuleConsent(kPolicyAppId, _, moduleUid)) + .WillOnce(Return(rc_rpc_types::ModuleConsent::NOT_EXISTS)); + EXPECT_CALL(*optional_mock_rpc_plugin, GetCommandFactory()) .WillOnce(ReturnRef(mock_command_factory)); auto rc_consent_request = @@ -241,7 +269,7 @@ TEST_F(RCGetInteriorVehicleDataConsentTest, auto mobile_message = CreateBasicMessage(); // Expectations - EXPECT_CALL(mock_allocation_manager_, AcquireResource(_, _)) + EXPECT_CALL(mock_allocation_manager_, AcquireResource(_, _, _)) .WillOnce(Return(rc_rpc_plugin::AcquireResult::IN_USE)); EXPECT_CALL(*optional_mock_rpc_plugin, GetCommandFactory()) diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/release_interior_vehicle_data_module_request_test.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/release_interior_vehicle_data_module_request_test.cc new file mode 100644 index 0000000000..200e458c17 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/release_interior_vehicle_data_module_request_test.cc @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2019, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <memory> +#include <string> + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#include "rc_rpc_plugin/commands/mobile/release_interior_vehicle_data_module_request.h" + +#include "application_manager/commands/command_request_test.h" +#include "application_manager/mock_application.h" +#include "rc_rpc_plugin/mock/mock_interior_data_cache.h" +#include "rc_rpc_plugin/mock/mock_interior_data_manager.h" +#include "rc_rpc_plugin/mock/mock_rc_capabilities_manager.h" +#include "rc_rpc_plugin/mock/mock_rc_consent_manager.h" +#include "rc_rpc_plugin/mock/mock_resource_allocation_manager.h" +#include "rc_rpc_plugin/rc_module_constants.h" + +using application_manager::commands::MessageSharedPtr; +using rc_rpc_plugin_test::MockInteriorDataCache; +using rc_rpc_plugin_test::MockInteriorDataManager; +using rc_rpc_plugin_test::MockRCCapabilitiesManager; +using rc_rpc_plugin_test::MockRCConsentManager; +using rc_rpc_plugin_test::MockResourceAllocationManager; +using test::components::application_manager_test::MockApplication; +using test::components::commands_test::CommandRequestTest; +using test::components::commands_test::CommandsTestMocks; + +using testing::_; +using ::testing::DoAll; +using ::testing::Mock; +using ::testing::NiceMock; +using ::testing::Return; +using ::testing::SaveArg; + +typedef std::shared_ptr< + rc_rpc_plugin::commands::ReleaseInteriorVehicleDataModuleRequest> + ReleaseCommandPtr; + +namespace { +std::string kPolicyAppID = "app_id"; +std::uint32_t kAppID = 2u; +std::uint32_t kConnectionKey = 1u; +std::string kModuleType = "RADIO"; +std::string kModuleID = "76149d9b-5317-4cf5-9196-b8fac690fec5"; +std::string kDefaultModuleID = "eb7739ea-b263-4fe1-af9c-9311d1acac2d"; +} // namespace + +namespace rc_rpc_plugin_test { +namespace release_interior_vehicle_data_module_request { +using namespace rc_rpc_plugin; + +class ReleaseInteriorVehicleDataModuleRequestTest + : public CommandRequestTest<CommandsTestMocks::kIsNice> { + public: + ReleaseInteriorVehicleDataModuleRequestTest() : mock_app_(CreateMockApp()) {} + + void SetUp() OVERRIDE { + TestPreCondition(); + ON_CALL(app_mngr_, application(kAppID)).WillByDefault(Return(mock_app_)); + ON_CALL(*mock_app_, app_id()).WillByDefault(Return(kAppID)); + ON_CALL(mock_rc_capabilities_manager_, + GetDefaultModuleIdFromCapabilities(kModuleType)) + .WillByDefault(Return(kDefaultModuleID)); + } + + MessageSharedPtr CreateBasicMessage() { + MessageSharedPtr message = CreateMessage(); + (*message)[application_manager::strings::params] + [application_manager::strings::function_id] = + mobile_apis::FunctionID::ReleaseInteriorVehicleDataModuleID; + (*message)[application_manager::strings::params] + [application_manager::strings::connection_key] = kConnectionKey; + (*message)[application_manager::strings::params] + [application_manager::strings::connection_key] = kAppID; + (*message)[application_manager::strings::msg_params] + [message_params::kModuleType] = mobile_apis::ModuleType::RADIO; + (*message)[application_manager::strings::msg_params] + [message_params::kModuleId] = kModuleID; + return message; + } + + void TestPreCondition() { + message_ = CreateBasicMessage(); + command_ = + CreateRCCommand<commands::ReleaseInteriorVehicleDataModuleRequest>( + message_); + } + + template <class Command> + std::shared_ptr<Command> CreateRCCommand(MessageSharedPtr& msg) { + InitCommand(kDefaultTimeout_); + RCCommandParams params{app_mngr_, + mock_rpc_service_, + mock_hmi_capabilities_, + mock_policy_handler_, + mock_allocation_manager_, + mock_interior_data_cache_, + mock_interior_data_manager_, + mock_rc_capabilities_manager_, + mock_rc_consent_manger_}; + return std::make_shared<Command>(msg ? msg : msg = CreateMessage(), params); + } + + protected: + MessageSharedPtr message_; + ReleaseCommandPtr command_; + + MockAppPtr mock_app_; + NiceMock<MockResourceAllocationManager> mock_allocation_manager_; + MockInteriorDataCache mock_interior_data_cache_; + MockInteriorDataManager mock_interior_data_manager_; + NiceMock<MockRCCapabilitiesManager> mock_rc_capabilities_manager_; + MockRCConsentManager mock_rc_consent_manger_; +}; + +TEST_F(ReleaseInteriorVehicleDataModuleRequestTest, + ModuleIDIsAbsnetInMessage_ReturnsDefaultFromCapabilities) { + (*message_)[application_manager::strings::msg_params].erase( + message_params::kModuleId); + + auto module_id = command_->ModuleId(); + EXPECT_EQ(kDefaultModuleID, module_id); +} + +TEST_F(ReleaseInteriorVehicleDataModuleRequestTest, + ResourceIsNotAllocated_ResponseToMobile_UNSUCCESS_IGNORED) { + ON_CALL(mock_allocation_manager_, + ReleaseResource(kModuleType, kModuleID, kAppID)) + .WillByDefault(Return(ResourceReleasedState::eType::NOT_ALLOCATED)); + + MessageSharedPtr message_to_mobile = CreateMessage(); + + EXPECT_CALL( + mock_rpc_service_, + ManageMobileCommand( + _, application_manager::commands::Command::CommandSource::SOURCE_SDL)) + .WillOnce(DoAll(SaveArg<0>(&message_to_mobile), Return(true))); + + command_->Execute(); + + const bool success = + (*message_to_mobile)[application_manager::strings::msg_params] + [application_manager::strings::success] + .asBool(); + auto result_code = static_cast<mobile_apis::Result::eType>( + (*message_to_mobile)[application_manager::strings::msg_params] + [application_manager::strings::result_code] + .asUInt()); + + EXPECT_FALSE(success); + EXPECT_EQ(mobile_apis::Result::eType::IGNORED, result_code); +} + +TEST_F(ReleaseInteriorVehicleDataModuleRequestTest, + ResourceIsAllocated_ResponseToMobile_UNSUCCESS_REJECTED) { + ON_CALL(mock_allocation_manager_, + ReleaseResource(kModuleType, kModuleID, kAppID)) + .WillByDefault(Return(ResourceReleasedState::eType::IS_ALLOCATED)); + MessageSharedPtr message_to_mobile = CreateMessage(); + + EXPECT_CALL( + mock_rpc_service_, + ManageMobileCommand( + _, application_manager::commands::Command::CommandSource::SOURCE_SDL)) + .WillOnce(DoAll(SaveArg<0>(&message_to_mobile), Return(true))); + + command_->Execute(); + + const bool success = + (*message_to_mobile)[application_manager::strings::msg_params] + [application_manager::strings::success] + .asBool(); + auto result_code = static_cast<mobile_apis::Result::eType>( + (*message_to_mobile)[application_manager::strings::msg_params] + [application_manager::strings::result_code] + .asUInt()); + + EXPECT_FALSE(success); + EXPECT_EQ(mobile_apis::Result::eType::REJECTED, result_code); +} + +TEST_F(ReleaseInteriorVehicleDataModuleRequestTest, + ResourceIsReleased_ResponseToMobile_SUCCESS_SUCCESS) { + ON_CALL(mock_allocation_manager_, + ReleaseResource(kModuleType, kModuleID, kAppID)) + .WillByDefault(Return(ResourceReleasedState::eType::IS_RELEASED)); + + MessageSharedPtr message_to_mobile = CreateMessage(); + + EXPECT_CALL( + mock_rpc_service_, + ManageMobileCommand( + _, application_manager::commands::Command::CommandSource::SOURCE_SDL)) + .WillOnce(DoAll(SaveArg<0>(&message_to_mobile), Return(true))); + + command_->Execute(); + + const bool success = + (*message_to_mobile)[application_manager::strings::msg_params] + [application_manager::strings::success] + .asBool(); + auto result_code = static_cast<mobile_apis::Result::eType>( + (*message_to_mobile)[application_manager::strings::msg_params] + [application_manager::strings::result_code] + .asUInt()); + + EXPECT_TRUE(success); + EXPECT_EQ(mobile_apis::Result::eType::SUCCESS, result_code); +} +} // namespace release_interior_vehicle_data_module_request +} // namespace rc_rpc_plugin_test diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/set_interior_vehicle_data_request_test.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/set_interior_vehicle_data_request_test.cc index f7718a7248..5a822a2fe4 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/set_interior_vehicle_data_request_test.cc +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/commands/set_interior_vehicle_data_request_test.cc @@ -37,6 +37,8 @@ #include "interfaces/MOBILE_API.h" #include "rc_rpc_plugin/mock/mock_interior_data_cache.h" #include "rc_rpc_plugin/mock/mock_interior_data_manager.h" +#include "rc_rpc_plugin/mock/mock_rc_capabilities_manager.h" +#include "rc_rpc_plugin/mock/mock_rc_consent_manager.h" #include "rc_rpc_plugin/mock/mock_resource_allocation_manager.h" #include "rc_rpc_plugin/rc_module_constants.h" #include "rc_rpc_plugin/rc_rpc_plugin.h" @@ -71,9 +73,12 @@ class SetInteriorVehicleDataRequestTest public: SetInteriorVehicleDataRequestTest() : mock_app_(std::make_shared<NiceMock<MockApplication> >()) - , rc_app_extention_(std::make_shared<RCAppExtension>(kModuleId)) {} + , rc_app_extention_(std::make_shared<RCAppExtension>(kModuleId)) + , rc_capabilities_(smart_objects::SmartType::SmartType_Array) {} void SetUp() OVERRIDE { + smart_objects::SmartObject control_caps((smart_objects::SmartType_Array)); + rc_capabilities_[strings::kradioControlCapabilities] = control_caps; ON_CALL(app_mngr_, hmi_interfaces()) .WillByDefault(ReturnRef(mock_hmi_interfaces_)); ON_CALL( @@ -86,9 +91,9 @@ class SetInteriorVehicleDataRequestTest .WillByDefault(Return(rc_app_extention_)); ON_CALL(*mock_app_, policy_app_id()).WillByDefault(Return(kPolicyAppId)); - ON_CALL(mock_allocation_manager_, IsResourceFree(_)) + ON_CALL(mock_allocation_manager_, IsResourceFree(_, _)) .WillByDefault(Return(true)); - ON_CALL(mock_allocation_manager_, AcquireResource(_, _)) + ON_CALL(mock_allocation_manager_, AcquireResource(_, _, _)) .WillByDefault(Return(AcquireResult::ALLOWED)); ON_CALL(*mock_app_, app_id()).WillByDefault(Return(kAppId)); ON_CALL(mock_policy_handler_, @@ -96,8 +101,14 @@ class SetInteriorVehicleDataRequestTest mobile_apis::AppHMIType::eType::REMOTE_CONTROL, nullptr)) .WillByDefault(Return(true)); + ON_CALL(mock_hmi_capabilities_, rc_capability()) + .WillByDefault(Return(&rc_capabilities_)); ON_CALL(mock_allocation_manager_, is_rc_enabled()) .WillByDefault(Return(true)); + ON_CALL(mock_rc_capabilities_manager_, CheckIfModuleExistsInCapabilities(_)) + .WillByDefault(Return(true)); + ON_CALL(mock_rc_capabilities_manager_, GetModuleDataCapabilities(_, _)) + .WillByDefault(Return(std::make_pair("", capabilitiesStatus::success))); } MessageSharedPtr CreateBasicMessage() { @@ -121,7 +132,9 @@ class SetInteriorVehicleDataRequestTest mock_policy_handler_, mock_allocation_manager_, mock_interior_data_cache_, - mock_interior_data_manager_}; + mock_interior_data_manager_, + mock_rc_capabilities_manager_, + mock_rc_consent_manger_}; return std::make_shared<Command>(msg ? msg : msg = CreateMessage(), params); } @@ -134,6 +147,10 @@ class SetInteriorVehicleDataRequestTest mock_interior_data_manager_; std::shared_ptr<MockApplication> mock_app_; std::shared_ptr<RCAppExtension> rc_app_extention_; + testing::NiceMock<rc_rpc_plugin_test::MockRCCapabilitiesManager> + mock_rc_capabilities_manager_; + smart_objects::SmartObject rc_capabilities_; + testing::NiceMock<MockRCConsentManager> mock_rc_consent_manger_; }; TEST_F(SetInteriorVehicleDataRequestTest, @@ -153,18 +170,14 @@ TEST_F(SetInteriorVehicleDataRequestTest, EXPECT_CALL(mock_policy_handler_, CheckModule(kPolicyAppId, _)) .WillOnce(Return(rc_rpc_plugin::TypeAccess::kAllowed)); - EXPECT_CALL(mock_hmi_capabilities_, rc_capability()) - .WillOnce(Return(nullptr)); - EXPECT_CALL( mock_rpc_service_, ManageHMICommand( HMIResultCodeIs(hmi_apis::FunctionID::RC_SetInteriorVehicleData), _)) .WillOnce(Return(true)); // Act - std::shared_ptr<rc_rpc_plugin::commands::SetInteriorVehicleDataRequest> - command = CreateRCCommand< - rc_rpc_plugin::commands::SetInteriorVehicleDataRequest>( + auto command = + CreateRCCommand<rc_rpc_plugin::commands::SetInteriorVehicleDataRequest>( mobile_message); ASSERT_TRUE(command->Init()); command->Run(); @@ -190,9 +203,6 @@ TEST_F( EXPECT_CALL(mock_policy_handler_, CheckModule(kPolicyAppId, _)) .WillOnce(Return(rc_rpc_plugin::TypeAccess::kAllowed)); - EXPECT_CALL(mock_hmi_capabilities_, rc_capability()) - .WillOnce(Return(nullptr)); - EXPECT_CALL(app_mngr_, RemoveHMIFakeParameters(_, _)); EXPECT_CALL( @@ -260,9 +270,6 @@ TEST_F(SetInteriorVehicleDataRequestTest, EXPECT_CALL(mock_policy_handler_, CheckModule(kPolicyAppId, _)) .WillOnce(Return(rc_rpc_plugin::TypeAccess::kAllowed)); - EXPECT_CALL(mock_hmi_capabilities_, rc_capability()) - .WillOnce(Return(nullptr)); - MessageSharedPtr message_from_mobile = CreateBasicMessage(); EXPECT_CALL(mock_rpc_service_, ManageHMICommand(_, _)) @@ -306,9 +313,6 @@ TEST_F(SetInteriorVehicleDataRequestTest, EXPECT_CALL(mock_policy_handler_, CheckModule(kPolicyAppId, _)) .WillOnce(Return(rc_rpc_plugin::TypeAccess::kAllowed)); - EXPECT_CALL(mock_hmi_capabilities_, rc_capability()) - .WillOnce(Return(nullptr)); - auto message_from_mobile = CreateBasicMessage(); EXPECT_CALL(mock_rpc_service_, ManageHMICommand(_, _)) diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/grid_test.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/grid_test.cc new file mode 100644 index 0000000000..b8a0d71203 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/grid_test.cc @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2019, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "gtest/gtest.h" + +#include "rc_rpc_plugin/rc_app_extension.h" + +namespace rc_rpc_plugin_test { +namespace grid_test { +using namespace rc_rpc_plugin; + +TEST(Grid, IsLevelIntersectionExists) { + Grid grid_level0{1, 1, 0, 1, 1, 1}; + Grid grid_level1{1, 1, 1, 1, 1, 1}; + EXPECT_FALSE(grid_level0.LevelIntersectionExists(grid_level1)); + + Grid grid_level1_v2{1, 2, 1, 1, 2, 1}; + EXPECT_TRUE(grid_level1.LevelIntersectionExists(grid_level1_v2)); +} + +TEST(Grid, TwoSameGrisAreEqual) { + Grid grid2{1, 1, 0, 1, 1, 1}; + Grid grid1{1, 1, 0, 1, 1, 1}; + + EXPECT_EQ(grid1, grid2); +} + +TEST(Grid, IsIntersectionExists) { + Grid grid_1{0, 1, 2, 1, 1, 1}; + Grid grid_2{0, 0, 1, 0, 0, 1}; + + // There is intersection but levels missmatch + EXPECT_FALSE(grid_1.IntersectionExists(grid_2)); + + Grid grid_3{1, 0, 2, 0, 0, 0}; + // There isn't intersection but level match + EXPECT_FALSE(grid_1.IntersectionExists(grid_3)); + + Grid grid_4{0, 1, 2, 1, 1, 1}; + EXPECT_TRUE(grid_1.IntersectionExists(grid_4)); +} +} // namespace grid_test +} // namespace rc_rpc_plugin_test diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/include/rc_rpc_plugin/mock/mock_interior_data_cache.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/include/rc_rpc_plugin/mock/mock_interior_data_cache.h index 45465f96b0..025cef2165 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/include/rc_rpc_plugin/mock/mock_interior_data_cache.h +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/include/rc_rpc_plugin/mock/mock_interior_data_cache.h @@ -42,10 +42,14 @@ namespace rc_rpc_plugin_test { class MockInteriorDataCache : public rc_rpc_plugin::InteriorDataCache { public: MOCK_METHOD2(Add, - void(const std::string&, const smart_objects::SmartObject&)); - MOCK_CONST_METHOD1(Retrieve, smart_objects::SmartObject(const std::string&)); - MOCK_CONST_METHOD1(Contains, bool(const std::string&)); - MOCK_METHOD1(Remove, void(const std::string&)); + void(const rc_rpc_plugin::ModuleUid&, + const smart_objects::SmartObject&)); + MOCK_CONST_METHOD1( + Retrieve, smart_objects::SmartObject(const rc_rpc_plugin::ModuleUid&)); + MOCK_CONST_METHOD1(GetCachedModulesByType, + std::vector<rc_rpc_plugin::ModuleUid>(const std::string&)); + MOCK_CONST_METHOD1(Contains, bool(const rc_rpc_plugin::ModuleUid&)); + MOCK_METHOD1(Remove, void(const rc_rpc_plugin::ModuleUid&)); MOCK_METHOD0(Clear, void()); }; diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/include/rc_rpc_plugin/mock/mock_interior_data_manager.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/include/rc_rpc_plugin/mock/mock_interior_data_manager.h index fc19c6a889..231ac2ae36 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/include/rc_rpc_plugin/mock/mock_interior_data_manager.h +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/include/rc_rpc_plugin/mock/mock_interior_data_manager.h @@ -46,8 +46,9 @@ class MockInteriorDataManager : public rc_rpc_plugin::InteriorDataManager { void(application_manager::plugin_manager::ApplicationEvent, application_manager::ApplicationSharedPtr)); MOCK_METHOD0(OnDisablingRC, void()); - MOCK_METHOD1(StoreRequestToHMITime, void(const std::string&)); - MOCK_METHOD1(CheckRequestsToHMIFrequency, bool(const std::string&)); + MOCK_METHOD1(StoreRequestToHMITime, void(const rc_rpc_plugin::ModuleUid&)); + MOCK_METHOD1(CheckRequestsToHMIFrequency, + bool(const rc_rpc_plugin::ModuleUid&)); }; } // namespace rc_rpc_plugin_test diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/include/rc_rpc_plugin/mock/mock_rc_capabilities_manager.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/include/rc_rpc_plugin/mock/mock_rc_capabilities_manager.h new file mode 100644 index 0000000000..6f1593dcbb --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/include/rc_rpc_plugin/mock/mock_rc_capabilities_manager.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2019, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_TEST_INCLUDE_RC_RPC_PLUGIN_MOCK_MOCK_RC_CAPABILITIES_MANAGER_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_TEST_INCLUDE_RC_RPC_PLUGIN_MOCK_MOCK_RC_CAPABILITIES_MANAGER_H_ +#include "gmock/gmock.h" +#include "rc_rpc_plugin/rc_capabilities_manager.h" + +namespace rc_rpc_plugin_test { +class MockRCCapabilitiesManager : public rc_rpc_plugin::RCCapabilitiesManager { + public: + MOCK_CONST_METHOD2(CheckButtonName, + bool(const std::string& module_type, + const std::string& button_name)); + + MOCK_CONST_METHOD1(CheckIfModuleExistsInCapabilities, + bool(const rc_rpc_plugin::ModuleUid& module_type)); + + MOCK_CONST_METHOD2(GetModuleDataCapabilities, + rc_rpc_plugin::ModuleTypeCapability( + const smart_objects::SmartObject& module_data, + const std::string& module_id)); + + MOCK_CONST_METHOD2(ControlDataForType, + const smart_objects::SmartObject&( + const smart_objects::SmartObject& module_data, + const std::string& module_type)); + + MOCK_CONST_METHOD3( + AreReadOnlyParamsPresent, + bool(const smart_objects::SmartObject& module_data, + const std::string& module_type, + rc_rpc_plugin::ModuleTypeCapability& module_data_capabilities)); + + MOCK_CONST_METHOD2(AreAllParamsReadOnly, + bool(const smart_objects::SmartObject& module_data, + const std::string& module_type)); + + MOCK_CONST_METHOD1(GetDefaultModuleIdFromCapabilities, + const std::string(const std::string& module_type)); + + MOCK_CONST_METHOD1(CheckIfButtonExistInRCCaps, + bool(const mobile_apis::ButtonName::eType button)); + + MOCK_CONST_METHOD0(GetResources, + const std::vector<rc_rpc_plugin::ModuleUid>()); + + MOCK_CONST_METHOD1(GetModuleServiceArea, + rc_rpc_plugin::Grid(const rc_rpc_plugin::ModuleUid&)); + + MOCK_CONST_METHOD1(IsMultipleAccessAllowed, + bool(const rc_rpc_plugin::ModuleUid&)); + + MOCK_CONST_METHOD0(GetDriverLocationFromSeatLocationCapability, + const rc_rpc_plugin::Grid()); + + MOCK_CONST_METHOD0(IsSeatLocationCapabilityProvided, bool()); + + MOCK_CONST_METHOD1( + GetModuleIdForSeatLocation, + const std::string(const mobile_apis::SupportedSeat::eType id)); +}; +} // namespace rc_rpc_plugin_test +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_RC_RPC_PLUGIN_TEST_INCLUDE_RC_RPC_PLUGIN_MOCK_MOCK_RC_СAPABILITIES_MANAGER_H_ diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/include/rc_rpc_plugin/mock/mock_rc_consent_manager.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/include/rc_rpc_plugin/mock/mock_rc_consent_manager.h new file mode 100644 index 0000000000..147da9ed55 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/include/rc_rpc_plugin/mock/mock_rc_consent_manager.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2019, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_PLUGIN_MANAGER_MOCK_RC_CONSENT_MANAGER_H +#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_PLUGIN_MANAGER_MOCK_RC_CONSENT_MANAGER_H + +#include <string> + +#include "gmock/gmock.h" +#include "rc_rpc_plugin/rc_consent_manager.h" + +namespace rc_rpc_plugin_test { + +class MockRCConsentManager : public rc_rpc_plugin::RCConsentManager { + public: + MOCK_METHOD3(SaveModuleConsents, + void(const std::string&, + const std::string&, + const rc_rpc_plugin::rc_rpc_types::ModuleIdConsentVector&)); + MOCK_CONST_METHOD3(GetModuleConsent, + rc_rpc_plugin::rc_rpc_types::ModuleConsent( + const std::string&, + const std::string&, + const rc_rpc_plugin::rc_rpc_types::ModuleUid&)); + MOCK_METHOD0(RemoveExpiredConsents, void()); + MOCK_METHOD0(RemoveAllConsents, void()); +}; + +} // namespace rc_rpc_plugin_test + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_PLUGIN_MANAGER_MOCK_RC_CONSENT_MANAGER_H diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/include/rc_rpc_plugin/mock/mock_rc_helpers.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/include/rc_rpc_plugin/mock/mock_rc_helpers.h new file mode 100644 index 0000000000..2473909ce5 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/include/rc_rpc_plugin/mock/mock_rc_helpers.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2019, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_RC_RPC_PLUGINS_RC_RPC_PLUGIN_TEST_INCLUDE_RC_RPC_PLUGIN_MOCK_MOCK_RC_HELPERS_H +#define SRC_COMPONENTS_APPLICATION_MANAGER_RC_RPC_PLUGINS_RC_RPC_PLUGIN_TEST_INCLUDE_RC_RPC_PLUGIN_MOCK_MOCK_RC_HELPERS_H + +#include <functional> +#include <map> +#include <string> +#include "gmock/gmock.h" + +#include "application_manager/application.h" +#include "application_manager/application_manager.h" +#include "rc_rpc_plugin/rc_helpers.h" + +namespace rc_rpc_plugin { + +class MockRCHelpers { + public: + MOCK_METHOD0(GetModuleTypeToDataMapping, + std::function<std::string(const std::string&)>()); + MOCK_METHOD0(GetModuleTypeToCapabilitiesMapping, + std::function<std::string(const std::string&)>()); + MOCK_METHOD0(GetModuleTypesList, const std::vector<std::string>()); + MOCK_METHOD1( + GetRCExtension, + rc_rpc_plugin::RCAppExtensionPtr(application_manager::Application&)); + MOCK_METHOD2(CreateUnsubscribeRequestToHMI, + smart_objects::SmartObjectSPtr(const rc_rpc_plugin::ModuleUid&, + const uint32_t)); + MOCK_METHOD2(AppsSubscribedToModule, + std::vector<application_manager::ApplicationSharedPtr>( + application_manager::ApplicationManager&, + const rc_rpc_plugin::ModuleUid&)); + MOCK_METHOD2(AppsSubscribedToModuleType, + std::vector<application_manager::ApplicationSharedPtr>( + application_manager::ApplicationManager&, + const std::string&)); + MOCK_METHOD1(GetApplicationsAllowedModuleTypes, + rc_rpc_plugin::RCHelpers::AppsModuleTypes( + application_manager::ApplicationManager&)); + MOCK_METHOD0(buttons_climate, const std::vector<std::string>()); + MOCK_METHOD0(buttons_radio, const std::vector<std::string>()); + MOCK_METHOD0(buttons_map, const rc_rpc_plugin::RCHelpers::ButtonsMap()); + MOCK_METHOD1(GetModuleReadOnlyParams, + std::vector<std::string>(const std::string&)); + MOCK_METHOD3( + FillModuleConsents, + rc_rpc_types::ModuleIdConsentVector(const std::string&, + const std::vector<std::string>&, + const std::vector<bool>)); + MOCK_METHOD1(RetrieveModuleIds, + std::vector<std::string>(const smart_objects::SmartObject&)); + MOCK_METHOD1(RetrieveModuleConsents, + std::vector<bool>(const smart_objects::SmartObject& consents)); + MOCK_METHOD1(RemoveRedundantGPSDataFromIVDataMsg, + void(smart_objects::SmartObject& msg_params)); + + static MockRCHelpers* rc_helpers_mock(); +}; + +} // namespace rc_rpc_plugin + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_RC_RPC_PLUGINS_RC_RPC_PLUGIN_TEST_INCLUDE_RC_RPC_PLUGIN_MOCK_MOCK_RC_HELPERS_H diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/include/rc_rpc_plugin/mock/mock_resource_allocation_manager.h b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/include/rc_rpc_plugin/mock/mock_resource_allocation_manager.h index 828e2eea11..fca6c9c77e 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/include/rc_rpc_plugin/mock/mock_resource_allocation_manager.h +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/include/rc_rpc_plugin/mock/mock_resource_allocation_manager.h @@ -41,13 +41,19 @@ namespace rc_rpc_plugin_test { class MockResourceAllocationManager : public rc_rpc_plugin::ResourceAllocationManager { public: - MOCK_METHOD2(AcquireResource, - rc_rpc_plugin::AcquireResult::eType( - const std::string& module_type, const uint32_t app_id)); - MOCK_METHOD2(ForceAcquireResource, - void(const std::string& module_type, const uint32_t app_id)); - MOCK_METHOD2(OnDriverDisallowed, - void(const std::string& module_type, const uint32_t app_id)); + MOCK_METHOD3( + AcquireResource, + rc_rpc_plugin::AcquireResult::eType(const std::string& module_type, + const std::string& module_id, + const uint32_t app_id)); + MOCK_METHOD3(ForceAcquireResource, + void(const std::string& module_type, + const std::string& module_id, + const uint32_t app_id)); + MOCK_METHOD3(OnDriverDisallowed, + void(const std::string& module_type, + const std::string& module_id, + const uint32_t app_id)); MOCK_METHOD2(OnApplicationEvent, void(application_manager::plugin_manager::ApplicationEvent event, application_manager::ApplicationSharedPtr application)); @@ -56,17 +62,32 @@ class MockResourceAllocationManager MOCK_METHOD1(SetAccessMode, void(const hmi_apis::Common_RCAccessMode::eType access_mode)); MOCK_CONST_METHOD0(GetAccessMode, hmi_apis::Common_RCAccessMode::eType()); - MOCK_METHOD3(SetResourceState, + MOCK_METHOD4(SetResourceState, void(const std::string& module_type, + const std::string& module_id, const uint32_t app_id, const rc_rpc_plugin::ResourceState::eType state)); - MOCK_CONST_METHOD1(IsResourceFree, bool(const std::string& module_type)); + MOCK_CONST_METHOD2(IsResourceFree, + bool(const std::string& module_type, + const std::string& module_id)); MOCK_METHOD0(ResetAllAllocations, void()); MOCK_METHOD2(SendOnRCStatusNotifications, void(rc_rpc_plugin::NotificationTrigger::eType, application_manager::ApplicationSharedPtr application)); MOCK_CONST_METHOD0(is_rc_enabled, bool()); MOCK_METHOD1(set_rc_enabled, void(const bool value)); + MOCK_METHOD3(ReleaseResource, + rc_rpc_plugin::ResourceReleasedState::eType( + const std::string& module_type, + const std::string& module_id, + const uint32_t application_id)); + MOCK_METHOD3(SetResourceAcquired, + void(const std::string& module_type, + const std::string& module_id, + const uint32_t app_id)); + MOCK_CONST_METHOD2(IsResourceAlreadyAcquiredByApp, + bool(const rc_rpc_plugin::ModuleUid& moduleUid, + const uint32_t app_id)); }; } // namespace rc_rpc_plugin_test diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/interior_data_cache_test.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/interior_data_cache_test.cc index b7eb4a554a..e8d9f6e45d 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/interior_data_cache_test.cc +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/interior_data_cache_test.cc @@ -44,35 +44,41 @@ TEST_F(InteriorDataCacheTest, InteriorDataCacheDoesNotContainRandomDataInitialy) { rc_rpc_plugin::InteriorDataCacheImpl cache; std::string module_type_key = "random_module_type"; - EXPECT_FALSE(cache.Contains(module_type_key)); - auto retrieved_data = cache.Retrieve(module_type_key); + std::string module_id = "34045662-a9dc-4823-8435-91056d4c26cb"; + rc_rpc_plugin::ModuleUid module(module_type_key, module_id); + EXPECT_FALSE(cache.Contains(module)); + auto retrieved_data = cache.Retrieve(module); EXPECT_EQ(smart_objects::SmartType_Null, retrieved_data.getType()); } TEST_F(InteriorDataCacheTest, CheckThatCacheContansDataAfterAdding) { rc_rpc_plugin::InteriorDataCacheImpl cache; const std::string module_type_key = "random_module_type"; + std::string module_id = "34045662-a9dc-4823-8435-91056d4c26cb"; + rc_rpc_plugin::ModuleUid module(module_type_key, module_id); smart_objects::SmartObject data; data["key"] = "value"; - cache.Add(module_type_key, data); - EXPECT_TRUE(cache.Contains(module_type_key)); - auto retrieved_data = cache.Retrieve(module_type_key); + cache.Add(module, data); + EXPECT_TRUE(cache.Contains(module)); + auto retrieved_data = cache.Retrieve(module); EXPECT_EQ(data, retrieved_data); } TEST_F(InteriorDataCacheTest, DataDoesNotExistAfterClear) { rc_rpc_plugin::InteriorDataCacheImpl cache; const std::string module_type_key = "random_module_type"; + std::string module_id = "34045662-a9dc-4823-8435-91056d4c26cb"; + rc_rpc_plugin::ModuleUid module(module_type_key, module_id); smart_objects::SmartObject data; data["key"] = "value"; - cache.Add(module_type_key, data); - EXPECT_TRUE(cache.Contains(module_type_key)); - auto Retrieved_data = cache.Retrieve(module_type_key); + cache.Add(module, data); + EXPECT_TRUE(cache.Contains(module)); + auto Retrieved_data = cache.Retrieve(module); EXPECT_EQ(Retrieved_data, data); cache.Clear(); - auto Retrieved_data_after_clear = cache.Retrieve(module_type_key); + auto Retrieved_data_after_clear = cache.Retrieve(module); EXPECT_EQ(smart_objects::SmartType_Null, Retrieved_data_after_clear.getType()); } @@ -81,19 +87,23 @@ TEST_F(InteriorDataCacheTest, MultipleDataCached) { rc_rpc_plugin::InteriorDataCacheImpl cache; const std::string module_type_key1 = "random_module_type"; + std::string module_id1 = "34045662-a9dc-4823-8435-91056d4c26cb"; + rc_rpc_plugin::ModuleUid module1(module_type_key1, module_id1); smart_objects::SmartObject data1; data1["key"] = "value1"; - cache.Add(module_type_key1, data1); - EXPECT_TRUE(cache.Contains(module_type_key1)); - auto retrieved_data1 = cache.Retrieve(module_type_key1); + cache.Add(module1, data1); + EXPECT_TRUE(cache.Contains(module1)); + auto retrieved_data1 = cache.Retrieve(module1); EXPECT_EQ(data1, retrieved_data1); std::string module_type_key2 = "random_module_type2"; + std::string module_id2 = "eb7739ea-b263-4fe1-af9c-9311d1acac2d"; + rc_rpc_plugin::ModuleUid module2(module_type_key2, module_id2); smart_objects::SmartObject data2; data2["key"] = "value2"; - cache.Add(module_type_key2, data2); - EXPECT_TRUE(cache.Contains(module_type_key2)); - auto retrieved_data2 = cache.Retrieve(module_type_key2); + cache.Add(module2, data2); + EXPECT_TRUE(cache.Contains(module2)); + auto retrieved_data2 = cache.Retrieve(module2); EXPECT_EQ(retrieved_data2, data2); ASSERT_TRUE(data1 != data2); @@ -105,30 +115,36 @@ TEST_F(InteriorDataCacheTest, RemoveFromChacheSuccessful) { rc_rpc_plugin::InteriorDataCacheImpl cache; const std::string module_type = "random_module_type"; + std::string module_id = "34045662-a9dc-4823-8435-91056d4c26cb"; + rc_rpc_plugin::ModuleUid module(module_type, module_id); smart_objects::SmartObject data; data["key"] = "value1"; - cache.Add(module_type, data); - EXPECT_TRUE(cache.Contains(module_type)); - auto retrieved_data1 = cache.Retrieve(module_type); + cache.Add(module, data); + EXPECT_TRUE(cache.Contains(module)); + auto retrieved_data1 = cache.Retrieve(module); EXPECT_EQ(data, retrieved_data1); - cache.Remove(module_type); - EXPECT_FALSE(cache.Contains(module_type)); - auto retreived = cache.Retrieve(module_type); + cache.Remove(module); + EXPECT_FALSE(cache.Contains(module)); + auto retreived = cache.Retrieve(module); EXPECT_EQ(smart_objects::SmartType_Null, retreived.getType()); } TEST_F(InteriorDataCacheTest, RemoveNotExistingNoSideEffects) { rc_rpc_plugin::InteriorDataCacheImpl cache; const std::string module_type_key = "random_module_type"; + std::string module_id = "34045662-a9dc-4823-8435-91056d4c26cb"; + rc_rpc_plugin::ModuleUid module(module_type_key, module_id); smart_objects::SmartObject data; data["key"] = "value"; - cache.Add(module_type_key, data); - cache.Remove("some other module_type"); + cache.Add(module, data); + rc_rpc_plugin::ModuleUid other_module("some other module_type", + "some other module id"); + cache.Remove(other_module); - EXPECT_TRUE(cache.Contains(module_type_key)); - auto retrieved_data = cache.Retrieve(module_type_key); + EXPECT_TRUE(cache.Contains(module)); + auto retrieved_data = cache.Retrieve(module); EXPECT_EQ(data, retrieved_data); } @@ -136,24 +152,28 @@ TEST_F(InteriorDataCacheTest, Exist2ModuleTypesRemoveOneAnotherOneLeft) { rc_rpc_plugin::InteriorDataCacheImpl cache; const std::string module_type_key1 = "random_module_type"; + std::string module_id1 = "34045662-a9dc-4823-8435-91056d4c26cb"; + rc_rpc_plugin::ModuleUid module1(module_type_key1, module_id1); smart_objects::SmartObject data1; data1["key"] = "value1"; - cache.Add(module_type_key1, data1); + cache.Add(module1, data1); std::string module_type_key2 = "random_module_type2"; + std::string module_id2 = "eb7739ea-b263-4fe1-af9c-9311d1acac2d"; + rc_rpc_plugin::ModuleUid module2(module_type_key2, module_id2); smart_objects::SmartObject data2; data2["key"] = "value2"; - cache.Add(module_type_key2, data2); + cache.Add(module2, data2); ASSERT_TRUE(data1 != data2); - cache.Remove(module_type_key1); - EXPECT_FALSE(cache.Contains(module_type_key1)); - EXPECT_TRUE(cache.Contains(module_type_key2)); + cache.Remove(module1); + EXPECT_FALSE(cache.Contains(module1)); + EXPECT_TRUE(cache.Contains(module2)); - auto retrieved_data1 = cache.Retrieve(module_type_key1); + auto retrieved_data1 = cache.Retrieve(module1); EXPECT_EQ(smart_objects::SmartType_Null, retrieved_data1.getType()); - auto retrieved_data2 = cache.Retrieve(module_type_key2); + auto retrieved_data2 = cache.Retrieve(module2); EXPECT_EQ(data2, retrieved_data2); } diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/mock_rc_helpers.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/mock_rc_helpers.cc new file mode 100644 index 0000000000..d5c8d09ae9 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/mock_rc_helpers.cc @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2019, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "rc_rpc_plugin/mock/mock_rc_helpers.h" + +namespace rc_rpc_plugin { + +const std::function<std::string(const std::string&)> +rc_rpc_plugin::RCHelpers::GetModuleTypeToDataMapping() { + return MockRCHelpers::rc_helpers_mock()->GetModuleTypeToDataMapping(); +} + +const std::function<std::string(const std::string&)> +rc_rpc_plugin::RCHelpers::GetModuleTypeToCapabilitiesMapping() { + return MockRCHelpers::rc_helpers_mock()->GetModuleTypeToCapabilitiesMapping(); +} + +const std::vector<std::string> rc_rpc_plugin::RCHelpers::GetModuleTypesList() { + return MockRCHelpers::rc_helpers_mock()->GetModuleTypesList(); +} + +rc_rpc_plugin::RCAppExtensionPtr rc_rpc_plugin::RCHelpers::GetRCExtension( + application_manager::Application& app) { + return MockRCHelpers::rc_helpers_mock()->GetRCExtension(app); +} + +smart_objects::SmartObjectSPtr +rc_rpc_plugin::RCHelpers::CreateUnsubscribeRequestToHMI( + const ModuleUid& module, const uint32_t correlation_id) { + return MockRCHelpers::rc_helpers_mock()->CreateUnsubscribeRequestToHMI( + module, correlation_id); +} + +std::vector<application_manager::ApplicationSharedPtr> +rc_rpc_plugin::RCHelpers::AppsSubscribedToModule( + application_manager::ApplicationManager& app_mngr, + const ModuleUid& module) { + return MockRCHelpers::rc_helpers_mock()->AppsSubscribedToModule(app_mngr, + module); +} + +std::vector<application_manager::ApplicationSharedPtr> +rc_rpc_plugin::RCHelpers::AppsSubscribedToModuleType( + application_manager::ApplicationManager& app_mngr, + const std::string& module_type) { + return MockRCHelpers::rc_helpers_mock()->AppsSubscribedToModuleType( + app_mngr, module_type); +} + +rc_rpc_plugin::RCHelpers::AppsModuleTypes +rc_rpc_plugin::RCHelpers::GetApplicationsAllowedModuleTypes( + application_manager::ApplicationManager& app_mngr) { + return MockRCHelpers::rc_helpers_mock()->GetApplicationsAllowedModuleTypes( + app_mngr); +} + +const std::vector<std::string> RCHelpers::buttons_climate() { + return MockRCHelpers::rc_helpers_mock()->buttons_climate(); +} + +const std::vector<std::string> RCHelpers::buttons_radio() { + return MockRCHelpers::rc_helpers_mock()->buttons_radio(); +} + +const rc_rpc_plugin::RCHelpers::ButtonsMap RCHelpers::buttons_map() { + return MockRCHelpers::rc_helpers_mock()->buttons_map(); +} + +std::vector<std::string> RCHelpers::GetModuleReadOnlyParams( + const std::string& module_type) { + return MockRCHelpers::rc_helpers_mock()->GetModuleReadOnlyParams(module_type); +} + +rc_rpc_types::ModuleIdConsentVector RCHelpers::FillModuleConsents( + const std::string& module_type, + const std::vector<std::string>& module_ids, + const std::vector<bool> allowed) { + return MockRCHelpers::rc_helpers_mock()->FillModuleConsents( + module_type, module_ids, allowed); +} + +std::vector<std::string> RCHelpers::RetrieveModuleIds( + const smart_objects::SmartObject& moduleIds) { + return MockRCHelpers::rc_helpers_mock()->RetrieveModuleIds(moduleIds); +} + +std::vector<bool> RCHelpers::RetrieveModuleConsents( + const smart_objects::SmartObject& consents) { + return MockRCHelpers::rc_helpers_mock()->RetrieveModuleConsents(consents); +} + +void RCHelpers::RemoveRedundantGPSDataFromIVDataMsg( + smart_objects::SmartObject& msg_params) { + return MockRCHelpers::rc_helpers_mock()->RemoveRedundantGPSDataFromIVDataMsg( + msg_params); +} + +MockRCHelpers* MockRCHelpers::rc_helpers_mock() { + static ::testing::NiceMock<MockRCHelpers> mock_rc_helpers; + return &mock_rc_helpers; +} + +} // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/rc_consent_manager_impl_test.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/rc_consent_manager_impl_test.cc new file mode 100644 index 0000000000..b4d826719a --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/rc_consent_manager_impl_test.cc @@ -0,0 +1,339 @@ +/* + * Copyright (c) 2019, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <ctime> +#include <memory> +#include <string> +#include <vector> + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#include "application_manager/mock_application_manager_settings.h" +#include "rc_rpc_plugin/rc_consent_manager_impl.h" +#include "resumption/last_state.h" +#include "resumption/last_state_impl.h" +#include "utils/date_time.h" +#include "utils/file_system.h" + +#include "application_manager/mock_application_manager.h" + +using test::components::application_manager_test::MockApplicationManager; +using test::components::application_manager_test:: + MockApplicationManagerSettings; + +using ::testing::NiceMock; +using ::testing::Return; +using ::testing::ReturnRef; + +namespace { +const std::string kPolicyApp1Id = "app1_id"; +const std::string kPolicyApp2Id = "app2_id"; +const std::string kMacAddress1 = "device1"; +const std::string kMacAddress2 = "device2"; +const std::string kClimateModule = "CLIMATE"; +const std::string kRadioModule = "RADIO"; +const std::string kAppTestStorageFolder = "app_test_storage_folder"; +const std::string kAppTestInfoStorage = "app_test_info_storage"; +const uint32_t kPeriodOfConsentExpired = 30; // in days +} // namespace + +namespace rc_rpc_plugin_test { +namespace rc_consent_manager_test { +using namespace rc_rpc_plugin::rc_rpc_types; +using namespace rc_rpc_plugin; + +class RCConsentManagerImplTest : public ::testing::Test { + public: + RCConsentManagerImplTest() + : current_date_(0u) + , last_state_(new resumption::LastStateImpl(kAppTestStorageFolder, + kAppTestInfoStorage)) + , rc_consent_manager_(new rc_rpc_plugin::RCConsentManagerImpl( + *last_state_, mock_app_mngr_, kPeriodOfConsentExpired)) {} + + void SetUp() OVERRIDE { + current_date_ = std::time(0); + RemoveTemproraryTetsFiles(); + + ON_CALL(mock_app_mngr_, get_settings()) + .WillByDefault(ReturnRef(mock_app_mnrg_settings_)); + ON_CALL(mock_app_mnrg_settings_, period_for_consent_expiration()) + .WillByDefault(Return(kPeriodOfConsentExpired)); + } + + void RemoveTemproraryTetsFiles() { + // Remove exists storage file + if (file_system::FileExists(kAppTestInfoStorage)) { + file_system::DeleteFile(kAppTestInfoStorage); + } + + // Remove exists storage folder + if (file_system::DirectoryExists(kAppTestStorageFolder)) { + file_system::RemoveDirectory(kAppTestStorageFolder); + } + + last_state_->get_dictionary().clear(); + } + + protected: + time_t current_date_; + NiceMock<MockApplicationManagerSettings> mock_app_mnrg_settings_; + NiceMock<MockApplicationManager> mock_app_mngr_; + std::unique_ptr<resumption::LastState> last_state_; + std::unique_ptr<rc_rpc_plugin::RCConsentManagerImpl> rc_consent_manager_; +}; + +TEST_F(RCConsentManagerImplTest, SaveAndGetModuleConsents_SUCCESS) { + const std::string radio_moduleId = "eb7739ea-b263-4fe1-af9c-9311d1acac2d"; + const std::string climate_moduleId = "34045662-a9dc-4823-8435-91056d4c26cb"; + + ModuleIdConsent radio_module_consent{ + {kRadioModule, radio_moduleId}, ModuleConsent::CONSENTED, current_date_}; + + ModuleIdConsent climate_module_consent{{kClimateModule, climate_moduleId}, + ModuleConsent::NOT_CONSENTED, + current_date_}; + + ModuleIdConsentVector module_consents{radio_module_consent, + climate_module_consent}; + + rc_consent_manager_->SaveModuleConsents( + kPolicyApp1Id, kMacAddress1, module_consents); + last_state_->SaveStateToFileSystem(); + + auto radio_consent = rc_consent_manager_->GetModuleConsent( + kPolicyApp1Id, kMacAddress1, {kRadioModule, radio_moduleId}); + auto climate_consent = rc_consent_manager_->GetModuleConsent( + kPolicyApp1Id, kMacAddress1, {kClimateModule, climate_moduleId}); + + EXPECT_EQ(ModuleConsent::CONSENTED, radio_consent); + EXPECT_EQ(ModuleConsent::NOT_CONSENTED, climate_consent); +} + +TEST_F(RCConsentManagerImplTest, ModuleId_NOT_EXISTS) { + const std::string radio_moduleId = "eb7739ea-b263-4fe1-af9c-9311d1acac2d"; + const std::string climate_moduleId = "34045662-a9dc-4823-8435-91056d4c26cb"; + + ModuleIdConsent radio_module_consent{ + {kRadioModule, radio_moduleId}, ModuleConsent::CONSENTED, current_date_}; + ModuleIdConsent climate_module_consent{{kClimateModule, climate_moduleId}, + ModuleConsent::CONSENTED, + current_date_}; + + const std::string uknown_moduleId = "639f1b7f-1d25-4dca-a2ce-00530860adea"; + const std::string uknown_moduleType = "UNKNOWN_TYPE"; + + ModuleUid unknown_module{uknown_moduleId, uknown_moduleType}; + + ModuleIdConsentVector module_consents{radio_module_consent, + climate_module_consent}; + + rc_consent_manager_->SaveModuleConsents( + kPolicyApp1Id, kMacAddress1, module_consents); + last_state_->SaveStateToFileSystem(); + + ModuleConsent consent = rc_consent_manager_->GetModuleConsent( + kPolicyApp1Id, kMacAddress1, unknown_module); + + EXPECT_EQ(ModuleConsent::NOT_EXISTS, consent); +} + +TEST_F(RCConsentManagerImplTest, ConsentIsExpired) { + time_t expired_date_45_days = + current_date_ - (date_time::SECONDS_IN_DAY * 45); + time_t expired_date_30_days = + current_date_ - (date_time::SECONDS_IN_DAY * 30); + time_t not_expired_date_29_days = + current_date_ - (date_time::SECONDS_IN_DAY * 29); + + const std::string moduleId1 = "dbef7693-adf9-42f1-95c7-5dff314d9985"; + const std::string moduleId2 = "1536b2ac-213f-463f-8589-a11453cd3729"; + const std::string moduleId3 = "e8b8169a-9f29-4499-a60b-2d126a1beffc"; + + ModuleUid module_resource1{kRadioModule, moduleId1}; + ModuleUid module_resource2{kRadioModule, moduleId2}; + ModuleUid module_resource3{kRadioModule, moduleId3}; + + ModuleIdConsent module_consent_expired1{ + module_resource1, ModuleConsent::CONSENTED, expired_date_45_days}; + ModuleIdConsent module_consent_expired2{ + module_resource2, ModuleConsent::CONSENTED, expired_date_30_days}; + + ModuleIdConsent module_consent_not_expired{ + module_resource3, ModuleConsent::CONSENTED, not_expired_date_29_days}; + + ModuleIdConsentVector module_consents{module_consent_expired1, + module_consent_expired2, + module_consent_not_expired}; + rc_consent_manager_->SaveModuleConsents( + kPolicyApp1Id, kMacAddress1, module_consents); + last_state_->SaveStateToFileSystem(); + + // All consents, which consent has been saved more than 30 days, will be + // removed. + rc_consent_manager_->RemoveExpiredConsents(); + + ModuleConsent expired_consent_45_days = rc_consent_manager_->GetModuleConsent( + kPolicyApp1Id, kMacAddress1, module_resource1); + EXPECT_EQ(ModuleConsent::NOT_EXISTS, expired_consent_45_days); + + ModuleConsent expired_consent_30_days = rc_consent_manager_->GetModuleConsent( + kPolicyApp1Id, kMacAddress1, module_resource2); + EXPECT_EQ(ModuleConsent::NOT_EXISTS, expired_consent_30_days); + + ModuleConsent not_expired_consent = rc_consent_manager_->GetModuleConsent( + kPolicyApp1Id, kMacAddress1, module_resource3); + EXPECT_EQ(ModuleConsent::CONSENTED, not_expired_consent); +} + +TEST_F(RCConsentManagerImplTest, + SaveModuleConsents_SameAppID_DifferentDeviceID_NotReplaced) { + const std::string moduleId = "cef4eae6-e22c-4943-bdc3-60e792414c4c"; + ModuleUid module_resource{kRadioModule, moduleId}; + + ModuleIdConsent radio_module_consent_app1_deviceId1{ + module_resource, ModuleConsent::CONSENTED, current_date_}; + + ModuleIdConsent radio_module_consent_app1_deviceId2{ + module_resource, ModuleConsent::NOT_CONSENTED, current_date_}; + + ModuleIdConsentVector module_consents_app1{ + radio_module_consent_app1_deviceId1}; + ModuleIdConsentVector module_consents_app2{ + radio_module_consent_app1_deviceId2}; + + rc_consent_manager_->SaveModuleConsents( + kPolicyApp1Id, kMacAddress1, module_consents_app1); + + rc_consent_manager_->SaveModuleConsents( + kPolicyApp1Id, kMacAddress2, module_consents_app2); + + last_state_->SaveStateToFileSystem(); + + // Module consents for same app ids and different device_id (mac_adress) will + // haven't been replaced each other + + ModuleConsent module_consent_deviceID1 = + rc_consent_manager_->GetModuleConsent( + kPolicyApp1Id, kMacAddress1, module_resource); + + ModuleConsent module_consent_deviceID2 = + rc_consent_manager_->GetModuleConsent( + kPolicyApp1Id, kMacAddress2, module_resource); + + EXPECT_EQ(ModuleConsent::CONSENTED, module_consent_deviceID1); + + // // Module consent for app_id2 has different value as has been saved above + EXPECT_EQ(ModuleConsent::NOT_CONSENTED, module_consent_deviceID2); +} + +TEST_F(RCConsentManagerImplTest, + SaveModuleConsents_SameAppID_SameDeviceID_Replaced) { + const std::string moduleId = "194aee9e-26cb-4f48-a775-8841a658002d"; + + ModuleUid radio_module_resource_consented{kRadioModule, moduleId}; + ModuleUid radio_module_resource_not_consented{kRadioModule, moduleId}; + + ModuleIdConsent radio_module_consent_app1_deviceId1{ + radio_module_resource_consented, ModuleConsent::CONSENTED, current_date_}; + + ModuleIdConsent radio_module_consent_app1_deviceId2{ + radio_module_resource_not_consented, + ModuleConsent::NOT_CONSENTED, + current_date_}; + + ModuleIdConsentVector module_consents_app1{ + radio_module_consent_app1_deviceId1}; + ModuleIdConsentVector module_consents_app2{ + radio_module_consent_app1_deviceId2}; + + rc_consent_manager_->SaveModuleConsents( + kPolicyApp1Id, kMacAddress1, module_consents_app1); + + last_state_->SaveStateToFileSystem(); + + rc_consent_manager_->SaveModuleConsents( + kPolicyApp1Id, kMacAddress1, module_consents_app2); + + last_state_->SaveStateToFileSystem(); + + // Module consents for same app ids and same device_id (mac_adress) will + // have been replaced each other + + ModuleConsent module_consent = rc_consent_manager_->GetModuleConsent( + kPolicyApp1Id, kMacAddress1, radio_module_resource_not_consented); + + EXPECT_EQ(ModuleConsent::NOT_CONSENTED, module_consent); +} + +TEST_F(RCConsentManagerImplTest, RemoveAllModuleConsents_SUCCESS) { + const std::string moduleId = "1c5408f2-9766-464c-a7bf-d834b62f43fa"; + + ModuleUid module_resource{kRadioModule, moduleId}; + + ModuleIdConsent radio_module_consent_app1_deviceId1{ + module_resource, ModuleConsent::CONSENTED, current_date_}; + + ModuleIdConsent radio_module_consent_app1_deviceId2{ + module_resource, ModuleConsent::NOT_CONSENTED, current_date_}; + + ModuleIdConsentVector module_consents_app1{ + radio_module_consent_app1_deviceId1}; + ModuleIdConsentVector module_consents_app2{ + radio_module_consent_app1_deviceId2}; + + rc_consent_manager_->SaveModuleConsents( + kPolicyApp1Id, kMacAddress1, module_consents_app1); + + rc_consent_manager_->SaveModuleConsents( + kPolicyApp1Id, kMacAddress2, module_consents_app2); + + last_state_->SaveStateToFileSystem(); + + rc_consent_manager_->RemoveAllConsents(); + + ModuleConsent module_consent_deviceID1 = + rc_consent_manager_->GetModuleConsent( + kPolicyApp1Id, kMacAddress1, module_resource); + + ModuleConsent module_consent_deviceID2 = + rc_consent_manager_->GetModuleConsent( + kPolicyApp1Id, kMacAddress2, module_resource); + + EXPECT_EQ(ModuleConsent::NOT_EXISTS, module_consent_deviceID1); + + EXPECT_EQ(ModuleConsent::NOT_EXISTS, module_consent_deviceID2); +} + +} // namespace rc_consent_manager_test +} // namespace rc_rpc_plugin_test diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/resource_allocation_manager_impl_test.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/resource_allocation_manager_impl_test.cc index bbf9032c96..70ed832cb1 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/resource_allocation_manager_impl_test.cc +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/test/resource_allocation_manager_impl_test.cc @@ -30,14 +30,18 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include <algorithm> +#include <memory> #include "gtest/gtest.h" #include "application_manager/mock_application.h" #include "application_manager/mock_application_manager.h" +#include "application_manager/mock_hmi_capabilities.h" #include "application_manager/mock_rpc_service.h" #include "application_manager/policies/mock_policy_handler_interface.h" #include "interfaces/HMI_API.h" #include "interfaces/MOBILE_API.h" +#include "rc_rpc_plugin/mock/mock_rc_capabilities_manager.h" +#include "rc_rpc_plugin/mock/mock_rc_helpers.h" #include "rc_rpc_plugin/rc_module_constants.h" #include "rc_rpc_plugin/rc_rpc_plugin.h" #include "rc_rpc_plugin/resource_allocation_manager_impl.h" @@ -50,6 +54,7 @@ using ::application_manager::ApplicationSharedPtr; using ::application_manager::Message; using ::application_manager::MessageType; using ::protocol_handler::MessagePriority; +using ::rc_rpc_plugin::MockRCHelpers; using ::testing::_; using ::testing::DoAll; using ::testing::Eq; @@ -65,6 +70,7 @@ namespace { const bool kDeviceHandle = 1u; const std::string kModuleType1 = "CLIMATE"; const std::string kModuleType2 = "RADIO"; +const std::string kModuleId = "id1"; const int32_t kConnectionKey = 5; const int32_t kCorrelationId = 5; const uint32_t kAppId1 = 11u; @@ -74,12 +80,25 @@ const std::string policy_app_id_1_ = "policy_id_1"; const uint32_t kSizeOfModules = 6u; const application_manager::WindowID kDefaultWindowId = mobile_apis::PredefinedWindows::DEFAULT_WINDOW; +const rc_rpc_plugin::Grid KDefaultUserLocation = {2, 0, 0, 1, 1, 1}; +const rc_rpc_plugin::Grid kDriverLocation = {0, 0, 0, 1, 1, 1}; +const rc_rpc_plugin::Grid kInvalidLocation = {0, 0, 0, 0, 0, 0}; +const std::vector<std::string> kModuleList = { + rc_rpc_plugin::enums_value::kClimate, + rc_rpc_plugin::enums_value::kRadio, + rc_rpc_plugin::enums_value::kSeat, + rc_rpc_plugin::enums_value::kAudio, + rc_rpc_plugin::enums_value::kLight, + rc_rpc_plugin::enums_value::kHmiSettings}; + } // namespace namespace rc_rpc_plugin_test { using namespace rc_rpc_plugin; +typedef std::shared_ptr<MockRCHelpers> MockRCHelpersPtr; + class RAManagerTest : public ::testing::Test { public: RAManagerTest() @@ -88,22 +107,58 @@ class RAManagerTest : public ::testing::Test { , mock_app_1_(std::make_shared<NiceMock<MockApplication> >()) , mock_app_2_(std::make_shared<NiceMock<MockApplication> >()) , apps_lock_ptr_(std::make_shared<sync_primitives::Lock>()) - , apps_da_(apps_, apps_lock_ptr_) { + , apps_da_(apps_, apps_lock_ptr_) + , module_service_area_(0, 0, 0, 3, 2, 1) + , mock_rc_helpers_(MockRCHelpers::rc_helpers_mock()) { ON_CALL(mock_app_mngr_, GetPolicyHandler()) .WillByDefault(ReturnRef(mock_policy_handler_)); auto plugin_id = rc_rpc_plugin::RCRPCPlugin::kRCPluginID; app_ext_ptr_ = std::make_shared<rc_rpc_plugin::RCAppExtension>(plugin_id); ON_CALL(*mock_app_1_, app_id()).WillByDefault(Return(kAppId1)); + PrepareResources(); + ON_CALL(mock_rc_capabilities_manager_, GetResources()) + .WillByDefault(Return(resources_)); + ON_CALL(mock_rc_capabilities_manager_, IsSeatLocationCapabilityProvided()) + .WillByDefault(Return(false)); + ON_CALL(mock_rc_capabilities_manager_, IsMultipleAccessAllowed(_)) + .WillByDefault(Return(true)); + ON_CALL(mock_rc_capabilities_manager_, GetModuleServiceArea(_)) + .WillByDefault(Return(module_service_area_)); + + ON_CALL(mock_app_mngr_, application(kAppId1)) + .WillByDefault(Return(mock_app_1_)); + ON_CALL(*mock_app_1_, + QueryInterface(rc_rpc_plugin::RCRPCPlugin::kRCPluginID)) + .WillByDefault(Return(app_ext_ptr_)); + + ON_CALL(mock_app_mngr_, application(kAppId2)) + .WillByDefault(Return(mock_app_2_)); + ON_CALL(*mock_app_2_, + QueryInterface(rc_rpc_plugin::RCRPCPlugin::kRCPluginID)) + .WillByDefault(Return(app_ext_ptr_)); + OnRCStatusNotificationExpectations(); } + void SetUp() OVERRIDE { + rc_app_extension_ = std::make_shared<rc_rpc_plugin::RCAppExtension>( + static_cast<application_manager::AppExtensionUID>( + rc_rpc_plugin::RCRPCPlugin::kRCPluginID)); + ON_CALL(mock_rc_capabilities_manager_, + GetDriverLocationFromSeatLocationCapability()) + .WillByDefault(Return(kDriverLocation)); + ON_CALL(*mock_rc_helpers_, GetRCExtension(_)) + .WillByDefault(Return(rc_app_extension_)); + } + void CheckResultWithHMILevelAndAccessMode( ResourceAllocationManagerImpl& ra_manager, mobile_apis::HMILevel::eType app_level, const rc_rpc_plugin::AcquireResult::eType expected_result, const hmi_apis::Common_RCAccessMode::eType access_mode); + void PrepareResources(); void OnRCStatusNotificationExpectations(); protected: @@ -119,6 +174,12 @@ class RAManagerTest : public ::testing::Test { application_manager::ApplicationSet apps_; std::shared_ptr<sync_primitives::Lock> apps_lock_ptr_; DataAccessor<application_manager::ApplicationSet> apps_da_; + testing::NiceMock<rc_rpc_plugin_test::MockRCCapabilitiesManager> + mock_rc_capabilities_manager_; + std::vector<ModuleUid> resources_; + Grid module_service_area_; + RCAppExtensionPtr rc_app_extension_; + MockRCHelpers* mock_rc_helpers_; }; void RAManagerTest::CheckResultWithHMILevelAndAccessMode( @@ -133,20 +194,27 @@ void RAManagerTest::CheckResultWithHMILevelAndAccessMode( ra_manager.SetAccessMode(access_mode); EXPECT_EQ(rc_rpc_plugin::AcquireResult::ALLOWED, - ra_manager.AcquireResource(kModuleType1, kAppId1)); + ra_manager.AcquireResource(kModuleType1, kModuleId, kAppId1)); + + ra_manager.SetResourceAcquired(kModuleType1, kModuleId, kAppId1); + EXPECT_CALL(mock_app_mngr_, application(kAppId2)) .WillOnce(Return(mock_app_2_)); EXPECT_CALL(*mock_app_2_, hmi_level(kDefaultWindowId)) .WillOnce(Return(app_level)); // Second app tries to get already acquired resource by 1st app - EXPECT_EQ(expected_result, ra_manager.AcquireResource(kModuleType1, kAppId2)); + EXPECT_EQ(expected_result, + ra_manager.AcquireResource(kModuleType1, kModuleId, kAppId2)); +} + +void RAManagerTest::PrepareResources() { + for (auto& module_type : kModuleList) { + ModuleUid module(module_type, kModuleId); + resources_.push_back(module); + } } void RAManagerTest::OnRCStatusNotificationExpectations() { - ON_CALL(mock_app_mngr_, application(kAppId1)) - .WillByDefault(Return(mock_app_1_)); - ON_CALL(*mock_app_1_, QueryInterface(rc_rpc_plugin::RCRPCPlugin::kRCPluginID)) - .WillByDefault(Return(app_ext_ptr_)); apps_.insert(mock_app_1_); ON_CALL(mock_app_mngr_, applications()).WillByDefault(Return(apps_da_)); } @@ -155,19 +223,21 @@ TEST_F(RAManagerTest, AcquireResource_NoAppRegistered_Expect_InUse) { // Arrange EXPECT_CALL(mock_app_mngr_, application(kAppId1)) .WillOnce(Return(ApplicationSharedPtr())); - ResourceAllocationManagerImpl ra_manager(mock_app_mngr_, mock_rpc_service_); + ResourceAllocationManagerImpl ra_manager( + mock_app_mngr_, mock_rpc_service_, mock_rc_capabilities_manager_); // Act & Assert EXPECT_EQ(rc_rpc_plugin::AcquireResult::IN_USE, - ra_manager.AcquireResource(kModuleType1, kAppId1)); + ra_manager.AcquireResource(kModuleType1, kModuleId, kAppId1)); } TEST_F(RAManagerTest, AcquireResource_AppRegisteredAnyHmiLevelResourceFree_Expect_Allowed) { // Arrange - ResourceAllocationManagerImpl ra_manager(mock_app_mngr_, mock_rpc_service_); + ResourceAllocationManagerImpl ra_manager( + mock_app_mngr_, mock_rpc_service_, mock_rc_capabilities_manager_); // Act & Assert EXPECT_EQ(rc_rpc_plugin::AcquireResult::ALLOWED, - ra_manager.AcquireResource(kModuleType1, kAppId1)); + ra_manager.AcquireResource(kModuleType1, kModuleId, kAppId1)); } TEST_F( @@ -176,14 +246,15 @@ TEST_F( // Arrange EXPECT_CALL(mock_app_mngr_, application(kAppId1)) .WillOnce(Return(mock_app_1_)); - ResourceAllocationManagerImpl ra_manager(mock_app_mngr_, mock_rpc_service_); + ResourceAllocationManagerImpl ra_manager( + mock_app_mngr_, mock_rpc_service_, mock_rc_capabilities_manager_); EXPECT_EQ(rc_rpc_plugin::AcquireResult::ALLOWED, - ra_manager.AcquireResource(kModuleType1, kAppId1)); + ra_manager.AcquireResource(kModuleType1, kModuleId, kAppId1)); EXPECT_CALL(mock_app_mngr_, application(kAppId1)) .WillOnce(Return(mock_app_1_)); // Same app tries to get already acquired resource EXPECT_EQ(rc_rpc_plugin::AcquireResult::ALLOWED, - ra_manager.AcquireResource(kModuleType1, kAppId1)); + ra_manager.AcquireResource(kModuleType1, kModuleId, kAppId1)); } TEST_F( @@ -196,7 +267,8 @@ TEST_F( const AcquireResult::eType expected_result = AcquireResult::REJECTED; const Common_RCAccessMode::eType access_mode = Common_RCAccessMode::eType::AUTO_ALLOW; - ResourceAllocationManagerImpl ra_manager(mock_app_mngr_, mock_rpc_service_); + ResourceAllocationManagerImpl ra_manager( + mock_app_mngr_, mock_rpc_service_, mock_rc_capabilities_manager_); CheckResultWithHMILevelAndAccessMode( ra_manager, app_level, expected_result, access_mode); } @@ -211,7 +283,8 @@ TEST_F( const AcquireResult::eType expected_result = AcquireResult::IN_USE; const Common_RCAccessMode::eType access_mode = Common_RCAccessMode::eType::AUTO_DENY; - ResourceAllocationManagerImpl ra_manager(mock_app_mngr_, mock_rpc_service_); + ResourceAllocationManagerImpl ra_manager( + mock_app_mngr_, mock_rpc_service_, mock_rc_capabilities_manager_); CheckResultWithHMILevelAndAccessMode( ra_manager, app_level, expected_result, access_mode); } @@ -226,7 +299,8 @@ TEST_F( const AcquireResult::eType expected_result = AcquireResult::ALLOWED; const Common_RCAccessMode::eType access_mode = Common_RCAccessMode::eType::AUTO_ALLOW; - ResourceAllocationManagerImpl ra_manager(mock_app_mngr_, mock_rpc_service_); + ResourceAllocationManagerImpl ra_manager( + mock_app_mngr_, mock_rpc_service_, mock_rc_capabilities_manager_); CheckResultWithHMILevelAndAccessMode( ra_manager, app_level, expected_result, access_mode); } @@ -241,7 +315,8 @@ TEST_F( const AcquireResult::eType expected_result = AcquireResult::ASK_DRIVER; const Common_RCAccessMode::eType access_mode = Common_RCAccessMode::eType::ASK_DRIVER; - ResourceAllocationManagerImpl ra_manager(mock_app_mngr_, mock_rpc_service_); + ResourceAllocationManagerImpl ra_manager( + mock_app_mngr_, mock_rpc_service_, mock_rc_capabilities_manager_); CheckResultWithHMILevelAndAccessMode( ra_manager, app_level, expected_result, access_mode); } @@ -249,32 +324,36 @@ TEST_F( TEST_F(RAManagerTest, AcquireResource_AcquiredModuleIsRejectedForApp2_ExpectApp2Rejected) { // Arrange - ResourceAllocationManagerImpl ra_manager(mock_app_mngr_, mock_rpc_service_); + ResourceAllocationManagerImpl ra_manager( + mock_app_mngr_, mock_rpc_service_, mock_rc_capabilities_manager_); EXPECT_CALL(mock_app_mngr_, application(kAppId1)) .WillRepeatedly(Return(mock_app_1_)); EXPECT_EQ(AcquireResult::ALLOWED, - ra_manager.AcquireResource(kModuleType1, kAppId1)); + ra_manager.AcquireResource(kModuleType1, kModuleId, kAppId1)); + + ra_manager.SetResourceAcquired(kModuleType1, kModuleId, kAppId1); // Act - ra_manager.OnDriverDisallowed(kModuleType1, kAppId2); + ra_manager.OnDriverDisallowed(kModuleType1, kModuleId, kAppId2); // Assert EXPECT_CALL(mock_app_mngr_, application(kAppId2)) .WillOnce(Return(mock_app_2_)); EXPECT_EQ(AcquireResult::REJECTED, - ra_manager.AcquireResource(kModuleType1, kAppId2)); + ra_manager.AcquireResource(kModuleType1, kModuleId, kAppId2)); } TEST_F(RAManagerTest, AppExit_ReleaseResource) { // Arrange - ResourceAllocationManagerImpl ra_manager(mock_app_mngr_, mock_rpc_service_); + ResourceAllocationManagerImpl ra_manager( + mock_app_mngr_, mock_rpc_service_, mock_rc_capabilities_manager_); ra_manager.SetAccessMode(hmi_apis::Common_RCAccessMode::eType::AUTO_DENY); EXPECT_CALL(mock_app_mngr_, application(kAppId1)) .WillRepeatedly(Return(mock_app_1_)); EXPECT_EQ(rc_rpc_plugin::AcquireResult::ALLOWED, - ra_manager.AcquireResource(kModuleType1, kAppId1)); + ra_manager.AcquireResource(kModuleType1, kModuleId, kAppId1)); // Act ra_manager.OnApplicationEvent( @@ -284,19 +363,22 @@ TEST_F(RAManagerTest, AppExit_ReleaseResource) { .WillRepeatedly(Return(mock_app_2_)); EXPECT_EQ(rc_rpc_plugin::AcquireResult::ALLOWED, - ra_manager.AcquireResource(kModuleType1, kAppId2)); + ra_manager.AcquireResource(kModuleType1, kModuleId, kAppId2)); } TEST_F(RAManagerTest, AnotherAppExit_NoReleaseResource) { // Arrange - ResourceAllocationManagerImpl ra_manager(mock_app_mngr_, mock_rpc_service_); + ResourceAllocationManagerImpl ra_manager( + mock_app_mngr_, mock_rpc_service_, mock_rc_capabilities_manager_); ra_manager.SetAccessMode(hmi_apis::Common_RCAccessMode::eType::AUTO_DENY); EXPECT_CALL(mock_app_mngr_, application(kAppId1)) .WillOnce(Return(mock_app_1_)); EXPECT_EQ(rc_rpc_plugin::AcquireResult::ALLOWED, - ra_manager.AcquireResource(kModuleType1, kAppId1)); + ra_manager.AcquireResource(kModuleType1, kModuleId, kAppId1)); + + ra_manager.SetResourceAcquired(kModuleType1, kModuleId, kAppId1); EXPECT_CALL(mock_app_mngr_, application(kAppId2)) .WillRepeatedly(Return(mock_app_2_)); @@ -312,12 +394,13 @@ TEST_F(RAManagerTest, AnotherAppExit_NoReleaseResource) { EXPECT_CALL(*mock_app_2_, hmi_level(kDefaultWindowId)) .WillOnce(Return(mobile_apis::HMILevel::HMI_FULL)); EXPECT_EQ(rc_rpc_plugin::AcquireResult::IN_USE, - ra_manager.AcquireResource(kModuleType1, kAppId2)); + ra_manager.AcquireResource(kModuleType1, kModuleId, kAppId2)); } TEST_F(RAManagerTest, AppUnregistered_ReleaseResource) { // Arrange - ResourceAllocationManagerImpl ra_manager(mock_app_mngr_, mock_rpc_service_); + ResourceAllocationManagerImpl ra_manager( + mock_app_mngr_, mock_rpc_service_, mock_rc_capabilities_manager_); ra_manager.SetAccessMode(hmi_apis::Common_RCAccessMode::eType::AUTO_DENY); RCAppExtensionPtr rc_extention_ptr = @@ -325,7 +408,7 @@ TEST_F(RAManagerTest, AppUnregistered_ReleaseResource) { rc_rpc_plugin::RCRPCPlugin::kRCPluginID)); EXPECT_EQ(rc_rpc_plugin::AcquireResult::ALLOWED, - ra_manager.AcquireResource(kModuleType1, kAppId1)); + ra_manager.AcquireResource(kModuleType1, kModuleId, kAppId1)); // Act application_manager::ApplicationSharedPtr app_ptr(mock_app_1_); @@ -338,18 +421,21 @@ TEST_F(RAManagerTest, AppUnregistered_ReleaseResource) { .WillOnce(Return(mock_app_2_)); EXPECT_EQ(rc_rpc_plugin::AcquireResult::ALLOWED, - ra_manager.AcquireResource(kModuleType1, kAppId2)); + ra_manager.AcquireResource(kModuleType1, kModuleId, kAppId2)); } TEST_F(RAManagerTest, AnotherAppUnregistered_NoReleaseResource) { // Arrange - ResourceAllocationManagerImpl ra_manager(mock_app_mngr_, mock_rpc_service_); + ResourceAllocationManagerImpl ra_manager( + mock_app_mngr_, mock_rpc_service_, mock_rc_capabilities_manager_); ra_manager.SetAccessMode(hmi_apis::Common_RCAccessMode::eType::AUTO_DENY); EXPECT_CALL(mock_app_mngr_, application(kAppId1)) .WillOnce(Return(mock_app_1_)); EXPECT_EQ(rc_rpc_plugin::AcquireResult::ALLOWED, - ra_manager.AcquireResource(kModuleType1, kAppId1)); + ra_manager.AcquireResource(kModuleType1, kModuleId, kAppId1)); + + ra_manager.SetResourceAcquired(kModuleType1, kModuleId, kAppId1); EXPECT_CALL(mock_app_mngr_, application(kAppId1)) .WillRepeatedly(Return(mock_app_2_)); @@ -366,21 +452,22 @@ TEST_F(RAManagerTest, AnotherAppUnregistered_NoReleaseResource) { EXPECT_CALL(*mock_app_2_, hmi_level(kDefaultWindowId)) .WillOnce(Return(mobile_apis::HMILevel::HMI_FULL)); EXPECT_EQ(rc_rpc_plugin::AcquireResult::IN_USE, - ra_manager.AcquireResource(kModuleType1, kAppId2)); + ra_manager.AcquireResource(kModuleType1, kModuleId, kAppId2)); } TEST_F(RAManagerTest, AppsDisallowed_ReleaseAllResources) { // Arrange - ResourceAllocationManagerImpl ra_manager(mock_app_mngr_, mock_rpc_service_); + ResourceAllocationManagerImpl ra_manager( + mock_app_mngr_, mock_rpc_service_, mock_rc_capabilities_manager_); ra_manager.SetAccessMode(hmi_apis::Common_RCAccessMode::eType::AUTO_DENY); EXPECT_CALL(mock_app_mngr_, application(kAppId1)) .WillRepeatedly(Return(mock_app_1_)); EXPECT_EQ(rc_rpc_plugin::AcquireResult::ALLOWED, - ra_manager.AcquireResource(kModuleType1, kAppId1)); + ra_manager.AcquireResource(kModuleType1, kModuleId, kAppId1)); EXPECT_EQ(rc_rpc_plugin::AcquireResult::ALLOWED, - ra_manager.AcquireResource(kModuleType2, kAppId1)); + ra_manager.AcquireResource(kModuleType2, kModuleId, kAppId1)); application_manager::ApplicationSet apps; apps.insert(mock_app_1_); @@ -406,15 +493,16 @@ TEST_F(RAManagerTest, AppsDisallowed_ReleaseAllResources) { EXPECT_CALL(*mock_app_2_, hmi_level(kDefaultWindowId)) .WillRepeatedly(Return(mobile_apis::HMILevel::HMI_FULL)); EXPECT_EQ(rc_rpc_plugin::AcquireResult::ALLOWED, - ra_manager.AcquireResource(kModuleType1, kAppId2)); + ra_manager.AcquireResource(kModuleType1, kModuleId, kAppId2)); EXPECT_EQ(rc_rpc_plugin::AcquireResult::ALLOWED, - ra_manager.AcquireResource(kModuleType2, kAppId2)); + ra_manager.AcquireResource(kModuleType2, kModuleId, kAppId2)); Mock::VerifyAndClearExpectations(&mock_app_mngr_); } TEST_F(RAManagerTest, AppGotRevokedModulesWithPTU_ReleaseRevokedResource) { // Arrange - ResourceAllocationManagerImpl ra_manager(mock_app_mngr_, mock_rpc_service_); + ResourceAllocationManagerImpl ra_manager( + mock_app_mngr_, mock_rpc_service_, mock_rc_capabilities_manager_); ra_manager.SetAccessMode(hmi_apis::Common_RCAccessMode::eType::AUTO_DENY); EXPECT_CALL(mock_app_mngr_, application(kAppId1)) @@ -440,9 +528,13 @@ TEST_F(RAManagerTest, AppGotRevokedModulesWithPTU_ReleaseRevokedResource) { .WillRepeatedly(Return(policy_app_id_1_)); EXPECT_EQ(rc_rpc_plugin::AcquireResult::ALLOWED, - ra_manager.AcquireResource(kModuleType1, kAppId1)); + ra_manager.AcquireResource(kModuleType1, kModuleId, kAppId1)); + + ra_manager.SetResourceAcquired(kModuleType1, kModuleId, kAppId1); + EXPECT_EQ(rc_rpc_plugin::AcquireResult::ALLOWED, - ra_manager.AcquireResource(kModuleType2, kAppId1)); + ra_manager.AcquireResource(kModuleType2, kModuleId, kAppId1)); + ra_manager.SetResourceAcquired(kModuleType2, kModuleId, kAppId1); application_manager::ApplicationSet apps; apps.insert(mock_app_1_); @@ -452,29 +544,31 @@ TEST_F(RAManagerTest, AppGotRevokedModulesWithPTU_ReleaseRevokedResource) { EXPECT_CALL(mock_app_mngr_, applications()).WillRepeatedly(Return(apps_da)); - Resources allowed_modules; + std::vector<std::string> allowed_modules; allowed_modules.push_back(kModuleType1); EXPECT_CALL(mock_policy_handler_, GetModuleTypes(policy_app_id_1_, _)) .WillOnce(DoAll(SetArgPointee<1>(allowed_modules), Return(true))); - // Act - ra_manager.OnPolicyEvent(application_manager::plugin_manager::PolicyEvent:: - kApplicationPolicyUpdated); - EXPECT_CALL(mock_app_mngr_, application(kAppId2)) .WillRepeatedly(Return(mock_app_2_)); EXPECT_CALL(*mock_app_2_, hmi_level(kDefaultWindowId)) .WillRepeatedly(Return(mobile_apis::HMILevel::HMI_FULL)); + + // Act + ra_manager.OnPolicyEvent(application_manager::plugin_manager::PolicyEvent:: + kApplicationPolicyUpdated); + EXPECT_EQ(rc_rpc_plugin::AcquireResult::IN_USE, - ra_manager.AcquireResource(kModuleType1, kAppId2)); + ra_manager.AcquireResource(kModuleType1, kModuleId, kAppId2)); EXPECT_EQ(rc_rpc_plugin::AcquireResult::ALLOWED, - ra_manager.AcquireResource(kModuleType2, kAppId2)); + ra_manager.AcquireResource(kModuleType2, kModuleId, kAppId2)); Mock::VerifyAndClearExpectations(&mock_app_mngr_); } TEST_F(RAManagerTest, GetAccessMode_ExpectedSameAsHadSet) { - ResourceAllocationManagerImpl ra_manager(mock_app_mngr_, mock_rpc_service_); + ResourceAllocationManagerImpl ra_manager( + mock_app_mngr_, mock_rpc_service_, mock_rc_capabilities_manager_); ra_manager.SetAccessMode(hmi_apis::Common_RCAccessMode::AUTO_DENY); EXPECT_EQ(hmi_apis::Common_RCAccessMode::AUTO_DENY, @@ -495,7 +589,8 @@ TEST_F(RAManagerTest, GetAccessMode_ExpectedSameAsHadSet) { TEST_F(RAManagerTest, OnRCStatus_AppRegistation_RC_allowed) { // Arrange - ResourceAllocationManagerImpl ra_manager(mock_app_mngr_, mock_rpc_service_); + ResourceAllocationManagerImpl ra_manager( + mock_app_mngr_, mock_rpc_service_, mock_rc_capabilities_manager_); ON_CALL((*mock_app_1_), is_remote_control_supported()) .WillByDefault(Return(true)); ON_CALL((*mock_app_1_), hmi_app_id()).WillByDefault(Return(kHMIAppId1)); @@ -524,7 +619,8 @@ TEST_F(RAManagerTest, OnRCStatus_AppRegistation_RC_allowed) { TEST_F(RAManagerTest, OnRCStatus_AppRegistation_RC_disallowed) { // Arrange - ResourceAllocationManagerImpl ra_manager(mock_app_mngr_, mock_rpc_service_); + ResourceAllocationManagerImpl ra_manager( + mock_app_mngr_, mock_rpc_service_, mock_rc_capabilities_manager_); ra_manager.set_rc_enabled(false); ON_CALL((*mock_app_1_), is_remote_control_supported()) @@ -552,7 +648,8 @@ TEST_F(RAManagerTest, OnRCStatus_AppRegistation_RC_disallowed) { TEST_F(RAManagerTest, OnRCStatus_RCStateChanging_RC_disabling) { // Arrange - ResourceAllocationManagerImpl ra_manager(mock_app_mngr_, mock_rpc_service_); + ResourceAllocationManagerImpl ra_manager( + mock_app_mngr_, mock_rpc_service_, mock_rc_capabilities_manager_); ON_CALL((*mock_app_1_), is_remote_control_supported()) .WillByDefault(Return(true)); ON_CALL((*mock_app_1_), hmi_app_id()).WillByDefault(Return(kHMIAppId1)); @@ -589,7 +686,8 @@ TEST_F(RAManagerTest, OnRCStatus_RCStateChanging_RC_disabling) { TEST_F(RAManagerTest, OnRCStatus_RCStateChanging_RC_enabling) { // Arrange - ResourceAllocationManagerImpl ra_manager(mock_app_mngr_, mock_rpc_service_); + ResourceAllocationManagerImpl ra_manager( + mock_app_mngr_, mock_rpc_service_, mock_rc_capabilities_manager_); ON_CALL((*mock_app_1_), is_remote_control_supported()) .WillByDefault(Return(true)); ON_CALL((*mock_app_1_), hmi_app_id()).WillByDefault(Return(kHMIAppId1)); @@ -626,14 +724,17 @@ TEST_F(RAManagerTest, OnRCStatus_RCStateChanging_RC_enabling) { TEST_F(RAManagerTest, OnRCStatus_ModuleAllocation) { // Arrange - ResourceAllocationManagerImpl ra_manager(mock_app_mngr_, mock_rpc_service_); + ResourceAllocationManagerImpl ra_manager( + mock_app_mngr_, mock_rpc_service_, mock_rc_capabilities_manager_); ON_CALL((*mock_app_1_), is_remote_control_supported()) .WillByDefault(Return(true)); ON_CALL((*mock_app_1_), hmi_app_id()).WillByDefault(Return(kHMIAppId1)); EXPECT_EQ(rc_rpc_plugin::AcquireResult::ALLOWED, - ra_manager.AcquireResource(kModuleType1, kAppId1)); + ra_manager.AcquireResource(kModuleType1, kModuleId, kAppId1)); + + ra_manager.SetResourceAcquired(kModuleType1, kModuleId, kAppId1); application_manager::commands::MessageSharedPtr message_to_mob; EXPECT_CALL(mock_rpc_service_, SendMessageToMobile(_, false)) @@ -668,4 +769,118 @@ TEST_F(RAManagerTest, OnRCStatus_ModuleAllocation) { kHMIAppId1); } +// UL - User Location +// If User Location is invalid, in any case AcquireResult will be REJECTED +TEST_F(RAManagerTest, AcquireResource_UL_IsInvalid_REJECTED) { + ResourceAllocationManagerImpl ra_manager( + mock_app_mngr_, mock_rpc_service_, mock_rc_capabilities_manager_); + + ON_CALL(mock_rc_capabilities_manager_, IsSeatLocationCapabilityProvided()) + .WillByDefault(Return(true)); + rc_app_extension_->SetUserLocation(kInvalidLocation); + + EXPECT_EQ(AcquireResult::REJECTED, + ra_manager.AcquireResource(kModuleType1, kModuleId, kAppId1)); +} + +// UL - User Location, MA - Multiple Access +TEST_F(RAManagerTest, + AcquireResource_UL_IsValid_ResourceIsFree_MA_False_ALLOWED) { + ResourceAllocationManagerImpl ra_manager( + mock_app_mngr_, mock_rpc_service_, mock_rc_capabilities_manager_); + + ON_CALL(mock_rc_capabilities_manager_, IsSeatLocationCapabilityProvided()) + .WillByDefault(Return(true)); + rc_app_extension_->SetUserLocation(KDefaultUserLocation); + + EXPECT_EQ(AcquireResult::ALLOWED, + ra_manager.AcquireResource(kModuleType1, kModuleId, kAppId1)); +} + +// UL - User Location, MA - Multiple Access +TEST_F(RAManagerTest, + AcquireResource_UL_IsValid_ResourceIsAcquired_MA_False_REJECTED) { + ResourceAllocationManagerImpl ra_manager( + mock_app_mngr_, mock_rpc_service_, mock_rc_capabilities_manager_); + + ON_CALL(mock_rc_capabilities_manager_, IsSeatLocationCapabilityProvided()) + .WillByDefault(Return(true)); + rc_app_extension_->SetUserLocation(KDefaultUserLocation); + + EXPECT_EQ(AcquireResult::ALLOWED, + ra_manager.AcquireResource(kModuleType1, kModuleId, kAppId1)); + + ra_manager.SetResourceAcquired(kModuleType1, kModuleId, kAppId1); + ON_CALL(*mock_app_2_, hmi_level(kDefaultWindowId)) + .WillByDefault(Return(mobile_apis::HMILevel::HMI_FULL)); + ON_CALL(mock_rc_capabilities_manager_, IsMultipleAccessAllowed(_)) + .WillByDefault(Return(false)); + EXPECT_EQ(AcquireResult::REJECTED, + ra_manager.AcquireResource(kModuleType1, kModuleId, kAppId2)); +} + +// UL - User Location, MA - Multiple Access +TEST_F(RAManagerTest, + AcquireResource_UL_IsValid_ResourceIsFree_MA_True_ALLOWED) { + ResourceAllocationManagerImpl ra_manager( + mock_app_mngr_, mock_rpc_service_, mock_rc_capabilities_manager_); + + ON_CALL(mock_rc_capabilities_manager_, IsSeatLocationCapabilityProvided()) + .WillByDefault(Return(true)); + rc_app_extension_->SetUserLocation(KDefaultUserLocation); + + EXPECT_EQ(AcquireResult::ALLOWED, + ra_manager.AcquireResource(kModuleType1, kModuleId, kAppId1)); + + ON_CALL(*mock_app_2_, hmi_level(kDefaultWindowId)) + .WillByDefault(Return(mobile_apis::HMILevel::HMI_FULL)); + EXPECT_EQ(AcquireResult::ALLOWED, + ra_manager.AcquireResource(kModuleType1, kModuleId, kAppId2)); +} + +// UL - User Location, MA - Multiple Access, AM - Access Mode +TEST_F(RAManagerTest, + AcquireResource_UL_IsValid_ResourceIsAcquired_MA_True_AM_AUTO_DENY) { + ResourceAllocationManagerImpl ra_manager( + mock_app_mngr_, mock_rpc_service_, mock_rc_capabilities_manager_); + + ON_CALL(mock_rc_capabilities_manager_, IsSeatLocationCapabilityProvided()) + .WillByDefault(Return(true)); + rc_app_extension_->SetUserLocation(KDefaultUserLocation); + + EXPECT_EQ(AcquireResult::ALLOWED, + ra_manager.AcquireResource(kModuleType1, kModuleId, kAppId1)); + + ra_manager.SetResourceAcquired(kModuleType1, kModuleId, kAppId1); + + ra_manager.SetAccessMode(hmi_apis::Common_RCAccessMode::AUTO_DENY); + + ON_CALL(*mock_app_2_, hmi_level(kDefaultWindowId)) + .WillByDefault(Return(mobile_apis::HMILevel::HMI_FULL)); + EXPECT_EQ(AcquireResult::IN_USE, + ra_manager.AcquireResource(kModuleType1, kModuleId, kAppId2)); +} + +TEST_F(RAManagerTest, + AcquireResource_UL_IsValid_ResourceIsAcquired_MA_True_AM_ASK_DRIVER) { + ResourceAllocationManagerImpl ra_manager( + mock_app_mngr_, mock_rpc_service_, mock_rc_capabilities_manager_); + + ON_CALL(mock_rc_capabilities_manager_, IsSeatLocationCapabilityProvided()) + .WillByDefault(Return(true)); + rc_app_extension_->SetUserLocation(KDefaultUserLocation); + + EXPECT_EQ(AcquireResult::ALLOWED, + ra_manager.AcquireResource(kModuleType1, kModuleId, kAppId1)); + + ra_manager.SetResourceAcquired(kModuleType1, kModuleId, kAppId1); + + ra_manager.SetAccessMode(hmi_apis::Common_RCAccessMode::ASK_DRIVER); + + ON_CALL(*mock_app_2_, hmi_level(kDefaultWindowId)) + .WillByDefault(Return(mobile_apis::HMILevel::HMI_FULL)); + EXPECT_EQ(AcquireResult::ASK_DRIVER, + ra_manager.AcquireResource(kModuleType1, kModuleId, kAppId2)); +} + } // namespace rc_rpc_plugin_test diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/set_global_properties_request.h b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/set_global_properties_request.h index 7e67428fb0..3a32d1b671 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/set_global_properties_request.h +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/set_global_properties_request.h @@ -82,7 +82,76 @@ class SetGlobalPropertiesRequest */ bool Init() FINAL; + /** + * @brief Prepares total result for mobile according to three results: + * ui_properties_result, tts_properties_result, rc_properties_result. + * @param first ResponseInfo as first argument + * @param second ResponseInfo as secondargument + * @param third ResponseInfo as third argument + * @return total result + */ + bool PrepareResultForMobileResponse( + const app_mngr::commands::ResponseInfo& first, + const app_mngr::commands::ResponseInfo& second, + const app_mngr::commands::ResponseInfo& third) const; + + /** + * @brief Prepare result code for sending to mobile application + * @param first contains result_code from HMI response and + * interface that returns response + * @param second contains result_code from HMI response and + * interface that returns response. + * * @param third contains result_code from HMI response and + * interface that returns response. + * @return resulting code for sending to mobile application. + */ + mobile_apis::Result::eType PrepareResultCodeForResponse( + const app_mngr::commands::ResponseInfo& first, + const app_mngr::commands::ResponseInfo& second, + const app_mngr::commands::ResponseInfo& third); + + /** + * @brief Resolves if the return code must be + * UNSUPPORTED_RESOURCE + * @param first contains result_code from HMI response and + * interface that returns response + * @param second contains result_code from HMI response and + * interface that returns response. + * * @param third contains result_code from HMI response and + * interface that returns response. + * @return True, if the communication return code must be + * UNSUPPORTED_RESOURCE, otherwise false. + */ + bool IsResultCodeUnsupported( + const app_mngr::commands::ResponseInfo& first, + const app_mngr::commands::ResponseInfo& second, + const app_mngr::commands::ResponseInfo& third) const; + private: + /** + * @brief MergeInfos merge 2 infos into one string with info + * @param first_info -contains result_code from HMI response and + * interface that returns response + * @param first_str - info string that should be first in result info + * @param second_info -contains result_code from HMI response and + * interface that returns response + * @param second_str - info string that should be second in result info + * @param third_info - contains result_code from HMI response and + * interface that returns response + * @param third_str - info string that should be third in result info + * @return if first_info is not available and second_str and third_info not + * empty return second if second_info is not available and first_str and + * third_info not empty return first if third_info is not available and + * first_str and second_str not empty return first other cases return result + * MergeInfos for 2 params + */ + std::string MergeInfos(const app_mngr::commands::ResponseInfo& first_info, + const std::string& first_str, + const app_mngr::commands::ResponseInfo& second_info, + const std::string& second_str, + const app_mngr::commands::ResponseInfo& third_info, + const std::string& third_str); + // prepare UI sending data (VrHelps, Menus, Keyboard) to SmartObject static void PrepareUIRequestVRHelpData( const app_mngr::ApplicationSharedPtr app, @@ -101,6 +170,9 @@ class SetGlobalPropertiesRequest // Send UI request to HMI void SendUIRequest(const smart_objects::SmartObject& params, bool use_events); + // Send SetGlobalProperties with userLocation parameter + void SendRCRequest(const smart_objects::SmartObject& params, bool use_events); + // VRHelp shall contain sequential positions and start from 1 static bool CheckVrHelpItemsOrder(const smart_objects::SmartObject& vr_help); @@ -140,14 +212,18 @@ class SetGlobalPropertiesRequest bool is_ui_send_; bool is_tts_send_; + bool is_rc_send_; bool is_ui_received_; bool is_tts_received_; + bool is_rc_received_; hmi_apis::Common_Result::eType ui_result_; hmi_apis::Common_Result::eType tts_result_; + hmi_apis::Common_Result::eType rc_result_; std::string ui_response_info_; std::string tts_response_info_; + std::string rc_response_info_; bool is_menu_layout_available_ = true; diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/sdl_rpc_plugin.h b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/sdl_rpc_plugin.h index 288410e342..91298f4883 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/sdl_rpc_plugin.h +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/sdl_rpc_plugin.h @@ -47,7 +47,8 @@ class SDLRPCPlugin : public plugins::RPCPlugin { bool Init(app_mngr::ApplicationManager& app_manager, app_mngr::rpc_service::RPCService& rpc_service, app_mngr::HMICapabilities& hmi_capabilities, - policy::PolicyHandlerInterface& policy_handler) OVERRIDE; + policy::PolicyHandlerInterface& policy_handler, + resumption::LastState& last_state) OVERRIDE; bool IsAbleToProcess( const int32_t function_id, diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/rc_get_capabilities_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/rc_get_capabilities_response.cc index f4651ee0cb..128b111c5e 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/rc_get_capabilities_response.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/rc_get_capabilities_response.cc @@ -54,14 +54,24 @@ void RCGetCapabilitiesResponse::Run() { LOG4CXX_AUTO_TRACE(logger_); HMICapabilities& hmi_capabilities = hmi_capabilities_; - bool capability_exists = + bool rc_capability_exists = (*message_)[strings::msg_params].keyExists(strings::rc_capability); - if (capability_exists) { + if (rc_capability_exists) { hmi_capabilities.set_rc_capability( (*message_)[strings::msg_params][strings::rc_capability]); } - hmi_capabilities.set_rc_supported(capability_exists); + + bool seat_location_capability_exists = + (*message_)[strings::msg_params].keyExists( + strings::seat_location_capability); + + if (seat_location_capability_exists) { + hmi_capabilities.set_seat_location_capability( + (*message_)[strings::msg_params][strings::seat_location_capability]); + } + + hmi_capabilities.set_rc_supported(rc_capability_exists); } } // namespace commands diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_system_capability_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_system_capability_request.cc index dfc48ce2d5..6121747ccc 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_system_capability_request.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_system_capability_request.cc @@ -133,6 +133,17 @@ void GetSystemCapabilityRequest::Run() { } break; } + case mobile_apis::SystemCapabilityType::SEAT_LOCATION: { + if (hmi_capabilities.seat_location_capability()) { + response_params[strings::system_capability] + [strings::seat_location_capability] = + *hmi_capabilities.seat_location_capability(); + } else { + SendResponse(false, mobile_apis::Result::DATA_NOT_AVAILABLE); + return; + } + break; + } case mobile_apis::SystemCapabilityType::VIDEO_STREAMING: if (hmi_capabilities.video_streaming_capability()) { response_params[strings::system_capability] diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_global_properties_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_global_properties_request.cc index 4a73740ccf..e28566a44f 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_global_properties_request.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_global_properties_request.cc @@ -38,6 +38,7 @@ #include "application_manager/message_helper.h" #include "interfaces/HMI_API.h" #include "interfaces/MOBILE_API.h" + #include "utils/helpers.h" namespace sdl_rpc_plugin { @@ -45,6 +46,24 @@ using namespace application_manager; namespace commands { +namespace { +bool IsResultCodeWarning(const app_mngr::commands::ResponseInfo& first, + const app_mngr::commands::ResponseInfo& second, + const app_mngr::commands::ResponseInfo& third) { + const bool first_is_ok_second_is_warn = + (first.is_ok || first.is_not_used) && + (hmi_apis::Common_Result::WARNINGS == second.result_code) && + (hmi_apis::Common_Result::WARNINGS == third.result_code); + + const bool final_warnings = + hmi_apis::Common_Result::WARNINGS == first.result_code && + ((hmi_apis::Common_Result::WARNINGS == second.result_code) && + (hmi_apis::Common_Result::WARNINGS == third.result_code)); + + return first_is_ok_second_is_warn || final_warnings; +} +} // namespace + SetGlobalPropertiesRequest::SetGlobalPropertiesRequest( const application_manager::commands::MessageSharedPtr& message, ApplicationManager& application_manager, @@ -58,10 +77,13 @@ SetGlobalPropertiesRequest::SetGlobalPropertiesRequest( policy_handler) , is_ui_send_(false) , is_tts_send_(false) + , is_rc_send_(false) , is_ui_received_(false) , is_tts_received_(false) + , is_rc_received_(false) , ui_result_(hmi_apis::Common_Result::INVALID_ENUM) - , tts_result_(hmi_apis::Common_Result::INVALID_ENUM) {} + , tts_result_(hmi_apis::Common_Result::INVALID_ENUM) + , rc_result_(hmi_apis::Common_Result::INVALID_ENUM) {} SetGlobalPropertiesRequest::~SetGlobalPropertiesRequest() {} @@ -199,6 +221,34 @@ void SetGlobalPropertiesRequest::Run() { } } + // Check RC params + const bool is_user_location_present = + msg_params.keyExists(strings::user_location); + if (is_user_location_present) { + if (msg_params[strings::user_location].empty()) { + SendResponse( + false, mobile_apis::Result::INVALID_DATA, "UserLocation is empty"); + return; + } + LOG4CXX_DEBUG(logger_, "Userlocation params presents"); + const auto& user_location = msg_params[strings::user_location]; + app->set_user_location(user_location); + + auto on_global_properties_updated = [app]( + plugin_manager::RPCPlugin& plugin) { + plugin.OnApplicationEvent(plugin_manager::kGlobalPropertiesUpdated, app); + }; + + application_manager_.GetPluginManager().ForEachPlugin( + on_global_properties_updated); + + smart_objects::SmartObject params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + params[strings::app_id] = app->app_id(); + params[strings::user_location] = user_location; + SendRCRequest(params, true); + } + // check TTS params if (is_help_prompt_present || is_timeout_prompt_present) { LOG4CXX_DEBUG(logger_, "TTS params presents"); @@ -258,7 +308,7 @@ void SetGlobalPropertiesRequest::Run() { auto& help_prompt_manager = app->help_prompt_manager(); help_prompt_manager.OnSetGlobalPropertiesReceived(tts_params, false); - } else if (!is_ui_send_) { + } else if (!is_ui_send_ && !is_rc_send_) { std::string response_info = "There are no parameters present in request."; if (!is_menu_layout_available_) { response_info += " The MenuLayout specified is unsupported."; @@ -299,7 +349,7 @@ void SetGlobalPropertiesRequest::on_event(const event_engine::Event& event) { switch (event.id()) { case hmi_apis::FunctionID::UI_SetGlobalProperties: { - LOG4CXX_INFO(logger_, "Received UI_SetGlobalProperties event"); + LOG4CXX_DEBUG(logger_, "Received UI_SetGlobalProperties event"); EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_UI); is_ui_received_ = true; ui_result_ = static_cast<hmi_apis::Common_Result::eType>( @@ -312,7 +362,7 @@ void SetGlobalPropertiesRequest::on_event(const event_engine::Event& event) { break; } case hmi_apis::FunctionID::TTS_SetGlobalProperties: { - LOG4CXX_INFO(logger_, "Received TTS_SetGlobalProperties event"); + LOG4CXX_DEBUG(logger_, "Received TTS_SetGlobalProperties event"); EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_TTS); is_tts_received_ = true; tts_result_ = static_cast<hmi_apis::Common_Result::eType>( @@ -324,6 +374,15 @@ void SetGlobalPropertiesRequest::on_event(const event_engine::Event& event) { } break; } + case hmi_apis::FunctionID::RC_SetGlobalProperties: { + LOG4CXX_DEBUG(logger_, "Received RC_SetGlobalProperties event"); + EndAwaitForInterface(HmiInterfaces::HMI_INTERFACE_RC); + is_rc_received_ = true; + rc_result_ = static_cast<hmi_apis::Common_Result::eType>( + message[strings::params][hmi_response::code].asInt()); + GetInfo(message, rc_response_info_); + break; + } default: { LOG4CXX_ERROR(logger_, "Received unknown event" << event.id()); return; @@ -370,28 +429,173 @@ bool SetGlobalPropertiesRequest::PrepareResponseParameters( app_mngr::commands::ResponseInfo tts_properties_info( tts_result_, HmiInterfaces::HMI_INTERFACE_TTS, application_manager_); - const bool result = - PrepareResultForMobileResponse(ui_properties_info, tts_properties_info); + + app_mngr::commands::ResponseInfo rc_properties_info( + rc_result_, HmiInterfaces::HMI_INTERFACE_RC, application_manager_); + + bool result = false; + + if (!is_rc_send_) { + result = CommandRequestImpl::PrepareResultForMobileResponse( + ui_properties_info, tts_properties_info); + } else { + result = PrepareResultForMobileResponse( + ui_properties_info, tts_properties_info, rc_properties_info); + } if (result && (HmiInterfaces::STATE_AVAILABLE == tts_properties_info.interface_state) && (tts_properties_info.is_unsupported_resource)) { result_code = mobile_apis::Result::WARNINGS; tts_response_info_ = "Unsupported phoneme type sent in a prompt"; - info = app_mngr::commands::MergeInfos(tts_properties_info, - tts_response_info_, - ui_properties_info, - ui_response_info_); + info = MergeInfos(tts_properties_info, + tts_response_info_, + ui_properties_info, + ui_response_info_, + rc_properties_info, + rc_response_info_); return result; } - result_code = - PrepareResultCodeForResponse(ui_properties_info, tts_properties_info); - info = app_mngr::commands::MergeInfos(tts_properties_info, - tts_response_info_, - ui_properties_info, - ui_response_info_); + + if (!is_rc_send_) { + result_code = CommandRequestImpl::PrepareResultCodeForResponse( + ui_properties_info, tts_properties_info); + } else { + result_code = PrepareResultCodeForResponse( + ui_properties_info, tts_properties_info, rc_properties_info); + } + info = MergeInfos(tts_properties_info, + tts_response_info_, + ui_properties_info, + ui_response_info_, + rc_properties_info, + rc_response_info_); return result; } +bool SetGlobalPropertiesRequest::PrepareResultForMobileResponse( + const app_mngr::commands::ResponseInfo& first, + const app_mngr::commands::ResponseInfo& second, + const app_mngr::commands::ResponseInfo& third) const { + LOG4CXX_AUTO_TRACE(logger_); + + app_mngr::commands::ResponseInfo both_info; + std::vector<hmi_apis::Common_Result::eType> success_result_codes{ + hmi_apis::Common_Result::SUCCESS, + hmi_apis::Common_Result::WARNINGS, + hmi_apis::Common_Result::WRONG_LANGUAGE, + hmi_apis::Common_Result::RETRY, + hmi_apis::Common_Result::SAVED}; + + both_info.is_ok = + helpers::in_range(success_result_codes, first.result_code) && + helpers::in_range(success_result_codes, second.result_code); + + both_info.is_not_used = + (hmi_apis::Common_Result::INVALID_ENUM == first.result_code) || + (hmi_apis::Common_Result::INVALID_ENUM == second.result_code); + + both_info.is_unsupported_resource = + (hmi_apis::Common_Result::UNSUPPORTED_RESOURCE == first.result_code) || + (hmi_apis::Common_Result::UNSUPPORTED_RESOURCE == second.result_code); + + const bool final_result = CommandRequestImpl::CheckResult(both_info, third) || + CommandRequestImpl::CheckResult(third, both_info); + + return final_result; +} + +mobile_apis::Result::eType +SetGlobalPropertiesRequest::PrepareResultCodeForResponse( + const app_mngr::commands::ResponseInfo& first, + const app_mngr::commands::ResponseInfo& second, + const app_mngr::commands::ResponseInfo& third) { + LOG4CXX_AUTO_TRACE(logger_); + mobile_apis::Result::eType result_code = mobile_apis::Result::INVALID_ENUM; + if (IsResultCodeUnsupported(first, second, third) || + IsResultCodeUnsupported(second, third, first) || + IsResultCodeUnsupported(third, first, second)) { + return mobile_apis::Result::UNSUPPORTED_RESOURCE; + } + if (IsResultCodeWarning(first, second, third) || + IsResultCodeWarning(second, third, first) || + IsResultCodeWarning(third, first, second)) { + return mobile_apis::Result::WARNINGS; + } + // If response contains erroneous result code SDL need return erroneous + // result code. + auto first_result = hmi_apis::Common_Result::INVALID_ENUM; + auto second_result = hmi_apis::Common_Result::INVALID_ENUM; + auto third_result = hmi_apis::Common_Result::INVALID_ENUM; + + if (!first.is_unsupported_resource) { + first_result = first.result_code; + } + if (!second.is_unsupported_resource) { + second_result = second.result_code; + } + if (!third.is_unsupported_resource) { + third_result = third.result_code; + } + + hmi_apis::Common_Result::eType intermediate_result = + std::max(first_result, second_result); + result_code = MessageHelper::HMIToMobileResult( + std::max(intermediate_result, third_result)); + + return result_code; +} + +bool SetGlobalPropertiesRequest::IsResultCodeUnsupported( + const application_manager::commands::ResponseInfo& first, + const application_manager::commands::ResponseInfo& second, + const application_manager::commands::ResponseInfo& third) const { + const bool first_ok_second_or_third_unsupported = + (first.is_ok || first.is_not_used) && + (second.is_unsupported_resource || third.is_unsupported_resource); + const bool final_unsupported = first.is_unsupported_resource && + second.is_unsupported_resource && + third.is_unsupported_resource; + + return first_ok_second_or_third_unsupported || final_unsupported; +} + +std::string SetGlobalPropertiesRequest::MergeInfos( + const app_mngr::commands::ResponseInfo& first_info, + const std::string& first_str, + const app_mngr::commands::ResponseInfo& second_info, + const std::string& second_str, + const app_mngr::commands::ResponseInfo& third_info, + const std::string& third_str) { + if ((first_info.interface_state == HmiInterfaces::STATE_NOT_AVAILABLE) && + + ((second_info.interface_state != HmiInterfaces::STATE_NOT_AVAILABLE) && + !second_str.empty()) && + ((third_info.interface_state != HmiInterfaces::STATE_NOT_AVAILABLE) && + !third_str.empty())) { + return second_str; + } + + if ((second_info.interface_state == HmiInterfaces::STATE_NOT_AVAILABLE) && + ((first_info.interface_state != HmiInterfaces::STATE_NOT_AVAILABLE) && + !first_str.empty()) && + ((third_info.interface_state != HmiInterfaces::STATE_NOT_AVAILABLE) && + !third_str.empty())) { + return first_str; + } + + if ((third_info.interface_state == HmiInterfaces::STATE_NOT_AVAILABLE) && + ((first_info.interface_state != HmiInterfaces::STATE_NOT_AVAILABLE) && + !first_str.empty()) && + ((second_info.interface_state != HmiInterfaces::STATE_NOT_AVAILABLE) && + !second_str.empty())) { + return third_str; + } + + std::string intermediate_result = + app_mngr::commands::MergeInfos(first_str, second_str); + return app_mngr::commands::MergeInfos(intermediate_result, third_str); +} + void SetGlobalPropertiesRequest::PrepareUIRequestVRHelpData( const ApplicationSharedPtr app, const smart_objects::SmartObject& msg_params, @@ -454,8 +658,19 @@ void SetGlobalPropertiesRequest::SendUIRequest( hmi_apis::FunctionID::UI_SetGlobalProperties, ¶ms, use_events); } +void SetGlobalPropertiesRequest::SendRCRequest( + const ns_smart_device_link::ns_smart_objects::SmartObject& params, + bool use_events) { + LOG4CXX_AUTO_TRACE(logger_); + is_rc_send_ = true; + StartAwaitForInterface(HmiInterfaces::HMI_INTERFACE_RC); + SendHMIRequest( + hmi_apis::FunctionID::RC_SetGlobalProperties, ¶ms, use_events); +} + bool SetGlobalPropertiesRequest::IsPendingResponseExist() { - return is_ui_send_ != is_ui_received_ || is_tts_send_ != is_tts_received_; + return is_ui_send_ != is_ui_received_ || is_tts_send_ != is_tts_received_ || + is_rc_send_ != is_rc_received_; } bool SetGlobalPropertiesRequest::ValidateConditionalMandatoryParameters( @@ -468,7 +683,8 @@ bool SetGlobalPropertiesRequest::ValidateConditionalMandatoryParameters( params.keyExists(strings::menu_title) || params.keyExists(strings::menu_icon) || params.keyExists(strings::keyboard_properties) || - params.keyExists(strings::menu_layout); + params.keyExists(strings::menu_layout) || + params.keyExists(strings::user_location); } bool SetGlobalPropertiesRequest::IsWhiteSpaceExist() { diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unsubscribe_button_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unsubscribe_button_request.cc index ebd463d4fa..ec8de68c9e 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unsubscribe_button_request.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unsubscribe_button_request.cc @@ -94,7 +94,7 @@ void UnsubscribeButtonRequest::Run() { if (!app->UnsubscribeFromButton( static_cast<mobile_apis::ButtonName::eType>(btn_id))) { - LOG4CXX_ERROR(logger_, "App doesn't subscibe to button " << btn_id); + LOG4CXX_ERROR(logger_, "App doesn't subscribe to button " << btn_id); SendResponse(false, mobile_apis::Result::IGNORED); return; } diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/sdl_rpc_plugin.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/sdl_rpc_plugin.cc index 43462bfaf1..05ff794aee 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/sdl_rpc_plugin.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/sdl_rpc_plugin.cc @@ -44,7 +44,9 @@ CREATE_LOGGERPTR_GLOBAL(logger_, "SdlRPCPlugin") bool SDLRPCPlugin::Init(app_mngr::ApplicationManager& app_manager, app_mngr::rpc_service::RPCService& rpc_service, app_mngr::HMICapabilities& hmi_capabilities, - policy::PolicyHandlerInterface& policy_handler) { + policy::PolicyHandlerInterface& policy_handler, + resumption::LastState& last_state) { + UNUSED(last_state); command_factory_.reset(new sdl_rpc_plugin::SDLCommandFactory( app_manager, rpc_service, hmi_capabilities, policy_handler)); return true; diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/set_global_properties_test.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/set_global_properties_test.cc index 3e791aef01..9b72d41f7e 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/set_global_properties_test.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/set_global_properties_test.cc @@ -39,6 +39,7 @@ #include "application_manager/commands/command_request_test.h" #include "application_manager/event_engine/event.h" +#include "application_manager/message_helper.h" #include "application_manager/mock_application.h" #include "application_manager/mock_application_manager.h" #include "application_manager/mock_help_prompt_manager.h" @@ -70,6 +71,13 @@ const uint32_t kCmdId = 1u; const uint32_t kConnectionKey = 1u; const std::string kText = "one"; const uint32_t kPosition = 1u; + +const std::vector<hmi_apis::Common_Result::eType> success_result_codes{ + hmi_apis::Common_Result::SUCCESS, + hmi_apis::Common_Result::WARNINGS, + hmi_apis::Common_Result::WRONG_LANGUAGE, + hmi_apis::Common_Result::RETRY, + hmi_apis::Common_Result::SAVED}; } // namespace class SetGlobalPropertiesRequestTest @@ -233,9 +241,16 @@ class SetGlobalPropertiesRequestTest ON_CALL(app_mngr_, application(kConnectionKey)) .WillByDefault(Return(mock_app_)); ON_CALL(*mock_app_, app_id()).WillByDefault(Return(kConnectionKey)); - ON_CALL(mock_hmi_interfaces_, - GetInterfaceState(am::HmiInterfaces::HMI_INTERFACE_UI)) + ON_CALL(mock_hmi_interfaces_, GetInterfaceState(_)) .WillByDefault(Return(am::HmiInterfaces::STATE_AVAILABLE)); + ON_CALL(mock_app_manager_, hmi_interfaces()) + .WillByDefault(ReturnRef(mock_hmi_interfaces_)); + ON_CALL(mock_message_helper_, + MobileToHMIResult(mobile_apis::Result::UNSUPPORTED_RESOURCE)) + .WillByDefault(Return(hmi_apis::Common_Result::UNSUPPORTED_RESOURCE)); + ON_CALL(mock_message_helper_, + MobileToHMIResult(mobile_apis::Result::WARNINGS)) + .WillByDefault(Return(hmi_apis::Common_Result::WARNINGS)); } void ResultCommandExpectations(MessageSharedPtr msg, @@ -243,8 +258,8 @@ class SetGlobalPropertiesRequestTest EXPECT_EQ((*msg)[am::strings::msg_params][am::strings::success].asBool(), true); EXPECT_EQ( - (*msg)[am::strings::msg_params][am::strings::result_code].asInt(), - static_cast<int32_t>(hmi_apis::Common_Result::UNSUPPORTED_RESOURCE)); + static_cast<int32_t>(hmi_apis::Common_Result::UNSUPPORTED_RESOURCE), + (*msg)[am::strings::msg_params][am::strings::result_code].asInt()); EXPECT_EQ((*msg)[am::strings::msg_params][am::strings::info].asString(), info); } @@ -265,10 +280,128 @@ class SetGlobalPropertiesRequestTest GetInterfaceState(am::HmiInterfaces::HMI_INTERFACE_TTS)) .WillByDefault(Return(am::HmiInterfaces::STATE_AVAILABLE)); } + + // Checks total result code for each properties + void PrepareResultCodeForResponse_CheckTotalCode( + const hmi_apis::Common_Result::eType& ui_result, + const hmi_apis::Common_Result::eType& tts_result, + const hmi_apis::Common_Result::eType& rc_result, + const mobile_apis::Result::eType expected_total_result_code) { + using namespace application_manager; + using namespace hmi_apis; + + commands::ResponseInfo ui_properties_info( + ui_result, HmiInterfaces::HMI_INTERFACE_UI, mock_app_manager_); + commands::ResponseInfo tts_properties_info( + tts_result, HmiInterfaces::HMI_INTERFACE_TTS, mock_app_manager_); + commands::ResponseInfo rc_properties_info( + rc_result, HmiInterfaces::HMI_INTERFACE_RC, mock_app_manager_); + + MessageSharedPtr msg = CreateMsgParams(); + std::shared_ptr<SetGlobalPropertiesRequest> command( + CreateCommand<SetGlobalPropertiesRequest>(msg)); + + auto result = command->PrepareResultCodeForResponse( + ui_properties_info, tts_properties_info, rc_properties_info); + + EXPECT_EQ(expected_total_result_code, result); + } + + // Sets in rotation for each result UNSUPPROTED result code and checks total + // result code + void PrepareResultCodeForResponse_CheckAllResultsForSpecifiedTotalResult( + mobile_apis::Result::eType expected_total_result_code) { + using namespace application_manager; + using namespace hmi_apis; + + Common_Result::eType ui_result = + MessageHelper::MobileToHMIResult(expected_total_result_code); + Common_Result::eType tts_result = Common_Result::SUCCESS; + Common_Result::eType rc_result = Common_Result::SUCCESS; + + PrepareResultCodeForResponse_CheckTotalCode( + ui_result, tts_result, rc_result, expected_total_result_code); + + ui_result = Common_Result::SUCCESS; + tts_result = MessageHelper::MobileToHMIResult(expected_total_result_code); + + PrepareResultCodeForResponse_CheckTotalCode( + ui_result, tts_result, rc_result, expected_total_result_code); + + tts_result = Common_Result::SUCCESS; + rc_result = MessageHelper::MobileToHMIResult(expected_total_result_code); + + PrepareResultCodeForResponse_CheckTotalCode( + ui_result, tts_result, rc_result, expected_total_result_code); + } + + void PrepareResultForMobileResponse_CheckTotalReault( + const hmi_apis::Common_Result::eType& ui_result, + const hmi_apis::Common_Result::eType& tts_result, + const hmi_apis::Common_Result::eType& rc_result, + const bool expected_total_result) { + using namespace application_manager; + using namespace hmi_apis; + + commands::ResponseInfo ui_properties_info( + ui_result, HmiInterfaces::HMI_INTERFACE_UI, mock_app_manager_); + commands::ResponseInfo tts_properties_info( + tts_result, HmiInterfaces::HMI_INTERFACE_TTS, mock_app_manager_); + commands::ResponseInfo rc_properties_info( + rc_result, HmiInterfaces::HMI_INTERFACE_RC, mock_app_manager_); + + MessageSharedPtr msg = CreateMsgParams(); + std::shared_ptr<SetGlobalPropertiesRequest> command( + CreateCommand<SetGlobalPropertiesRequest>(msg)); + + bool result = command->PrepareResultForMobileResponse( + ui_properties_info, tts_properties_info, rc_properties_info); + + EXPECT_EQ(expected_total_result, result); + } + + void PrepareResultForMobileResponse_CheckResultsForAllCases() { + using namespace application_manager; + using namespace hmi_apis; + + Common_Result::eType ui_result = Common_Result::SUCCESS; + Common_Result::eType tts_result = Common_Result::SUCCESS; + Common_Result::eType rc_result = Common_Result::SUCCESS; + + PrepareResultForMobileResponse_CheckTotalReault( + ui_result, tts_result, rc_result, true); + + // Result code isn't success + EXPECT_FALSE(helpers::in_range(success_result_codes, + Common_Result::UNSUPPORTED_REQUEST)); + + ui_result = Common_Result::UNSUPPORTED_REQUEST; + tts_result = Common_Result::SUCCESS; + rc_result = Common_Result::SUCCESS; + + PrepareResultForMobileResponse_CheckTotalReault( + ui_result, tts_result, rc_result, false); + + ui_result = Common_Result::SUCCESS; + tts_result = Common_Result::UNSUPPORTED_REQUEST; + rc_result = Common_Result::SUCCESS; + + PrepareResultForMobileResponse_CheckTotalReault( + ui_result, tts_result, rc_result, false); + + ui_result = Common_Result::SUCCESS; + tts_result = Common_Result::SUCCESS; + rc_result = Common_Result::UNSUPPORTED_REQUEST; + + PrepareResultForMobileResponse_CheckTotalReault( + ui_result, tts_result, rc_result, false); + } + std::shared_ptr<sync_primitives::Lock> lock_ptr_; MockAppPtr mock_app_; std::shared_ptr<application_manager_test::MockHelpPromptManager> mock_help_prompt_manager_; + NiceMock<MockApplicationManager> mock_app_manager_; }; TEST_F(SetGlobalPropertiesRequestTest, @@ -332,6 +465,7 @@ TEST_F(SetGlobalPropertiesRequestTest, ManageHMICommand( HMIResultCodeIs(hmi_apis::FunctionID::TTS_SetGlobalProperties), _)) .WillOnce(Return(true)); + (*msg_vr)[am::strings::params][am::hmi_response::code] = hmi_apis::Common_Result::SUCCESS; Event event_vr(hmi_apis::FunctionID::TTS_SetGlobalProperties); @@ -1372,6 +1506,51 @@ TEST_F(SetGlobalPropertiesRequestTest, static_cast<int32_t>(hmi_apis::Common_Result::WARNINGS)); } +TEST_F(SetGlobalPropertiesRequestTest, + PrepareResultCodeForResponse_AllResultsAreSUCCESS_TotalResultSUCCESS) { + using namespace application_manager; + using namespace hmi_apis; + const auto expected_total_result = mobile_apis::Result::eType::SUCCESS; + + Common_Result::eType ui_result = Common_Result::SUCCESS; + Common_Result::eType tts_result = Common_Result::SUCCESS; + Common_Result::eType rc_result = Common_Result::SUCCESS; + + app_mngr::commands::ResponseInfo ui_properties_info( + ui_result, HmiInterfaces::HMI_INTERFACE_UI, mock_app_manager_); + + app_mngr::commands::ResponseInfo tts_properties_info( + tts_result, HmiInterfaces::HMI_INTERFACE_TTS, mock_app_manager_); + + app_mngr::commands::ResponseInfo rc_properties_info( + rc_result, HmiInterfaces::HMI_INTERFACE_RC, mock_app_manager_); + + MessageSharedPtr msg = CreateMsgParams(); + std::shared_ptr<SetGlobalPropertiesRequest> command( + CreateCommand<SetGlobalPropertiesRequest>(msg)); + + auto result = command->PrepareResultCodeForResponse( + ui_properties_info, tts_properties_info, rc_properties_info); + + EXPECT_EQ(expected_total_result, result); +} + +TEST_F(SetGlobalPropertiesRequestTest, + PrepareResultCodeForResponse_UNSUPPORTED) { + PrepareResultCodeForResponse_CheckAllResultsForSpecifiedTotalResult( + mobile_apis::Result::UNSUPPORTED_RESOURCE); +} + +TEST_F(SetGlobalPropertiesRequestTest, PrepareResultCodeForResponse_WARNINGS) { + PrepareResultCodeForResponse_CheckAllResultsForSpecifiedTotalResult( + mobile_apis::Result::WARNINGS); +} + +TEST_F(SetGlobalPropertiesRequestTest, + PrepareResultForMobileResponse_AllCases) { + PrepareResultForMobileResponse_CheckResultsForAllCases(); +} + } // namespace set_global_properties_request } // namespace mobile_commands_test } // namespace commands_test diff --git a/src/components/application_manager/rpc_plugins/vehicle_info_plugin/include/vehicle_info_plugin/vehicle_info_plugin.h b/src/components/application_manager/rpc_plugins/vehicle_info_plugin/include/vehicle_info_plugin/vehicle_info_plugin.h index 4781fa396c..ecb86532bc 100644 --- a/src/components/application_manager/rpc_plugins/vehicle_info_plugin/include/vehicle_info_plugin/vehicle_info_plugin.h +++ b/src/components/application_manager/rpc_plugins/vehicle_info_plugin/include/vehicle_info_plugin/vehicle_info_plugin.h @@ -48,7 +48,8 @@ class VehicleInfoPlugin : public plugins::RPCPlugin { bool Init(app_mngr::ApplicationManager& application_manager, app_mngr::rpc_service::RPCService& rpc_service, app_mngr::HMICapabilities& hmi_capabilities, - policy::PolicyHandlerInterface& policy_handler) OVERRIDE; + policy::PolicyHandlerInterface& policy_handler, + resumption::LastState& last_state) OVERRIDE; bool IsAbleToProcess( const int32_t function_id, diff --git a/src/components/application_manager/rpc_plugins/vehicle_info_plugin/src/vehicle_info_plugin.cc b/src/components/application_manager/rpc_plugins/vehicle_info_plugin/src/vehicle_info_plugin.cc index d2aa4c64fb..aa45ee704a 100644 --- a/src/components/application_manager/rpc_plugins/vehicle_info_plugin/src/vehicle_info_plugin.cc +++ b/src/components/application_manager/rpc_plugins/vehicle_info_plugin/src/vehicle_info_plugin.cc @@ -52,7 +52,9 @@ bool VehicleInfoPlugin::Init( application_manager::ApplicationManager& app_manager, application_manager::rpc_service::RPCService& rpc_service, application_manager::HMICapabilities& hmi_capabilities, - policy::PolicyHandlerInterface& policy_handler) { + policy::PolicyHandlerInterface& policy_handler, + resumption::LastState& last_state) { + UNUSED(last_state); application_manager_ = &app_manager; custom_vehicle_data_manager_.reset( new CustomVehicleDataManagerImpl(policy_handler, rpc_service)); diff --git a/src/components/application_manager/rpc_plugins/vehicle_info_plugin/test/commands/mobile/unsubscribe_vehicle_request_test.cc b/src/components/application_manager/rpc_plugins/vehicle_info_plugin/test/commands/mobile/unsubscribe_vehicle_request_test.cc index a88ea3f8b8..3a200ff282 100644 --- a/src/components/application_manager/rpc_plugins/vehicle_info_plugin/test/commands/mobile/unsubscribe_vehicle_request_test.cc +++ b/src/components/application_manager/rpc_plugins/vehicle_info_plugin/test/commands/mobile/unsubscribe_vehicle_request_test.cc @@ -35,9 +35,11 @@ #include "gtest/gtest.h" +#include "application_manager/commands/command_request_test.h" #include "application_manager/mock_application_manager.h" #include "application_manager/mock_message_helper.h" #include "mobile/unsubscribe_vehicle_data_request.h" +#include "resumption/mock_last_state.h" #include "vehicle_info_plugin/commands/vi_command_request_test.h" #include "vehicle_info_plugin/vehicle_info_app_extension.h" #include "vehicle_info_plugin/vehicle_info_plugin.h" @@ -87,7 +89,8 @@ class UnsubscribeVehicleRequestTest vi_plugin_.Init(app_mngr_, mock_rpc_service_, mock_hmi_capabilities_, - mock_policy_handler_); + mock_policy_handler_, + mock_last_state_); ON_CALL(*mock_app_, AddExtension(vi_app_extension_ptr_)); vi_plugin_.OnApplicationEvent(application_manager::plugin_manager:: ApplicationEvent::kApplicationRegistered, @@ -104,6 +107,7 @@ class UnsubscribeVehicleRequestTest std::shared_ptr<sync_primitives::Lock> app_set_lock_ptr_; vehicle_info_plugin::VehicleInfoPlugin vi_plugin_; application_manager_test::MockRPCHandler mock_rpc_handler_; + resumption_test::MockLastState mock_last_state_; }; TEST_F(UnsubscribeVehicleRequestTest, Run_AppNotRegistered_UNSUCCESS) { diff --git a/src/components/application_manager/src/application_impl.cc b/src/components/application_manager/src/application_impl.cc index bb505e2498..683054618b 100644 --- a/src/components/application_manager/src/application_impl.cc +++ b/src/components/application_manager/src/application_impl.cc @@ -1313,6 +1313,15 @@ void ApplicationImpl::set_cloud_app_certificate( certificate_ = certificate; } +void ApplicationImpl::set_user_location( + const smart_objects::SmartObject& user_location) { + user_location_ = user_location; +} + +const smart_objects::SmartObject& ApplicationImpl::get_user_location() const { + return user_location_; +} + void ApplicationImpl::PushMobileMessage( smart_objects::SmartObjectSPtr mobile_message) { sync_primitives::AutoLock lock(mobile_message_lock_); diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc index 5b5da8ea64..9db62d09d3 100644 --- a/src/components/application_manager/src/application_manager_impl.cc +++ b/src/components/application_manager/src/application_manager_impl.cc @@ -2257,7 +2257,7 @@ bool ApplicationManagerImpl::Init(resumption::LastState& last_state, media_manager::MediaManager* media_manager) { LOG4CXX_TRACE(logger_, "Init application manager"); plugin_manager_.reset(new plugin_manager::RPCPluginManagerImpl( - *this, *rpc_service_, *hmi_capabilities_, *policy_handler_)); + *this, *rpc_service_, *hmi_capabilities_, *policy_handler_, last_state)); if (!plugin_manager_->LoadPlugins(get_settings().plugins_folder())) { LOG4CXX_ERROR(logger_, "Plugins are not loaded"); return false; 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 4e321b18b0..1379bc9f48 100644 --- a/src/components/application_manager/src/commands/command_request_impl.cc +++ b/src/components/application_manager/src/commands/command_request_impl.cc @@ -112,7 +112,8 @@ const std::string CreateInfoForUnsupportedResult( } } -bool CheckResultCode(const ResponseInfo& first, const ResponseInfo& second) { +bool CommandRequestImpl::CheckResult(const ResponseInfo& first, + const ResponseInfo& second) const { if (first.is_ok && second.is_unsupported_resource) { return true; } @@ -935,8 +936,8 @@ bool CommandRequestImpl::PrepareResultForMobileResponse( bool CommandRequestImpl::PrepareResultForMobileResponse( ResponseInfo& out_first, ResponseInfo& out_second) const { LOG4CXX_AUTO_TRACE(logger_); - bool result = CheckResultCode(out_first, out_second) || - CheckResultCode(out_second, out_first); + bool result = + CheckResult(out_first, out_second) || CheckResult(out_second, out_first); return result; } diff --git a/src/components/application_manager/src/hmi_capabilities_impl.cc b/src/components/application_manager/src/hmi_capabilities_impl.cc index 6b209ade0c..e91f425770 100644 --- a/src/components/application_manager/src/hmi_capabilities_impl.cc +++ b/src/components/application_manager/src/hmi_capabilities_impl.cc @@ -453,6 +453,7 @@ HMICapabilitiesImpl::HMICapabilitiesImpl(ApplicationManager& app_mngr) , phone_capability_(NULL) , video_streaming_capability_(NULL) , rc_capability_(NULL) + , seat_location_capability_(NULL) , app_mngr_(app_mngr) , hmi_language_handler_(app_mngr) { InitCapabilities(); @@ -757,6 +758,15 @@ void HMICapabilitiesImpl::set_rc_capability( rc_capability_ = new smart_objects::SmartObject(rc_capability); } +void HMICapabilitiesImpl::set_seat_location_capability( + const smart_objects::SmartObject& seat_location_capability) { + if (seat_location_capability_) { + delete seat_location_capability_; + } + seat_location_capability_ = + new smart_objects::SmartObject(seat_location_capability); +} + void HMICapabilitiesImpl::Init(resumption::LastState* last_state) { hmi_language_handler_.Init(last_state); if (false == load_capabilities_from_file()) { @@ -924,6 +934,11 @@ const smart_objects::SmartObject* HMICapabilitiesImpl::rc_capability() const { return rc_capability_; } +const smart_objects::SmartObject* +HMICapabilitiesImpl::seat_location_capability() const { + return seat_location_capability_; +} + bool HMICapabilitiesImpl::load_capabilities_from_file() { std::string json_string; std::string file_name = app_mngr_.get_settings().hmi_capabilities_file_name(); @@ -1265,6 +1280,15 @@ bool HMICapabilitiesImpl::load_capabilities_from_file() { set_rc_supported(true); } } + if (check_existing_json_member(system_capabilities, + "seatLocationCapability")) { + Json::Value seat_location_capability = + system_capabilities.get("seatLocationCapability", ""); + smart_objects::SmartObject seat_location_capability_so; + formatters::CFormatterJsonBase::jsonValueToObj( + seat_location_capability, seat_location_capability_so); + set_seat_location_capability(seat_location_capability_so); + } } } // UI end diff --git a/src/components/application_manager/src/hmi_interfaces_impl.cc b/src/components/application_manager/src/hmi_interfaces_impl.cc index 0e79930e89..d0e888efb2 100644 --- a/src/components/application_manager/src/hmi_interfaces_impl.cc +++ b/src/components/application_manager/src/hmi_interfaces_impl.cc @@ -236,6 +236,7 @@ generate_function_to_interface_convert_map() { HmiInterfaces::HMI_INTERFACE_RC; convert_map[RC_OnInteriorVehicleData] = HmiInterfaces::HMI_INTERFACE_RC; convert_map[RC_OnRemoteControlSettings] = HmiInterfaces::HMI_INTERFACE_RC; + convert_map[RC_SetGlobalProperties] = HmiInterfaces::HMI_INTERFACE_RC; convert_map[AppService_PublishAppService] = HmiInterfaces::HMI_INTERFACE_AppService; convert_map[AppService_UnpublishAppService] = diff --git a/src/components/application_manager/src/plugin_manager/rpc_plugin_manager_impl.cc b/src/components/application_manager/src/plugin_manager/rpc_plugin_manager_impl.cc index 2248711037..af2373fbc1 100644 --- a/src/components/application_manager/src/plugin_manager/rpc_plugin_manager_impl.cc +++ b/src/components/application_manager/src/plugin_manager/rpc_plugin_manager_impl.cc @@ -1,6 +1,6 @@ -#include "application_manager/plugin_manager/rpc_plugin_manager_impl.h" #include <dlfcn.h> +#include "application_manager/plugin_manager/rpc_plugin_manager_impl.h" #include "utils/file_system.h" namespace application_manager { @@ -12,11 +12,13 @@ RPCPluginManagerImpl::RPCPluginManagerImpl( ApplicationManager& app_manager, rpc_service::RPCService& rpc_service, HMICapabilities& hmi_capabilities, - policy::PolicyHandlerInterface& policy_handler) + policy::PolicyHandlerInterface& policy_handler, + resumption::LastState& last_state) : app_manager_(app_manager) , rpc_service_(rpc_service) , hmi_capabilities_(hmi_capabilities) - , policy_handler_(policy_handler) {} + , policy_handler_(policy_handler) + , last_state_(last_state) {} bool IsLibraryFile(const std::string& file_path) { size_t pos = file_path.find_last_of("."); @@ -94,8 +96,11 @@ uint32_t RPCPluginManagerImpl::LoadPlugins(const std::string& plugins_path) { LOG4CXX_DEBUG( logger_, "Loaded " << plugin->PluginName() << " plugin from " << full_name); - if (plugin->Init( - app_manager_, rpc_service_, hmi_capabilities_, policy_handler_)) { + if (plugin->Init(app_manager_, + rpc_service_, + hmi_capabilities_, + policy_handler_, + last_state_)) { loaded_plugins_.push_back(std::move(plugin)); } else { LOG4CXX_ERROR(logger_, diff --git a/src/components/application_manager/src/smart_object_keys.cc b/src/components/application_manager/src/smart_object_keys.cc index badffe9b39..488f9c9d36 100644 --- a/src/components/application_manager/src/smart_object_keys.cc +++ b/src/components/application_manager/src/smart_object_keys.cc @@ -81,6 +81,7 @@ const char* menu_icon = "menuIcon"; const char* keyboard_properties = "keyboardProperties"; const char* vr_commands = "vrCommands"; const char* position = "position"; +const char* user_location = "userLocation"; const char* num_ticks = "numTicks"; const char* slider_footer = "sliderFooter"; const char* menu_id = "menuID"; @@ -163,6 +164,7 @@ const char* navigation_capability = "navigationCapability"; const char* phone_capability = "phoneCapability"; const char* video_streaming_capability = "videoStreamingCapability"; const char* rc_capability = "remoteControlCapability"; +const char* seat_location_capability = "seatLocationCapability"; const char* app_services_capabilities = "appServicesCapabilities"; const char* day_color_scheme = "dayColorScheme"; const char* night_color_scheme = "nightColorScheme"; diff --git a/src/components/application_manager/test/include/application_manager/mock_application.h b/src/components/application_manager/test/include/application_manager/mock_application.h index 29e1c1cf9f..c02cd5c392 100644 --- a/src/components/application_manager/test/include/application_manager/mock_application.h +++ b/src/components/application_manager/test/include/application_manager/mock_application.h @@ -425,6 +425,9 @@ class MockApplication : public ::application_manager::Application { application_manager::WindowID(const uint32_t button_id)); MOCK_METHOD1(remove_window_capability, void(const application_manager::WindowID window_id)); + MOCK_METHOD1(set_user_location, + void(const smart_objects::SmartObject& user_location)); + MOCK_CONST_METHOD0(get_user_location, const smart_objects::SmartObject&()); }; } // namespace application_manager_test diff --git a/src/components/application_manager/test/include/application_manager/mock_hmi_capabilities.h b/src/components/application_manager/test/include/application_manager/mock_hmi_capabilities.h index 6ca987c1b2..2c3d7c267e 100644 --- a/src/components/application_manager/test/include/application_manager/mock_hmi_capabilities.h +++ b/src/components/application_manager/test/include/application_manager/mock_hmi_capabilities.h @@ -189,6 +189,12 @@ class MockHMICapabilities : public ::application_manager::HMICapabilities { MOCK_METHOD1(set_rc_capability, void(const smart_objects::SmartObject& rc_capability)); + MOCK_CONST_METHOD0(seat_location_capability, + const smart_objects::SmartObject*()); + MOCK_METHOD1( + set_seat_location_capability, + void(const smart_objects::SmartObject& seat_location_capability)); + MOCK_METHOD1(Init, void(resumption::LastState* last_state)); MOCK_CONST_METHOD0(ccpu_version, const std::string&()); diff --git a/src/components/config_profile/include/config_profile/profile.h b/src/components/config_profile/include/config_profile/profile.h index a6773e8987..5489a962e8 100644 --- a/src/components/config_profile/include/config_profile/profile.h +++ b/src/components/config_profile/include/config_profile/profile.h @@ -536,6 +536,11 @@ class Profile : public protocol_handler::ProtocolHandlerSettings, const std::vector<std::string>& video_service_transports() const OVERRIDE; uint32_t rpc_pass_through_timeout() const OVERRIDE; + + // RcConsentManager + uint16_t period_for_consent_expiration() const OVERRIDE; + // RcConsentManager end + const std::vector<std::string>& embedded_services() const OVERRIDE; const std::string hmi_origin_id() const OVERRIDE; /** @@ -1087,6 +1092,7 @@ class Profile : public protocol_handler::ProtocolHandlerSettings, int wake_up_signal_offset_; int ignition_off_signal_offset_; uint32_t rpc_pass_through_timeout_; + uint16_t period_for_consent_expiration_; std::vector<std::string> embedded_services_; diff --git a/src/components/config_profile/src/profile.cc b/src/components/config_profile/src/profile.cc index 02015e66d5..dd0dc50f44 100644 --- a/src/components/config_profile/src/profile.cc +++ b/src/components/config_profile/src/profile.cc @@ -97,6 +97,7 @@ const char* kTransportRequiredForResumptionSection = const char* kLowBandwidthTransportResumptionLevelSection = "LowBandwidthTransportResumptionLevel"; const char* kAppServicesSection = "AppServices"; +const char* kRCModuleConsentSection = "RCModuleConsent"; const char* kSDLVersionKey = "SDLVersion"; const char* kHmiCapabilitiesKey = "HMICapabilities"; @@ -247,6 +248,7 @@ const char* kSecondaryTransportForWiFiKey = "SecondaryTransportForWiFi"; const char* kAudioServiceTransportsKey = "AudioServiceTransports"; const char* kVideoServiceTransportsKey = "VideoServiceTransports"; const char* kRpcPassThroughTimeoutKey = "RpcPassThroughTimeout"; +const char* kPeriodForConsentExpirationKey = "PeriodForConsentExpiration"; const char* kDefaultTransportRequiredForResumptionKey = "DefaultTransportRequiredForResumption"; @@ -403,6 +405,7 @@ const std::string kAllowedSymbols = const bool kDefaultMultipleTransportsEnabled = false; const char* kDefaultLowBandwidthResumptionLevel = "NONE"; const uint32_t kDefaultRpcPassThroughTimeout = 10000; +const uint16_t kDefaultPeriodForConsentExpiration = 30; const char* kDefaultHMIOriginId = "HMI_ID"; const std::vector<uint8_t> kDefaultBluetoothUUID = {0x93, 0x6D, @@ -542,7 +545,8 @@ Profile::Profile() , low_voltage_signal_offset_(kDefaultLowVoltageSignalOffset) , wake_up_signal_offset_(kDefaultWakeUpSignalOffset) , ignition_off_signal_offset_(kDefaultIgnitionOffSignalOffset) - , rpc_pass_through_timeout_(kDefaultRpcPassThroughTimeout) { + , rpc_pass_through_timeout_(kDefaultRpcPassThroughTimeout) + , period_for_consent_expiration_(kDefaultPeriodForConsentExpiration) { // SDL version ReadStringValue( &sdl_version_, kDefaultSDLVersion, kMainSection, kSDLVersionKey); @@ -1146,6 +1150,10 @@ uint32_t Profile::rpc_pass_through_timeout() const { return rpc_pass_through_timeout_; } +uint16_t Profile::period_for_consent_expiration() const { + return period_for_consent_expiration_; +} + const std::vector<std::string>& Profile::secondary_transports_for_bluetooth() const { return secondary_transports_for_bluetooth_; @@ -2378,6 +2386,15 @@ void Profile::UpdateValues() { kRpcPassThroughTimeoutKey, kAppServicesSection); + ReadUIntValue(&period_for_consent_expiration_, + kDefaultPeriodForConsentExpiration, + kRCModuleConsentSection, + kPeriodForConsentExpirationKey); + + LOG_UPDATED_VALUE(period_for_consent_expiration_, + kPeriodForConsentExpirationKey, + kRCModuleConsentSection); + { // Secondary Transports and ServicesMap struct KeyPair { std::vector<std::string>* ini_vector; diff --git a/src/components/include/application_manager/application_manager_settings.h b/src/components/include/application_manager/application_manager_settings.h index 0f73ea94ed..524feed6e5 100644 --- a/src/components/include/application_manager/application_manager_settings.h +++ b/src/components/include/application_manager/application_manager_settings.h @@ -83,6 +83,7 @@ class ApplicationManagerSettings : public RequestControlerSettings, virtual const std::string& named_audio_pipe_path() const = 0; virtual const std::string& video_stream_file() const = 0; virtual const std::string& audio_stream_file() const = 0; + virtual uint16_t period_for_consent_expiration() const = 0; virtual bool use_full_app_id() const = 0; virtual uint32_t rpc_pass_through_timeout() const = 0; diff --git a/src/components/include/application_manager/hmi_capabilities.h b/src/components/include/application_manager/hmi_capabilities.h index a30625347d..ab8d5ba4e6 100644 --- a/src/components/include/application_manager/hmi_capabilities.h +++ b/src/components/include/application_manager/hmi_capabilities.h @@ -521,6 +521,22 @@ class HMICapabilities { virtual const smart_objects::SmartObject* rc_capability() const = 0; + /** + * @brief Sets available SeatLocation capabilities for further usage by + * RC functionality + * @param seat_location_capability capabilities to set + */ + virtual void set_seat_location_capability( + const smart_objects::SmartObject& seat_location_capability) = 0; + + /** + * @brief seat_location_capability Retrieves information regarding the + * seat location capability + * @return smart object of seat location capability + */ + virtual const smart_objects::SmartObject* seat_location_capability() + const = 0; + virtual void Init(resumption::LastState* last_state) = 0; /** diff --git a/src/components/include/test/application_manager/mock_application_manager_settings.h b/src/components/include/test/application_manager/mock_application_manager_settings.h index 483e78b3f0..998ff252fe 100644 --- a/src/components/include/test/application_manager/mock_application_manager_settings.h +++ b/src/components/include/test/application_manager/mock_application_manager_settings.h @@ -89,6 +89,7 @@ class MockApplicationManagerSettings MOCK_CONST_METHOD0(named_audio_pipe_path, const std::string&()); MOCK_CONST_METHOD0(video_stream_file, const std::string&()); MOCK_CONST_METHOD0(audio_stream_file, const std::string&()); + MOCK_CONST_METHOD0(period_for_consent_expiration, uint16_t()); MOCK_CONST_METHOD0(use_full_app_id, bool()); MOCK_CONST_METHOD0(cloud_app_retry_timeout, uint32_t()); MOCK_CONST_METHOD0(cloud_app_max_retry_attempts, uint16_t()); diff --git a/src/components/include/test/application_manager/mock_rpc_plugin.h b/src/components/include/test/application_manager/mock_rpc_plugin.h index 94ce8ccbb6..7e4ff11bc7 100644 --- a/src/components/include/test/application_manager/mock_rpc_plugin.h +++ b/src/components/include/test/application_manager/mock_rpc_plugin.h @@ -10,11 +10,12 @@ namespace plugin_manager { class MockRPCPlugin : public RPCPlugin { public: - MOCK_METHOD4(Init, + MOCK_METHOD5(Init, bool(ApplicationManager& app_manager, rpc_service::RPCService& rpc_service, HMICapabilities& hmi_capabilities, - policy::PolicyHandlerInterface& policy_handler)); + policy::PolicyHandlerInterface& policy_handler, + resumption::LastState& last_state)); MOCK_METHOD2(IsAbleToProcess, bool(const int32_t function_id, const commands::Command::CommandSource message_source)); diff --git a/src/components/include/utils/date_time.h b/src/components/include/utils/date_time.h index 17b4fafe38..747cb0ea69 100644 --- a/src/components/include/utils/date_time.h +++ b/src/components/include/utils/date_time.h @@ -53,6 +53,7 @@ const int32_t MILLISECONDS_IN_SECOND = 1000; const int32_t MICROSECONDS_IN_MILLISECOND = 1000; const int32_t NANOSECONDS_IN_MICROSECOND = 1000; const int32_t SECONDS_IN_HOUR = 3600; +const int32_t SECONDS_IN_DAY = 86400; const int32_t MICROSECONDS_IN_SECOND = MILLISECONDS_IN_SECOND * MICROSECONDS_IN_MILLISECOND; const int32_t NANOSECONDS_IN_MILLISECOND = @@ -83,6 +84,9 @@ int64_t calculateTimeSpan(const TimeDuration& sinceTime); // return MILLISECONDS count between time1 and time2 int64_t calculateTimeDiff(const TimeDuration& time1, const TimeDuration& time2); +// returns difference between specific date and current date +int64_t calculateAmountDaysFromDate(const std::time_t& start_date); + /** * @brief Adds milliseconds to time struct * @param time contains time struct diff --git a/src/components/interfaces/HMI_API.xml b/src/components/interfaces/HMI_API.xml index 9afb64b174..8e2d8dd0d1 100644 --- a/src/components/interfaces/HMI_API.xml +++ b/src/components/interfaces/HMI_API.xml @@ -1655,6 +1655,56 @@ <!-- End of Policies --> <!-- Remote Control --> + +<struct name="Grid"> + <description>Describes a location (origin coordinates and span) of a vehicle component.</description> + <param name="col" type="Integer" mandatory="true" minvalue="-1" maxvalue="100"> + </param> + <param name="row" type="Integer" mandatory="true" minvalue="-1" maxvalue="100"> + </param> + <param name="level" type="Integer" mandatory="false" defvalue="0" minvalue="-1" maxvalue="100" > + </param> + <param name="colspan" type="Integer" mandatory="false" defvalue="1" minvalue="1" maxvalue="100"> + </param> + <param name="rowspan" type="Integer" mandatory="false" defvalue="1" minvalue="1" maxvalue="100"> + </param> + <param name="levelspan" type="Integer" mandatory="false" defvalue="1" minvalue="1" maxvalue="100"> + </param> +</struct> + +<struct name="ModuleInfo"> + <description>Information about a RC module</description> + <param name="moduleId" type="String" maxlength="100" mandatory="true"> + <description> uuid of a module. "moduleId + moduleType" uniquely identify a module.</description> + </param> + <param name="location" type="Grid" mandatory="false"> + <description>Location of a module.</description> + </param> + <param name="serviceArea" type="Grid" mandatory="false"> + <description>Service area of a module. </description> + </param> + <param name="allowMultipleAccess" type="Boolean" mandatory="false" defvalue="true"> + <description>allow multiple users/apps to access the module or not </description> + </param> +</struct> + +<struct name="SeatLocation"> + <description>Describes the location of a seat.</description> + <param name="grid" type="Grid" mandatory="false"> + </param> +</struct> + +<struct name="SeatLocationCapability"> + <description>Contains information about the locations of each seat</description> + <param name="rows" type="Integer" minvalue="1" maxvalue="100" mandatory="false"></param> + <param name="columns" type="Integer" minvalue="1" maxvalue="100" mandatory="false"></param> + <param name="levels" type="Integer" minvalue="1" maxvalue="100" defvalue="1" mandatory="false"> + </param> + <param name="seats" type="SeatLocation" array="true" mandatory="false"> + <description>Contains a list of SeatLocation in the vehicle</description> + </param> +</struct> + <enum name="ModuleType"> <element name="CLIMATE"/> <element name="RADIO"/> @@ -1728,8 +1778,7 @@ <struct name="SeatControlData"> <description>Seat control data corresponds to "SEAT" ModuleType. </description> - <param name="id" type="SupportedSeat" mandatory="true"></param> - + <param name="id" type="SupportedSeat" mandatory="false"></param> <param name="heatingEnabled" type="Boolean" mandatory="false"></param> <param name="coolingEnabled" type="Boolean" mandatory="false"></param> <param name="heatingLevel" type="Integer" minvalue="0" maxvalue="100" mandatory="false"></param> @@ -1757,6 +1806,9 @@ It should not be used to identify a module by mobile application. </description> </param> + <param name="moduleInfo" type="ModuleInfo" mandatory="false"> + <description>Information about a RC module, including its id. </description> + </param> <param name="heatingEnabledAvailable" type="Boolean" mandatory="false"> </param> <param name="coolingEnabledAvailable" type="Boolean" mandatory="false"> @@ -1968,6 +2020,9 @@ <param name="moduleName" type="String" maxlength="100" mandatory="true" > <description>The short name or a short description of the radio control module.</description> </param> + <param name="moduleInfo" type="ModuleInfo" mandatory="false"> + <description>Information about a RC module, including its id. </description> + </param> <param name="radioEnableAvailable" type="Boolean" mandatory="false"> <description> Availability of the control of enable/disable radio. @@ -2120,6 +2175,9 @@ <param name="moduleName" type="String" maxlength="100" mandatory="true" > <description>The short name or a short description of the climate control module.</description> </param> + <param name="moduleInfo" type="ModuleInfo" mandatory="false"> + <description>Information about a RC module, including its id. </description> + </param> <param name="currentTemperatureAvailable" type="Boolean" mandatory="false"> <description> Availability of the reading of current temperature. @@ -2263,6 +2321,9 @@ It should not be used to identify a module by mobile application. </description> </param> + <param name="moduleInfo" type="ModuleInfo" mandatory="false"> + <description>Information about a RC module, including its id. </description> + </param> <param name="sourceAvailable" type="Boolean" mandatory="false"> <description>Availability of the control of audio source. </description> </param> @@ -2422,6 +2483,9 @@ It should not be used to identify a module by mobile application. </description> </param> + <param name="moduleInfo" type="ModuleInfo" mandatory="false"> + <description>Information about a RC module, including its id. </description> + </param> <param name="supportedLights" type="LightCapabilities" minsize="1" maxsize="100" array="true" mandatory="true"> <description> An array of available light names that are controllable. </description> </param> @@ -2466,6 +2530,9 @@ It should not be used to identify a module by mobile application. </description> </param> + <param name="moduleInfo" type="ModuleInfo" mandatory="false"> + <description>Information about a RC module, including its id. </description> + </param> <param name="distanceUnitAvailable" type="Boolean" mandatory="false"> <description>Availability of the control of distance unit. </description> </param> @@ -2481,6 +2548,9 @@ <description>The moduleType indicates which type of data should be changed and identifies which data object exists in this struct. For example, if the moduleType is CLIMATE then a "climateControlData" should exist</description> <param name="moduleType" type="Common.ModuleType" mandatory="true" > </param> + <param name="moduleId" type="String" maxlength="100" mandatory="false"> + <description>Id of a module, published by System Capability. </description> + </param> <param name="radioControlData" type="Common.RadioControlData" mandatory="false"> </param> <param name="climateControlData" type="Common.ClimateControlData" mandatory="false"> @@ -2523,6 +2593,9 @@ <param name="name" type="Common.ButtonName" mandatory="true"> <description>The name of the Button from the ButtonName enum</description> </param> + <param name="moduleInfo" type="ModuleInfo" mandatory="false"> + <description>Information about a RC module, including its id. </description> + </param> <param name="shortPressAvailable" type="Boolean" mandatory="true"> <description>The button supports a short press. Whenever the button is pressed short, onButtonPressed(SHORT) should be invoked.</description> </param> @@ -4009,6 +4082,7 @@ <element name="REMOTE_CONTROL"/> <element name="APP_SERVICES" /> <element name="DISPLAYS"/> + <element name="SEAT_LOCATION"/> </enum> <struct name="SystemCapability"> @@ -4039,6 +4113,9 @@ </description> </param> <param name="displayCapabilities" type="Common.DisplayCapability" array="true" minsize="1" maxsize="1000" mandatory="false"/> + <param name="seatLocationCapability" type="SeatLocationCapability" mandatory="false"> + <description>Contains information about the locations of each seat</description> + </param> </struct> </interface> @@ -4061,6 +4138,9 @@ <param name="moduleType" type="Common.ModuleType" mandatory="true" > <description>The module where the button should be pressed</description> </param> + <param name="moduleId" type="String" maxlength="100" mandatory="false"> + <description>Id of a module, published by System Capability. </description> + </param> <param name="buttonName" type="Common.ButtonName" mandatory="true" /> <param name="buttonPressMode" type="Common.ButtonPressMode" mandatory="true" > <description>Indicates whether this is a LONG or SHORT button press event.</description> @@ -6714,7 +6794,23 @@ <param name="remoteControlCapability" type="Common.RemoteControlCapabilities" mandatory="false"> <description>See RemoteControlCapabilities, all available RC modules and buttons shall be returned.</description> </param> + <param name="seatLocationCapability" type="Common.SeatLocationCapability" mandatory="false"> + <description>See SeatLocationCapability, all available seat locations shall be returned.</description> + </param> </function> + +<function name="SetGlobalProperties" messagetype="request"> + <description>Sets some properties for the application initiated request.</description> + <param name="userLocation" type="Common.SeatLocation" mandatory="false"> + <description>Location of the user's seat. Default is driver's seat location if it is not set yet.</description> + </param> + <param name="appID" type="Integer" mandatory="true"> + <description>ID of application related to this RPC.</description> + </param> +</function> + +<function name="SetGlobalProperties" messagetype="response"> +</function> <function name="SetInteriorVehicleData" functionID="SetInteriorVehicleDataID" messagetype="request"> <param name="moduleData" type="Common.ModuleData" mandatory="true" > @@ -6735,8 +6831,11 @@ <param name="moduleType" type="Common.ModuleType" mandatory="true" > <description>The module data to retrieve from the vehicle for that type</description> </param> + <param name="moduleId" type="String" maxlength="100" mandatory="false"> + <description>Id of a module, published by System Capability. </description> + </param> <param name="subscribe" type="Boolean" mandatory="false"> - <description>If subscribe is true, the head unit will send OnInteriorVehicleData notifications for the module type</description> + <description>If subscribe is true, the head unit will send OnInteriorVehicleData notifications for the requested module (moduleId and moduleType)</description> </param> </function> @@ -6751,20 +6850,23 @@ </function> <function name="GetInteriorVehicleDataConsent" messagetype="request"> - <description>Sender: SDL->HMI. </description> <description>HMI is expected to display a permission prompt to the driver showing the RC module and app details (for example, app's name). The driver is expected to have an ability to grant or deny the permission.</description> <param name="moduleType" type="Common.ModuleType" mandatory="true"> <description>The module type that the app requests to control.</description> </param> + <param name="moduleIds" type="String" maxlength="100" array="true" mandatory="false"> + <description>Ids of a module, published by System Capability. </description> + </param> <param name="appID" type="Integer" mandatory="true"> <description>ID of the application that triggers the permission prompt.</description> </param> </function> <function name="GetInteriorVehicleDataConsent" messagetype="response"> - <param name="allowed" type="Boolean" mandatory="true"> - <description>"true" - if the driver grants the permission for controlling to the named app; - "false" - in case the driver denies the permission for controlling to the named app.</description> + <param name="allowed" type="Boolean" array="true" mandatory="true"> + <description>This array has the same size as "moduleIds" in the request; each element corresponding to one moduleId + "true" - if the driver grants the permission for controlling the named app; + "false" - in case the driver denies the permission for controlling the named app.</description> </param> </function> diff --git a/src/components/interfaces/MOBILE_API.xml b/src/components/interfaces/MOBILE_API.xml index b74ee7f384..8ad9acb6d8 100644 --- a/src/components/interfaces/MOBILE_API.xml +++ b/src/components/interfaces/MOBILE_API.xml @@ -1128,6 +1128,9 @@ <enum name="GlobalProperty" since="1.0"> <description>The different global properties.</description> + <element name="USER_LOCATION" since="6.0"> + <description>Location of the user's seat of setGlobalProperties</description> + </element> <element name="HELPPROMPT" since="1.0"> <description>The property helpPrompt of setGlobalProperties</description> </element> @@ -2285,12 +2288,47 @@ </param> <!-- TODO: Add pixel density? --> </struct> - + + <struct name="Grid" since="6.0"> + <description>Describes a location (origin coordinates and span) of a vehicle component.</description> + <param name="col" type="Integer" mandatory="true" minvalue="-1" maxvalue="100"> + </param> + <param name="row" type="Integer" mandatory="true" minvalue="-1" maxvalue="100"> + </param> + <param name="level" type="Integer" mandatory="false" defvalue="0" minvalue="-1" maxvalue="100" > + </param> + <param name="colspan" type="Integer" mandatory="false" defvalue="1" minvalue="1" maxvalue="100"> + </param> + <param name="rowspan" type="Integer" mandatory="false" defvalue="1" minvalue="1" maxvalue="100"> + </param> + <param name="levelspan" type="Integer" mandatory="false" defvalue="1" minvalue="1" maxvalue="100"> + </param> + </struct> + + <struct name="ModuleInfo" since="6.0"> + <description>Information about a RC module</description> + <param name="moduleId" type="String" maxlength="100" mandatory="true"> + <description> uuid of a module. "moduleId + moduleType" uniquely identify a module.</description> + </param> + <param name="location" type="Grid" mandatory="false"> + <description>Location of a module.</description> + </param> + <param name="serviceArea" type="Grid" mandatory="false"> + <description>Service area of a module. </description> + </param> + <param name="allowMultipleAccess" type="Boolean" mandatory="false" defvalue="true"> + <description>allow multiple users/apps to access the module or not </description> + </param> + </struct> + <struct name="ButtonCapabilities" since="1.0"> <description>Contains information about a button's capabilities.</description> <param name="name" type="ButtonName" mandatory="true"> <description>The name of the button. See ButtonName.</description> </param> + <param name="moduleInfo" type="ModuleInfo" mandatory="false" since="6.0"> + <description>Information about a RC module, including its id. </description> + </param> <param name="shortPressAvailable" type="Boolean" mandatory="true"> <description> The button supports a short press. @@ -2796,6 +2834,8 @@ <element name="ShowAppMenuID" value="59" hexvalue="3B" since="6.0" /> <element name="CreateWindowID" value="60" hexvalue="3C" since="6.0" /> <element name="DeleteWindowID" value="61" hexvalue="3D" since="6.0" /> + <element name="GetInteriorVehicleDataConsentID" value="62" hexvalue="3E" since="6.0" /> + <element name="ReleaseInteriorVehicleDataModuleID" value="63" hexvalue="3F" since="6.0" /> <!-- Base Notifications @@ -2981,6 +3021,7 @@ <element name="REMOTE_CONTROL"/> <element name="APP_SERVICES" since="5.1"/> <element name="DISPLAYS" since="6.0"/> + <element name="SEAT_LOCATION" since="6.0"/> </enum> <struct name="NavigationCapability" since="4.5"> @@ -3069,6 +3110,23 @@ <!---Remote control --> + <struct name="SeatLocation" since="6.0"> + <description>Describes the location of a seat.</description> + <param name="grid" type="Grid" mandatory="false"> + </param> + </struct> + + <struct name="SeatLocationCapability" since="6.0"> + <description>Contains information about the locations of each seat</description> + <param name="rows" type="Integer" minvalue="1" maxvalue="100" mandatory="false"></param> + <param name="columns" type="Integer" minvalue="1" maxvalue="100" mandatory="false"></param> + <param name="levels" type="Integer" minvalue="1" maxvalue="100" defvalue="1" mandatory="false"> + </param> + <param name="seats" type="SeatLocation" array="true" mandatory="false"> + <description>Contains a list of SeatLocation in the vehicle</description> + </param> + </struct> + <enum name="MassageZone" since="5.0"> <description>List possible zones of a multi-contour massage seat.</description> <element name="LUMBAR"> @@ -3125,16 +3183,22 @@ <param name="action" type="SeatMemoryActionType" mandatory="true"/> </struct> - <enum name="SupportedSeat" since="5.0"> + <enum name="SupportedSeat" deprecated="true" since="6.0"> <description>List possible seats that is a remote controllable seat.</description> + <history> + <enum name="SupportedSeat" since="5.0" until="6.0"/> + </history> <element name="DRIVER"/> <element name="FRONT_PASSENGER"/> </enum> <struct name="SeatControlData" since="5.0"> <description>Seat control data corresponds to "SEAT" ModuleType. </description> - <param name="id" type="SupportedSeat" mandatory="true"></param> - + <param name="id" type="SupportedSeat" mandatory="true" deprecated="true" since="6.0"> + <history> + <param name="id" type="SupportedSeat" mandatory="true" since="5.0" until="6.0"/> + </history> + </param> <param name="heatingEnabled" type="Boolean" mandatory="false"></param> <param name="coolingEnabled" type="Boolean" mandatory="false"></param> <param name="heatingLevel" type="Integer" minvalue="0" maxvalue="100" mandatory="false"></param> @@ -3163,6 +3227,9 @@ It should not be used to identify a module by mobile application. </description> </param> + <param name="moduleInfo" type="ModuleInfo" mandatory="false" since="6.0"> + <description>Information about a RC module, including its id. </description> + </param> <param name="heatingEnabledAvailable" type="Boolean" mandatory="false"> </param> <param name="coolingEnabledAvailable" type="Boolean" mandatory="false"> @@ -3343,13 +3410,15 @@ <struct name="RadioControlCapabilities" since="4.5"> <description>Contains information about a radio control module's capabilities.</description> - <!-- need an ID in the future --> <param name="moduleName" type="String" maxlength="100" mandatory="true"> <description> The short friendly name of the climate control module. It should not be used to identify a module by mobile application. </description> </param> + <param name="moduleInfo" type="ModuleInfo" mandatory="false" since="6.0"> + <description>Information about a RC module, including its id. </description> + </param> <param name="radioEnableAvailable" type="Boolean" mandatory="false"> <description> Availability of the control of enable/disable radio. @@ -3435,11 +3504,13 @@ <struct name="ClimateControlCapabilities" since="4.5"> <description>Contains information about a climate control module's capabilities.</description> - <!-- need an ID in the future --> <param name="moduleName" type="String" maxlength="100" mandatory="true"> <description>The short friendly name of the climate control module. It should not be used to identify a module by mobile application.</description> </param> + <param name="moduleInfo" type="ModuleInfo" mandatory="false" since="6.0"> + <description>Information about a RC module, including its id. </description> + </param> <param name="currentTemperatureAvailable" type="Boolean" mandatory="false" since="5.0"> <description> Availability of the reading of current temperature. @@ -3585,6 +3656,9 @@ It should not be used to identify a module by mobile application. </description> </param> + <param name="moduleInfo" type="ModuleInfo" mandatory="false" since="6.0"> + <description>Information about a RC module, including its id. </description> + </param> <param name="sourceAvailable" type="Boolean" mandatory="false"> <description>Availability of the control of audio source. </description> </param> @@ -3737,6 +3811,9 @@ It should not be used to identify a module by mobile application. </description> </param> + <param name="moduleInfo" type="ModuleInfo" mandatory="false" since="6.0"> + <description>Information about a RC module, including its id. </description> + </param> <param name="supportedLights" type="LightCapabilities" minsize="1" maxsize="100" array="true" mandatory="true"> <description> An array of available LightCapabilities that are controllable. </description> </param> @@ -3782,6 +3859,9 @@ It should not be used to identify a module by mobile application. </description> </param> + <param name="moduleInfo" type="ModuleInfo" mandatory="false" since="6.0"> + <description>Information about a RC module, including its id. </description> + </param> <param name="distanceUnitAvailable" type="Boolean" mandatory="false"> <description>Availability of the control of distance unit. </description> </param> @@ -3797,6 +3877,9 @@ <description>The moduleType indicates which type of data should be changed and identifies which data object exists in this struct. For example, if the moduleType is CLIMATE then a "climateControlData" should exist</description> <param name="moduleType" type="ModuleType" mandatory="true"> </param> + <param name="moduleId" type="String" maxlength="100" mandatory="false" since="6.0"> + <description>Id of a module, published by System Capability. </description> + </param> <param name="radioControlData" type="RadioControlData" mandatory="false"> </param> <param name="climateControlData" type="ClimateControlData" mandatory="false"> @@ -4343,6 +4426,9 @@ <description>An array of currently available services. If this is an update to the capability the affected services will include an update reason in that item</description> </param> <param name="displayCapabilities" type="DisplayCapability" array="true" minsize="1" maxsize="1000" mandatory="false" since="6.0"/> + <param name="seatLocationCapability" type="SeatLocationCapability" mandatory="false" since="6.0"> + <description>Contains information about the locations of each seat</description> + </param> </struct> <!-- Requests/Responses --> @@ -4718,6 +4804,9 @@ <function name="SetGlobalProperties" functionID="SetGlobalPropertiesID" messagetype="request" since="1.0"> <description>Allows setting global properties.</description> + <param name="userLocation" type="SeatLocation" mandatory="false" since="6.0"> + <description>Location of the user's seat. Default is driver's seat location if it is not set yet.</description> + </param> <param name="helpPrompt" type="TTSChunk" minsize="1" maxsize="100" array="true" mandatory="false" since="1.0"> <description> @@ -7293,6 +7382,9 @@ <param name="moduleType" type="ModuleType" mandatory="true"> <description>The module where the button should be pressed</description> </param> + <param name="moduleId" type="String" maxlength="100" mandatory="false" since="6.0"> + <description>Id of a module, published by System Capability. </description> + </param> <param name="buttonName" type="ButtonName" mandatory="true"> <description>The name of supported RC climate or radio button.</description> </param> @@ -7329,11 +7421,14 @@ In the future, this should be the Identification of a module. </description> </param> + <param name="moduleId" type="String" maxlength="100" mandatory="false" since="6.0"> + <description>Id of a module, published by System Capability. </description> + </param> <param name="subscribe" type="Boolean" mandatory="false" since="4.5.1"> <description> - If subscribe is true, the head unit will register OnInteriorVehicleData notifications for the requested moduleType. - If subscribe is false, the head unit will unregister OnInteriorVehicleData notifications for the requested moduleType. - If subscribe is not included, the subscription status of the app for the requested moduleType will remain unchanged. + If subscribe is true, the head unit will register OnInteriorVehicleData notifications for the requested module (moduleId and moduleType). + If subscribe is false, the head unit will unregister OnInteriorVehicleData notifications for the requested module (moduleId and moduleType). + If subscribe is not included, the subscription status of the app for the requested module (moduleId and moduleType) will remain unchanged. </description> <history> <param name="subscribe" type="Boolean" mandatory="false" defvalue="false" since="4.5" until="4.5.1"/> @@ -7371,6 +7466,70 @@ </description> </param> </function> + <function name="GetInteriorVehicleDataConsent" functionID="GetInteriorVehicleDataConsentID" messagetype="request" since="6.0"> + <param name="moduleType" type="ModuleType" mandatory="true"> + <description>The module type that the app requests to control.</description> + </param> + <param name="moduleIds" type="String" maxlength="100" array="true" mandatory="true"> + <description>Ids of a module of same type, published by System Capability. </description> + </param> + </function> + + <function name="GetInteriorVehicleDataConsent" functionID="GetInteriorVehicleDataConsentID" messagetype="response" since="6.0"> + <param name="allowed" type="Boolean" array="true" mandatory="false"> + <description>This array has the same size as "moduleIds" in the request; each element corresponding to one moduleId + "true" - if SDL grants the permission for the requested module; + "false" - SDL denies the permission for the requested module.</description> + </param> + <param name="resultCode" type="Result" platform="documentation" mandatory="true"> + <description>See Result</description> + <element name="SUCCESS"/> + <element name="INVALID_DATA"/> + <element name="OUT_OF_MEMORY"/> + <element name="TOO_MANY_PENDING_REQUESTS"/> + <element name="APPLICATION_NOT_REGISTERED"/> + <element name="GENERIC_ERROR"/> + <element name="REJECTED"/> + <element name="IGNORED"/> + <element name="DISALLOWED"/> + <element name="USER_DISALLOWED"/> + <element name="UNSUPPORTED_RESOURCE"/> + </param> + <param name="info" type="String" maxlength="1000" mandatory="false"> + </param> + <param name="success" type="Boolean" platform="documentation" mandatory="true"> + <description> true if successful; false, if failed </description> + </param> + </function> + + <function name="ReleaseInteriorVehicleDataModule" functionID="ReleaseInteriorVehicleDataModuleID" messagetype="request" since="6.0"> + <param name="moduleType" type="ModuleType" mandatory="true"> + </param> + <param name="moduleId" type="String" maxlength="100" mandatory="false" since="5.1"> + <description>Id of a module, published by System Capability. </description> + </param> + </function> + + <function name="ReleaseInteriorVehicleDataModule" functionID="ReleaseInteriorVehicleDataModuleID" messagetype="response" since="6.0"> + <param name="resultCode" type="Result" platform="documentation" mandatory="true"> + <description>See Result</description> + <element name="SUCCESS"/> + <element name="INVALID_DATA"/> + <element name="OUT_OF_MEMORY"/> + <element name="TOO_MANY_PENDING_REQUESTS"/> + <element name="APPLICATION_NOT_REGISTERED"/> + <element name="GENERIC_ERROR"/> + <element name="REJECTED"/> + <element name="IGNORED"/> + <element name="DISALLOWED"/> + <element name="UNSUPPORTED_RESOURCE"/> + </param> + <param name="info" type="String" maxlength="1000" mandatory="false"> + </param> + <param name="success" type="Boolean" platform="documentation" mandatory="true"> + <description> true if successful; false, if failed </description> + </param> + </function> <function name="SetInteriorVehicleData" functionID="SetInteriorVehicleDataID" messagetype="request" since="4.5"> <param name="moduleData" type="ModuleData" mandatory="true"> diff --git a/src/components/utils/src/date_time.cc b/src/components/utils/src/date_time.cc index 3ca6050b3f..cea35a977e 100644 --- a/src/components/utils/src/date_time.cc +++ b/src/components/utils/src/date_time.cc @@ -102,4 +102,17 @@ TimeCompare compareTime(const TimeDuration& time1, const TimeDuration& time2) { return EQUAL; } +int64_t calculateAmountDaysFromDate(const std::time_t& start_date) { + const time_t current_date = std::time(NULL); + + // std::difftime returns difference between two timepoints in seconds + const uint32_t diff_consent_and_current_dates = (static_cast<uint32_t>( + std::fabs(std::difftime(current_date, start_date)))); + + const uint32_t past_period_in_days = + diff_consent_and_current_dates / date_time::SECONDS_IN_DAY; + + return past_period_in_days; +} + } // namespace date_time |