diff options
author | Alexander Kutsan <akutsan@luxoft.com> | 2017-08-10 14:07:09 +0300 |
---|---|---|
committer | Andrey Oleynik <aoleynik@luxoft.com> | 2017-08-16 22:34:23 +0300 |
commit | 59f437dc8608e1ec54c517416a39860d9a7be3b8 (patch) | |
tree | 2908c276bd5ea066741c034eb2bd144682ba8649 | |
parent | 06729e8b744374a4d9694f669101b6c554ce42e0 (diff) | |
download | sdl_core-59f437dc8608e1ec54c517416a39860d9a7be3b8.tar.gz |
Implementation of Remote Control plugin
Stype changes after integration
Fix policy handler remote unit tests
153 files changed, 19435 insertions, 365 deletions
diff --git a/src/components/application_manager/CMakeLists.txt b/src/components/application_manager/CMakeLists.txt index 0d532c9a5c..e61411d063 100644 --- a/src/components/application_manager/CMakeLists.txt +++ b/src/components/application_manager/CMakeLists.txt @@ -38,6 +38,7 @@ set (AM_MOCK_DIR ${AM_TEST_DIR}/mock) include_directories ( include/ ${COMPONENTS_DIR} + ${COMPONENTS_DIR}/functional_module/include/ ${COMPONENTS_DIR}/utils/include/ ${COMPONENTS_DIR}/formatters/include/ ${COMPONENTS_DIR}/protocol_handler/include/ @@ -389,6 +390,11 @@ set(PATHS ) collect_sources(SOURCES "${PATHS}" "${EXCLUDE_PATHS}") +if (NOT REMOTE_CONTROL) + list(REMOVE_ITEM SOURCES + ${COMPONENTS_DIR}/application_manager/src/core_service.cc) +endif() + set(LIBRARIES HMI_API MOBILE_API @@ -404,6 +410,13 @@ set(LIBRARIES emhashmap -L${EMHASHMAP_LIBS_DIRECTORY} ) +if(REMOTE_CONTROL) + SET (LIBRARIES + ${LIBRARIES} + FunctionalModule + ) +endif(REMOTE_CONTROL) + if (CMAKE_SYSTEM_NAME STREQUAL "Linux") list(APPEND LIBRARIES sqlite3) endif () diff --git a/src/components/application_manager/include/application_manager/application.h b/src/components/application_manager/include/application_manager/application.h index aa0227efda..01b305e876 100644 --- a/src/components/application_manager/include/application_manager/application.h +++ b/src/components/application_manager/include/application_manager/application.h @@ -42,6 +42,7 @@ #include "utils/data_accessor.h" #include "interfaces/MOBILE_API.h" #include "connection_handler/device.h" +#include "application_manager/app_extension.h" #include "application_manager/message.h" #include "application_manager/hmi_state.h" #include "application_manager/application_state.h" @@ -384,7 +385,6 @@ class Application : public virtual InitialApplicationData, public: enum ApplicationRegisterState { kRegistered = 0, kWaitingForRegistration }; - public: Application() : is_greyed_out_(false) {} virtual ~Application() {} @@ -786,6 +786,31 @@ class Application : public virtual InitialApplicationData, */ virtual uint32_t GetAvailableDiskSpace() = 0; +#ifdef SDL_REMOTE_CONTROL + virtual void set_system_context( + const mobile_api::SystemContext::eType& system_context) = 0; + virtual void set_audio_streaming_state( + const mobile_api::AudioStreamingState::eType& state) = 0; + virtual bool IsSubscribedToInteriorVehicleData( + smart_objects::SmartObject module) = 0; + virtual bool SubscribeToInteriorVehicleData( + smart_objects::SmartObject module) = 0; + virtual bool UnsubscribeFromInteriorVehicleData( + smart_objects::SmartObject module) = 0; + virtual void set_hmi_level(const mobile_api::HMILevel::eType& hmi_level) = 0; + + /** + * @brief Return pointer to extension by uid + * @param uid uid of extension + * @return Pointer to extension, if extension was initialized, otherwise NULL + */ + virtual AppExtensionPtr QueryInterface(AppExtensionUID uid) = 0; + virtual bool AddExtension(AppExtensionPtr extention) = 0; + virtual bool RemoveExtension(AppExtensionUID uid) = 0; + virtual void RemoveExtensions() = 0; + virtual const std::set<uint32_t>& SubscribesIVI() const = 0; +#endif // SDL_REMOTE_CONTROL + protected: mutable sync_primitives::Lock hmi_states_lock_; @@ -800,6 +825,7 @@ class Application : public virtual InitialApplicationData, typedef utils::SharedPtr<Application> ApplicationSharedPtr; typedef utils::SharedPtr<const Application> ApplicationConstSharedPtr; +typedef uint32_t ApplicationId; } // namespace application_manager 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 089be323cf..979abe945d 100644 --- a/src/components/application_manager/include/application_manager/application_impl.h +++ b/src/components/application_manager/include/application_manager/application_impl.h @@ -38,6 +38,7 @@ #include <vector> #include <utility> #include <list> +#include <forward_list> #include <stdint.h> #include "utils/date_time.h" @@ -64,7 +65,8 @@ using namespace timer; namespace mobile_api = mobile_apis; namespace custom_str = custom_string; -class ApplicationImpl : public virtual InitialApplicationDataImpl, +class ApplicationImpl : public virtual Application, + public virtual InitialApplicationDataImpl, public virtual DynamicApplicationDataImpl { public: ApplicationImpl( @@ -188,9 +190,18 @@ class ApplicationImpl : public virtual InitialApplicationDataImpl, DataAccessor<VehicleInfoSubscriptions> SubscribedIVI() const OVERRIDE; inline bool IsRegistered() const OVERRIDE; - /** - * @brief ResetDataInNone reset data counters in NONE - */ +#ifdef SDL_REMOTE_CONTROL + bool SubscribeToInteriorVehicleData( + smart_objects::SmartObject module) OVERRIDE; + bool IsSubscribedToInteriorVehicleData( + smart_objects::SmartObject module) OVERRIDE; + bool UnsubscribeFromInteriorVehicleData( + smart_objects::SmartObject module) OVERRIDE; + +#endif // SDL_REMOTE_CONTROL + /** + * @brief ResetDataInNone reset data counters in NONE + */ virtual void ResetDataInNone(); virtual DataAccessor<ButtonSubscriptions> SubscribedButtons() const OVERRIDE; @@ -306,6 +317,39 @@ class ApplicationImpl : public virtual InitialApplicationDataImpl, */ uint32_t GetAvailableDiskSpace() OVERRIDE; +#ifdef SDL_REMOTE_CONTROL + /** + * @brief Sets current system context + * @param system_context new system context + */ + void set_system_context( + const mobile_api::SystemContext::eType& system_context) OVERRIDE; + /** + * @brief Sets current audio streaming state + * @param state new audio streaming state + */ + void set_audio_streaming_state( + const mobile_api::AudioStreamingState::eType& state) OVERRIDE; + /** + * @brief Sets current HMI level + * @param hmi_level new HMI level + */ + void set_hmi_level(const mobile_api::HMILevel::eType& hmi_level) OVERRIDE; + + /** + * @brief Get list of subscriptions to vehicle info notifications + * @return list of subscriptions to vehicle info notifications + */ + const std::set<uint32_t>& SubscribesIVI() const OVERRIDE; + + /** + * @brief Return pointer to extension by uid + * @param uid uid of extension + * @return Pointer to extension, if extension was initialized, otherwise NULL + */ + AppExtensionPtr QueryInterface(AppExtensionUID uid) OVERRIDE; +#endif + protected: /** * @brief Clean up application folder. Persistent files will stay @@ -335,6 +379,27 @@ class ApplicationImpl : public virtual InitialApplicationDataImpl, */ void OnAudioStreamSuspend(); +#ifdef SDL_REMOTE_CONTROL + /** + * @brief Add extension to application + * @param extension pointer to extension + * @return true if success, false if extension already initialized + */ + bool AddExtension(AppExtensionPtr extention) OVERRIDE; + + /** + * @brief Remove extension from application + * @param uid uid of extension + * @return true if success, false if extension is not present + */ + bool RemoveExtension(AppExtensionUID uid) OVERRIDE; + + /** + * @brief Removes all extensions + */ + void RemoveExtensions() OVERRIDE; +#endif // SDL_REMOTE_CONTROL + std::string hash_val_; uint32_t grammar_id_; @@ -384,6 +449,13 @@ class ApplicationImpl : public virtual InitialApplicationDataImpl, Timer video_stream_suspend_timer_; Timer audio_stream_suspend_timer_; +#ifdef SDL_REMOTE_CONTROL + std::list<AppExtensionPtr> extensions_; + + std::forward_list<smart_objects::SmartObject> + subscribed_interior_vehicle_data_; +#endif // SDL_REMOTE_CONTROL + /** * @brief Defines number per time in seconds limits */ diff --git a/src/components/application_manager/include/application_manager/application_manager_impl.h b/src/components/application_manager/include/application_manager/application_manager_impl.h index c0b7b7bd46..f0afbc78b2 100644 --- a/src/components/application_manager/include/application_manager/application_manager_impl.h +++ b/src/components/application_manager/include/application_manager/application_manager_impl.h @@ -59,6 +59,7 @@ #include "protocol_handler/protocol_handler.h" #include "hmi_message_handler/hmi_message_observer.h" #include "hmi_message_handler/hmi_message_sender.h" +#include "application_manager/policies/policy_handler_interface.h" #include "application_manager/policies/policy_handler_observer.h" #include "connection_handler/connection_handler.h" #include "connection_handler/connection_handler_observer.h" @@ -264,6 +265,72 @@ class ApplicationManagerImpl void SendHMIStatusNotification( const utils::SharedPtr<Application> app) OVERRIDE; + +#ifdef SDL_REMOTE_CONTROL + ApplicationSharedPtr application( + const std::string& device_id, + const std::string& policy_app_id) const OVERRIDE; + + uint32_t GetDeviceHandle(uint32_t connection_key) OVERRIDE; + /** + * @brief ChangeAppsHMILevel the function that will change application's + * hmi level. + * + * @param app_id id of the application whose hmi level should be changed. + * + * @param level new hmi level for certain application. + */ + void ChangeAppsHMILevel(uint32_t app_id, mobile_apis::HMILevel::eType level); + /** + * @brief MakeAppNotAudible allows to make certain application not audible. + * + * @param app_id applicatin's id whose audible state should be changed. + */ + void MakeAppNotAudible(uint32_t app_id); + + /** + * @brief MakeAppFullScreen allows ti change application's properties + * in order to make it full screen. + * + * @param app_id the id of application which should be in full screen mode. + * + * @return true if operation was success, false otherwise. + */ + bool MakeAppFullScreen(uint32_t app_id); + + /** + * @brief Subscribes to notification from HMI + * @param hmi_notification string with notification name + */ + void SubscribeToHMINotification(const std::string& hmi_notification) OVERRIDE; + + /** + * @brief Checks HMI level and returns true if audio streaming is allowed + */ + bool IsAudioStreamingAllowed(uint32_t connection_key) const OVERRIDE; + + /** + * @brief Checks HMI level and returns true if video streaming is allowed + */ + bool IsVideoStreamingAllowed(uint32_t connection_key) const OVERRIDE; + + void Erase(ApplicationSharedPtr app_to_remove) { + app_to_remove->RemoveExtensions(); + applications_.erase(app_to_remove); + } + + virtual functional_modules::PluginManager& GetPluginManager() OVERRIDE { + return plugin_manager_; + } + + std::vector<std::string> devices( + const std::string& policy_app_id) const OVERRIDE; + + virtual void SendPostMessageToMobile(const MessagePtr& message) OVERRIDE; + + virtual void SendPostMessageToHMI(const MessagePtr& message) OVERRIDE; +#endif // SDL_REMOTE_CONTROL + /** * @brief Checks if application with the same HMI type * (media, voice communication or navi) exists @@ -763,6 +830,9 @@ class ApplicationManagerImpl void SendMessageToHMI(const commands::MessageSharedPtr message) OVERRIDE; + void RemoveHMIFakeParameters( + application_manager::MessagePtr& message) OVERRIDE; + bool ManageMobileCommand(const commands::MessageSharedPtr message, commands::Command::CommandOrigin origin) OVERRIDE; bool ManageHMICommand(const commands::MessageSharedPtr message) OVERRIDE; @@ -1216,6 +1286,10 @@ class ApplicationManagerImpl smart_objects::SmartObject& output); bool ConvertSOtoMessage(const smart_objects::SmartObject& message, Message& output); + + MessageValidationResult ValidateMessageBySchema( + const Message& message) OVERRIDE; + utils::SharedPtr<Message> ConvertRawMsgToMessage( const ::protocol_handler::RawMessagePtr message); @@ -1499,6 +1573,28 @@ class ApplicationManagerImpl protocol_handler::ProtocolHandler* protocol_handler_; request_controller::RequestController request_ctrl_; +#ifdef SDL_REMOTE_CONTROL + functional_modules::PluginManager plugin_manager_; + + /** + * @brief Map contains apps with HMI state before incoming call + * After incoming call ends previous HMI state must restore + * + */ + struct AppState { + AppState(const mobile_apis::HMILevel::eType& level, + const mobile_apis::AudioStreamingState::eType& streaming_state, + const mobile_apis::SystemContext::eType& context) + : hmi_level(level) + , audio_streaming_state(streaming_state) + , system_context(context) {} + + mobile_apis::HMILevel::eType hmi_level; + mobile_apis::AudioStreamingState::eType audio_streaming_state; + mobile_apis::SystemContext::eType system_context; + }; +#endif // SDL_REMOTE_CONTROL + hmi_apis::HMI_API* hmi_so_factory_; mobile_apis::MOBILE_API* mobile_so_factory_; diff --git a/src/components/application_manager/include/application_manager/message.h b/src/components/application_manager/include/application_manager/message.h index 70d80f44ef..77ef5479ee 100644 --- a/src/components/application_manager/include/application_manager/message.h +++ b/src/components/application_manager/include/application_manager/message.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Ford Motor Company + * Copyright (c) 2017, Ford Motor Company * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -60,14 +60,17 @@ MessageType MessageTypeFromRpcType(protocol_handler::RpcType rpc_type); class Message { public: - Message(protocol_handler::MessagePriority priority); + explicit Message(protocol_handler::MessagePriority priority); Message(const Message& message); Message& operator=(const Message& message); - bool operator==(const Message& message); + bool operator==(const Message& message) const; ~Message(); //! -------------------------------------------------------------------------- int32_t function_id() const; +#ifdef SDL_REMOTE_CONTROL + std::string function_name() const; +#endif // SDL_REMOTE_CONTROL int32_t correlation_id() const; int32_t connection_key() const; @@ -81,8 +84,12 @@ class Message { size_t payload_size() const; const smart_objects::SmartObject& smart_object() const; - //! -------------------------------------------------------------------------- + //! + //--------------------------------------------------------------------------. void set_function_id(int32_t id); +#ifdef SDL_REMOTE_CONTROL + void set_function_name(const std::string& name); +#endif // SDL_REMOTE_CONTROL void set_correlation_id(int32_t id); void set_connection_key(int32_t key); void set_message_type(MessageType type); @@ -105,6 +112,9 @@ class Message { int32_t function_id_; // @remark protocol V2. int32_t correlation_id_; // @remark protocol V2. MessageType type_; // @remark protocol V2. +#ifdef SDL_REMOTE_CONTROL + std::string function_name_; +#endif // SDL_REMOTE_CONTROL // Pre-calculated message priority, higher priority messages are // Processed first @@ -120,6 +130,9 @@ class Message { size_t payload_size_; protocol_handler::MajorProtocolVersion version_; }; + +typedef utils::SharedPtr<application_manager::Message> MobileMessage; +typedef utils::SharedPtr<application_manager::Message> MessagePtr; } // namespace application_manager #endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_MESSAGE_H_ diff --git a/src/components/application_manager/include/application_manager/message_helper.h b/src/components/application_manager/include/application_manager/message_helper.h index 8ec1d4745e..45a1215531 100644 --- a/src/components/application_manager/include/application_manager/message_helper.h +++ b/src/components/application_manager/include/application_manager/message_helper.h @@ -129,6 +129,17 @@ class MessageHelper { static hmi_apis::Common_Result::eType HMIResultFromString( const std::string& hmi_result); +#ifdef SDL_REMOTE_CONTROL + /** + * @brief Converts string to device rank, if possible + * @param device_rank Stringified device rank + * @return Appropriate enum from device rank, or INVALID_ENUM, if conversion + * is not possible + */ + static mobile_api::DeviceRank::eType StringToDeviceRank( + const std::string& device_rank); +#endif // SDL_REMOTE_CONTROL + /** * @brief Converts mobile Result enum value to string * @param mobile_result mobile Result enum value @@ -702,6 +713,24 @@ class MessageHelper { int32_t connection_key, mobile_api::AppInterfaceUnregisteredReason::eType reason); +#ifdef SDL_REMOTE_CONTROL + /** + * @brief Sends HMI status notification to mobile + * + * @param application_impl application with changed HMI status + * + **/ + static void SendHMIStatusNotification( + const Application& application_impl, + ApplicationManager& application_manager); + + static void SendActivateAppToHMI( + uint32_t const app_id, + ApplicationManager& application_manager, + hmi_apis::Common_HMILevel::eType level = hmi_apis::Common_HMILevel::FULL, + bool send_policy_priority = true); +#endif // SDL_REMOTE_CONTROL + private: /** * @brief Creates new request object and fill its header diff --git a/src/components/application_manager/include/application_manager/policies/policy_handler.h b/src/components/application_manager/include/application_manager/policies/policy_handler.h index 0b808b13f5..3dd2bb76e0 100644 --- a/src/components/application_manager/include/application_manager/policies/policy_handler.h +++ b/src/components/application_manager/include/application_manager/policies/policy_handler.h @@ -112,6 +112,159 @@ class PolicyHandler : public PolicyHandlerInterface, uint32_t GetNotificationsNumber(const std::string& priority) const OVERRIDE; virtual DeviceConsent GetUserConsentForDevice( const std::string& device_id) const OVERRIDE; + +#ifdef SDL_REMOTE_CONTROL + /** + * @brief Sets HMI default type for specified application + * @param application_id ID application + * @param app_types list of HMI types + */ + void SetDefaultHmiTypes(const std::string& application_id, + const smart_objects::SmartObject* app_types) OVERRIDE; + + /** + * Checks if application has HMI type + * @param application_id ID application + * @param hmi HMI type to check + * @param app_types additional list of HMI type to search in it + * @return true if hmi is contained in policy or app_types + */ + bool CheckHMIType(const std::string& application_id, + mobile_apis::AppHMIType::eType hmi, + const smart_objects::SmartObject* app_types) OVERRIDE; + + /** + * Notifies about changing HMI level + * @param device_id unique identifier of device + * @param policy_app_id unique identifier of application in policy + * @param hmi_level default HMI level for this application + */ + void OnUpdateHMILevel(const std::string& device_id, + const std::string& policy_app_id, + const std::string& hmi_level) OVERRIDE; + + /** + * Checks access to equipment of vehicle for application by RPC + * @param device_id unique identifier of device + * @param app_id policy id application + * @param module type + * @param rpc name of rpc + * @param params parameters list + */ + application_manager::TypeAccess CheckAccess( + const PTString& device_id, + const PTString& app_id, + const PTString& module, + const std::string& rpc, + const std::vector<PTString>& params) OVERRIDE; + + /** + * Checks access to module for application + * @param app_id policy id application + * @param module + * @return true if module is allowed for application + */ + bool CheckModule(const PTString& app_id, const PTString& module) OVERRIDE; + + /** + * Sets access to equipment of vehicle for application by RPC + * @param device_id unique identifier of device + * @param app_id policy id application + * @param module type + * @param allowed true if access is allowed + */ + void SetAccess(const PTString& device_id, + const PTString& app_id, + const PTString& module, + bool allowed) OVERRIDE; + + /** + * Resets access application to all resources + * @param device_id unique identifier of device + * @param app_id policy id application + */ + void ResetAccess(const PTString& device_id, const PTString& app_id) OVERRIDE; + + /** + * Resets access by group name for all applications + * @param module type + */ + void ResetAccess(const std::string& module) OVERRIDE; + + /** + * Sets device as primary device + * @param dev_id ID device + */ + void SetPrimaryDevice(const PTString& dev_id) OVERRIDE; + + /** + * Resets driver's device + */ + void ResetPrimaryDevice() OVERRIDE; + + /** + * Return id of primary device + */ + uint32_t PrimaryDevice() const OVERRIDE; + + /** + * Sets mode of remote control (on/off) + * @param enabled true if remote control is turned on + */ + void SetRemoteControl(bool enabled) OVERRIDE; + + /** + * @brief If remote control is enabled + * by User and by Policy + */ + bool GetRemoteControl() const OVERRIDE; + + /** + * @brief Notifies passengers' apps about change + * @param new_consent New value of remote permission + */ + void OnRemoteAllowedChanged(bool new_consent) OVERRIDE; + + /** + * @brief Notifies Remote apps about change in permissions + * @param device_id Device on which app is running + * @param application_id ID of app whose permissions are changed + */ + void OnRemoteAppPermissionsChanged( + const std::string& device_id, const std::string& application_id) OVERRIDE; + + /** + * @brief Notifies Remote apps about change in HMI status + * @param device_id Device on which app is running + * @param policy_app_id ID of application + * @param hmi_level new HMI level for this application + */ + void OnUpdateHMIStatus(const std::string& device_id, + const std::string& policy_app_id, + const std::string& hmi_level) OVERRIDE; + + /** + * @brief Notifies Remote apps about change in HMI status + * @param device_id Device on which app is running + * @param policy_app_id ID of application + * @param hmi_level new HMI level for this application + * @param device_rank new device rank + */ + void OnUpdateHMIStatus(const std::string& device_id, + const std::string& policy_app_id, + const std::string& hmi_level, + const std::string& device_rank) OVERRIDE; + + /** + * Gets all allowed module types + * @param app_id unique identifier of application + * @param list of allowed module types + * @return true if application has allowed modules + */ + bool GetModuleTypes(const std::string& policy_app_id, + std::vector<std::string>* modules) const OVERRIDE; +#endif // SDL_REMOTE_CONTROL + bool GetDefaultHmi(const std::string& policy_app_id, std::string* default_hmi) const OVERRIDE; bool GetInitialAppData(const std::string& application_id, @@ -348,7 +501,8 @@ class PolicyHandler : public PolicyHandlerInterface, * @brief Allows to add new or update existed application during * registration process * @param application_id The policy aplication id. - ** @return function that will notify update manager about new application + * @param hmi_types list of hmi types + * @return function that will notify update manager about new application */ StatusNotifier AddApplication( const std::string& application_id, @@ -506,6 +660,18 @@ class PolicyHandler : public PolicyHandlerInterface, PermissionConsent& out_permissions) OVERRIDE; #endif +#ifdef SDL_REMOTE_CONTROL + /** + * @brief Updates HMI level for specified application and send notification + * @param app application where HMI level was changed + * @param level new HMI level + */ + void UpdateHMILevel(application_manager::ApplicationSharedPtr app, + mobile_apis::HMILevel::eType level); + std::vector<std::string> GetDevicesIds( + const std::string& policy_app_id) OVERRIDE; +#endif // SDL_REMOTE_CONTROL + /** * @brief Sets days after epoch on successful policy update */ @@ -644,7 +810,6 @@ class PolicyHandler : public PolicyHandlerInterface, * otherwise FALSE */ bool IsUrlAppIdValid(const uint32_t app_idx, const EndpointUrls& urls) const; - DISALLOW_COPY_AND_ASSIGN(PolicyHandler); }; diff --git a/src/components/application_manager/src/application_impl.cc b/src/components/application_manager/src/application_impl.cc index 5764a7c5f7..08672732b7 100644 --- a/src/components/application_manager/src/application_impl.cc +++ b/src/components/application_manager/src/application_impl.cc @@ -1008,4 +1008,105 @@ void ApplicationImpl::UnsubscribeFromSoftButtons(int32_t cmd_id) { } } +#ifdef SDL_REMOTE_CONTROL + +void ApplicationImpl::set_system_context( + const mobile_api::SystemContext::eType& system_context) { + const HmiStatePtr hmi_state = CurrentHmiState(); + hmi_state->set_system_context(system_context); +} + +void ApplicationImpl::set_audio_streaming_state( + const mobile_api::AudioStreamingState::eType& state) { + if (!(is_media_application() || is_navi()) && + state != mobile_api::AudioStreamingState::NOT_AUDIBLE) { + LOG4CXX_WARN(logger_, + "Trying to set audio streaming state" + " for non-media application to different from NOT_AUDIBLE"); + return; + } + CurrentHmiState()->set_audio_streaming_state(state); +} + +void ApplicationImpl::set_hmi_level( + const mobile_api::HMILevel::eType& new_hmi_level) { + using namespace mobile_apis; + const HMILevel::eType current_hmi_level = hmi_level(); + if (HMILevel::HMI_NONE != current_hmi_level && + HMILevel::HMI_NONE == new_hmi_level) { + put_file_in_none_count_ = 0; + delete_file_in_none_count_ = 0; + list_files_in_none_count_ = 0; + } + ApplicationSharedPtr app = application_manager_.application(app_id()); + DCHECK_OR_RETURN_VOID(app) + application_manager_.state_controller().SetRegularState(app, new_hmi_level); + LOG4CXX_INFO(logger_, "hmi_level = " << new_hmi_level); + usage_report_.RecordHmiStateChanged(new_hmi_level); +} + +bool ApplicationImpl::SubscribeToInteriorVehicleData( + smart_objects::SmartObject module) { + subscribed_interior_vehicle_data_.push_front(module); + return true; +} + +bool ApplicationImpl::IsSubscribedToInteriorVehicleData( + smart_objects::SmartObject module) { + for (auto it = subscribed_interior_vehicle_data_.begin(); + it != subscribed_interior_vehicle_data_.end(); + ++it) { + if (*it == module) { + return true; + } + } + return false; +} + +bool ApplicationImpl::UnsubscribeFromInteriorVehicleData( + smart_objects::SmartObject module) { + subscribed_interior_vehicle_data_.remove(module); + return true; +} + +const std::set<uint32_t>& ApplicationImpl::SubscribesIVI() const { + return subscribed_vehicle_info_; +} + +AppExtensionPtr ApplicationImpl::QueryInterface(AppExtensionUID uid) { + std::list<AppExtensionPtr>::const_iterator it = extensions_.begin(); + for (; it != extensions_.end(); ++it) { + if ((*it)->uid() == uid) { + return (*it); + } + } + + return AppExtensionPtr(); +} + +bool ApplicationImpl::AddExtension(AppExtensionPtr extension) { + if (!QueryInterface(extension->uid())) { + extensions_.push_back(extension); + return true; + } + return false; +} + +bool ApplicationImpl::RemoveExtension(AppExtensionUID uid) { + for (std::list<AppExtensionPtr>::iterator it = extensions_.begin(); + extensions_.end() != it; + ++it) { + if ((*it)->uid() == uid) { + extensions_.erase(it); + return true; + } + } + return false; +} + +void ApplicationImpl::RemoveExtensions() { + application_manager_.GetPluginManager().RemoveAppExtension(app_id_); +} +#endif // SDL_REMOTE_CONTROL + } // namespace application_manager diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc index c141a16515..72896c289e 100644 --- a/src/components/application_manager/src/application_manager_impl.cc +++ b/src/components/application_manager/src/application_manager_impl.cc @@ -71,6 +71,12 @@ #include "utils/custom_string.h" #include <time.h> +#ifdef SDL_REMOTE_CONTROL +#include "policy/usage_statistics/counter.h" +#include "functional_module/plugin_manager.h" +#include "application_manager/core_service.h" +#endif // SDL_REMOTE_CONTROL + namespace { int get_rand_from_range(uint32_t from = 0, int to = RAND_MAX) { return std::rand() % to + from; @@ -333,6 +339,20 @@ struct SubscribedToIVIPredicate { } }; +struct IsApplication { + IsApplication(connection_handler::DeviceHandle device_handle, + const std::string& policy_app_id) + : device_handle_(device_handle), policy_app_id_(policy_app_id) {} + bool operator()(const ApplicationSharedPtr app) const { + return app && app->device() == device_handle_ && + app->policy_app_id() == policy_app_id_; + } + + private: + connection_handler::DeviceHandle device_handle_; + const std::string& policy_app_id_; +}; + std::vector<ApplicationSharedPtr> ApplicationManagerImpl::IviInfoUpdated( VehicleDataType vehicle_info, int value) { // Notify Policy Manager if available about info it's interested in, @@ -1571,6 +1591,11 @@ void ApplicationManagerImpl::SendMessageToMobile( } smart_objects::SmartObject& msg_to_mobile = *message; +#ifdef SDL_REMOTE_CONTROL + mobile_apis::FunctionID::eType function_id = + static_cast<mobile_apis::FunctionID::eType>( + (*message)[strings::params][strings::function_id].asUInt()); +#endif // If correlation_id is not present, it is from-HMI message which should be // checked against policy permissions if (msg_to_mobile[strings::params].keyExists(strings::correlation_id)) { @@ -1578,6 +1603,16 @@ void ApplicationManagerImpl::SendMessageToMobile( msg_to_mobile[strings::params][strings::correlation_id].asUInt(), msg_to_mobile[strings::params][strings::connection_key].asUInt(), msg_to_mobile[strings::params][strings::function_id].asInt()); +#ifdef SDL_REMOTE_CONTROL + if (function_id == mobile_apis::FunctionID::RegisterAppInterfaceID && + (*message)[strings::msg_params][strings::success].asBool()) { + bool is_for_plugin = plugin_manager_.IsAppForPlugins(app); + LOG4CXX_INFO(logger_, + "Registered app " << app->app_id() << " is " + << (is_for_plugin ? "" : "not ") + << "for plugins."); + } +#endif } else if (app) { mobile_apis::FunctionID::eType function_id = static_cast<mobile_apis::FunctionID::eType>( @@ -1810,6 +1845,25 @@ bool ApplicationManagerImpl::ManageMobileCommand( return false; } +void ApplicationManagerImpl::RemoveHMIFakeParameters( + application_manager::MessagePtr& message) { + LOG4CXX_AUTO_TRACE(logger_); + using namespace NsSmartDeviceLink::NsSmartObjects; + using namespace NsSmartDeviceLink::NsJSONHandler; + SmartObject so; + + Formatters::FormatterJsonRpc::FromString<hmi_apis::FunctionID::eType, + hmi_apis::messageType::eType>( + message->json_message(), so); + + std::string formatted_message; + namespace Formatters = NsSmartDeviceLink::NsJSONHandler::Formatters; + hmi_apis::HMI_API factory; + factory.attachSchema(so, true); + Formatters::FormatterJsonRpc::ToString(so, formatted_message); + message->set_json_message(formatted_message); +} + void ApplicationManagerImpl::SendMessageToHMI( const commands::MessageSharedPtr message) { LOG4CXX_AUTO_TRACE(logger_); @@ -1954,6 +2008,17 @@ bool ApplicationManagerImpl::Init(resumption::LastState& last_state, app_launch_ctrl_.reset(new app_launch::AppLaunchCtrlImpl( *app_launch_dto_.get(), *this, settings_)); +#ifdef SDL_REMOTE_CONTROL + if (!hmi_handler_) { + LOG4CXX_ERROR(logger_, "HMI message handler was not initialized"); + return false; + } + plugin_manager_.SetServiceHandler(utils::MakeShared<CoreService>(*this)); + plugin_manager_.LoadPlugins(settings_.plugins_folder()); + plugin_manager_.OnServiceStateChanged( + functional_modules::ServiceState::HMI_ADAPTER_INITIALIZED); +#endif // SDL_REMOTE_CONTROL + return true; } @@ -2059,24 +2124,7 @@ bool ApplicationManagerImpl::ConvertMessageToSO( } if (output.validate() != smart_objects::Errors::OK) { LOG4CXX_ERROR(logger_, "Incorrect parameter from HMI"); - - if (application_manager::MessageType::kNotification == - output[strings::params][strings::message_type].asInt()) { - LOG4CXX_ERROR(logger_, "Ignore wrong HMI notification"); - return false; - } - - if (application_manager::MessageType::kRequest == - output[strings::params][strings::message_type].asInt()) { - LOG4CXX_ERROR(logger_, "Ignore wrong HMI request"); - return false; - } - - output.erase(strings::msg_params); - output[strings::params][hmi_response::code] = - hmi_apis::Common_Result::INVALID_DATA; - output[strings::msg_params][strings::info] = - std::string("Received invalid data on HMI response"); + return false; } break; } @@ -2234,6 +2282,58 @@ bool ApplicationManagerImpl::ConvertSOtoMessage( return true; } +MessageValidationResult ApplicationManagerImpl::ValidateMessageBySchema( + const Message& message) { + LOG4CXX_AUTO_TRACE(logger_); + smart_objects::SmartObject so; + switch (message.protocol_version()) { + case ProtocolVersion::kV4: + case ProtocolVersion::kV3: + case ProtocolVersion::kV2: { + const bool conversion_result = + formatters::CFormatterJsonSDLRPCv2::fromString( + message.json_message(), + so, + message.function_id(), + message.type(), + message.correlation_id()); + if (!conversion_result) { + return INVALID_JSON; + } + + if (!mobile_so_factory().attachSchema(so, true)) { + return INVALID_METADATA; + } + + if (so.validate() != smart_objects::Errors::OK) { + return SCHEMA_MISMATCH; + } + break; + } + case ProtocolVersion::kHMI: { + const int32_t conversion_result = formatters::FormatterJsonRpc:: + FromString<hmi_apis::FunctionID::eType, hmi_apis::messageType::eType>( + message.json_message(), so); + if (0 != conversion_result) { + LOG4CXX_WARN(logger_, + "Failed to parse json from HMI: " << conversion_result); + return INVALID_JSON; + } + + if (!hmi_so_factory().attachSchema(so, true)) { + return INVALID_METADATA; + } + + if (so.validate() != smart_objects::Errors::OK) { + return SCHEMA_MISMATCH; + } + break; + } + default: { return UNSUPPORTED_PROTOCOL; } + } + return SUCCESS; +} + utils::SharedPtr<Message> ApplicationManagerImpl::ConvertRawMsgToMessage( const ::protocol_handler::RawMessagePtr message) { LOG4CXX_AUTO_TRACE(logger_); @@ -2309,8 +2409,17 @@ void ApplicationManagerImpl::ProcessMessageFromHMI( *smart_object = message->smart_object(); #else if (!ConvertMessageToSO(*message, *smart_object)) { - LOG4CXX_ERROR(logger_, "Cannot create smart object from message"); - return; + if (application_manager::MessageType::kResponse == + (*smart_object)[strings::params][strings::message_type].asInt()) { + (*smart_object).erase(strings::msg_params); + (*smart_object)[strings::params][hmi_response::code] = + hmi_apis::Common_Result::INVALID_DATA; + (*smart_object)[strings::msg_params][strings::info] = + std::string("Received invalid data on HMI response"); + } else { + LOG4CXX_ERROR(logger_, "Cannot create smart object from message"); + return; + } } #endif // HMI_DBUS_API @@ -2852,6 +2961,10 @@ void ApplicationManagerImpl::UnregisterApplication( MessageHelper::SendStopAudioPathThru(*this); } +#ifdef SDL_REMOTE_CONTROL + plugin_manager_.OnUnregisterApplication(app_id); +#endif + MessageHelper::SendOnAppUnregNotificationToHMI( app_to_remove, is_unexpected_disconnect, *this); request_ctrl_.terminateAppRequests(app_id); @@ -2875,6 +2988,13 @@ void ApplicationManagerImpl::Handle(const impl::MessageFromMobile message) { LOG4CXX_INFO(logger_, "Application manager is stopping"); return; } +#ifdef SDL_REMOTE_CONTROL + if (plugin_manager_.IsMessageForPlugin(message)) { + LOG4CXX_INFO(logger_, "Message will be processed by plugin."); + plugin_manager_.ProcessMessage(message); + return; + } +#endif ProcessMessageFromMobile(message); } @@ -2920,6 +3040,18 @@ void ApplicationManagerImpl::Handle(const impl::MessageFromHmi message) { return; } +#ifdef SDL_REMOTE_CONTROL + if (plugin_manager_.IsHMIMessageForPlugin(message)) { + LOG4CXX_INFO(logger_, "Message will be processed by plugin."); + functional_modules::ProcessResult result = + plugin_manager_.ProcessHMIMessage(message); + if (functional_modules::ProcessResult::PROCESSED == result || + functional_modules::ProcessResult::FAILED == result) { + return; + } + } +#endif + ProcessMessageFromHMI(message); } @@ -3889,5 +4021,158 @@ void ApplicationManagerImpl::AddMockApplication(ApplicationSharedPtr mock_app) { applications_list_lock_.Release(); } #endif // BUILD_TESTS +#ifdef SDL_REMOTE_CONTROL +struct MobileAppIdPredicate { + std::string policy_app_id_; + MobileAppIdPredicate(const std::string& policy_app_id) + : policy_app_id_(policy_app_id) {} + bool operator()(const ApplicationSharedPtr app) const { + return app ? policy_app_id_ == app->policy_app_id() : false; + } +}; + +struct TakeDeviceHandle { + public: + TakeDeviceHandle(const ApplicationManager& app_mngr) : app_mngr_(app_mngr) {} + std::string operator()(ApplicationSharedPtr& app) { + return MessageHelper::GetDeviceMacAddressForHandle(app->device(), + app_mngr_); + } + + private: + const ApplicationManager& app_mngr_; +}; + +ApplicationSharedPtr ApplicationManagerImpl::application( + const std::string& device_id, const std::string& policy_app_id) const { + connection_handler::DeviceHandle device_handle; + connection_handler().GetDeviceID(device_id, &device_handle); + + DataAccessor<ApplicationSet> accessor = applications(); + ApplicationSharedPtr app = + FindApp(accessor, IsApplication(device_handle, policy_app_id)); + + LOG4CXX_DEBUG(logger_, + " policy_app_id << " << policy_app_id << "Found = " << app); + return app; +} + +std::vector<std::string> ApplicationManagerImpl::devices( + const std::string& policy_app_id) const { + MobileAppIdPredicate matcher(policy_app_id); + AppSharedPtrs apps = FindAllApps(applications(), matcher); + std::vector<std::string> devices; + std::transform(apps.begin(), + apps.end(), + std::back_inserter(devices), + TakeDeviceHandle(*this)); + return devices; +} + +bool ApplicationManagerImpl::IsAudioStreamingAllowed( + uint32_t application_key) const { + ApplicationSharedPtr app = application(application_key); + + using namespace mobile_apis::HMILevel; + using namespace helpers; + if (!app) { + LOG4CXX_WARN(logger_, "An application is not registered."); + return false; + } + + return Compare<eType, EQ, ONE>(app->hmi_level(), HMI_FULL, HMI_LIMITED); +} + +bool ApplicationManagerImpl::IsVideoStreamingAllowed( + uint32_t application_key) const { + ApplicationSharedPtr app = application(application_key); + using namespace mobile_apis::HMILevel; + using namespace helpers; + + if (!app) { + LOG4CXX_WARN(logger_, "An application is not registered."); + return false; + } + + LOG4CXX_DEBUG(logger_, "HMILevel: " << app->hmi_level()); + return Compare<eType, EQ, ONE>(app->hmi_level(), HMI_FULL, HMI_LIMITED); +} + +void ApplicationManagerImpl::SubscribeToHMINotification( + const std::string& hmi_notification) { + hmi_handler_->SubscribeToHMINotification(hmi_notification); +} + +void ApplicationManagerImpl::ChangeAppsHMILevel( + uint32_t app_id, mobile_apis::HMILevel::eType level) { + using namespace mobile_apis::HMILevel; + LOG4CXX_AUTO_TRACE(logger_); + LOG4CXX_DEBUG(logger_, "AppID to change: " << app_id << " -> " << level); + ApplicationSharedPtr app = application(app_id); + if (!app) { + LOG4CXX_ERROR(logger_, "There is no app with id: " << app_id); + return; + } + eType old_level = app->hmi_level(); + if (old_level != level) { + app->set_hmi_level(level); + OnHMILevelChanged(app_id, old_level, level); + + plugin_manager_.OnAppHMILevelChanged(app, old_level); + } else { + LOG4CXX_WARN(logger_, "Redudant changing HMI level : " << level); + } +} + +void ApplicationManagerImpl::MakeAppNotAudible(uint32_t app_id) { + using namespace mobile_apis; + ApplicationSharedPtr app = application(app_id); + if (!app) { + LOG4CXX_ERROR(logger_, "There is no app with id: " << app_id); + return; + } + ChangeAppsHMILevel(app_id, HMILevel::HMI_BACKGROUND); + app->set_audio_streaming_state(AudioStreamingState::NOT_AUDIBLE); +} + +bool ApplicationManagerImpl::MakeAppFullScreen(uint32_t app_id) { + using namespace mobile_apis; + ApplicationSharedPtr app = application(app_id); + if (!app) { + LOG4CXX_ERROR(logger_, "There is no app with id: " << app_id); + return false; + } + + ChangeAppsHMILevel(app_id, HMILevel::HMI_FULL); + if (app->is_media_application() || app->is_navi()) { + app->set_audio_streaming_state(AudioStreamingState::AUDIBLE); + } + app->set_system_context(SystemContext::SYSCTXT_MAIN); + + if (!app->has_been_activated()) { + app->set_activated(true); + } + + return true; +} + +uint32_t ApplicationManagerImpl::GetDeviceHandle(uint32_t connection_key) { + using namespace connection_handler; + uint32_t device_handle = 0; + connection_handler().GetDataOnSessionKey( + connection_key, 0, NULL, &device_handle); + return device_handle; +} + +void ApplicationManagerImpl::SendPostMessageToMobile( + const MessagePtr& message) { + messages_to_mobile_.PostMessage(impl::MessageToMobile(message, false)); +} + +void ApplicationManagerImpl::SendPostMessageToHMI(const MessagePtr& message) { + messages_to_hmi_.PostMessage(impl::MessageToHmi(message)); +} + +#endif // SDL_REMOTE_CONTROL } // namespace application_manager diff --git a/src/components/application_manager/src/commands/mobile/register_app_interface_request.cc b/src/components/application_manager/src/commands/mobile/register_app_interface_request.cc index 63231438f4..74bc0c032e 100644 --- a/src/components/application_manager/src/commands/mobile/register_app_interface_request.cc +++ b/src/components/application_manager/src/commands/mobile/register_app_interface_request.cc @@ -76,6 +76,10 @@ mobile_apis::AppHMIType::eType StringToAppHMIType(const std::string& str) { return mobile_apis::AppHMIType::SYSTEM; } else if ("PROJECTION" == str) { return mobile_apis::AppHMIType::PROJECTION; +#ifdef SDL_REMOTE_CONTROL + } else if ("REMOTE_CONTROL" == str) { + return mobile_apis::AppHMIType::REMOTE_CONTROL; +#endif } else { return mobile_apis::AppHMIType::INVALID_ENUM; } @@ -84,6 +88,9 @@ mobile_apis::AppHMIType::eType StringToAppHMIType(const std::string& str) { std::string AppHMITypeToString(mobile_apis::AppHMIType::eType type) { const std::map<mobile_apis::AppHMIType::eType, std::string> app_hmi_type_map = {{mobile_apis::AppHMIType::DEFAULT, "DEFAULT"}, +#ifdef SDL_REMOTE_CONTROL + {mobile_apis::AppHMIType::REMOTE_CONTROL, "REMOTE_CONTROL"}, +#endif // SDL_REMOTE_CONTROL {mobile_apis::AppHMIType::COMMUNICATION, "COMMUNICATION"}, {mobile_apis::AppHMIType::MEDIA, "MEDIA"}, {mobile_apis::AppHMIType::MESSAGING, "MESSAGING"}, @@ -673,6 +680,12 @@ void RegisterAppInterfaceRequest::SendRegisterAppInterfaceResponseToMobile() { SendResponse(true, result_code, add_info.c_str(), &response_params); SendOnAppRegisteredNotificationToHMI( *(application.get()), resumption, need_restore_vr); +#ifdef SDL_REMOTE_CONTROL + if (msg_params.keyExists(strings::app_hmi_type)) { + GetPolicyHandler().SetDefaultHmiTypes(application->policy_app_id(), + &(msg_params[strings::app_hmi_type])); + } +#endif // SDL_REMOTE_CONTROL // Default HMI level should be set before any permissions validation, since it // relies on HMI level. diff --git a/src/components/application_manager/src/message_helper/message_helper.cc b/src/components/application_manager/src/message_helper/message_helper.cc index 7bc676620e..1ceadbdc6e 100644 --- a/src/components/application_manager/src/message_helper/message_helper.cc +++ b/src/components/application_manager/src/message_helper/message_helper.cc @@ -443,6 +443,108 @@ hmi_apis::Common_Result::eType MessageHelper::MobileToHMIResult( return HMIResultFromString(result); } +#ifdef SDL_REMOTE_CONTROL +mobile_apis::DeviceRank::eType MessageHelper::StringToDeviceRank( + const std::string& device_rank) { + using namespace NsSmartDeviceLink::NsSmartObjects; + mobile_apis::DeviceRank::eType value; + if (EnumConversionHelper<mobile_apis::DeviceRank::eType>::StringToEnum( + device_rank, &value)) { + return value; + } + return mobile_apis::DeviceRank::INVALID_ENUM; +} + +void MessageHelper::SendHMIStatusNotification( + const Application& application_impl, + ApplicationManager& application_manager) { + LOG4CXX_AUTO_TRACE(logger_); + smart_objects::SmartObjectSPtr notification = new smart_objects::SmartObject; + if (!notification) { + LOG4CXX_ERROR(logger_, "Failed to create smart object"); + return; + } + smart_objects::SmartObject& message = *notification; + + message[strings::params][strings::function_id] = + static_cast<int32_t>(mobile_api::FunctionID::OnHMIStatusID); + + message[strings::params][strings::message_type] = + static_cast<int32_t>(application_manager::MessageType::kNotification); + + message[strings::params][strings::connection_key] = + static_cast<int32_t>(application_impl.app_id()); + + message[strings::msg_params][strings::hmi_level] = + static_cast<int32_t>(application_impl.hmi_level()); + + message[strings::msg_params][strings::audio_streaming_state] = + static_cast<int32_t>(application_impl.audio_streaming_state()); + + message[strings::msg_params][strings::system_context] = + static_cast<int32_t>(application_impl.system_context()); + + application_manager.ManageMobileCommand(notification, + commands::Command::ORIGIN_SDL); +} + +void MessageHelper::SendActivateAppToHMI( + uint32_t const app_id, + ApplicationManager& application_manager, + hmi_apis::Common_HMILevel::eType level, + bool send_policy_priority) { + application_manager::ApplicationConstSharedPtr app = + application_manager.application(app_id); + if (!app) { + LOG4CXX_WARN(logger_, "Invalid app_id: " << app_id); + return; + } + + utils::SharedPtr<smart_objects::SmartObject> message = + new smart_objects::SmartObject(smart_objects::SmartType_Map); + + (*message)[strings::params][strings::function_id] = + hmi_apis::FunctionID::BasicCommunication_ActivateApp; + (*message)[strings::params][strings::message_type] = MessageType::kRequest; + (*message)[strings::params][strings::correlation_id] = + application_manager.GetNextHMICorrelationID(); + (*message)[strings::msg_params][strings::app_id] = app_id; + + if (send_policy_priority) { + std::string priority; + // TODO(KKolodiy): need remove method policy_manager + + application_manager.GetPolicyHandler().GetPriority(app->policy_app_id(), + &priority); + // According SDLAQ-CRS-2794 + // SDL have to send ActivateApp without "proirity" parameter to HMI. + // in case of unconsented device + std::string mac_adress; + connection_handler::DeviceHandle device_handle = app->device(); + application_manager.connection_handler() + .get_session_observer() + .GetDataOnDeviceID(device_handle, NULL, NULL, &mac_adress, NULL); + + policy::DeviceConsent consent = + application_manager.GetPolicyHandler().GetUserConsentForDevice( + mac_adress); + if (!priority.empty() && + (policy::DeviceConsent::kDeviceAllowed == consent)) { + (*message)[strings::msg_params][strings::priority] = + GetPriorityCode(priority); + } + } + + // We haven't send HMI level to HMI in case it FULL. + if (hmi_apis::Common_HMILevel::INVALID_ENUM != level && + hmi_apis::Common_HMILevel::FULL != level) { + (*message)[strings::msg_params][strings::activate_app_hmi_level] = level; + } + + application_manager.ManageHMICommand(message); +} +#endif // SDL_REMOTE_CONTROL + mobile_apis::HMILevel::eType MessageHelper::StringToHMILevel( const std::string& hmi_level) { using namespace NsSmartDeviceLink::NsSmartObjects; diff --git a/src/components/application_manager/src/policies/policy_handler.cc b/src/components/application_manager/src/policies/policy_handler.cc index ec8b36477c..49d79dd92e 100644 --- a/src/components/application_manager/src/policies/policy_handler.cc +++ b/src/components/application_manager/src/policies/policy_handler.cc @@ -541,6 +541,12 @@ void PolicyHandler::GetAvailableApps(std::queue<std::string>& apps) { } } +struct SmartObjectToInt { + int operator()(const smart_objects::SmartObject& item) const { + return item.asInt(); + } +}; + StatusNotifier PolicyHandler::AddApplication( const std::string& application_id, const rpc::policy_table_interface_base::AppHmiTypes& hmi_types) { @@ -1941,4 +1947,348 @@ bool PolicyHandler::IsUrlAppIdValid(const uint32_t app_idx, return ((is_registered && !is_empty_urls) || is_default); } + +#ifdef SDL_REMOTE_CONTROL + +std::vector<std::string> PolicyHandler::GetDevicesIds( + const std::string& policy_app_id) { + return application_manager_.devices(policy_app_id); +} + +namespace { +application_manager::TypeAccess ConvertTypeAccess(policy::TypeAccess access) { + application_manager::TypeAccess converted; + switch (access) { + case policy::TypeAccess::kAllowed: + converted = application_manager::TypeAccess::kAllowed; + break; + case policy::TypeAccess::kManual: + converted = application_manager::TypeAccess::kManual; + break; + case policy::TypeAccess::kDisallowed: + converted = application_manager::TypeAccess::kDisallowed; + break; + default: + converted = application_manager::TypeAccess::kNone; + } + return converted; +} +} // namespace + +void PolicyHandler::UpdateHMILevel(ApplicationSharedPtr app, + mobile_apis::HMILevel::eType level) { + LOG4CXX_AUTO_TRACE(logger_); + if (app->hmi_level() == mobile_apis::HMILevel::HMI_NONE) { + // If default is FULL, send request to HMI. Notification to mobile will be + // sent on response receiving. + if (mobile_apis::HMILevel::HMI_FULL == level) { + MessageHelper::SendActivateAppToHMI(app->app_id(), application_manager_); + } else { + LOG4CXX_INFO(logger_, + "Changing hmi level of application " + << app->app_id() << " to default hmi level " << level); + // Set application hmi level + application_manager_.ChangeAppsHMILevel(app->app_id(), level); + // If hmi Level is full, it will be seted after ActivateApp response + MessageHelper::SendHMIStatusNotification(*app, application_manager_); + } + } +} + +application_manager::TypeAccess PolicyHandler::CheckAccess( + const PTString& device_id, + const PTString& app_id, + const PTString& module, + const std::string& rpc, + const std::vector<PTString>& params) { + POLICY_LIB_CHECK(application_manager::TypeAccess::kNone); + policy::TypeAccess access = + policy_manager_->CheckAccess(device_id, app_id, module, rpc, params); + return ConvertTypeAccess(access); +} + +bool PolicyHandler::CheckModule(const PTString& app_id, + const PTString& module) { + POLICY_LIB_CHECK(false); + return policy_manager_->CheckModule(app_id, module); +} + +void PolicyHandler::SetAccess(const PTString& device_id, + const PTString& app_id, + const PTString& module, + bool allowed) { + POLICY_LIB_CHECK_VOID(); + policy_manager_->SetAccess(device_id, app_id, module, allowed); +} + +void PolicyHandler::ResetAccess(const PTString& device_id, + const PTString& app_id) { + POLICY_LIB_CHECK_VOID(); + policy_manager_->ResetAccess(device_id, app_id); +} + +void PolicyHandler::ResetAccess(const std::string& module) { + POLICY_LIB_CHECK_VOID(); + policy_manager_->ResetAccess(module); +} + +void PolicyHandler::SetPrimaryDevice(const PTString& dev_id) { + using namespace application_manager; + POLICY_LIB_CHECK_VOID(); + PTString old_dev_id = policy_manager_->PrimaryDevice(); + if (dev_id == old_dev_id) { + LOG4CXX_INFO(logger_, "Driver's device has not changed."); + return; + } + policy_manager_->SetPrimaryDevice(dev_id); + + connection_handler::DeviceHandle old_device_handle; + application_manager_.connection_handler().GetDeviceID(old_dev_id, + &old_device_handle); + + connection_handler::DeviceHandle device_handle; + application_manager_.connection_handler().GetDeviceID(dev_id, &device_handle); + + LOG4CXX_DEBUG(logger_, + "Old: " << old_dev_id << "(" << old_device_handle << ")" + << "New: " << dev_id << "(" << device_handle << ")"); + std::map<connection_handler::DeviceHandle, PTString> devices; + devices[device_handle] = dev_id; + devices[old_device_handle] = old_dev_id; + DataAccessor<ApplicationSet> accessor = application_manager_.applications(); + for (ApplicationSetConstIt i = accessor.GetData().begin(); + i != accessor.GetData().end(); + ++i) { + const ApplicationSharedPtr app = *i; + LOG4CXX_DEBUG(logger_, + "Item: " << app->device() << " - " << app->policy_app_id()); + if (devices.find(app->device()) != devices.end()) { + LOG4CXX_DEBUG(logger_, + "Send notify " << app->device() << " - " + << app->policy_app_id()); + policy_manager_->OnChangedPrimaryDevice(devices[app->device()], + app->policy_app_id()); + } + } +} + +void PolicyHandler::ResetPrimaryDevice() { + POLICY_LIB_CHECK_VOID(); + PTString old_dev_id = policy_manager_->PrimaryDevice(); + policy_manager_->ResetPrimaryDevice(); + + connection_handler::DeviceHandle old_device_handle; + application_manager_.connection_handler().GetDeviceID(old_dev_id, + &old_device_handle); + + LOG4CXX_DEBUG(logger_, + "Old: " << old_dev_id << "(" << old_device_handle << ")"); + + DataAccessor<ApplicationSet> accessor = application_manager_.applications(); + for (ApplicationSetConstIt i = accessor.GetData().begin(); + i != accessor.GetData().end(); + ++i) { + const ApplicationSharedPtr app = *i; + LOG4CXX_DEBUG(logger_, + "Item: " << app->device() << " - " << app->policy_app_id()); + if (app->device() == old_device_handle) { + LOG4CXX_DEBUG(logger_, + "Send notify " << app->device() << " - " + << app->policy_app_id()); + policy_manager_->OnChangedPrimaryDevice(old_dev_id, app->policy_app_id()); + } + } +} + +uint32_t PolicyHandler::PrimaryDevice() const { + POLICY_LIB_CHECK(0); + PTString device_id = policy_manager_->PrimaryDevice(); + connection_handler::DeviceHandle device_handle; + if (application_manager_.connection_handler().GetDeviceID(device_id, + &device_handle)) { + return device_handle; + } else { + return 0; + } +} + +void PolicyHandler::SetRemoteControl(bool enabled) { + POLICY_LIB_CHECK_VOID(); + policy_manager_->SetRemoteControl(enabled); + + OnRemoteAllowedChanged(enabled); +} + +bool PolicyHandler::GetRemoteControl() const { + POLICY_LIB_CHECK(false); + return policy_manager_->GetRemoteControl(); +} + +void PolicyHandler::OnRemoteAllowedChanged(bool /*new_consent*/) { + POLICY_LIB_CHECK_VOID(); + connection_handler::DeviceHandle device_handle = PrimaryDevice(); + + DataAccessor<ApplicationSet> accessor = application_manager_.applications(); + for (ApplicationSetConstIt i = accessor.GetData().begin(); + i != accessor.GetData().end(); + ++i) { + const ApplicationSharedPtr app = *i; + LOG4CXX_DEBUG(logger_, + "Item: " << app->device() << " - " << app->policy_app_id()); + if (app->device() != device_handle) { + LOG4CXX_DEBUG(logger_, + "Send notify " << app->device() << " - " + << app->policy_app_id()); + std::string mac = MessageHelper::GetDeviceMacAddressForHandle( + app->device(), application_manager_); + policy_manager_->OnChangedRemoteControl(mac, app->policy_app_id()); + } + } +} + +void PolicyHandler::OnRemoteAppPermissionsChanged( + const std::string& device_id, const std::string& application_id) { + POLICY_LIB_CHECK_VOID(); + policy_manager_->SendAppPermissionsChanged(device_id, application_id); +} + +void PolicyHandler::OnUpdateHMIStatus(const std::string& device_id, + const std::string& policy_app_id, + const std::string& hmi_level) { + LOG4CXX_AUTO_TRACE(logger_); + ApplicationSharedPtr app = + application_manager_.application(device_id, policy_app_id); + if (!app) { + LOG4CXX_WARN(logger_, + "Could not find application: " << device_id << " - " + << policy_app_id); + return; + } + mobile_apis::HMILevel::eType level = + MessageHelper::StringToHMILevel(hmi_level); + if (mobile_apis::HMILevel::INVALID_ENUM == level) { + LOG4CXX_WARN(logger_, + "Couldn't convert default hmi level " << hmi_level + << " to enum."); + return; + } + + LOG4CXX_INFO(logger_, + "Changing hmi level of application " + << app->app_id() << " to default hmi level " << level); + // Set application hmi level + application_manager_.ChangeAppsHMILevel(app->app_id(), level); + MessageHelper::SendHMIStatusNotification(*app, application_manager_); +} + +void PolicyHandler::OnUpdateHMIStatus(const std::string& device_id, + const std::string& policy_app_id, + const std::string& hmi_level, + const std::string& device_rank) { + LOG4CXX_AUTO_TRACE(logger_); + ApplicationSharedPtr app = + application_manager_.application(device_id, policy_app_id); + if (!app) { + LOG4CXX_WARN(logger_, + "Could not find application: " << device_id << " - " + << policy_app_id); + return; + } + mobile_apis::HMILevel::eType level = + MessageHelper::StringToHMILevel(hmi_level); + if (mobile_apis::HMILevel::INVALID_ENUM == level) { + LOG4CXX_WARN(logger_, + "Couldn't convert default hmi level " << hmi_level + << " to enum."); + return; + } + mobile_apis::DeviceRank::eType rank = + MessageHelper::StringToDeviceRank(device_rank); + if (rank == mobile_apis::DeviceRank::INVALID_ENUM) { + LOG4CXX_WARN(logger_, + "Couldn't convert device rank " << device_rank << " to enum."); + return; + } + + if (rank == mobile_apis::DeviceRank::DRIVER) { + MessageHelper::SendHMIStatusNotification(*app, application_manager_); + LOG4CXX_DEBUG(logger_, "Device rank: " << rank); + return; + } + LOG4CXX_INFO(logger_, + "Changing hmi level of application " + << app->app_id() << " to default hmi level " << level); + + // Set application hmi level + application_manager_.ChangeAppsHMILevel(app->app_id(), level); + MessageHelper::SendHMIStatusNotification(*app, application_manager_); +} + +bool PolicyHandler::GetModuleTypes(const std::string& policy_app_id, + std::vector<std::string>* modules) const { + LOG4CXX_AUTO_TRACE(logger_); + POLICY_LIB_CHECK(false); + return policy_manager_->GetModuleTypes(policy_app_id, modules); +} + +void PolicyHandler::SetDefaultHmiTypes( + const std::string& application_id, + const smart_objects::SmartObject* app_types) { + LOG4CXX_AUTO_TRACE(logger_); + POLICY_LIB_CHECK_VOID(); + std::vector<int> hmi_types; + if (app_types && app_types->asArray()) { + smart_objects::SmartArray* hmi_list = app_types->asArray(); + std::transform(hmi_list->begin(), + hmi_list->end(), + std::back_inserter(hmi_types), + SmartObjectToInt()); + } + policy_manager_->SetDefaultHmiTypes(application_id, hmi_types); +} + +bool PolicyHandler::CheckHMIType(const std::string& application_id, + mobile_apis::AppHMIType::eType hmi, + const smart_objects::SmartObject* app_types) { + LOG4CXX_AUTO_TRACE(logger_); + POLICY_LIB_CHECK(false); + std::vector<int> policy_hmi_types; + bool ret = policy_manager_->GetHMITypes(application_id, &policy_hmi_types); + + std::vector<int> additional_hmi_types; + if (app_types && app_types->asArray()) { + smart_objects::SmartArray* hmi_list = app_types->asArray(); + std::transform(hmi_list->begin(), + hmi_list->end(), + std::back_inserter(additional_hmi_types), + SmartObjectToInt()); + } + const std::vector<int>& hmi_types = + ret ? policy_hmi_types : additional_hmi_types; + return std::find(hmi_types.begin(), hmi_types.end(), hmi) != hmi_types.end(); +} + +void PolicyHandler::OnUpdateHMILevel(const std::string& device_id, + const std::string& policy_app_id, + const std::string& hmi_level) { + LOG4CXX_AUTO_TRACE(logger_); + ApplicationSharedPtr app = + application_manager_.application(device_id, policy_app_id); + if (!app) { + LOG4CXX_WARN(logger_, + "Could not find application: " << device_id << " - " + << policy_app_id); + return; + } + mobile_apis::HMILevel::eType level = + MessageHelper::StringToHMILevel(hmi_level); + if (mobile_apis::HMILevel::INVALID_ENUM == level) { + LOG4CXX_WARN(logger_, + "Couldn't convert default hmi level " << hmi_level + << " to enum."); + return; + } + UpdateHMILevel(app, level); +} +#endif // SDL_REMOTE_CONTROL } // namespace policy diff --git a/src/components/application_manager/src/smart_object_keys.cc b/src/components/application_manager/src/smart_object_keys.cc index 75d324699c..7294b4c1a2 100644 --- a/src/components/application_manager/src/smart_object_keys.cc +++ b/src/components/application_manager/src/smart_object_keys.cc @@ -140,6 +140,7 @@ const char* system_capabilities = "systemCapabilities"; const char* navigation_capability = "navigationCapability"; const char* phone_capability = "phoneCapability"; const char* video_streaming_capability = "videoStreamingCapability"; +const char* device_rank = "deviceRank"; // PutFile const char* sync_file_name = "syncFileName"; diff --git a/src/components/application_manager/test/CMakeLists.txt b/src/components/application_manager/test/CMakeLists.txt index 579fa787b9..089f8fd25e 100644 --- a/src/components/application_manager/test/CMakeLists.txt +++ b/src/components/application_manager/test/CMakeLists.txt @@ -45,11 +45,11 @@ include_directories( ${COMPONENTS_DIR}/resumption/include/ ${COMPONENTS_DIR}/utils/include/ ${POLICY_PATH}/include/ + ${COMPONENTS_DIR}/policy/policy_regular/test/include ${POLICY_PATH}/policy/test/include/ ${POLICY_MOCK_INCLUDE_PATH}/ ${COMPONENTS_DIR}/media_manager/include/ ${COMPONENTS_DIR}/security_manager/include/ - ${COMPONENTS_DIR}/policy/test/include/ ${COMPONENTS_DIR}/application_manager/test/include/ ${BSON_INCLUDE_DIRECTORY} ) @@ -73,6 +73,10 @@ set(testSources ) +if(REMOTE_CONTROL) + list(APPEND testSources ${AM_TEST_DIR}/rc_policy_handler_test.cc) +endif(REMOTE_CONTROL) + set (RequestController_SOURCES ${AM_TEST_DIR}/request_controller/request_controller_test.cc ${AM_TEST_DIR}/mock_message_helper.cc 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 7702403cbe..c24e4590f5 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 @@ -34,6 +34,7 @@ #include <string> #include "gmock/gmock.h" #include "application_manager/application.h" +#include "application_manager/app_extension.h" #include "smart_objects/smart_object.h" #include "utils/custom_string.h" #include "application_manager/usage_statistics.h" @@ -280,12 +281,41 @@ class MockApplication : public ::application_manager::Application { MOCK_CONST_METHOD0(bundle_id, const std::string&()); MOCK_METHOD1(set_bundle_id, void(const std::string& bundle_id)); MOCK_METHOD0(GetAvailableDiskSpace, uint32_t()); + MOCK_METHOD1(set_mobile_app_id, void(const std::string& policy_app_id)); MOCK_CONST_METHOD0(is_foreground, bool()); MOCK_METHOD1(set_foreground, void(bool is_foreground)); MOCK_CONST_METHOD0(IsRegistered, bool()); MOCK_CONST_METHOD0(SchemaUrl, std::string()); MOCK_CONST_METHOD0(PackageName, std::string()); + +#ifdef SDL_REMOTE_CONTROL + MOCK_METHOD1( + set_system_context, + void(const application_manager::mobile_api::SystemContext::eType&)); + MOCK_METHOD1( + set_audio_streaming_state, + void(const application_manager::mobile_api::AudioStreamingState::eType& + state)); + MOCK_METHOD1(IsSubscribedToInteriorVehicleData, + bool(smart_objects::SmartObject module)); + MOCK_METHOD1(SubscribeToInteriorVehicleData, + bool(smart_objects::SmartObject module)); + MOCK_METHOD1(UnsubscribeFromInteriorVehicleData, + bool(smart_objects::SmartObject module)); + MOCK_METHOD1( + set_hmi_level, + void(const application_manager::mobile_api::HMILevel::eType& hmi_level)); + MOCK_METHOD1(QueryInterface, + application_manager::AppExtensionPtr( + application_manager::AppExtensionUID uid)); + MOCK_METHOD1(AddExtension, + bool(application_manager::AppExtensionPtr extention)); + MOCK_METHOD1(RemoveExtension, bool(application_manager::AppExtensionUID uid)); + MOCK_METHOD0(RemoveExtensions, void()); + MOCK_CONST_METHOD0(SubscribesIVI, const std::set<uint32_t>&()); + +#endif // SDL_REMOTE_CONTROL }; } // namespace application_manager_test diff --git a/src/components/application_manager/test/include/application_manager/mock_message_helper.h b/src/components/application_manager/test/include/application_manager/mock_message_helper.h index 4499605f5a..04dc7e1df8 100644 --- a/src/components/application_manager/test/include/application_manager/mock_message_helper.h +++ b/src/components/application_manager/test/include/application_manager/mock_message_helper.h @@ -113,7 +113,16 @@ class MockMessageHelper { uint32_t correlation_id, ApplicationManager& app_mngr)); MOCK_METHOD1(SendGetSystemInfoRequest, void(ApplicationManager& app_mngr)); - + MOCK_METHOD4(SendActivateAppToHMI, + void(uint32_t const app_id, + ApplicationManager& application_manager, + hmi_apis::Common_HMILevel::eType level, + bool send_policy_priority)); + MOCK_METHOD2(SendHMIStatusNotification, + void(const Application& application_impl, + ApplicationManager& application_manager)); + MOCK_METHOD1(StringToDeviceRank, + mobile_api::DeviceRank::eType(const std::string& device_rank)); MOCK_METHOD4(SendPolicyUpdate, void(const std::string& file_path, const uint32_t timeout, diff --git a/src/components/application_manager/test/mock_message_helper.cc b/src/components/application_manager/test/mock_message_helper.cc index 3039e1f677..e52a8f53ac 100644 --- a/src/components/application_manager/test/mock_message_helper.cc +++ b/src/components/application_manager/test/mock_message_helper.cc @@ -33,6 +33,8 @@ #include "application_manager/message_helper.h" #include "application_manager/mock_message_helper.h" #include "application_manager/policies/policy_handler_interface.h" +#include "gtest/gtest.h" +#include "gmock/gmock.h" namespace application_manager { @@ -227,6 +229,30 @@ void MessageHelper::SendPolicyUpdate(const std::string& file_path, file_path, timeout, retries, app_mngr); } +#ifdef SDL_REMOTE_CONTROL +void MessageHelper::SendActivateAppToHMI( + uint32_t const app_id, + ApplicationManager& application_manager, + hmi_apis::Common_HMILevel::eType level, + bool send_policy_priority) { + MockMessageHelper::message_helper_mock()->SendActivateAppToHMI( + app_id, application_manager, level, send_policy_priority); +} + +void MessageHelper::SendHMIStatusNotification( + const Application& application_impl, + ApplicationManager& application_manager) { + MockMessageHelper::message_helper_mock()->SendHMIStatusNotification( + application_impl, application_manager); +} + +mobile_api::DeviceRank::eType MessageHelper::StringToDeviceRank( + const std::string& device_rank) { + return MockMessageHelper::message_helper_mock()->StringToDeviceRank( + device_rank); +} +#endif // SDL_REMOTE_CONTROL + void MessageHelper::SendUpdateSDLResponse(const std::string& result, uint32_t correlation_id, ApplicationManager& app_mngr) { @@ -247,7 +273,7 @@ smart_objects::SmartObjectSPtr MessageHelper::CreateModuleInfoSO( } MockMessageHelper* MockMessageHelper::message_helper_mock() { - static MockMessageHelper message_helper_mock; + static ::testing::NiceMock<MockMessageHelper> message_helper_mock; return &message_helper_mock; } void MessageHelper::SendAllOnButtonSubscriptionNotificationsForApp( diff --git a/src/components/application_manager/test/rc_policy_handler_test.cc b/src/components/application_manager/test/rc_policy_handler_test.cc new file mode 100644 index 0000000000..0a50dd230f --- /dev/null +++ b/src/components/application_manager/test/rc_policy_handler_test.cc @@ -0,0 +1,643 @@ +/* + * Copyright (c) 2017, 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 <vector> +#include <fstream> +#include "gmock/gmock.h" + +#include "application_manager/policies/policy_handler.h" +#include "application_manager/policies/delegates/app_permission_delegate.h" +#include "policy/mock_cache_manager.h" +#include "application_manager/mock_message_helper.h" +#include "connection_handler/mock_connection_handler_settings.h" +#include "policy/policy_types.h" +#include "policy/access_remote.h" +#include "json/reader.h" +#include "json/writer.h" +#include "json/value.h" +#include "smart_objects/smart_object.h" +#include "utils/make_shared.h" +#include "utils/custom_string.h" +#include "interfaces/MOBILE_API.h" +#include "policy/mock_policy_settings.h" +#include "application_manager/mock_application.h" +#include "policy/usage_statistics/mock_statistics_manager.h" +#include "protocol_handler/mock_session_observer.h" +#include "connection_handler/mock_connection_handler.h" +#include "application_manager/mock_application_manager.h" +#include "application_manager/policies/mock_policy_handler_observer.h" +#include "application_manager/mock_event_dispatcher.h" +#include "policy/mock_policy_manager.h" + +namespace test { +namespace components { +namespace rc_policy_handler_test { + +using namespace application_manager; +using namespace policy; +using namespace utils::custom_string; +using testing::_; +using ::testing::Mock; +using ::testing::Return; +using ::testing::ReturnRef; +using ::testing::NiceMock; +using ::testing::DoAll; +using ::testing::SetArgPointee; + +class RCPolicyHandlerTest : public ::testing::Test { + public: + RCPolicyHandlerTest() + : policy_handler_(policy_settings_, app_manager_) + , kPolicyAppId_("fake_app_id") + , kMacAddr_("kMacAddr_ess") + , kDeviceId_("fake_device_id") + , kHmiLevel_("NONE") + , default_hmi_("fake_hmi") + , app_set(test_app, app_lock) + , kAppId1_(10u) + , kAppId2_(11u) + , kConnectionKey_(1u) + , kCorrelationKey_(2u) + , kUrl_("test_url") + , mock_message_helper_(*MockMessageHelper::message_helper_mock()) {} + + protected: + NiceMock<policy_handler_test::MockPolicySettings> policy_settings_; + utils::SharedPtr<application_manager_test::MockApplication> mock_app_; + connection_handler_test::MockConnectionHandler conn_handler; + protocol_handler_test::MockSessionObserver mock_session_observer; + components::usage_statistics_test::MockStatisticsManager + mock_statistics_manager_; + PolicyHandler policy_handler_; + utils::SharedPtr<policy_manager_test::MockPolicyManager> mock_policy_manager_; + application_manager_test::MockApplicationManager app_manager_; + const std::string kPolicyAppId_; + const std::string kMacAddr_; + const std::string kDeviceId_; + const std::string kHmiLevel_; + std::string default_hmi_; + ApplicationSet test_app; + sync_primitives::Lock app_lock; + DataAccessor<ApplicationSet> app_set; + const uint32_t kAppId1_; + const uint32_t kAppId2_; + const uint32_t kConnectionKey_; + const uint32_t kCorrelationKey_; + const std::string kUrl_; + application_manager::MockMessageHelper& mock_message_helper_; + + virtual void SetUp() OVERRIDE { + Mock::VerifyAndClearExpectations(&mock_message_helper_); + ON_CALL(app_manager_, applications()).WillByDefault(Return(app_set)); + ON_CALL(policy_settings_, enable_policy()).WillByDefault(Return(true)); + mock_policy_manager_ = + utils::MakeShared<policy_manager_test::MockPolicyManager>(); + ASSERT_TRUE(mock_policy_manager_.valid()); + + ON_CALL(app_manager_, connection_handler()) + .WillByDefault(ReturnRef(conn_handler)); + ON_CALL(conn_handler, get_session_observer()) + .WillByDefault(ReturnRef(mock_session_observer)); + + mock_app_ = utils::MakeShared<application_manager_test::MockApplication>(); + } + + virtual void TearDown() OVERRIDE { + Mock::VerifyAndClearExpectations(&mock_message_helper_); + } + + void ChangePolicyManagerToMock() { + policy_handler_.SetPolicyManager(mock_policy_manager_); + } + + void EnablePolicy() { + ON_CALL(policy_settings_, enable_policy()).WillByDefault(Return(true)); + } + + void EnablePolicyAndPolicyManagerMock() { + EnablePolicy(); + ChangePolicyManagerToMock(); + } +}; + +TEST_F(RCPolicyHandlerTest, + SendMessageToSDK_RemoteControlInvalidMobileAppId_UNSUCCESS) { + // Precondition + BinaryMessage msg; + EnablePolicyAndPolicyManagerMock(); + + EXPECT_CALL(app_manager_, applications()).WillOnce(Return(app_set)); + test_app.insert(mock_app_); + + ON_CALL(*mock_app_, app_id()).WillByDefault(Return(kAppId1_)); + ON_CALL(*mock_app_, hmi_level()) + .WillByDefault(Return(mobile_apis::HMILevel::HMI_FULL)); + EXPECT_CALL(*mock_app_, IsRegistered()).WillOnce(Return(true)); + + EXPECT_CALL(app_manager_, application(kAppId1_)) + .WillRepeatedly(Return(mock_app_)); + const std::string empty_mobile_app_id(""); + EXPECT_CALL(*mock_app_, policy_app_id()) + .WillOnce(Return(empty_mobile_app_id)); + + EXPECT_CALL(*mock_policy_manager_, GetUserConsentForDevice(_)) + .WillOnce(Return(kDeviceAllowed)); + + EXPECT_CALL(mock_message_helper_, SendPolicySnapshotNotification(_, _, _, _)) + .Times(0); + EXPECT_FALSE(policy_handler_.SendMessageToSDK(msg, kUrl_)); +} + +TEST_F(RCPolicyHandlerTest, SendMessageToSDK_RemoteControl_SUCCESS) { + BinaryMessage msg; + EnablePolicyAndPolicyManagerMock(); + EXPECT_CALL(app_manager_, applications()).WillOnce(Return(app_set)); + test_app.insert(mock_app_); + + ON_CALL(*mock_app_, app_id()).WillByDefault(Return(kAppId1_)); + ON_CALL(*mock_app_, hmi_level()) + .WillByDefault(Return(mobile_apis::HMILevel::HMI_FULL)); + EXPECT_CALL(*mock_app_, IsRegistered()).WillOnce(Return(true)); + + EXPECT_CALL(app_manager_, application(kAppId1_)) + .WillRepeatedly(Return(mock_app_)); + + EXPECT_CALL(*mock_app_, policy_app_id()).WillOnce(Return(kPolicyAppId_)); + + EXPECT_CALL(*mock_policy_manager_, GetUserConsentForDevice(_)) + .WillOnce(Return(kDeviceAllowed)); + + EXPECT_CALL(mock_message_helper_, + SendPolicySnapshotNotification(kAppId1_, _, kUrl_, _)); + EXPECT_TRUE(policy_handler_.SendMessageToSDK(msg, kUrl_)); +} + +TEST_F(RCPolicyHandlerTest, OnUpdateHMILevel_InvalidApp_UNSUCCESS) { + EnablePolicyAndPolicyManagerMock(); + + utils::SharedPtr<application_manager_test::MockApplication> invalid_app; + EXPECT_CALL(app_manager_, application(kDeviceId_, kPolicyAppId_)) + .WillOnce(Return(invalid_app)); + EXPECT_CALL(mock_message_helper_, StringToHMILevel(_)).Times(0); + + const std::string hmi_level("HMI_FULL"); + policy_handler_.OnUpdateHMILevel(kDeviceId_, kPolicyAppId_, hmi_level); +} + +TEST_F(RCPolicyHandlerTest, OnUpdateHMILevel_InvalidHmiLevel_UNSUCCESS) { + EnablePolicyAndPolicyManagerMock(); + + EXPECT_CALL(app_manager_, application(kDeviceId_, kPolicyAppId_)) + .WillOnce(Return(mock_app_)); + + const std::string hmi_level("INVALID_ENUM"); + EXPECT_CALL(mock_message_helper_, StringToHMILevel(hmi_level)) + .WillOnce(Return(mobile_apis::HMILevel::INVALID_ENUM)); + + policy_handler_.OnUpdateHMILevel(kDeviceId_, kPolicyAppId_, hmi_level); +} + +TEST_F(RCPolicyHandlerTest, OnUpdateHMILevel_HmiLevelFull_SUCCESS) { + EnablePolicyAndPolicyManagerMock(); + + EXPECT_CALL(app_manager_, application(kDeviceId_, kPolicyAppId_)) + .WillOnce(Return(mock_app_)); + + const std::string hmi_level("HMI_FULL"); + EXPECT_CALL(mock_message_helper_, StringToHMILevel(hmi_level)) + .WillOnce(Return(mobile_apis::HMILevel::HMI_FULL)); + + EXPECT_CALL(*mock_app_, hmi_level()) + .WillOnce(Return(mobile_apis::HMILevel::HMI_NONE)); + EXPECT_CALL(*mock_app_, app_id()).WillOnce(Return(kAppId1_)); + EXPECT_CALL(mock_message_helper_, SendActivateAppToHMI(kAppId1_, _, _, _)); + + policy_handler_.OnUpdateHMILevel(kDeviceId_, kPolicyAppId_, hmi_level); +} + +TEST_F(RCPolicyHandlerTest, OnUpdateHMILevel_HmiLevelChanged_SUCCESS) { + EnablePolicyAndPolicyManagerMock(); + + EXPECT_CALL(app_manager_, application(kDeviceId_, kPolicyAppId_)) + .WillOnce(Return(mock_app_)); + + const std::string hmi_level("HMI_LIMITED"); + EXPECT_CALL(mock_message_helper_, StringToHMILevel(hmi_level)) + .WillOnce(Return(mobile_apis::HMILevel::HMI_LIMITED)); + + EXPECT_CALL(*mock_app_, hmi_level()) + .WillOnce(Return(mobile_apis::HMILevel::HMI_NONE)); + EXPECT_CALL(*mock_app_, app_id()).WillRepeatedly(Return(kAppId1_)); + + EXPECT_CALL(app_manager_, + ChangeAppsHMILevel(kAppId1_, mobile_apis::HMILevel::HMI_LIMITED)); + + EXPECT_CALL(mock_message_helper_, SendHMIStatusNotification(_, _)); + + policy_handler_.OnUpdateHMILevel(kDeviceId_, kPolicyAppId_, hmi_level); +} + +TEST_F(RCPolicyHandlerTest, CheckAccess_ValidParams_SUCCESS) { + EnablePolicyAndPolicyManagerMock(); + + const PTString module("module"); + const PTString pt_rpc("rpc"); + const std::vector<PTString> params; + + EXPECT_CALL(*mock_policy_manager_, + CheckAccess(kDeviceId_, kPolicyAppId_, module, pt_rpc, _)) + .WillOnce(Return(policy::TypeAccess::kDisallowed)); + EXPECT_EQ(application_manager::TypeAccess::kDisallowed, + policy_handler_.CheckAccess( + kDeviceId_, kPolicyAppId_, module, pt_rpc, params)); + + EXPECT_CALL(*mock_policy_manager_, + CheckAccess(kDeviceId_, kPolicyAppId_, module, pt_rpc, _)) + .WillOnce(Return(policy::TypeAccess::kAllowed)); + + EXPECT_EQ(application_manager::TypeAccess::kAllowed, + policy_handler_.CheckAccess( + kDeviceId_, kPolicyAppId_, module, pt_rpc, params)); + + EXPECT_CALL(*mock_policy_manager_, + CheckAccess(kDeviceId_, kPolicyAppId_, module, pt_rpc, _)) + .WillOnce(Return(policy::TypeAccess::kManual)); + EXPECT_EQ(application_manager::TypeAccess::kManual, + policy_handler_.CheckAccess( + kDeviceId_, kPolicyAppId_, module, pt_rpc, params)); +} + +TEST_F(RCPolicyHandlerTest, SetAccess_ValidParams_SUCCESS) { + EnablePolicyAndPolicyManagerMock(); + + const PTString module("module"); + const bool allowed(true); + EXPECT_CALL(*mock_policy_manager_, + SetAccess(kDeviceId_, kPolicyAppId_, module, allowed)); + + policy_handler_.SetAccess(kDeviceId_, kPolicyAppId_, module, allowed); +} + +TEST_F(RCPolicyHandlerTest, ResetAccess_ValidParams_SUCCESS) { + EnablePolicyAndPolicyManagerMock(); + + EXPECT_CALL(*mock_policy_manager_, ResetAccess(kDeviceId_, kPolicyAppId_)); + + policy_handler_.ResetAccess(kDeviceId_, kPolicyAppId_); +} + +TEST_F(RCPolicyHandlerTest, ResetAccess_SUCCESS) { + EnablePolicyAndPolicyManagerMock(); + + const PTString module("module"); + EXPECT_CALL(*mock_policy_manager_, ResetAccess(module)); + + policy_handler_.ResetAccess(module); +} + +TEST_F(RCPolicyHandlerTest, CheckModule_SUCCESS) { + EnablePolicyAndPolicyManagerMock(); + + const PTString module("module"); + EXPECT_CALL(*mock_policy_manager_, CheckModule(kPolicyAppId_, module)) + .WillOnce(Return(true)); + + EXPECT_TRUE(policy_handler_.CheckModule(kPolicyAppId_, module)); +} + +TEST_F(RCPolicyHandlerTest, SetPrimaryDevice_EqualDeviceId_UNSUCCESS) { + EnablePolicyAndPolicyManagerMock(); + + EXPECT_CALL(*mock_policy_manager_, PrimaryDevice()) + .WillOnce(Return(kDeviceId_)); + + policy_handler_.SetPrimaryDevice(kDeviceId_); +} + +ACTION_P(SetDeviceHandle, handle) { + *arg1 = handle; +} + +TEST_F(RCPolicyHandlerTest, SetPrimaryDevice_DifferentSUCCESS) { + EnablePolicyAndPolicyManagerMock(); + const PTString old_device_id("00:00:00:00:00:01"); + + EXPECT_CALL(*mock_policy_manager_, PrimaryDevice()) + .WillOnce(Return(old_device_id)); + EXPECT_CALL(*mock_policy_manager_, SetPrimaryDevice(kDeviceId_)); + + connection_handler::DeviceHandle old_device_handle(1u); + EXPECT_CALL(conn_handler, GetDeviceID(old_device_id, _)) + .WillOnce(DoAll(SetDeviceHandle(old_device_handle), Return(true))); + + connection_handler::DeviceHandle device_handle(2u); + EXPECT_CALL(conn_handler, GetDeviceID(kDeviceId_, _)) + .WillOnce(DoAll(SetDeviceHandle(device_handle), Return(true))); + + test_app.insert(mock_app_); + EXPECT_CALL(app_manager_, applications()).WillOnce(Return(app_set)); + + EXPECT_CALL(*mock_app_, device()) + .WillOnce(Return(device_handle)) + .WillOnce(Return(device_handle)); + EXPECT_CALL(*mock_app_, policy_app_id()) + .WillRepeatedly(Return(kPolicyAppId_)); + + EXPECT_CALL(*mock_policy_manager_, + OnChangedPrimaryDevice(kDeviceId_, kPolicyAppId_)); + + policy_handler_.SetPrimaryDevice(kDeviceId_); +} + +TEST_F(RCPolicyHandlerTest, ResetPrimaryDevice_DifferenrDevIds_SUCCESS) { + EnablePolicyAndPolicyManagerMock(); + + EXPECT_CALL(*mock_policy_manager_, PrimaryDevice()) + .WillOnce(Return(kMacAddr_)); + EXPECT_CALL(*mock_policy_manager_, ResetPrimaryDevice()); + + connection_handler::DeviceHandle old_device_handle(1u); + EXPECT_CALL(conn_handler, GetDeviceID(kMacAddr_, _)) + .WillOnce(DoAll(SetDeviceHandle(old_device_handle), Return(true))); + + test_app.insert(mock_app_); + EXPECT_CALL(app_manager_, applications()).WillOnce(Return(app_set)); + + EXPECT_CALL(*mock_app_, device()).WillRepeatedly(Return(old_device_handle)); + EXPECT_CALL(*mock_app_, policy_app_id()) + .WillRepeatedly(Return(kPolicyAppId_)); + + EXPECT_CALL(*mock_policy_manager_, + OnChangedPrimaryDevice(kMacAddr_, kPolicyAppId_)); + + policy_handler_.ResetPrimaryDevice(); +} + +TEST_F(RCPolicyHandlerTest, PrimaryDevice_ValidDeviceHandle_SUCCESS) { + EnablePolicyAndPolicyManagerMock(); + + EXPECT_CALL(*mock_policy_manager_, PrimaryDevice()) + .WillOnce(Return(kDeviceId_)); + + connection_handler::DeviceHandle device_handle(1u); + EXPECT_CALL(conn_handler, GetDeviceID(kDeviceId_, _)) + .WillOnce(DoAll(SetDeviceHandle(device_handle), Return(true))); + + EXPECT_EQ(device_handle, policy_handler_.PrimaryDevice()); +} + +TEST_F(RCPolicyHandlerTest, PrimaryDevice_GetDeviceIdFalse_UNSUCCESS) { + EnablePolicyAndPolicyManagerMock(); + + EXPECT_CALL(*mock_policy_manager_, PrimaryDevice()) + .WillOnce(Return(kDeviceId_)); + + connection_handler::DeviceHandle device_handle(1u); + EXPECT_CALL(conn_handler, GetDeviceID(kDeviceId_, _)) + .WillOnce(DoAll(SetDeviceHandle(device_handle), Return(false))); + + EXPECT_EQ(0u, policy_handler_.PrimaryDevice()); +} + +TEST_F(RCPolicyHandlerTest, GetRemoteControl_SUCCESS) { + EnablePolicyAndPolicyManagerMock(); + EXPECT_CALL(*mock_policy_manager_, GetRemoteControl()).WillOnce(Return(true)); + + EXPECT_TRUE(policy_handler_.GetRemoteControl()); +} + +TEST_F(RCPolicyHandlerTest, SetRemoteControl_SUCCESS) { + EnablePolicyAndPolicyManagerMock(); + const bool enabled(true); + EXPECT_CALL(*mock_policy_manager_, SetRemoteControl(enabled)); + + EXPECT_CALL(*mock_policy_manager_, PrimaryDevice()) + .WillOnce(Return(kDeviceId_)); + + connection_handler::DeviceHandle device_handle(1u); + EXPECT_CALL(conn_handler, GetDeviceID(kDeviceId_, _)) + .WillOnce(DoAll(SetDeviceHandle(device_handle), Return(true))); + + test_app.insert(mock_app_); + EXPECT_CALL(app_manager_, applications()).WillOnce(Return(app_set)); + + connection_handler::DeviceHandle app_device_handle(2u); + EXPECT_CALL(*mock_app_, device()).WillRepeatedly(Return(app_device_handle)); + EXPECT_CALL(*mock_app_, policy_app_id()) + .WillRepeatedly(Return(kPolicyAppId_)); + + EXPECT_CALL(mock_message_helper_, + GetDeviceMacAddressForHandle(app_device_handle, _)) + .WillOnce(Return(kMacAddr_)); + + EXPECT_CALL(*mock_policy_manager_, + OnChangedRemoteControl(kMacAddr_, kPolicyAppId_)); + + policy_handler_.SetRemoteControl(enabled); +} + +TEST_F(RCPolicyHandlerTest, + OnRemoteAppPermissionsChanged_DifferentDeviceHandle_SUCCESS) { + EnablePolicyAndPolicyManagerMock(); + EXPECT_CALL(*mock_policy_manager_, + SendAppPermissionsChanged(kDeviceId_, kPolicyAppId_)); + + policy_handler_.OnRemoteAppPermissionsChanged(kDeviceId_, kPolicyAppId_); +} + +TEST_F(RCPolicyHandlerTest, OnUpdateHMIStatus_InvalidApp_UNSUCCESS) { + EnablePolicyAndPolicyManagerMock(); + utils::SharedPtr<application_manager_test::MockApplication> invalid_app; + EXPECT_CALL(app_manager_, application(_, _)).WillOnce(Return(invalid_app)); + EXPECT_CALL(app_manager_, ChangeAppsHMILevel(_, _)).Times(0); + + const std::string hmi_level("HMI_NONE"); + policy_handler_.OnUpdateHMIStatus(kDeviceId_, kPolicyAppId_, hmi_level); +} + +TEST_F(RCPolicyHandlerTest, OnUpdateHMIStatus_HmiLevelInvalidEnum_UNSUCCESS) { + EnablePolicyAndPolicyManagerMock(); + EXPECT_CALL(app_manager_, application(kDeviceId_, kPolicyAppId_)) + .WillOnce(Return(mock_app_)); + + const std::string hmi_level("INVALID_ENUM"); + EXPECT_CALL(mock_message_helper_, StringToHMILevel(hmi_level)) + .WillOnce(Return(mobile_apis::HMILevel::INVALID_ENUM)); + + EXPECT_CALL(app_manager_, ChangeAppsHMILevel(_, _)).Times(0); + + policy_handler_.OnUpdateHMIStatus(kDeviceId_, kPolicyAppId_, hmi_level); +} + +TEST_F(RCPolicyHandlerTest, OnUpdateHMIStatus_ValidAppAndHmiLevel_SUCCESS) { + EnablePolicyAndPolicyManagerMock(); + EXPECT_CALL(app_manager_, application(kDeviceId_, kPolicyAppId_)) + .WillOnce(Return(mock_app_)); + + const std::string hmi_level("HMI_NONE"); + EXPECT_CALL(mock_message_helper_, StringToHMILevel(hmi_level)) + .WillOnce(Return(mobile_apis::HMILevel::HMI_NONE)); + + EXPECT_CALL(*mock_app_, app_id()).WillRepeatedly(Return(kAppId1_)); + + EXPECT_CALL(app_manager_, + ChangeAppsHMILevel(kAppId1_, mobile_apis::HMILevel::HMI_NONE)); + EXPECT_CALL(mock_message_helper_, SendHMIStatusNotification(_, _)); + + policy_handler_.OnUpdateHMIStatus(kDeviceId_, kPolicyAppId_, hmi_level); +} + +TEST_F(RCPolicyHandlerTest, OnUpdateHMIStatusFourParams_InvalidApp_UNSUCCESS) { + EnablePolicyAndPolicyManagerMock(); + utils::SharedPtr<application_manager_test::MockApplication> invalid_app; + EXPECT_CALL(app_manager_, application(_, _)).WillOnce(Return(invalid_app)); + EXPECT_CALL(app_manager_, ChangeAppsHMILevel(_, _)).Times(0); + + const std::string hmi_level("HMI_NONE"); + const std::string device_rank("INVALID_ENUM"); + policy_handler_.OnUpdateHMIStatus( + kDeviceId_, kPolicyAppId_, hmi_level, device_rank); +} + +TEST_F(RCPolicyHandlerTest, + OnUpdateHMIStatusFourParams_HmiLevelInvalidEnum_UNSUCCESS) { + EnablePolicyAndPolicyManagerMock(); + EXPECT_CALL(app_manager_, application(kDeviceId_, kPolicyAppId_)) + .WillOnce(Return(mock_app_)); + + const std::string hmi_level("INVALID_ENUM"); + EXPECT_CALL(mock_message_helper_, StringToHMILevel(hmi_level)) + .WillOnce(Return(mobile_apis::HMILevel::INVALID_ENUM)); + + EXPECT_CALL(app_manager_, ChangeAppsHMILevel(_, _)).Times(0); + const std::string device_rank("INVALID_ENUM"); + policy_handler_.OnUpdateHMIStatus( + kDeviceId_, kPolicyAppId_, hmi_level, device_rank); +} + +TEST_F(RCPolicyHandlerTest, + OnUpdateHMIStatusFourParams_DeviceRankInvalidEnum_UNSUCCESS) { + EnablePolicyAndPolicyManagerMock(); + EXPECT_CALL(app_manager_, application(kDeviceId_, kPolicyAppId_)) + .WillOnce(Return(mock_app_)); + + const std::string hmi_level("HMI_NONE"); + EXPECT_CALL(mock_message_helper_, StringToHMILevel(hmi_level)) + .WillOnce(Return(mobile_apis::HMILevel::HMI_NONE)); + + const std::string device_rank("INVALID_ENUM"); + EXPECT_CALL(mock_message_helper_, StringToDeviceRank(device_rank)) + .WillOnce(Return(mobile_apis::DeviceRank::INVALID_ENUM)); + + EXPECT_CALL(app_manager_, ChangeAppsHMILevel(_, _)).Times(0); + policy_handler_.OnUpdateHMIStatus( + kDeviceId_, kPolicyAppId_, hmi_level, device_rank); +} + +TEST_F(RCPolicyHandlerTest, + OnUpdateHMIStatusFourParams_DeviceRankDriver_UNSUCCESS) { + EnablePolicyAndPolicyManagerMock(); + EXPECT_CALL(app_manager_, application(kDeviceId_, kPolicyAppId_)) + .WillOnce(Return(mock_app_)); + + const std::string hmi_level("HMI_NONE"); + EXPECT_CALL(mock_message_helper_, StringToHMILevel(hmi_level)) + .WillOnce(Return(mobile_apis::HMILevel::HMI_NONE)); + + const std::string device_rank("DRIVER"); + EXPECT_CALL(mock_message_helper_, StringToDeviceRank(device_rank)) + .WillOnce(Return(mobile_apis::DeviceRank::DRIVER)); + EXPECT_CALL(mock_message_helper_, SendHMIStatusNotification(_, _)); + + EXPECT_CALL(app_manager_, ChangeAppsHMILevel(_, _)).Times(0); + policy_handler_.OnUpdateHMIStatus( + kDeviceId_, kPolicyAppId_, hmi_level, device_rank); +} + +TEST_F(RCPolicyHandlerTest, OnUpdateHMIStatusFourParams_ValidParams_SUCCESS) { + EnablePolicyAndPolicyManagerMock(); + EXPECT_CALL(app_manager_, application(kDeviceId_, kPolicyAppId_)) + .WillOnce(Return(mock_app_)); + + const std::string hmi_level("HMI_NONE"); + EXPECT_CALL(mock_message_helper_, StringToHMILevel(hmi_level)) + .WillOnce(Return(mobile_apis::HMILevel::HMI_NONE)); + + const std::string device_rank("PASSENGER"); + EXPECT_CALL(mock_message_helper_, StringToDeviceRank(device_rank)) + .WillOnce(Return(mobile_apis::DeviceRank::PASSENGER)); + + EXPECT_CALL(*mock_app_, app_id()).WillRepeatedly(Return(kAppId1_)); + EXPECT_CALL(app_manager_, + ChangeAppsHMILevel(kAppId1_, mobile_apis::HMILevel::HMI_NONE)); + EXPECT_CALL(mock_message_helper_, SendHMIStatusNotification(_, _)); + + policy_handler_.OnUpdateHMIStatus( + kDeviceId_, kPolicyAppId_, hmi_level, device_rank); +} + +TEST_F(RCPolicyHandlerTest, GetModuleTypes_GetModuleTypes_SUCCESS) { + EnablePolicyAndPolicyManagerMock(); + std::vector<std::string> modules; + + EXPECT_CALL(*mock_policy_manager_, GetModuleTypes(kPolicyAppId_, &modules)) + .WillOnce(Return(true)); + + EXPECT_TRUE(policy_handler_.GetModuleTypes(kPolicyAppId_, &modules)); +} + +TEST_F(RCPolicyHandlerTest, CheckHMIType_ValidTypes_SUCCESS) { + EnablePolicyAndPolicyManagerMock(); + mobile_apis::AppHMIType::eType hmi = mobile_apis::AppHMIType::MEDIA; + + const smart_objects::SmartObjectSPtr app_types = + utils::MakeShared<smart_objects::SmartObject>( + smart_objects::SmartType_Array); + (*app_types)[strings::app_hmi_type][0] = mobile_apis::AppHMIType::MEDIA; + (*app_types)[strings::app_hmi_type][1] = + mobile_apis::AppHMIType::BACKGROUND_PROCESS; + + std::vector<int> policy_hmi_types; + policy_hmi_types.push_back(mobile_apis::AppHMIType::MEDIA); + policy_hmi_types.push_back(mobile_apis::AppHMIType::BACKGROUND_PROCESS); + + EXPECT_CALL(*mock_policy_manager_, GetHMITypes(kPolicyAppId_, _)) + .WillOnce(DoAll(SetArgPointee<1>(policy_hmi_types), Return(true))); + + EXPECT_TRUE(policy_handler_.CheckHMIType( + kPolicyAppId_, hmi, &(*app_types.get())[strings::app_hmi_type])); +} + +} // namespace rc_policy_handler_test +} // namespace components +} // namespace test diff --git a/src/components/hmi_message_handler/src/messagebroker_adapter.cc b/src/components/hmi_message_handler/src/messagebroker_adapter.cc index 39cae7ea76..853b5992c6 100644 --- a/src/components/hmi_message_handler/src/messagebroker_adapter.cc +++ b/src/components/hmi_message_handler/src/messagebroker_adapter.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Ford Motor Company + * Copyright (c) 2017, Ford Motor Company * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -116,6 +116,7 @@ void MessageBrokerAdapter::SubscribeTo() { MessageBrokerController::subscribeTo("VR.OnLanguageChange"); MessageBrokerController::subscribeTo("TTS.OnLanguageChange"); MessageBrokerController::subscribeTo("VehicleInfo.OnVehicleData"); + MessageBrokerController::subscribeTo("VehicleInfo.OnReverseAppsAllowing"); MessageBrokerController::subscribeTo("Navigation.OnTBTClientState"); MessageBrokerController::subscribeTo("Navigation.OnWayPointChange"); MessageBrokerController::subscribeTo("TTS.Started"); @@ -135,9 +136,18 @@ void MessageBrokerAdapter::SubscribeTo() { MessageBrokerController::subscribeTo("SDL.OnDeviceStateChanged"); MessageBrokerController::subscribeTo("SDL.OnPolicyUpdate"); MessageBrokerController::subscribeTo("BasicCommunication.OnEventChanged"); + MessageBrokerController::subscribeTo("RC.OnDeviceRankChanged"); + MessageBrokerController::subscribeTo("RC.OnInteriorVehicleData"); + MessageBrokerController::subscribeTo("RC.OnRemoteControlSettings"); LOG4CXX_INFO(logger_, "Subscribed to notifications."); } +#ifdef SDL_REMOTE_CONTROL +void MessageBrokerAdapter::SubscribeToHMINotification( + const std::string& hmi_notification) { + MessageBrokerController::subscribeTo(hmi_notification); +} +#endif void* MessageBrokerAdapter::SubscribeAndBeginReceiverThread(void* param) { PassToThread(threads::Thread::CurrentId()); diff --git a/src/components/include/application_manager/application_manager.h b/src/components/include/application_manager/application_manager.h index 7875c12ff5..e275d67f74 100644 --- a/src/components/include/application_manager/application_manager.h +++ b/src/components/include/application_manager/application_manager.h @@ -49,6 +49,9 @@ #include "application_manager/state_controller.h" #include "application_manager/hmi_interfaces.h" #include "policy/policy_types.h" +#ifdef SDL_REMOTE_CONTROL +#include "functional_module/plugin_manager.h" +#endif namespace resumption { class LastState; @@ -85,6 +88,7 @@ class Application; class StateControllerImpl; struct CommandParametersPermissions; using policy::RPCParams; +typedef std::vector<ApplicationSharedPtr> AppSharedPtrs; struct ApplicationsAppIdSorter { bool operator()(const ApplicationSharedPtr lhs, const ApplicationSharedPtr rhs) const { @@ -153,9 +157,40 @@ class ApplicationManager { virtual ApplicationSharedPtr application_by_policy_id( const std::string& policy_app_id) const = 0; - virtual std::vector<ApplicationSharedPtr> applications_by_button( - uint32_t button) = 0; - virtual std::vector<ApplicationSharedPtr> applications_with_navi() = 0; + virtual AppSharedPtrs applications_by_button(uint32_t button) = 0; + virtual AppSharedPtrs applications_with_navi() = 0; + +#ifdef SDL_REMOTE_CONTROL + virtual ApplicationSharedPtr application( + const std::string& device_id, const std::string& policy_app_id) const = 0; + + virtual void SubscribeToHMINotification( + const std::string& hmi_notification) = 0; + + virtual uint32_t GetDeviceHandle(uint32_t connection_key) = 0; + + /** + * @brief Checks HMI level and returns true if audio streaming is allowed + */ + virtual bool IsAudioStreamingAllowed(uint32_t connection_key) const = 0; + + /** + * @brief Checks HMI level and returns true if video streaming is allowed + */ + virtual bool IsVideoStreamingAllowed(uint32_t connection_key) const = 0; + + virtual void ChangeAppsHMILevel(uint32_t app_id, + mobile_apis::HMILevel::eType level) = 0; + + virtual std::vector<std::string> devices( + const std::string& policy_app_id) const = 0; + + virtual void SendPostMessageToMobile(const MessagePtr& message) = 0; + + virtual void SendPostMessageToHMI(const MessagePtr& message) = 0; + + virtual functional_modules::PluginManager& GetPluginManager() = 0; +#endif // SDL_REMOTE_CONTROL virtual std::vector<ApplicationSharedPtr> applications_with_mobile_projection() = 0; @@ -264,9 +299,16 @@ class ApplicationManager { virtual void SendMessageToHMI(const commands::MessageSharedPtr message) = 0; + virtual void RemoveHMIFakeParameters( + application_manager::MessagePtr& message) = 0; + virtual bool ManageHMICommand(const commands::MessageSharedPtr message) = 0; virtual bool ManageMobileCommand(const commands::MessageSharedPtr message, commands::Command::CommandOrigin origin) = 0; + + virtual MessageValidationResult ValidateMessageBySchema( + const Message& message) = 0; + virtual mobile_api::HMILevel::eType GetDefaultHmiLevel( ApplicationConstSharedPtr application) const = 0; /** @@ -340,8 +382,8 @@ class ApplicationManager { * @param vehicle_info Enum value of type of vehicle data * @param new value (for integer values currently) of vehicle data */ - virtual std::vector<ApplicationSharedPtr> IviInfoUpdated( - VehicleDataType vehicle_info, int value) = 0; + virtual AppSharedPtrs IviInfoUpdated(VehicleDataType vehicle_info, + int value) = 0; virtual ApplicationSharedPtr RegisterApplication(const utils::SharedPtr< smart_objects::SmartObject>& request_for_registration) = 0; @@ -609,6 +651,11 @@ class ApplicationManager { virtual const ApplicationManagerSettings& get_settings() const = 0; virtual event_engine::EventDispatcher& event_dispatcher() = 0; + + virtual uint32_t GetAvailableSpaceForApp(const std::string& folder_name) = 0; + virtual void OnTimerSendTTSGlobalProperties() = 0; + virtual void OnLowVoltage() = 0; + virtual void OnWakeUp() = 0; }; } // namespace application_manager diff --git a/src/components/include/application_manager/application_manager_settings.h b/src/components/include/application_manager/application_manager_settings.h index fa01b34783..415cc57d17 100644 --- a/src/components/include/application_manager/application_manager_settings.h +++ b/src/components/include/application_manager/application_manager_settings.h @@ -93,6 +93,7 @@ class ApplicationManagerSettings : public RequestControlerSettings, virtual const uint32_t& app_icons_folder_max_size() const = 0; virtual const uint32_t& app_icons_amount_to_remove() const = 0; virtual const uint32_t& list_files_response_size() const = 0; + virtual const std::string& plugins_folder() const = 0; }; } // namespace application_manager diff --git a/src/components/include/application_manager/policies/policy_handler_interface.h b/src/components/include/application_manager/policies/policy_handler_interface.h index a1c45c0bd6..5f7b6c5833 100644 --- a/src/components/include/application_manager/policies/policy_handler_interface.h +++ b/src/components/include/application_manager/policies/policy_handler_interface.h @@ -40,6 +40,7 @@ #include <queue> #include "interfaces/MOBILE_API.h" #include "application_manager/policies/policy_handler_observer.h" +#include "application_manager/core_service.h" #include "application_manager/application.h" #include "policy/usage_statistics/statistics_manager.h" #include "utils/custom_string.h" @@ -416,6 +417,160 @@ class PolicyHandlerInterface { virtual const PolicySettings& get_settings() const = 0; virtual const std::string RemoteAppsUrl() const = 0; +#ifdef SDL_REMOTE_CONTROL + /** + * @brief Sets HMI default type for specified application + * @param application_id ID application + * @param app_types list of HMI types + */ + virtual void SetDefaultHmiTypes( + const std::string& application_id, + const smart_objects::SmartObject* app_types) = 0; + + /** + * Checks if application has HMI type + * @param application_id ID application + * @param hmi HMI type to check + * @param app_types additional list of HMI type to search in it + * @return true if hmi is contained in policy or app_types + */ + virtual bool CheckHMIType(const std::string& application_id, + mobile_apis::AppHMIType::eType hmi, + const smart_objects::SmartObject* app_types) = 0; + + /** + * Notifies about changing HMI level + * @param device_id unique identifier of device + * @param policy_app_id unique identifier of application in policy + * @param hmi_level default HMI level for this application + */ + virtual void OnUpdateHMILevel(const std::string& device_id, + const std::string& policy_app_id, + const std::string& hmi_level) = 0; + + /** + * Checks access to equipment of vehicle for application by RPC + * @param device_id unique identifier of device + * @param app_id policy id application + * @param module type + * @param rpc name of rpc + * @param params parameters list + */ + virtual application_manager::TypeAccess CheckAccess( + const PTString& device_id, + const PTString& app_id, + const PTString& module, + const std::string& rpc, + const std::vector<PTString>& params) = 0; + + /** + * Checks access to module for application + * @param app_id policy id application + * @param module + * @return true if module is allowed for application + */ + virtual bool CheckModule(const PTString& app_id, const PTString& module) = 0; + + /** + * Sets access to equipment of vehicle for application by RPC + * @param device_id unique identifier of device + * @param app_id policy id application + * @param module type + * @param allowed true if access is allowed + */ + virtual void SetAccess(const PTString& device_id, + const PTString& app_id, + const PTString& module, + bool allowed) = 0; + + /** + * Resets access application to all resources + * @param device_id unique identifier of device + * @param app_id policy id application + */ + virtual void ResetAccess(const PTString& device_id, + const PTString& app_id) = 0; + + /** + * Resets access by group name for all applications + * @param module type + */ + virtual void ResetAccess(const std::string& module) = 0; + + /** + * Sets device as primary device + * @param dev_id ID device + */ + virtual void SetPrimaryDevice(const PTString& dev_id) = 0; + + /** + * Resets driver's device + */ + virtual void ResetPrimaryDevice() = 0; + + /** + * Return id of primary device + */ + virtual uint32_t PrimaryDevice() const = 0; + + /** + * Sets mode of remote control (on/off) + * @param enabled true if remote control is turned on + */ + virtual void SetRemoteControl(bool enabled) = 0; + + /** + * @brief If remote control is enabled + * by User and by Policy + */ + virtual bool GetRemoteControl() const = 0; + + /** + * @brief Notifies passengers' apps about change + * @param new_consent New value of remote permission + */ + virtual void OnRemoteAllowedChanged(bool new_consent) = 0; + + /** + * @brief Notifies Remote apps about change in permissions + * @param device_id Device on which app is running + * @param application_id ID of app whose permissions are changed + */ + virtual void OnRemoteAppPermissionsChanged( + const std::string& device_id, const std::string& application_id) = 0; + + /** + * @brief Notifies Remote apps about change in HMI status + * @param device_id Device on which app is running + * @param policy_app_id ID of application + * @param hmi_level new HMI level for this application + */ + virtual void OnUpdateHMIStatus(const std::string& device_id, + const std::string& policy_app_id, + const std::string& hmi_level) = 0; + + /** + * @brief Notifies Remote apps about change in HMI status + * @param device_id Device on which app is running + * @param policy_app_id ID of application + * @param hmi_level new HMI level for this application + * @param device_rank new device rank + */ + virtual void OnUpdateHMIStatus(const std::string& device_id, + const std::string& policy_app_id, + const std::string& hmi_level, + const std::string& device_rank) = 0; + + /** + * Gets all allowed module types + * @param app_id unique identifier of application + * @param list of allowed module types + * @return true if application has allowed modules + */ + virtual bool GetModuleTypes(const std::string& policy_app_id, + std::vector<std::string>* modules) const = 0; +#endif // SDL_REMOTE_CONTROL + private: /** * @brief Processes data received via OnAppPermissionChanged notification diff --git a/src/components/include/hmi_message_handler/hmi_message_adapter.h b/src/components/include/hmi_message_handler/hmi_message_adapter.h index 10e4231528..9423f74394 100644 --- a/src/components/include/hmi_message_handler/hmi_message_adapter.h +++ b/src/components/include/hmi_message_handler/hmi_message_adapter.h @@ -43,6 +43,21 @@ namespace hmi_message_handler { * SDL with HMI has to implement this interface. */ class HMIMessageAdapter : public HMIMessageSender { + public: + /** + * \brief Destructor + */ + virtual ~HMIMessageAdapter() {} + +#ifdef SDL_REMOTE_CONTROL + /** + * @brief Subscribes to notification from HMI + * @param hmi_notification string with notification name + */ + virtual void SubscribeToHMINotification( + const std::string& hmi_notification) = 0; +#endif // SDL_REMOTE_CONTROL + protected: /** * \brief Interface for subscriptions. diff --git a/src/components/include/hmi_message_handler/hmi_message_handler.h b/src/components/include/hmi_message_handler/hmi_message_handler.h index 411d19fb75..5c4a443407 100644 --- a/src/components/include/hmi_message_handler/hmi_message_handler.h +++ b/src/components/include/hmi_message_handler/hmi_message_handler.h @@ -51,6 +51,15 @@ class HMIMessageHandler : public HMIMessageObserver, public HMIMessageSender { virtual void AddHMIMessageAdapter(HMIMessageAdapter* adapter) = 0; virtual void RemoveHMIMessageAdapter(HMIMessageAdapter* adapter) = 0; +#ifdef SDL_REMOTE_CONTROL + /** + * @brief Subscribes to notification from HMI + * @param hmi_notification string with notification name + */ + virtual void SubscribeToHMINotification( + const std::string& hmi_notification) = 0; +#endif // SDL_REMOTE_CONTROL + /** * \brief Hmi message handler settings getter * \return pointer to hmi message handler settings class diff --git a/src/components/include/hmi_message_handler/hmi_message_handler_settings.h b/src/components/include/hmi_message_handler/hmi_message_handler_settings.h index 5386869555..8b24f2cf7d 100644 --- a/src/components/include/hmi_message_handler/hmi_message_handler_settings.h +++ b/src/components/include/hmi_message_handler/hmi_message_handler_settings.h @@ -44,7 +44,7 @@ class HMIMessageHandlerSettings { public: virtual ~HMIMessageHandlerSettings() {} - virtual const uint64_t& thread_min_stack_size() const = 0; + virtual const uint64_t thread_min_stack_size() const = 0; }; } // namespace hmi_message_handler #endif // SRC_COMPONENTS_INCLUDE_HMI_MESSAGE_HANDLER_HMI_MESSAGE_HANDLER_SETTINGS_H_ diff --git a/src/components/include/policy/policy_external/policy/policy_listener.h b/src/components/include/policy/policy_external/policy/policy_listener.h index f3388beb95..4331ae4847 100644 --- a/src/components/include/policy/policy_external/policy/policy_listener.h +++ b/src/components/include/policy/policy_external/policy/policy_listener.h @@ -52,12 +52,13 @@ class PolicyListener { const Permissions& permissions) = 0; virtual void OnPendingPermissionChange(const std::string& policy_app_id) = 0; virtual void OnUpdateStatusChanged(const std::string&) = 0; + /** - * Gets device ID - * @param policy_app_id - * @return device ID - * @deprecated see std::vector<std::string> GetDevicesIds(const std::string&) - */ + * Gets device ID + * @param policy_app_id + * @return device ID + * @deprecated see std::vector<std::string> GetDevicesIds(const std::string&) + */ virtual std::string OnCurrentDeviceIdUpdateRequired( const std::string& policy_app_id) = 0; virtual void OnSystemInfoUpdateRequired() = 0; @@ -67,12 +68,12 @@ class PolicyListener { std::map<std::string, StringArray> app_hmi_types) = 0; /** - * @brief CanUpdate allows to find active application - * and check whether related device consented. - * - * @return true if there are at least one application has been registered - * with consented device. - */ + * @brief CanUpdate allows to find active application + * and check whether related device consented. + * + * @return true if there are at least one application has been registered + * with consented device. + */ virtual bool CanUpdate() = 0; /** @@ -129,12 +130,67 @@ class PolicyListener { virtual void OnPTUFinished(const bool ptu_result) = 0; /** - * @brief Collects currently registered applications ids linked to their - * device id - * @return Collection of device_id-to-app_id links - */ + * @brief Collects currently registered applications ids linked to their + * device id + * @return Collection of device_id-to-app_id links + */ virtual void GetRegisteredLinks( std::map<std::string, std::string>& out_links) const = 0; + +#ifdef SDL_REMOTE_CONTROL + /** + * Gets devices ids by policy application id + * @param policy_app_id + * @return list devices ids + */ + virtual std::vector<std::string> GetDevicesIds( + const std::string& policy_app_id) = 0; + + /** + * Notifies about changing HMI level + * @param device_id unique identifier of device + * @param policy_app_id unique identifier of application in policy + * @param hmi_level default HMI level for this application + */ + virtual void OnUpdateHMILevel(const std::string& device_id, + const std::string& policy_app_id, + const std::string& hmi_level) = 0; + /** + * @brief Signal that country_consent field was updated during PTU + * @param new_consent New value of country_consent + */ + virtual void OnRemoteAllowedChanged(bool new_consent) = 0; + + /** + * @brief Notifies Remote apps about change in permissions + * @param device_id Device on which app is running + * @param application_id ID of app whose permissions are changed + */ + virtual void OnRemoteAppPermissionsChanged( + const std::string& device_id, const std::string& application_id) = 0; + + /** + * Notifies about changing HMI status + * @param device_id unique identifier of device + * @param policy_app_id unique identifier of application in policy + * @param hmi_level default HMI level for this application + */ + virtual void OnUpdateHMIStatus(const std::string& device_id, + const std::string& policy_app_id, + const std::string& hmi_level) = 0; + + /** + * Notifies about changing HMI status + * @param device_id unique identifier of device + * @param policy_app_id unique identifier of application in policy + * @param hmi_level default HMI level for this application + * @param device_rank device rank + */ + virtual void OnUpdateHMIStatus(const std::string& device_id, + const std::string& policy_app_id, + const std::string& hmi_level, + const std::string& device_rank) = 0; +#endif // SDL_REMOTE_CONTROL }; -} // namespace policy +} // namespace policy #endif // SRC_COMPONENTS_POLICY_POLICY_EXTERNAL_INCLUDE_POLICY_POLICY_LISTENER_H_ diff --git a/src/components/include/policy/policy_external/policy/policy_manager.h b/src/components/include/policy/policy_external/policy/policy_manager.h index 9201956e2a..fd3371bd06 100644 --- a/src/components/include/policy/policy_external/policy/policy_manager.h +++ b/src/components/include/policy/policy_external/policy/policy_manager.h @@ -40,7 +40,11 @@ #include "policy/policy_types.h" #include "policy/policy_table/types.h" #include "policy/policy_listener.h" -#include "usage_statistics/statistics_manager.h" +#include "policy/usage_statistics/statistics_manager.h" + +#ifdef SDL_REMOTE_CONTROL +#include "policy/access_remote.h" +#endif // SDL_REMOTE_CONTROL namespace policy { class PolicySettings; @@ -505,6 +509,132 @@ class PolicyManager : public usage_statistics::StatisticsManager { */ virtual AppIdURL GetNextUpdateUrl(const EndpointUrls& urls) = 0; +#ifdef SDL_REMOTE_CONTROL + virtual void SetDefaultHmiTypes(const std::string& application_id, + const std::vector<int>& hmi_types) = 0; + /** + * Gets HMI types + * @param application_id ID application + * @param app_types list to save HMI types + * @return true if policy has specific policy for this application + */ + virtual bool GetHMITypes(const std::string& application_id, + std::vector<int>* app_types) = 0; + + /** + * Checks access to equipment of vehicle for application by RPC + * @param device_id unique identifier of device + * @param app_id policy id application + * @param module + * @param rpc name of rpc + * @param params parameters list + */ + virtual TypeAccess CheckAccess(const PTString& device_id, + const PTString& app_id, + const PTString& module, + const PTString& rpc, + const RemoteControlParams& params) = 0; + + /** + * Checks access to module for application + * @param app_id policy id application + * @param module + * @return true if module is allowed for application + */ + virtual bool CheckModule(const PTString& app_id, const PTString& module) = 0; + + /** + * Sets access to equipment of vehicle for application by RPC + * @param dev_id unique identifier of device + * @param app_id policy id application + * @param module type + * @param allowed true if access is allowed + */ + virtual void SetAccess(const PTString& dev_id, + const PTString& app_id, + const PTString& module, + bool allowed) = 0; + + /** + * Resets access application to all resources + * @param dev_id unique identifier of device + * @param app_id policy id application + */ + virtual void ResetAccess(const PTString& dev_id, const PTString& app_id) = 0; + + /** + * Resets access by functional group for all applications + * @param module type + */ + virtual void ResetAccess(const PTString& module) = 0; + + /** + * Sets driver as primary device + * @param dev_id ID device + */ + virtual void SetPrimaryDevice(const PTString& dev_id) = 0; + + /** + * Resets driver's device + */ + virtual void ResetPrimaryDevice() = 0; + + /** + * Gets current primary device + * @return ID device + */ + virtual PTString PrimaryDevice() const = 0; + + /** + * Sets mode of remote control (on/off) + * @param enabled true if remote control is turned on + */ + virtual void SetRemoteControl(bool enabled) = 0; + + /* + * @brief If remote control is enabled + * by User and by Policy + */ + virtual bool GetRemoteControl() const = 0; + + /** + * Handles changed primary device event for a application + * @param device_id Device on which app is running + * @param application_id ID application + */ + virtual void OnChangedPrimaryDevice(const std::string& device_id, + const std::string& application_id) = 0; + + /** + * Handles changed remote control event for a application + * @param device_id Device on which app is running + * @param application_id ID application + */ + virtual void OnChangedRemoteControl(const std::string& device_id, + const std::string& application_id) = 0; + + /* + * Send OnPermissionsChange notification to mobile app + * when it's permissions are changed. + * @param device_id Device on which app is running + * @param application_id ID of app whose permissions are changed + */ + virtual void SendAppPermissionsChanged(const std::string& device_id, + const std::string& application_id) = 0; + + /** + * Gets all allowed module types + * @param app_id unique identifier of application + * @param list of allowed module types + * @return true if application has allowed modules + */ + virtual bool GetModuleTypes(const std::string& policy_app_id, + std::vector<std::string>* modules) const = 0; + + virtual void set_access_remote( + utils::SharedPtr<AccessRemote> access_remote) = 0; +#endif // SDL_REMOTE_CONTROL + /** * @brief Checks if there is existing URL in the EndpointUrls vector with * index saved in the policy manager and if not, it moves to the next diff --git a/src/components/include/policy/policy_regular/policy/policy_listener.h b/src/components/include/policy/policy_regular/policy/policy_listener.h new file mode 100644 index 0000000000..c7fc0de442 --- /dev/null +++ b/src/components/include/policy/policy_regular/policy/policy_listener.h @@ -0,0 +1,171 @@ +/* + Copyright (c) 2016, 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_POLICY_POLICY_REGULAR_INCLUDE_POLICY_POLICY_LISTENER_H_ +#define SRC_COMPONENTS_POLICY_POLICY_REGULAR_INCLUDE_POLICY_POLICY_LISTENER_H_ + +#include <queue> + +#include "policy/policy_types.h" +#include "utils/custom_string.h" + +namespace policy { + +namespace custom_str = utils::custom_string; + +class PolicyListener { + public: + virtual ~PolicyListener() {} + virtual void OnPermissionsUpdated(const std::string& policy_app_id, + const Permissions& permissions, + const policy::HMILevel& default_hmi) = 0; + virtual void OnPermissionsUpdated(const std::string& policy_app_id, + const Permissions& permissions) = 0; + virtual void OnPendingPermissionChange(const std::string& policy_app_id) = 0; + virtual void OnUpdateStatusChanged(const std::string&) = 0; + virtual std::string OnCurrentDeviceIdUpdateRequired( + const std::string& policy_app_id) = 0; + virtual void OnSystemInfoUpdateRequired() = 0; + virtual custom_str::CustomString GetAppName( + const std::string& policy_app_id) = 0; + virtual void OnUpdateHMIAppType( + std::map<std::string, StringArray> app_hmi_types) = 0; + + /** + * @brief CanUpdate allows to find active application + * and check whether related device consented. + * + * @return true if there are at least one application has been registered + * with consented device. + */ + virtual bool CanUpdate() = 0; + + /** + * @brief OnSnapshotCreated the notification which will be sent + * when snapshot for PTU has been created. + * + * @param pt_string the snapshot + * + * @param retry_seconds retry sequence timeouts. + * + * @param timeout_exceed timeout. + */ + virtual void OnSnapshotCreated(const BinaryMessage& pt_string) = 0; + + /** + * @brief Make appropriate changes for related applications permissions and + * notify them, if it possible + * @param device_id Unique device id, which consent had been changed + * @param device_consent Device consent, which is done by user + */ + virtual void OnDeviceConsentChanged(const std::string& device_id, + bool is_allowed) = 0; + + /** + * @brief Sends OnAppPermissionsChanged notification to HMI + * @param permissions contains parameter for OnAppPermisionChanged + * @param policy_app_id contains policy application id + */ + virtual void SendOnAppPermissionsChanged( + const AppPermissions& permissions, + const std::string& policy_app_id) const = 0; + + /** + * @brief GetAvailableApps allows to obtain list of registered applications. + */ + virtual void GetAvailableApps(std::queue<std::string>&) = 0; + + /** + * @brief OnCertificateUpdated the callback which signals if certificate field + * has been updated during PTU + * + * @param certificate_data the value of the updated field. + */ + virtual void OnCertificateUpdated(const std::string& certificate_data) = 0; + +#ifdef SDL_REMOTE_CONTROL + /** + * Gets devices ids by policy application id + * @param policy_app_id + * @return list devices ids + */ + virtual std::vector<std::string> GetDevicesIds( + const std::string& policy_app_id) = 0; + + /** + * Notifies about changing HMI level + * @param device_id unique identifier of device + * @param policy_app_id unique identifier of application in policy + * @param hmi_level default HMI level for this application + */ + virtual void OnUpdateHMILevel(const std::string& device_id, + const std::string& policy_app_id, + const std::string& hmi_level) = 0; + /** + * @brief Signal that country_consent field was updated during PTU + * @param new_consent New value of country_consent + */ + virtual void OnRemoteAllowedChanged(bool new_consent) = 0; + + /** + * @brief Notifies Remote apps about change in permissions + * @param device_id Device on which app is running + * @param application_id ID of app whose permissions are changed + */ + virtual void OnRemoteAppPermissionsChanged( + const std::string& device_id, const std::string& application_id) = 0; + + /** + * Notifies about changing HMI status + * @param device_id unique identifier of device + * @param policy_app_id unique identifier of application in policy + * @param hmi_level default HMI level for this application + */ + virtual void OnUpdateHMIStatus(const std::string& device_id, + const std::string& policy_app_id, + const std::string& hmi_level) = 0; + + /** + * Notifies about changing HMI status + * @param device_id unique identifier of device + * @param policy_app_id unique identifier of application in policy + * @param hmi_level default HMI level for this application + * @param device_rank device rank + */ + virtual void OnUpdateHMIStatus(const std::string& device_id, + const std::string& policy_app_id, + const std::string& hmi_level, + const std::string& device_rank) = 0; +#endif // SDL_REMOTE_CONTROL +}; +} // namespace policy +#endif // SRC_COMPONENTS_POLICY_POLICY_REGULAR_INCLUDE_POLICY_POLICY_LISTENER_H_ diff --git a/src/components/include/policy/policy_regular/policy/policy_manager.h b/src/components/include/policy/policy_regular/policy/policy_manager.h index c8074b3528..900f076395 100644 --- a/src/components/include/policy/policy_regular/policy/policy_manager.h +++ b/src/components/include/policy/policy_regular/policy/policy_manager.h @@ -41,6 +41,9 @@ #include "policy/policy_table/types.h" #include "policy/policy_listener.h" #include "policy/usage_statistics/statistics_manager.h" +#ifdef SDL_REMOTE_CONTROL +#include "policy/access_remote.h" +#endif // SDL_REMOTE_CONTROL namespace policy { class PolicySettings; @@ -479,6 +482,132 @@ class PolicyManager : public usage_statistics::StatisticsManager { * urls vector */ virtual AppIdURL GetNextUpdateUrl(const EndpointUrls& urls) = 0; +#ifdef SDL_REMOTE_CONTROL + virtual void SetDefaultHmiTypes(const std::string& application_id, + const std::vector<int>& hmi_types) = 0; + + /** + * Gets HMI types + * @param application_id ID application + * @param app_types list to save HMI types + * @return true if policy has specific policy for this application + */ + virtual bool GetHMITypes(const std::string& application_id, + std::vector<int>* app_types) = 0; + + /** + * Checks access to equipment of vehicle for application by RPC + * @param device_id unique identifier of device + * @param app_id policy id application + * @param module + * @param rpc name of rpc + * @param params parameters list + */ + virtual TypeAccess CheckAccess(const PTString& device_id, + const PTString& app_id, + const PTString& module, + const PTString& rpc, + const RemoteControlParams& params) = 0; + + /** + * Checks access to module for application + * @param app_id policy id application + * @param module + * @return true if module is allowed for application + */ + virtual bool CheckModule(const PTString& app_id, const PTString& module) = 0; + + /** + * Sets access to equipment of vehicle for application by RPC + * @param dev_id unique identifier of device + * @param app_id policy id application + * @param module type + * @param allowed true if access is allowed + */ + virtual void SetAccess(const PTString& dev_id, + const PTString& app_id, + const PTString& module, + bool allowed) = 0; + + /** + * Resets access application to all resources + * @param dev_id unique identifier of device + * @param app_id policy id application + */ + virtual void ResetAccess(const PTString& dev_id, const PTString& app_id) = 0; + + /** + * Resets access by functional group for all applications + * @param module type + */ + virtual void ResetAccess(const PTString& module) = 0; + + /** + * Sets driver as primary device + * @param dev_id ID device + */ + virtual void SetPrimaryDevice(const PTString& dev_id) = 0; + + /** + * Resets driver's device + */ + virtual void ResetPrimaryDevice() = 0; + + /** + * Gets current primary device + * @return ID device + */ + virtual PTString PrimaryDevice() const = 0; + + /** + * Sets mode of remote control (on/off) + * @param enabled true if remote control is turned on + */ + virtual void SetRemoteControl(bool enabled) = 0; + + /* + * @brief If remote control is enabled + * by User and by Policy + */ + virtual bool GetRemoteControl() const = 0; + + /** + * Handles changed primary device event for a application + * @param device_id Device on which app is running + * @param application_id ID application + */ + virtual void OnChangedPrimaryDevice(const std::string& device_id, + const std::string& application_id) = 0; + + /** + * Handles changed remote control event for a application + * @param device_id Device on which app is running + * @param application_id ID application + */ + virtual void OnChangedRemoteControl(const std::string& device_id, + const std::string& application_id) = 0; + + /* + * Send OnPermissionsChange notification to mobile app + * when it's permissions are changed. + * @param device_id Device on which app is running + * @param application_id ID of app whose permissions are changed + */ + virtual void SendAppPermissionsChanged(const std::string& device_id, + const std::string& application_id) = 0; + + /** + * Gets all allowed module types + * @param app_id unique identifier of application + * @param list of allowed module types + * @return true if application has allowed modules + */ + virtual bool GetModuleTypes(const std::string& policy_app_id, + std::vector<std::string>* modules) const = 0; + + virtual void set_access_remote( + utils::SharedPtr<AccessRemote> access_remote) = 0; +#endif // SDL_REMOTE_CONTROL /** * @brief Checks if there is existing URL in the EndpointUrls vector with diff --git a/src/components/policy/policy_regular/include/policy/usage_statistics/app_stopwatch.h b/src/components/include/policy/policy_regular/policy/usage_statistics/app_stopwatch.h index 8093c11467..8093c11467 100644 --- a/src/components/policy/policy_regular/include/policy/usage_statistics/app_stopwatch.h +++ b/src/components/include/policy/policy_regular/policy/usage_statistics/app_stopwatch.h diff --git a/src/components/include/test/application_manager/policies/mock_policy_handler_interface.h b/src/components/include/test/application_manager/policies/mock_policy_handler_interface.h index 2fad7b757e..56c7ff9b91 100644 --- a/src/components/include/test/application_manager/policies/mock_policy_handler_interface.h +++ b/src/components/include/test/application_manager/policies/mock_policy_handler_interface.h @@ -227,6 +227,73 @@ class MockPolicyHandlerInterface : public policy::PolicyHandlerInterface { void(const std::string& service_type, policy::EndpointUrls& end_points)); +#ifdef SDL_REMOTE_CONTROL + MOCK_METHOD3(OnUpdateHMILevel, + void(const std::string& device_id, + const std::string& policy_app_id, + const std::string& hmi_level)); + MOCK_METHOD3(CheckHMIType, + bool(const std::string& application_id, + mobile_apis::AppHMIType::eType hmi, + const smart_objects::SmartObject* app_types)); + MOCK_METHOD5(CheckAccess, + application_manager::TypeAccess( + const policy::PTString& device_id, + const policy::PTString& app_id, + const policy::PTString& module, + const std::string& rpc, + const std::vector<policy::PTString>& params)); + + MOCK_METHOD2(CheckModule, + bool(const policy::PTString& app_id, + const policy::PTString& module)); + + MOCK_METHOD4(SetAccess, + void(const policy::PTString& device_id, + const policy::PTString& app_id, + const policy::PTString& module, + bool allowed)); + + MOCK_METHOD2(ResetAccess, + void(const policy::PTString& device_id, + const policy::PTString& app_id)); + + MOCK_METHOD1(ResetAccess, void(const std::string& module)); + + MOCK_METHOD1(SetPrimaryDevice, void(const policy::PTString& dev_id)); + + MOCK_METHOD0(ResetPrimaryDevice, void()); + + MOCK_CONST_METHOD0(PrimaryDevice, uint32_t()); + + MOCK_METHOD1(SetRemoteControl, void(bool enabled)); + + MOCK_CONST_METHOD0(GetRemoteControl, bool()); + + MOCK_METHOD1(OnRemoteAllowedChanged, void(bool new_consent)); + + MOCK_METHOD2(OnRemoteAppPermissionsChanged, + void(const std::string& device_id, + const std::string& application_id)); + + MOCK_METHOD3(OnUpdateHMIStatus, + void(const std::string& device_id, + const std::string& policy_app_id, + const std::string& hmi_level)); + + MOCK_METHOD4(OnUpdateHMIStatus, + void(const std::string& device_id, + const std::string& policy_app_id, + const std::string& hmi_level, + const std::string& device_rank)); + MOCK_CONST_METHOD2(GetModuleTypes, + bool(const std::string& policy_app_id, + std::vector<std::string>* modules)); + MOCK_METHOD2(SetDefaultHmiTypes, + void(const std::string& application_id, + const smart_objects::SmartObject* app_types)); +#endif // SDL_REMOTE_CONTROL + private: #ifdef EXTERNAL_PROPRIETARY_MODE MOCK_METHOD3(OnAppPermissionConsentInternal, diff --git a/src/components/include/test/hmi_message_handler/mock_hmi_message_handler_settings.h b/src/components/include/test/hmi_message_handler/mock_hmi_message_handler_settings.h index fcbae93a70..a7e93ec25c 100644 --- a/src/components/include/test/hmi_message_handler/mock_hmi_message_handler_settings.h +++ b/src/components/include/test/hmi_message_handler/mock_hmi_message_handler_settings.h @@ -44,7 +44,7 @@ namespace hmi_message_handler_test { class MockHMIMessageHandlerSettings : public ::hmi_message_handler::HMIMessageHandlerSettings { public: - MOCK_CONST_METHOD0(thread_min_stack_size, const uint64_t&()); + MOCK_CONST_METHOD0(thread_min_stack_size, const uint64_t()); }; } // namespace hmi_message_handler_test } // namespace components diff --git a/src/components/include/test/policy/policy_external/policy/mock_cache_manager.h b/src/components/include/test/policy/policy_external/policy/mock_cache_manager.h new file mode 100644 index 0000000000..617e99358e --- /dev/null +++ b/src/components/include/test/policy/policy_external/policy/mock_cache_manager.h @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2016, 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_POLICY_POLICY_EXTERNAL_TEST_INCLUDE_POLICY_MOCK_CACHE_MANAGER_H_ +#define SRC_COMPONENTS_POLICY_POLICY_EXTERNAL_TEST_INCLUDE_POLICY_MOCK_CACHE_MANAGER_H_ + +#include <string> +#include <vector> + +#include "gmock/gmock.h" + +#include "policy/cache_manager_interface.h" + +namespace policy_table = rpc::policy_table_interface_base; + +using namespace ::policy; + +namespace test { +namespace components { +namespace policy_test { + +class MockCacheManagerInterface : public ::policy::CacheManagerInterface { + public: + MOCK_CONST_METHOD2(GetConsentsPriority, + ConsentPriorityType(const std::string& device_id, + const std::string& application_id)); + MOCK_METHOD4(CheckPermissions, + void(const PTString& app_id, + const PTString& hmi_level, + const PTString& rpc, + CheckPermissionResult& result)); + MOCK_METHOD0(IsPTPreloaded, bool()); + MOCK_METHOD0(IgnitionCyclesBeforeExchange, int()); + MOCK_METHOD1(KilometersBeforeExchange, int(int current)); + MOCK_CONST_METHOD1(GetPermissionsList, bool(StringArray& perm_list)); + MOCK_METHOD2(SetCountersPassedForSuccessfulUpdate, + bool(Counters counter, int value)); + MOCK_METHOD1(DaysBeforeExchange, int(uint16_t current)); + MOCK_METHOD0(IncrementIgnitionCycles, void()); + + MOCK_METHOD2(SaveDeviceConsentToCache, + void(const std::string& device_id, const bool is_allowed)); + + MOCK_METHOD1(ResetCalculatedPermissionsForDevice, + void(const std::string& device_id)); + MOCK_METHOD0(ResetIgnitionCycles, void()); + MOCK_METHOD0(TimeoutResponse, int()); + MOCK_METHOD1(SecondsBetweenRetries, bool(std::vector<int>& seconds)); + MOCK_CONST_METHOD1(IsDeviceConsentCached, bool(const std::string& device_id)); + MOCK_CONST_METHOD0(GetVehicleInfo, const VehicleInfo()); + MOCK_CONST_METHOD1(GetDeviceConsent, + DeviceConsent(const std::string& device_id)); + MOCK_METHOD2(SetDeviceConsent, + void(const std::string& device_id, bool is_allowed)); + + MOCK_CONST_METHOD2(HasDeviceSpecifiedConsent, + bool(const std::string& device_id, const bool is_allowed)); + MOCK_CONST_METHOD1(GetCachedDeviceConsent, + DeviceConsent(const std::string& device_id)); + MOCK_METHOD1(SetVINValue, bool(const std::string& value)); + MOCK_METHOD3(GetUserFriendlyMsg, + std::vector<UserFriendlyMessage>( + const std::vector<std::string>& msg_codes, + const std::string& language, + const std::string& active_hmi_language)); + MOCK_METHOD2(GetUpdateUrls, + void(const std::string& service_type, + EndpointUrls& out_end_points)); + MOCK_METHOD2(GetUpdateUrls, + void(const uint32_t service_type, EndpointUrls& out_end_points)); + MOCK_CONST_METHOD0(GetLockScreenIconUrl, std::string()); + MOCK_METHOD1( + GetNotificationsNumber, + policy_table::NumberOfNotificationsType(const std::string& priority)); + MOCK_CONST_METHOD2(GetPriority, + bool(const std::string& policy_app_id, + std::string& priority)); + MOCK_METHOD2(Init, + bool(const std::string& file_name, + const PolicySettings* settings)); + MOCK_METHOD0(GenerateSnapshot, utils::SharedPtr<policy_table::Table>()); + MOCK_METHOD1(ApplyUpdate, bool(const policy_table::Table& update_pt)); + MOCK_METHOD1(Save, bool(const policy_table::Table& table)); + MOCK_CONST_METHOD0(UpdateRequired, bool()); + MOCK_METHOD1(SaveUpdateRequired, void(bool status)); + MOCK_METHOD3(GetInitialAppData, + bool(const std::string& app_id, + StringArray& nicknames, + StringArray& app_hmi_types)); + MOCK_CONST_METHOD1(IsApplicationRevoked, bool(const std::string& app_id)); + MOCK_METHOD1(GetFunctionalGroupings, + bool(policy_table::FunctionalGroupings& groups)); + MOCK_CONST_METHOD1(IsApplicationRepresented, bool(const std::string& app_id)); + MOCK_CONST_METHOD1(IsDefaultPolicy, bool(const std::string& app_id)); + MOCK_METHOD1(SetIsDefault, bool(const std::string& app_id)); + MOCK_METHOD1(SetIsPredata, bool(const std::string& app_id)); + MOCK_CONST_METHOD1(IsPredataPolicy, bool(const std::string& app_id)); + MOCK_METHOD1(SetDefaultPolicy, bool(const std::string& app_id)); + MOCK_CONST_METHOD1(CanAppKeepContext, bool(const std::string& app_id)); + MOCK_CONST_METHOD1(CanAppStealFocus, bool(const std::string& app_id)); + MOCK_CONST_METHOD2(GetDefaultHMI, + bool(const std::string& app_id, std::string& default_hmi)); + MOCK_METHOD0(ResetUserConsent, bool()); + MOCK_CONST_METHOD3(GetUserPermissionsForDevice, + bool(const std::string& device_id, + StringArray& consented_groups, + StringArray& disallowed_groups)); + MOCK_METHOD3(GetPermissionsForApp, + bool(const std::string& device_id, + const std::string& app_id, + FunctionalIdType& group_types)); + MOCK_CONST_METHOD2( + GetDeviceGroupsFromPolicies, + bool(rpc::policy_table_interface_base::Strings& groups, + rpc::policy_table_interface_base::Strings& preconsented_groups)); + MOCK_METHOD2(AddDevice, + bool(const std::string& device_id, + const std::string& connection_type)); + MOCK_METHOD8(SetDeviceData, + bool(const std::string& device_id, + const std::string& hardware, + const std::string& firmware, + const std::string& os, + const std::string& os_version, + const std::string& carrier, + const uint32_t number_of_ports, + const std::string& connection_type)); + MOCK_METHOD3(SetUserPermissionsForDevice, + bool(const std::string& device_id, + const StringArray& consented_groups, + const StringArray& disallowed_groups)); + MOCK_METHOD2(ReactOnUserDevConsentForApp, + bool(const std::string& app_id, bool is_device_allowed)); + MOCK_METHOD2(SetUserPermissionsForApp, + bool(const PermissionConsent& permissions, + bool* out_app_permissions_changed)); + MOCK_METHOD3(SetMetaInfo, + bool(const std::string& ccpu_version, + const std::string& wers_country_code, + const std::string& language)); + MOCK_CONST_METHOD0(IsMetaInfoPresent, bool()); + MOCK_METHOD1(SetSystemLanguage, bool(const std::string& language)); + MOCK_METHOD1(Increment, void(usage_statistics::GlobalCounterId type)); + MOCK_METHOD2(Increment, + void(const std::string& app_id, + usage_statistics::AppCounterId type)); + MOCK_METHOD3(Set, + void(const std::string& app_id, + usage_statistics::AppInfoId type, + const std::string& value)); + MOCK_METHOD3(Add, + void(const std::string& app_id, + usage_statistics::AppStopwatchId type, + int seconds)); + MOCK_METHOD2(CountUnconsentedGroups, + int(const std::string& policy_app_id, + const std::string& device_id)); + MOCK_METHOD1(GetFunctionalGroupNames, bool(FunctionalGroupNames& names)); + MOCK_METHOD2(GetAllAppGroups, + void(const std::string& app_id, + FunctionalGroupIDs& all_group_ids)); + MOCK_METHOD2(GetPreConsentedGroups, + void(const std::string& app_id, + FunctionalGroupIDs& preconsented_groups)); + MOCK_METHOD4(GetConsentedGroups, + void(const std::string& device_id, + const std::string& app_id, + FunctionalGroupIDs& allowed_groups, + FunctionalGroupIDs& disallowed_groups)); + MOCK_METHOD3(GetUnconsentedGroups, + void(const std::string& device_id, + const std::string& policy_app_id, + FunctionalGroupIDs& unconsented_groups)); + MOCK_METHOD2(RemoveAppConsentForGroup, + void(const std::string& app_id, const std::string& group_name)); + MOCK_METHOD1(SetPredataPolicy, bool(const std::string& app_id)); + MOCK_METHOD0(CleanupUnpairedDevices, bool()); + MOCK_METHOD2(SetUnpairedDevice, + bool(const std::string& device_id, bool unpaired)); + MOCK_METHOD1(UnpairedDevicesList, bool(DeviceIds& device_ids)); + MOCK_METHOD1(ResetPT, bool(const std::string& file_name)); + MOCK_METHOD0(LoadFromBackup, bool()); + MOCK_METHOD2(LoadFromFile, + bool(const std::string& file_name, policy_table::Table&)); + MOCK_METHOD0(Backup, void()); + MOCK_CONST_METHOD1(HeartBeatTimeout, uint32_t(const std::string& app_id)); + MOCK_CONST_METHOD2(GetAppRequestTypes, + void(const std::string& policy_app_id, + std::vector<std::string>& request_types)); + MOCK_METHOD1(GetHMIAppTypeAfterUpdate, + void(std::map<std::string, StringArray>& app_hmi_types)); + + MOCK_CONST_METHOD2(AppHasHMIType, + bool(const std::string& application_id, + policy_table::AppHMIType hmi_type)); + + MOCK_METHOD0(ResetCalculatedPermissions, void()); + MOCK_METHOD3(AddCalculatedPermissions, + void(const std::string& device_id, + const std::string& policy_app_id, + const policy::Permissions& permissions)); + MOCK_METHOD3(IsPermissionsCalculated, + bool(const std::string& device_id, + const std::string& policy_app_id, + policy::Permissions& permission)); + MOCK_CONST_METHOD0(GetPT, utils::SharedPtr<policy_table::Table>()); + MOCK_CONST_METHOD0(GetMetaInfo, const MetaInfo()); + MOCK_CONST_METHOD0(GetCertificate, std::string()); + MOCK_METHOD1(SetDecryptedCertificate, void(const std::string&)); + MOCK_METHOD1(set_settings, void(const PolicySettings* settings)); + MOCK_METHOD1(GetHMITypes, + const policy_table::AppHMITypes*(const std::string& app_id)); + MOCK_METHOD1(GetGroups, const policy_table::Strings&(const PTString& app_id)); + + MOCK_METHOD1(SetExternalConsentStatus, bool(const ExternalConsentStatus&)); + MOCK_METHOD0(GetExternalConsentStatus, ExternalConsentStatus()); + MOCK_METHOD0(GetExternalConsentEntities, ExternalConsentStatus()); + MOCK_METHOD1(GetGroupsWithSameEntities, + GroupsByExternalConsentStatus(const ExternalConsentStatus&)); + MOCK_METHOD0(GetKnownLinksFromPT, std::map<std::string, std::string>()); + MOCK_METHOD1(SetExternalConsentForApp, void(const PermissionConsent&)); +}; + +} // namespace policy_test +} // namespace components +} // namespace test + +#endif // SRC_COMPONENTS_POLICY_POLICY_EXTERNAL_TEST_INCLUDE_POLICY_MOCK_CACHE_MANAGER_H_ diff --git a/src/components/include/test/policy/policy_external/policy/mock_policy_listener.h b/src/components/include/test/policy/policy_external/policy/mock_policy_listener.h index 893d5a334f..eba2bc45c0 100644 --- a/src/components/include/test/policy/policy_external/policy/mock_policy_listener.h +++ b/src/components/include/test/policy/policy_external/policy/mock_policy_listener.h @@ -92,6 +92,21 @@ class MockPolicyListener : public ::policy::PolicyListener { const std::string& hmi_level)); MOCK_CONST_METHOD1(GetRegisteredLinks, void(std::map<std::string, std::string>&)); +#ifdef SDL_REMOTE_CONTROL + MOCK_METHOD1(OnRemoteAllowedChanged, void(bool new_consent)); + MOCK_METHOD2(OnRemoteAppPermissionsChanged, + void(const std::string& device_id, + const std::string& application_id)); + MOCK_METHOD3(OnUpdateHMIStatus, + void(const std::string& device_id, + const std::string& policy_app_id, + const std::string& hmi_level)); + MOCK_METHOD4(OnUpdateHMIStatus, + void(const std::string& device_id, + const std::string& policy_app_id, + const std::string& hmi_level, + const std::string& device_rank)); +#endif // SDL_REMOTE_CONTROL }; } // namespace policy_test diff --git a/src/components/include/test/policy/policy_external/policy/mock_policy_manager.h b/src/components/include/test/policy/policy_external/policy/mock_policy_manager.h index 0332b94a89..399ae51169 100644 --- a/src/components/include/test/policy/policy_external/policy/mock_policy_manager.h +++ b/src/components/include/test/policy/policy_external/policy/mock_policy_manager.h @@ -148,6 +148,51 @@ class MockPolicyManager : public PolicyManager { StatusNotifier( const std::string& application_id, const rpc::policy_table_interface_base::AppHmiTypes& hmi_types)); +#ifdef SDL_REMOTE_CONTROL + MOCK_METHOD2(SetDefaultHmiTypes, + void(const std::string& application_id, + const std::vector<int>& hmi_types)); + MOCK_METHOD2(GetHMITypes, + bool(const std::string& application_id, + std::vector<int>* app_types)); + MOCK_METHOD5(CheckAccess, + TypeAccess(const PTString& device_id, + const PTString& app_id, + const PTString& module, + const PTString& rpc, + const RemoteControlParams& params)); + MOCK_METHOD2(CheckModule, + bool(const PTString& app_id, const PTString& module)); + MOCK_METHOD4(SetAccess, + void(const PTString& dev_id, + const PTString& app_id, + const PTString& module, + bool allowed)); + MOCK_METHOD2(ResetAccess, + void(const PTString& dev_id, const PTString& app_id)); + MOCK_METHOD1(ResetAccess, void(const PTString& module)); + MOCK_METHOD1(SetPrimaryDevice, void(const PTString& dev_id)); + MOCK_METHOD0(ResetPrimaryDevice, void()); + MOCK_CONST_METHOD0(PrimaryDevice, PTString()); + + MOCK_METHOD1(SetRemoteControl, void(bool enabled)); + MOCK_CONST_METHOD0(GetRemoteControl, bool()); + MOCK_METHOD2(OnChangedPrimaryDevice, + void(const std::string& device_id, + const std::string& application_id)); + MOCK_METHOD2(OnChangedRemoteControl, + void(const std::string& device_id, + const std::string& application_id)); + MOCK_METHOD2(SendAppPermissionsChanged, + void(const std::string& device_id, + const std::string& application_id)); + MOCK_CONST_METHOD2(GetModuleTypes, + bool(const std::string& policy_app_id, + std::vector<std::string>* modules)); + MOCK_METHOD1(set_access_remote, + void(utils::SharedPtr<AccessRemote> access_remote)); +#endif // SDL_REMOTE_CONTROL + MOCK_METHOD0(CleanupUnpairedDevices, bool()); MOCK_CONST_METHOD1(CanAppKeepContext, bool(const std::string& app_id)); MOCK_CONST_METHOD1(CanAppStealFocus, bool(const std::string& app_id)); diff --git a/src/components/policy/policy_regular/test/include/policy/mock_cache_manager.h b/src/components/include/test/policy/policy_regular/policy/mock_cache_manager.h index 7569e2195d..058ea73d51 100644 --- a/src/components/policy/policy_regular/test/include/policy/mock_cache_manager.h +++ b/src/components/include/test/policy/policy_regular/policy/mock_cache_manager.h @@ -202,7 +202,9 @@ class MockCacheManagerInterface : public CacheManagerInterface { bool(const std::string& device_id, const std::string& policy_app_id, policy::Permissions& permission)); - MOCK_CONST_METHOD0(GetPT, utils::SharedPtr<policy_table::Table>()); + MOCK_CONST_METHOD0(pt, utils::SharedPtr<policy_table::Table>()); + MOCK_METHOD1(GetHMITypes, + const policy_table::AppHMITypes*(const std::string& app_id)); MOCK_CONST_METHOD0(GetCertificate, std::string()); MOCK_METHOD1(SetDecryptedCertificate, void(const std::string&)); MOCK_METHOD1(GetGroups, const policy_table::Strings&(const PTString& app_id)); diff --git a/src/components/policy/policy_regular/test/include/policy/mock_policy_listener.h b/src/components/include/test/policy/policy_regular/policy/mock_policy_listener.h index 2e4073aae9..91d93908a2 100644 --- a/src/components/policy/policy_regular/test/include/policy/mock_policy_listener.h +++ b/src/components/include/test/policy/policy_regular/policy/mock_policy_listener.h @@ -43,19 +43,21 @@ namespace policy_table = ::rpc::policy_table_interface_base; -namespace policy { +namespace test { +namespace components { +namespace policy_test { namespace custom_str = utils::custom_string; -class MockPolicyListener : public PolicyListener { +class MockPolicyListener : public ::policy::PolicyListener { public: MOCK_METHOD3(OnPermissionsUpdated, void(const std::string& policy_app_id, - const Permissions& permissions, + const policy::Permissions& permissions, const policy::HMILevel& default_hmi)); MOCK_METHOD2(OnPermissionsUpdated, void(const std::string& policy_app_id, - const Permissions& permissions)); + const policy::Permissions& permissions)); MOCK_METHOD1(OnPendingPermissionChange, void(const std::string& policy_app_id)); MOCK_METHOD1(OnUpdateStatusChanged, void(const std::string& status)); @@ -67,17 +69,41 @@ class MockPolicyListener : public PolicyListener { MOCK_METHOD0(OnUserRequestedUpdateCheckRequired, void()); MOCK_METHOD2(OnDeviceConsentChanged, void(const std::string& device_id, bool is_allowed)); - MOCK_METHOD1(OnUpdateHMIAppType, void(std::map<std::string, StringArray>)); + MOCK_METHOD1(OnUpdateHMIAppType, + void(std::map<std::string, policy::StringArray>)); MOCK_METHOD1(GetAvailableApps, void(std::queue<std::string>&)); - MOCK_METHOD1(OnSnapshotCreated, void(const BinaryMessage& pt_string)); + MOCK_METHOD1(OnSnapshotCreated, void(const policy::BinaryMessage& pt_string)); MOCK_METHOD0(CanUpdate, bool()); MOCK_METHOD1(OnCertificateUpdated, void(const std::string&)); MOCK_CONST_METHOD2(SendOnAppPermissionsChanged, - void(const AppPermissions&, const std::string&)); + void(const policy::AppPermissions&, const std::string&)); + MOCK_METHOD3(OnUpdateHMILevel, + void(const std::string& device_id, + const std::string& policy_app_id, + const std::string& hmi_level)); + MOCK_METHOD1(GetDevicesIds, + std::vector<std::string>(const std::string& policy_app_id)); MOCK_CONST_METHOD1(GetRegisteredLinks, void(std::map<std::string, std::string>&)); +#ifdef SDL_REMOTE_CONTROL + MOCK_METHOD1(OnRemoteAllowedChanged, void(bool new_consent)); + MOCK_METHOD2(OnRemoteAppPermissionsChanged, + void(const std::string& device_id, + const std::string& application_id)); + MOCK_METHOD3(OnUpdateHMIStatus, + void(const std::string& device_id, + const std::string& policy_app_id, + const std::string& hmi_level)); + MOCK_METHOD4(OnUpdateHMIStatus, + void(const std::string& device_id, + const std::string& policy_app_id, + const std::string& hmi_level, + const std::string& device_rank)); +#endif // SDL_REMOTE_CONTROL }; -} // namespace policy +} // namespace policy_test +} // namespace components +} // namespace test #endif // SRC_COMPONENTS_POLICY_POLICY_REGULAR_TEST_INCLUDE_MOCK_POLICY_LISTENER_H_ diff --git a/src/components/include/test/policy/policy_regular/policy/mock_policy_manager.h b/src/components/include/test/policy/policy_regular/policy/mock_policy_manager.h index 1ccca81d79..a155a0b07f 100644 --- a/src/components/include/test/policy/policy_regular/policy/mock_policy_manager.h +++ b/src/components/include/test/policy/policy_regular/policy/mock_policy_manager.h @@ -147,6 +147,50 @@ class MockPolicyManager : public PolicyManager { StatusNotifier( const std::string& application_id, const rpc::policy_table_interface_base::AppHmiTypes& hmi_types)); +#ifdef SDL_REMOTE_CONTROL + MOCK_METHOD2(SetDefaultHmiTypes, + void(const std::string& application_id, + const std::vector<int>& hmi_types)); + MOCK_METHOD2(GetHMITypes, + bool(const std::string& application_id, + std::vector<int>* app_types)); + MOCK_METHOD5(CheckAccess, + TypeAccess(const PTString& device_id, + const PTString& app_id, + const PTString& module, + const PTString& rpc, + const RemoteControlParams& params)); + MOCK_METHOD2(CheckModule, + bool(const PTString& app_id, const PTString& module)); + MOCK_METHOD4(SetAccess, + void(const PTString& dev_id, + const PTString& app_id, + const PTString& module, + bool allowed)); + MOCK_METHOD2(ResetAccess, + void(const PTString& dev_id, const PTString& app_id)); + MOCK_METHOD1(ResetAccess, void(const PTString& module)); + MOCK_METHOD1(SetPrimaryDevice, void(const PTString& dev_id)); + MOCK_METHOD0(ResetPrimaryDevice, void()); + MOCK_CONST_METHOD0(PrimaryDevice, PTString()); + + MOCK_METHOD1(SetRemoteControl, void(bool enabled)); + MOCK_CONST_METHOD0(GetRemoteControl, bool()); + MOCK_METHOD2(OnChangedPrimaryDevice, + void(const std::string& device_id, + const std::string& application_id)); + MOCK_METHOD2(OnChangedRemoteControl, + void(const std::string& device_id, + const std::string& application_id)); + MOCK_METHOD2(SendAppPermissionsChanged, + void(const std::string& device_id, + const std::string& application_id)); + MOCK_CONST_METHOD2(GetModuleTypes, + bool(const std::string& policy_app_id, + std::vector<std::string>* modules)); + MOCK_METHOD1(set_access_remote, + void(utils::SharedPtr<AccessRemote> access_remote)); +#endif // SDL_REMOTE_CONTROL MOCK_METHOD0(CleanupUnpairedDevices, bool()); MOCK_CONST_METHOD1(CanAppKeepContext, bool(const std::string& app_id)); MOCK_CONST_METHOD1(CanAppStealFocus, bool(const std::string& app_id)); diff --git a/src/components/media_manager/CMakeLists.txt b/src/components/media_manager/CMakeLists.txt index c5b94ea7e1..4913102c9c 100644 --- a/src/components/media_manager/CMakeLists.txt +++ b/src/components/media_manager/CMakeLists.txt @@ -32,17 +32,20 @@ include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/platform.cmake) include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) include_directories( - include + ${COMPONENTS_DIR}/media_manager/include/ ${COMPONENTS_DIR}/media_manager/include/audio/ ${COMPONENTS_DIR}/media_manager/include/video/ + ${COMPONENTS_DIR}/remote_control/include/ ${COMPONENTS_DIR}/utils/include/ ${COMPONENTS_DIR}/protocol_handler/include/ ${COMPONENTS_DIR}/connection_handler/include/ ${COMPONENTS_DIR}/application_manager/include/ ${COMPONENTS_DIR}/smart_objects/include/ + ${COMPONENTS_DIR}/policy/include/ + ${COMPONENTS_DIR}/rpc_base/include/ + ${COMPONENTS_DIR}/functional_module/include/ ${COMPONENTS_DIR}/hmi_message_handler/include/ ${COMPONENTS_DIR}/formatters/include/ - ${COMPONENTS_DIR}/rpc_base/include/ ${COMPONENTS_DIR}/config_profile/include/ ${JSONCPP_INCLUDE_DIRECTORY} ${CMAKE_BINARY_DIR}/src/components/ diff --git a/src/components/media_manager/test/CMakeLists.txt b/src/components/media_manager/test/CMakeLists.txt index f5d596f681..d2cbced369 100644 --- a/src/components/media_manager/test/CMakeLists.txt +++ b/src/components/media_manager/test/CMakeLists.txt @@ -62,6 +62,13 @@ set(LIBRARIES ${SecurityManagerLibrary} ) +if(REMOTE_CONTROL) + SET (LIBRARIES + ${LIBRARIES} + FunctionalModule + ) +endif(REMOTE_CONTROL) + if(EXTENDED_MEDIA_MODE) list(APPEND LIBRARIES ${GSTREAMER_gstreamer_LIBRARY}) diff --git a/src/components/policy/policy_external/CMakeLists.txt b/src/components/policy/policy_external/CMakeLists.txt index 2cbdbd7f64..8d04f20470 100644 --- a/src/components/policy/policy_external/CMakeLists.txt +++ b/src/components/policy/policy_external/CMakeLists.txt @@ -58,6 +58,10 @@ set(SOURCES ${COMPONENTS_DIR}/rpc_base/src/rpc_base/rpc_base.cc ) +if (REMOTE_CONTROL) + list(APPEND SOURCES ${POLICY_PATH}/src/access_remote_impl.cc) +endif() + list(APPEND SOURCES ${POLICY_PATH}/src/sql_pt_ext_queries.cc ${POLICY_PATH}/src/sql_pt_ext_representation.cc diff --git a/src/components/policy/policy_external/include/policy/access_remote.h b/src/components/policy/policy_external/include/policy/access_remote.h new file mode 100644 index 0000000000..07efe25682 --- /dev/null +++ b/src/components/policy/policy_external/include/policy/access_remote.h @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2015, 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_POLICY_POLICY_EXTERNAL_INCLUDE_POLICY_ACCESS_REMOTE_H_ +#define SRC_COMPONENTS_POLICY_POLICY_EXTERNAL_INCLUDE_POLICY_ACCESS_REMOTE_H_ + +#include <vector> +#include <ostream> +#include <string> +#include "policy/policy_table/types.h" +#include "policy/policy_types.h" + +namespace policy_table = ::rpc::policy_table_interface_base; + +namespace policy { + +enum TypeAccess { kDisallowed, kAllowed, kManual }; +inline std::ostream& operator<<(std::ostream& output, TypeAccess x) { + output << "Access: "; + switch (x) { + case kDisallowed: + output << "DISALLOWED"; + break; + case kAllowed: + output << "ALLOWED"; + break; + case kManual: + output << "MANUAL"; + break; + default: + output << "Error: Unknown type"; + } + return output; +} + +struct Subject { + PTString dev_id; + PTString app_id; +}; +inline bool operator<(const Subject& x, const Subject& y) { + return x.dev_id < y.dev_id || (x.dev_id == y.dev_id && x.app_id < y.app_id); +} +inline bool operator==(const Subject& x, const Subject& y) { + return x.dev_id == y.dev_id && x.app_id == y.app_id; +} +inline std::ostream& operator<<(std::ostream& output, const Subject& who) { + output << "Subject(dev:" << who.dev_id << ", app:" << who.app_id << ")"; + return output; +} + +struct Object { + policy_table::ModuleType module; +}; +inline bool operator<(const Object& x, const Object& y) { + return x.module < y.module; +} +inline bool operator==(const Object& x, const Object& y) { + return x.module == y.module; +} +inline std::ostream& operator<<(std::ostream& output, const Object& what) { + output << "Object(module:" << EnumToJsonString(what.module) << ")"; + return output; +} + +typedef std::vector<PTString> RemoteControlParams; + +class AccessRemote { + public: + virtual ~AccessRemote() {} + + /** + * Initializes oneself + */ + virtual void Init() = 0; + + /** + * Enables remote control + */ + virtual void Enable() = 0; + + /** + * Disables remote control + */ + virtual void Disable() = 0; + + /** + * Checks if remote control is enabled + * @return true if enabled + */ + virtual bool IsEnabled() const = 0; + + /** + * Checks whether device is driver's device + * @param dev_id unique device id + * @return true if device is have driver + */ + virtual bool IsPrimaryDevice(const PTString& dev_id) const = 0; + + /** + * Sets device as driver's device + * @param dev_id ID device + */ + virtual void SetPrimaryDevice(const PTString& dev_id) = 0; + + /** + * Gets current primary device + * @return ID device + */ + virtual PTString PrimaryDevice() const = 0; + + /** + * Allows access subject to object + * @param who subject is dev_id and app_id + * @param what object is group_id + */ + virtual void Allow(const Subject& who, const Object& what) = 0; + + /** + * Denies access subject to object + * @param who subject is dev_id and app_id + * @param what object is group_id + */ + virtual void Deny(const Subject& who, const Object& what) = 0; + + /** + * Resets access subject to all object + * @param who subject is dev_id and app_id + */ + virtual void Reset(const Subject& who) = 0; + + /** + * Resets access to object for all subjects + * @param what object is group + */ + virtual void Reset(const Object& what) = 0; + + /* + * Resets all stored consents + */ + virtual void Reset() = 0; + + /** + * Checks access subject to object + * @param who subject is dev_id and app_id + * @param what object is group_id + * @return allowed if access was given, disallowed if access was denied + * manual if need to ask driver + */ + virtual TypeAccess Check(const Subject& who, const Object& what) const = 0; + + /** + * Checks permissions for module + * @param app_id application ID + * @param module type + * @return true if allowed + */ + virtual bool CheckModuleType(const PTString& app_id, + policy_table::ModuleType module) const = 0; + + /** + * Sets HMI types if application has default policy permissions + * @param who subject + * @param hmi_types list of HMI types + */ + virtual void SetDefaultHmiTypes(const Subject& who, + const std::vector<int>& hmi_types) = 0; + + /** + * Gets groups + * @param who subject + * @return list of groups + */ + virtual const policy_table::Strings& GetGroups(const Subject& who) = 0; + + /** + * Gets permissions for application + * @param device_id + * @param app_id + * @param group_types + * @return true if success + */ + virtual bool GetPermissionsForApp(const std::string& device_id, + const std::string& app_id, + FunctionalIdType& group_types) = 0; + + /** + * Checks if application has remote functionality + * @param who subject + * @return true if application uses remote control + */ + virtual bool IsAppRemoteControl(const Subject& who) = 0; + + /** + * Gets all allowed module types + * @param app_id unique identifier of application + * @param list of allowed module types + * @return true if application has allowed modules + */ + virtual bool GetModuleTypes(const std::string& policy_app_id, + std::vector<std::string>* modules) = 0; +}; + +} // namespace policy + +#endif // SRC_COMPONENTS_POLICY_POLICY_EXTERNAL_INCLUDE_POLICY_ACCESS_REMOTE_H_ diff --git a/src/components/policy/policy_external/include/policy/access_remote_impl.h b/src/components/policy/policy_external/include/policy/access_remote_impl.h new file mode 100644 index 0000000000..72223dccab --- /dev/null +++ b/src/components/policy/policy_external/include/policy/access_remote_impl.h @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2015, 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_POLICY_POLICY_EXTERNAL_INCLUDE_POLICY_ACCESS_REMOTE_IMPL_H_ +#define SRC_COMPONENTS_POLICY_POLICY_EXTERNAL_INCLUDE_POLICY_ACCESS_REMOTE_IMPL_H_ + +#include <map> +#include "policy/policy_table/types.h" +#include "utils/macro.h" +#include "utils/shared_ptr.h" +#include "policy/access_remote.h" +#include "policy/cache_manager.h" + +using policy_table::FunctionalGroupings; + +namespace policy { + +class AccessRemoteImpl : public AccessRemote { + public: + AccessRemoteImpl(); + explicit AccessRemoteImpl(utils::SharedPtr<CacheManager> cache); + + virtual void Init(); + virtual void Enable(); + virtual void Disable(); + virtual bool IsEnabled() const; + + virtual bool IsPrimaryDevice(const PTString& dev_id) const; + virtual void SetPrimaryDevice(const PTString& dev_id); + virtual PTString PrimaryDevice() const; + + virtual void Allow(const Subject& who, const Object& what); + virtual void Deny(const Subject& who, const Object& what); + virtual void Reset(const Subject& who); + virtual void Reset(const Object& what); + virtual void Reset(); + virtual TypeAccess Check(const Subject& who, const Object& what) const; + virtual bool CheckModuleType(const PTString& app_id, + policy_table::ModuleType module) const; + virtual void SetDefaultHmiTypes(const Subject& who, + const std::vector<int>& hmi_types); + virtual const policy_table::Strings& GetGroups(const Subject& who); + virtual bool GetPermissionsForApp(const std::string& device_id, + const std::string& app_id, + FunctionalIdType& group_types); + virtual bool IsAppRemoteControl(const Subject& who); + virtual bool GetModuleTypes(const std::string& policy_app_id, + std::vector<std::string>* modules); + + private: + typedef std::map<Subject, TypeAccess> AccessControlRow; + typedef std::map<Object, AccessControlRow> AccessControlList; + typedef std::map<Subject, policy_table::AppHMITypes> HMIList; + inline void set_enabled(bool value); + inline bool country_consent() const; + const policy_table::AppHMITypes& HmiTypes(const Subject& who); + void GetGroupsIds(const std::string& device_id, + const std::string& app_id, + FunctionalGroupIDs& grops_ids); + bool IsAllowed(const policy_table::AccessModules& modules, + const std::string& module_name, + const std::string& rpc_name, + RemoteControlParams* input) const; + bool CompareParameters(const policy_table::Strings& parameters, + RemoteControlParams* input) const; + utils::SharedPtr<CacheManager> cache_; + PTString primary_device_; + bool enabled_; + AccessControlList acl_; + HMIList hmi_types_; + + friend struct Erase; + friend struct IsTypeAccess; + +#ifdef BUILD_TESTS + FRIEND_TEST(AccessRemoteImplTest, KeyMapTest); + FRIEND_TEST(AccessRemoteImplTest, Allow); + FRIEND_TEST(AccessRemoteImplTest, Deny); + FRIEND_TEST(AccessRemoteImplTest, ChangeAccess); + FRIEND_TEST(AccessRemoteImplTest, ResetBySubject); + FRIEND_TEST(AccessRemoteImplTest, ResetByObject); + FRIEND_TEST(AccessRemoteImplTest, CheckAllowed); + FRIEND_TEST(AccessRemoteImplTest, CheckDisallowed); + FRIEND_TEST(AccessRemoteImplTest, CheckManual); + FRIEND_TEST(AccessRemoteImplTest, CheckModuleType); + FRIEND_TEST(AccessRemoteImplTest, EnableDisable); + FRIEND_TEST(AccessRemoteImplTest, SetDefaultHmiTypes); + FRIEND_TEST(AccessRemoteImplTest, GetGroups); +#endif // BUILD_TESTS +}; + +} // namespace policy + +#endif // SRC_COMPONENTS_POLICY_POLICY_EXTERNAL_INCLUDE_POLICY_ACCESS_REMOTE_IMPL_H_ diff --git a/src/components/policy/policy_external/include/policy/cache_manager.h b/src/components/policy/policy_external/include/policy/cache_manager.h index 95aed36f89..428a9bd2f6 100644 --- a/src/components/policy/policy_external/include/policy/cache_manager.h +++ b/src/components/policy/policy_external/include/policy/cache_manager.h @@ -914,6 +914,14 @@ class CacheManager : public CacheManagerInterface { sync_primitives::Lock backuper_locker_; BackgroundBackuper* backuper_; const PolicySettings* settings_; + + friend class AccessRemoteImpl; + +#ifdef BUILD_TESTS + FRIEND_TEST(AccessRemoteImplTest, CheckModuleType); + FRIEND_TEST(AccessRemoteImplTest, EnableDisable); + FRIEND_TEST(AccessRemoteImplTest, GetGroups); +#endif // BUILD_TESTS }; } // namespace policy #endif // SRC_COMPONENTS_POLICY_POLICY_EXTERNAL_INCLUDE_POLICY_CACHE_MANAGER_H_ diff --git a/src/components/policy/policy_external/include/policy/policy_helper.h b/src/components/policy/policy_external/include/policy/policy_helper.h index 10d6908b14..ece033c23c 100644 --- a/src/components/policy/policy_external/include/policy/policy_helper.h +++ b/src/components/policy/policy_external/include/policy/policy_helper.h @@ -323,6 +323,23 @@ FunctionalGroupIDs FindSame(const FunctionalGroupIDs& first, * @return true, if succeded, otherwise - false */ bool UnwrapAppPolicies(policy_table::ApplicationPolicies& app_policies); -} + +#ifdef SDL_REMOTE_CONTROL + +struct ProccessAppGroups { + ProccessAppGroups(const policy_table::ApplicationPolicies& apps, + PolicyManagerImpl* pm) + : new_apps_(apps), pm_(pm), default_(new_apps_.find(kDefaultId)) {} + void operator()(const policy_table::ApplicationPolicies::value_type& app); + + private: + const policy_table::ApplicationPolicies& new_apps_; + PolicyManagerImpl* pm_; + policy_table::ApplicationPolicies::const_iterator default_; +}; + +#endif // SDL_REMOTE_CONTROL + +} // namespace policy #endif // SRC_COMPONENTS_POLICY_POLICY_EXTERNAL_INCLUDE_POLICY_POLICY_HELPER_H_ diff --git a/src/components/policy/policy_external/include/policy/policy_manager_impl.h b/src/components/policy/policy_external/include/policy/policy_manager_impl.h index a37d0d66b9..952aa5d32e 100644 --- a/src/components/policy/policy_external/include/policy/policy_manager_impl.h +++ b/src/components/policy/policy_external/include/policy/policy_manager_impl.h @@ -43,6 +43,11 @@ #include "policy/policy_table/functions.h" #include "policy/usage_statistics/statistics_manager.h" +#ifdef SDL_REMOTE_CONTROL +#include "policy/access_remote.h" +#include "policy/access_remote_impl.h" +#endif // SDL_REMOTE_CONTROL + namespace policy_table = rpc::policy_table_interface_base; namespace policy { @@ -174,6 +179,41 @@ class PolicyManagerImpl : public PolicyManager { const std::string& application_id, const rpc::policy_table_interface_base::AppHmiTypes& hmi_types); +#ifdef SDL_REMOTE_CONTROL + void SetDefaultHmiTypes(const std::string& application_id, + const std::vector<int>& hmi_types); + + /** + * Gets HMI types + * @param application_id ID application + * @param app_types list to save HMI types + * @return true if policy has specific policy for this application + */ + virtual bool GetHMITypes(const std::string& application_id, + std::vector<int>* app_types) OVERRIDE; + virtual void set_access_remote(utils::SharedPtr<AccessRemote> access_remote); + TypeAccess CheckDriverConsent(const Subject& who, + const Object& what, + const std::string& rpc, + const RemoteControlParams& params); + void CheckPTUUpdatesChange( + const utils::SharedPtr<policy_table::Table> pt_update, + const utils::SharedPtr<policy_table::Table> snapshot); + bool CheckPTURemoteCtrlChange( + const utils::SharedPtr<policy_table::Table> pt_update, + const utils::SharedPtr<policy_table::Table> snapshot); + + void CheckRemoteGroupsChange( + const utils::SharedPtr<policy_table::Table> pt_update, + const utils::SharedPtr<policy_table::Table> snapshot); + + void SendHMILevelChanged(const Subject& who); + void UpdateDeviceRank(const Subject& who, const std::string& rank); + + void OnPrimaryGroupsChanged(const std::string& application_id); + void OnNonPrimaryGroupsChanged(const std::string& application_id); +#endif // SDL_REMOTE_CONTROL + virtual void RemoveAppConsentForGroup(const std::string& app_id, const std::string& group_name); @@ -345,6 +385,37 @@ class PolicyManagerImpl : public PolicyManager { bool IsPTValid(utils::SharedPtr<policy_table::Table> policy_table, policy_table::PolicyTableType type) const; +#ifdef SDL_REMOTE_CONTROL + void GetPermissions(const std::string device_id, + const std::string application_id, + Permissions* data); + virtual TypeAccess CheckAccess(const PTString& device_id, + const PTString& app_id, + const PTString& module, + const PTString& rpc, + const RemoteControlParams& params); + virtual bool CheckModule(const PTString& app_id, const PTString& module); + virtual void SetAccess(const PTString& dev_id, + const PTString& app_id, + const PTString& module, + bool allowed); + virtual void ResetAccess(const PTString& dev_id, const PTString& app_id); + virtual void ResetAccess(const PTString& module); + virtual void SetPrimaryDevice(const PTString& dev_id); + virtual void ResetPrimaryDevice(); + virtual PTString PrimaryDevice() const; + virtual void SetRemoteControl(bool enabled); + virtual bool GetRemoteControl() const; + virtual void OnChangedPrimaryDevice(const std::string& device_id, + const std::string& application_id); + virtual void OnChangedRemoteControl(const std::string& device_id, + const std::string& application_id); + virtual void SendAppPermissionsChanged(const std::string& device_id, + const std::string& application_id); + virtual bool GetModuleTypes(const std::string& policy_app_id, + std::vector<std::string>* modules) const; +#endif // SDL_REMOTE_CONTROL + /** * @brief Notify application about its permissions changes by preparing and * sending OnPermissionsChanged notification @@ -449,6 +520,10 @@ class PolicyManagerImpl : public PolicyManager { UpdateStatusManager update_status_manager_; CacheManagerInterfaceSPtr cache_; +#ifdef SDL_REMOTE_CONTROL + utils::SharedPtr<AccessRemote> access_remote_; +#endif + sync_primitives::Lock apps_registration_lock_; sync_primitives::Lock app_permissions_diff_lock_; diff --git a/src/components/policy/policy_external/include/policy/policy_table/enums.h b/src/components/policy/policy_external/include/policy/policy_table/enums.h index 4b0a7d74bc..4f8ae5c98d 100644 --- a/src/components/policy/policy_external/include/policy/policy_table/enums.h +++ b/src/components/policy/policy_external/include/policy/policy_table/enums.h @@ -120,7 +120,8 @@ enum AppHMIType { AHT_BACKGROUND_PROCESS, AHT_TESTING, AHT_SYSTEM, - AHT_PROJECTION + AHT_PROJECTION, + AHT_REMOTE_CONTROL, }; bool IsValidEnum(AppHMIType val); const char* EnumToJsonString(AppHMIType val); diff --git a/src/components/policy/policy_external/include/policy/policy_table/types.h b/src/components/policy/policy_external/include/policy/policy_table/types.h index 9606788bae..a5121ec021 100644 --- a/src/components/policy/policy_external/include/policy/policy_table/types.h +++ b/src/components/policy/policy_external/include/policy/policy_table/types.h @@ -102,6 +102,12 @@ typedef Map<DeviceParams, 0, 255> DeviceData; typedef Array<Enum<RequestType>, 0, 255> RequestsTypeArray; +#ifdef SDL_REMOTE_CONTROL +typedef Map<Strings, 0, 255> RemoteRpcs; +typedef Map<RemoteRpcs, 0, 255> AccessModules; +typedef Array<Enum<ModuleType>, 0, 255> ModuleTypes; +#endif // SDL_REMOTE_CONTROL + typedef AppHMIType AppHmiType; typedef std::vector<AppHMIType> AppHmiTypes; @@ -169,6 +175,11 @@ struct ApplicationParams : PolicyBase { Optional<RequestTypes> RequestType; Optional<Integer<uint16_t, 0, 65225> > memory_kb; Optional<Integer<uint32_t, 0, UINT_MAX> > heart_beat_timeout_ms; +#ifdef SDL_REMOTE_CONTROL + Optional<Strings> groups_primaryRC; + Optional<Strings> groups_nonPrimaryRC; + mutable Optional<ModuleTypes> moduleType; +#endif // SDL_REMOTE_CONTROL public: ApplicationParams(); @@ -188,6 +199,9 @@ struct ApplicationParams : PolicyBase { private: bool Validate() const; +#ifdef SDL_REMOTE_CONTROL + bool ValidateModuleTypes() const; +#endif // SDL_REMOTE_CONTROL }; struct ApplicationPoliciesSection : CompositeType { @@ -294,6 +308,10 @@ struct ModuleConfig : CompositeType { Optional<String<0, 10> > preloaded_date; Optional<String<0, 65535> > certificate; Optional<Boolean> preloaded_pt; +#ifdef SDL_REMOTE_CONTROL + Optional<Boolean> user_consent_passengersRC; + Optional<Boolean> country_consent_passengersRC; +#endif // SDL_REMOTE_CONTROL public: ModuleConfig(); diff --git a/src/components/policy/policy_external/include/policy/policy_types.h b/src/components/policy/policy_external/include/policy/policy_types.h index ab95659917..375d4b4b59 100644 --- a/src/components/policy/policy_external/include/policy/policy_types.h +++ b/src/components/policy/policy_external/include/policy/policy_types.h @@ -56,6 +56,7 @@ const std::string kDefaultDeviceConnectionType = "UNKNOWN"; */ const std::string kPreDataConsentId = "pre_DataConsent"; const std::string kDefaultId = "default"; +const std::string kPreConsentPassengersRC = "pre_consent_passengersRC"; const std::string kDeviceId = "device"; const std::string kPrimary = "rc_primaryDevice"; diff --git a/src/components/policy/policy_external/include/policy/sql_pt_queries.h b/src/components/policy/policy_external/include/policy/sql_pt_queries.h index 685c84742f..a4832aab26 100644 --- a/src/components/policy/policy_external/include/policy/sql_pt_queries.h +++ b/src/components/policy/policy_external/include/policy/sql_pt_queries.h @@ -126,10 +126,6 @@ extern const std::string kSelectModuleTypes; extern const std::string kInsertAppGroupPrimary; extern const std::string kInsertAppGroupNonPrimary; extern const std::string kInsertModuleType; -extern const std::string kInsertInteriorZone; -extern const std::string kCountInteriorZones; -extern const std::string kSelectInteriorZones; -extern const std::string kDeleteInteriorZones; extern const std::string kInsertAccessModule; extern const std::string kSelectAccessModules; extern const std::string kDeleteAccessModules; diff --git a/src/components/policy/policy_external/include/policy/sql_pt_representation.h b/src/components/policy/policy_external/include/policy/sql_pt_representation.h index b3ce0a69be..424769fb41 100644 --- a/src/components/policy/policy_external/include/policy/sql_pt_representation.h +++ b/src/components/policy/policy_external/include/policy/sql_pt_representation.h @@ -98,6 +98,31 @@ class SQLPTRepresentation : public virtual PTRepresentation { } #endif // BUILD_TESTS protected: +#ifdef SDL_REMOTE_CONTROL + enum TypeAccess { kAllowed, kManual }; + bool GatherAppGroupPrimary(const std::string& app_id, + policy_table::Strings* app_groups) const; + bool GatherAppGroupNonPrimary(const std::string& app_id, + policy_table::Strings* app_groups) const; + bool GatherModuleType(const std::string& app_id, + policy_table::ModuleTypes* module_types) const; + bool GatherRemoteControlDenied(const std::string& app_id, bool* denied) const; + bool GatherAccessModule(TypeAccess access, + policy_table::AccessModules* modules) const; + bool GatherRemoteRpc(int module_id, policy_table::RemoteRpcs* rpcs) const; + bool SaveAppGroupPrimary(const std::string& app_id, + const policy_table::Strings& app_groups); + bool SaveAppGroupNonPrimary(const std::string& app_id, + const policy_table::Strings& app_groups); + bool SaveModuleType(const std::string& app_id, + const policy_table::ModuleTypes& types); + bool SaveRemoteControlDenied(const std::string& app_id, bool deny); + + bool SaveAccessModule(TypeAccess access, + const policy_table::AccessModules& modules); + bool SaveRemoteRpc(int module_id, const policy_table::RemoteRpcs& rpcs); +#endif // SDL_REMOTE_CONTROL + virtual void GatherModuleMeta(policy_table::ModuleMeta* meta) const; virtual void GatherModuleConfig(policy_table::ModuleConfig* config) const; virtual bool GatherUsageAndErrorCounts( diff --git a/src/components/policy/policy_external/src/access_remote_impl.cc b/src/components/policy/policy_external/src/access_remote_impl.cc new file mode 100644 index 0000000000..929d9eb1d8 --- /dev/null +++ b/src/components/policy/policy_external/src/access_remote_impl.cc @@ -0,0 +1,389 @@ +/* + * Copyright (c) 2015, 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 "policy/access_remote_impl.h" + +#include <algorithm> +#include <iterator> +#include "policy/cache_manager.h" +#include "utils/logger.h" + +CREATE_LOGGERPTR_GLOBAL(logger_, "PolicyManagerImpl") + +using policy_table::DeviceData; +using policy_table::FunctionalGroupings; +using rpc::policy_table_interface_base::EnumFromJsonString; + +namespace policy { + +struct Erase { + private: + const Subject& who_; + + public: + explicit Erase(const Subject& who) : who_(who) {} + void operator()(AccessRemoteImpl::AccessControlList::value_type& row) const { + row.second.erase(who_); + } +}; + +struct IsTypeAccess { + private: + const TypeAccess& type_; + + public: + explicit IsTypeAccess(const TypeAccess& type) : type_(type) {} + bool operator()( + const AccessRemoteImpl::AccessControlRow::value_type& item) const { + return item.second == type_; + } +}; + +struct ToHMIType { + policy_table::AppHMITypes::value_type operator()(int item) const { + policy_table::AppHMIType type = static_cast<policy_table::AppHMIType>(item); + if (!IsValidEnum(type)) { + LOG4CXX_WARN(logger_, "HMI type isn't known " << item); + type = policy_table::AHT_DEFAULT; + } + LOG4CXX_DEBUG(logger_, + "HMI type: " << item << " - " << EnumToJsonString(type)); + return policy_table::AppHMITypes::value_type(type); + } +}; + +struct Contained { + private: + const policy_table::Strings& params_; + + public: + explicit Contained(const policy_table::Strings& params) : params_(params) {} + bool operator()(const RemoteControlParams::value_type& item) const { + return std::find_if(params_.begin(), params_.end(), CompareString(item)) != + params_.end(); + } + struct CompareString { + private: + const RemoteControlParams::value_type& value_; + + public: + explicit CompareString(const RemoteControlParams::value_type& value) + : value_(value) {} + bool operator()(const policy_table::Strings::value_type& item) const { + return value_ == static_cast<std::string>(item); + } + }; +}; + +struct ToModuleType { + std::string operator()(policy_table::ModuleTypes::value_type item) const { + policy_table::ModuleType type = static_cast<policy_table::ModuleType>(item); + return EnumToJsonString(type); + } +}; + +AccessRemoteImpl::AccessRemoteImpl() + : cache_(new CacheManager()), primary_device_(), enabled_(true), acl_() {} + +AccessRemoteImpl::AccessRemoteImpl(utils::SharedPtr<CacheManager> cache) + : cache_(cache), primary_device_(), enabled_(true), acl_() {} + +void AccessRemoteImpl::Init() { + LOG4CXX_AUTO_TRACE(logger_); + DCHECK(cache_->pt_); + + policy_table::ModuleConfig& config = cache_->pt_->policy_table.module_config; + enabled_ = country_consent() && + (!config.user_consent_passengersRC.is_initialized() || + *config.user_consent_passengersRC); +} + +bool AccessRemoteImpl::IsPrimaryDevice(const PTString& dev_id) const { + LOG4CXX_AUTO_TRACE(logger_); + return primary_device_ == dev_id; +} + +TypeAccess AccessRemoteImpl::Check(const Subject& who, + const Object& what) const { + LOG4CXX_AUTO_TRACE(logger_); + AccessControlList::const_iterator i = acl_.find(what); + if (i != acl_.end()) { + const AccessControlRow& row = i->second; + AccessControlRow::const_iterator j = row.find(who); + if (j != row.end()) { + // who has permissions + TypeAccess ret = j->second; + LOG4CXX_TRACE(logger_, + "Subject " << who << " has permissions " << ret + << " to object " << what); + return ret; + } + } + return TypeAccess::kManual; +} + +bool AccessRemoteImpl::CheckModuleType(const PTString& app_id, + policy_table::ModuleType module) const { + LOG4CXX_AUTO_TRACE(logger_); + if (!cache_->IsApplicationRepresented(app_id)) { + return false; + } + + const policy_table::ApplicationParams& app = + cache_->pt_->policy_table.app_policies_section.apps[app_id]; + if (!app.moduleType.is_initialized()) { + return false; + } + + const policy_table::ModuleTypes& modules = *app.moduleType; + if (modules.empty()) { + return true; + } + + return std::find(modules.begin(), modules.end(), module) != modules.end(); +} + +bool AccessRemoteImpl::IsAllowed(const policy_table::AccessModules& modules, + const std::string& module_name, + const std::string& rpc_name, + RemoteControlParams* input) const { + LOG4CXX_AUTO_TRACE(logger_); + policy_table::AccessModules::const_iterator i = modules.find(module_name); + if (i == modules.end()) { + LOG4CXX_DEBUG(logger_, "Module " << module_name << " wasn't found"); + return false; + } + + const policy_table::RemoteRpcs& rpcs = i->second; + if (rpcs.empty()) { + return true; + } + policy_table::RemoteRpcs::const_iterator j = rpcs.find(rpc_name); + if (j != rpcs.end()) { + const policy_table::Strings& parameters = j->second; + return CompareParameters(parameters, input); + } + LOG4CXX_DEBUG(logger_, "RPC " << rpc_name << " wasn't found"); + return false; +} + +bool AccessRemoteImpl::CompareParameters( + const policy_table::Strings& parameters, RemoteControlParams* input) const { + LOG4CXX_AUTO_TRACE(logger_); + if (parameters.empty()) { + return true; + } + + if (input->empty()) { + LOG4CXX_DEBUG(logger_, "Input is empty"); + return false; + } + + input->erase( + std::remove_if(input->begin(), input->end(), Contained(parameters)), + input->end()); + return input->empty(); +} + +void AccessRemoteImpl::Allow(const Subject& who, const Object& what) { + LOG4CXX_AUTO_TRACE(logger_); + acl_[what][who] = TypeAccess::kAllowed; +} + +void AccessRemoteImpl::Deny(const Subject& who, const Object& what) { + LOG4CXX_AUTO_TRACE(logger_); + acl_[what][who] = TypeAccess::kDisallowed; +} + +void AccessRemoteImpl::Reset(const Subject& who) { + LOG4CXX_AUTO_TRACE(logger_); + std::for_each(acl_.begin(), acl_.end(), Erase(who)); +} + +void AccessRemoteImpl::Reset(const Object& what) { + LOG4CXX_AUTO_TRACE(logger_); + acl_.erase(what); +} + +void AccessRemoteImpl::Reset() { + acl_.clear(); +} + +void AccessRemoteImpl::SetPrimaryDevice(const PTString& dev_id) { + LOG4CXX_AUTO_TRACE(logger_); + primary_device_ = dev_id; +} + +PTString AccessRemoteImpl::PrimaryDevice() const { + return primary_device_; +} + +void AccessRemoteImpl::Enable() { + LOG4CXX_AUTO_TRACE(logger_); + set_enabled(true); +} + +void AccessRemoteImpl::Disable() { + LOG4CXX_AUTO_TRACE(logger_); + set_enabled(false); +} + +void AccessRemoteImpl::set_enabled(bool value) { + enabled_ = country_consent() && value; + *cache_->pt_->policy_table.module_config.user_consent_passengersRC = value; + cache_->Backup(); +} + +bool AccessRemoteImpl::country_consent() const { + policy_table::ModuleConfig& config = cache_->pt_->policy_table.module_config; + return !config.country_consent_passengersRC.is_initialized() || + *config.country_consent_passengersRC; +} + +bool AccessRemoteImpl::IsEnabled() const { + LOG4CXX_AUTO_TRACE(logger_); + return enabled_; +} + +void AccessRemoteImpl::SetDefaultHmiTypes(const Subject& who, + const std::vector<int>& hmi_types) { + LOG4CXX_AUTO_TRACE(logger_); + HMIList::mapped_type types; + std::transform(hmi_types.begin(), + hmi_types.end(), + std::back_inserter(types), + ToHMIType()); + hmi_types_[who] = types; +} + +const policy_table::AppHMITypes& AccessRemoteImpl::HmiTypes( + const Subject& who) { + LOG4CXX_AUTO_TRACE(logger_); + if (cache_->IsDefaultPolicy(who.app_id)) { + return hmi_types_[who]; + } else { + return *cache_->pt_->policy_table.app_policies_section.apps[who.app_id] + .AppHMIType; + } +} + +const policy_table::Strings& AccessRemoteImpl::GetGroups(const Subject& who) { + LOG4CXX_AUTO_TRACE(logger_); + if (IsAppRemoteControl(who)) { + if (IsPrimaryDevice(who.dev_id)) { + return *cache_->pt_->policy_table.app_policies_section.apps[who.app_id] + .groups_primaryRC; + } else if (IsEnabled()) { + return *cache_->pt_->policy_table.app_policies_section.apps[who.app_id] + .groups_nonPrimaryRC; + } else { + return cache_->GetGroups(kPreConsentPassengersRC); + } + } + return cache_->GetGroups(who.app_id); +} + +bool AccessRemoteImpl::IsAppRemoteControl(const Subject& who) { + const policy_table::AppHMITypes& hmi_types = HmiTypes(who); + return std::find(hmi_types.begin(), + hmi_types.end(), + policy_table::AHT_REMOTE_CONTROL) != hmi_types.end(); +} + +bool AccessRemoteImpl::GetPermissionsForApp(const std::string& device_id, + const std::string& app_id, + FunctionalIdType& group_types) { + LOG4CXX_AUTO_TRACE(logger_); + GetGroupsIds(device_id, app_id, group_types[kTypeGeneral]); + GetGroupsIds(device_id, kDefaultId, group_types[kTypeDefault]); + GetGroupsIds( + device_id, kPreDataConsentId, group_types[kTypePreDataConsented]); + + cache_->GetPreConsentedGroups(app_id, group_types[kTypePreconsented]); + + cache_->GetConsentedGroups(device_id, + app_id, + group_types[kTypeAllowed], + group_types[kTypeDisallowed]); + + cache_->GetUnconsentedGroups( + device_id, app_id, group_types[kTypeUnconsented]); + + cache_->GetAllAppGroups(kDeviceId, group_types[kTypeDevice]); + return true; +} + +std::ostream& operator<<(std::ostream& output, + const FunctionalGroupIDs& types) { + std::copy(types.begin(), + types.end(), + std::ostream_iterator<FunctionalGroupIDs::value_type>(output, " ")); + return output; +} + +extern std::ostream& operator<<(std::ostream& output, + const policy_table::Strings& groups); + +void AccessRemoteImpl::GetGroupsIds(const std::string& device_id, + const std::string& app_id, + FunctionalGroupIDs& groups_ids) { + Subject who = {device_id, app_id}; + const policy_table::Strings& groups = GetGroups(who); + LOG4CXX_DEBUG(logger_, "Groups Names: " << groups); + groups_ids.resize(groups.size()); + std::transform(groups.begin(), + groups.end(), + groups_ids.begin(), + &CacheManager::GenerateHash); + LOG4CXX_DEBUG(logger_, "Groups Ids: " << groups_ids); +} + +bool AccessRemoteImpl::GetModuleTypes(const std::string& application_id, + std::vector<std::string>* modules) { + DCHECK(modules); + policy_table::ApplicationPolicies& apps = + cache_->pt_->policy_table.app_policies_section.apps; + policy_table::ApplicationPolicies::iterator i = apps.find(application_id); + if (i == apps.end()) { + return false; + } + rpc::Optional<policy_table::ModuleTypes> moduleTypes = i->second.moduleType; + if (!moduleTypes.is_initialized()) { + return false; + } + std::transform(moduleTypes->begin(), + moduleTypes->end(), + std::back_inserter(*modules), + ToModuleType()); + return true; +} + +} // namespace policy diff --git a/src/components/policy/policy_external/src/policy_helper.cc b/src/components/policy/policy_external/src/policy_helper.cc index cb27e7f0b3..f9c69f58d3 100644 --- a/src/components/policy/policy_external/src/policy_helper.cc +++ b/src/components/policy/policy_external/src/policy_helper.cc @@ -865,4 +865,53 @@ bool UnwrapAppPolicies(policy_table::ApplicationPolicies& app_policies) { return true; } + +#ifdef SDL_REMOTE_CONTROL +bool HaveGroupsChanged(const rpc::Optional<policy_table::Strings>& old_groups, + const rpc::Optional<policy_table::Strings>& new_groups) { + if (!old_groups.is_initialized() && !new_groups.is_initialized()) { + return false; + } + if (!old_groups.is_initialized() || !new_groups.is_initialized()) { + return true; + } + policy_table::Strings old_groups_abs = *old_groups; + policy_table::Strings new_groups_abs = *new_groups; + if (old_groups_abs.size() != new_groups_abs.size()) { + return true; + } + std::sort(new_groups_abs.begin(), new_groups_abs.end(), Compare); + std::sort(old_groups_abs.begin(), old_groups_abs.end(), Compare); + + return std::equal(new_groups_abs.begin(), + new_groups_abs.end(), + old_groups_abs.begin(), + Compare); } + +void ProccessAppGroups::operator()( + const policy_table::ApplicationPolicies::value_type& app) { + policy_table::ApplicationPolicies::const_iterator i = + new_apps_.find(app.first); + if (i == new_apps_.end() && default_ != new_apps_.end()) { + i = default_; + } + if (i != new_apps_.end()) { + if (HaveGroupsChanged(i->second.groups_primaryRC, + app.second.groups_primaryRC)) { + LOG4CXX_DEBUG(logger_, + "Primary groups for " << app.first << " have changed"); + + pm_->OnPrimaryGroupsChanged(app.first); + } + if (HaveGroupsChanged(i->second.groups_nonPrimaryRC, + app.second.groups_nonPrimaryRC)) { + LOG4CXX_DEBUG(logger_, + "Non-primary groups for " << app.first << " have changed"); + pm_->OnNonPrimaryGroupsChanged(app.first); + } + } +} + +#endif // SDL_REMOTE_CONTROL +} // namespace policy diff --git a/src/components/policy/policy_external/src/policy_manager_impl.cc b/src/components/policy/policy_external/src/policy_manager_impl.cc index 0a774f6b79..d968912725 100644 --- a/src/components/policy/policy_external/src/policy_manager_impl.cc +++ b/src/components/policy/policy_external/src/policy_manager_impl.cc @@ -51,6 +51,11 @@ #include "config_profile/profile.h" #include "utils/make_shared.h" +#ifdef SDL_REMOTE_CONTROL +#include "policy/access_remote.h" +#include "policy/access_remote_impl.h" +#endif // SDL_REMOTE_CONTROL + policy::PolicyManager* CreateManager() { return new policy::PolicyManagerImpl(); } @@ -211,22 +216,32 @@ PolicyManagerImpl::PolicyManagerImpl() : PolicyManager() , listener_(NULL) , cache_(new CacheManager) +#ifdef SDL_REMOTE_CONTROL + , access_remote_(new AccessRemoteImpl( + CacheManagerInterfaceSPtr::static_pointer_cast<CacheManager>(cache_))) +#endif // SDL_REMOTE_CONTROL , retry_sequence_timeout_(60) , retry_sequence_index_(0) , ignition_check(true) - , retry_sequence_url_(0, 0, "") {} + , retry_sequence_url_(0, 0, "") { +} PolicyManagerImpl::PolicyManagerImpl(bool in_memory) : PolicyManager() , listener_(NULL) , cache_(new CacheManager(in_memory)) +#ifdef SDL_REMOTE_CONTROL + , access_remote_(new AccessRemoteImpl( + CacheManagerInterfaceSPtr::static_pointer_cast<CacheManager>(cache_))) +#endif // SDL_REMOTE_CONTROL , retry_sequence_timeout_(60) , retry_sequence_index_(0) , ignition_check(true) , retry_sequence_url_(0, 0, "") , wrong_ptu_update_received_(false) , send_on_update_sent_out_(false) - , trigger_ptu_(false) {} + , trigger_ptu_(false) { +} void PolicyManagerImpl::set_listener(PolicyListener* listener) { listener_ = listener; @@ -325,6 +340,10 @@ bool PolicyManagerImpl::LoadPT(const std::string& file, listener_->OnCertificateUpdated( *(pt_update->policy_table.module_config.certificate)); +#ifdef SDL_REMOTE_CONTROL + access_remote_->Init(); + CheckPTUUpdatesChange(pt_update, policy_table_snapshot); +#endif // SDL_REMOTE_CONTROL std::map<std::string, StringArray> app_hmi_types; cache_->GetHMIAppTypeAfterUpdate(app_hmi_types); @@ -578,7 +597,13 @@ void PolicyManagerImpl::CheckPermissions(const PTString& app_id, policy_table::FunctionalGroupings functional_groupings; cache_->GetFunctionalGroupings(functional_groupings); - policy_table::Strings app_groups = GetGroupsNames(app_group_permissions); +#ifdef SDL_REMOTE_CONTROL + Subject who = {device_id, app_id}; + const policy_table::Strings app_groups = access_remote_->GetGroups(who); +#else // SDL_REMOTE_CONTROL + const policy_table::Strings app_groups = + GetGroupsNames(app_group_permissions); +#endif // SDL_REMOTE_CONTROL // Undefined groups (without user consent) disallowed by default, since // OnPermissionsChange notification has no "undefined" section @@ -757,6 +782,17 @@ void PolicyManagerImpl::SendNotificationOnPermissionsUpdated( LOG4CXX_INFO(logger_, "Send notification for application_id:" << application_id); +#ifdef SDL_REMOTE_CONTROL + const Subject who = {device_id, application_id}; + if (access_remote_->IsAppRemoteControl(who)) { + const std::string rank = + access_remote_->IsPrimaryDevice(who.dev_id) ? "DRIVER" : "PASSENGER"; + UpdateDeviceRank(who, rank); + listener()->OnPermissionsUpdated(application_id, notification_data); + return; + } +#endif // SDL_REMOTE_CONTROL + std::string default_hmi; GetDefaultHmi(application_id, &default_hmi); @@ -1135,7 +1171,17 @@ void PolicyManagerImpl::GetPermissionsForApp( } FunctionalIdType group_types; - if (!cache_->GetPermissionsForApp(device_id, app_id_to_check, group_types)) { + +#ifdef SDL_REMOTE_CONTROL + allowed_by_default = false; + const bool ret = access_remote_->GetPermissionsForApp( + device_id, app_id_to_check, group_types); +#else + const bool ret = + cache_->GetPermissionsForApp(device_id, app_id_to_check, group_types); +#endif // REMOTE_CONTROL + + if (!ret) { LOG4CXX_WARN(logger_, "Can't get user permissions for app " << policy_app_id); return; @@ -1863,6 +1909,9 @@ bool PolicyManagerImpl::InitPT(const std::string& file_name, if (ret) { RefreshRetrySequence(); update_status_manager_.OnPolicyInit(cache_->UpdateRequired()); +#ifdef SDL_REMOTE_CONTROL + access_remote_->Init(); +#endif // SDL_REMOTE_CONTROL } return ret; } @@ -1880,4 +1929,346 @@ void PolicyManagerImpl::set_cache_manager( cache_ = cache_manager; } +std::ostream& operator<<(std::ostream& output, + const policy_table::Strings& groups) { + for (policy_table::Strings::const_iterator i = groups.begin(); + i != groups.end(); + ++i) { + output << static_cast<std::string>(*i) << " "; + } + return output; +} + +#ifdef SDL_REMOTE_CONTROL +void PolicyManagerImpl::SetDefaultHmiTypes(const std::string& application_id, + const std::vector<int>& hmi_types) { + LOG4CXX_INFO(logger_, "SetDefaultHmiTypes"); + const std::string device_id = GetCurrentDeviceId(application_id); + Subject who = {device_id, application_id}; + access_remote_->SetDefaultHmiTypes(who, hmi_types); +} + +struct HMITypeToInt { + int operator()(const policy_table::AppHMITypes::value_type item) { + return policy_table::AppHMIType(item); + } +}; + +bool PolicyManagerImpl::GetHMITypes(const std::string& application_id, + std::vector<int>* app_types) { + LOG4CXX_AUTO_TRACE(logger_); + if (cache_->IsDefaultPolicy(application_id)) { + return false; + } + const policy_table::AppHMITypes* hmi_types = + cache_->GetHMITypes(application_id); + if (hmi_types) { + std::transform(hmi_types->begin(), + hmi_types->end(), + std::back_inserter(*app_types), + HMITypeToInt()); + } + return hmi_types; +} + +TypeAccess PolicyManagerImpl::CheckAccess(const PTString& device_id, + const PTString& app_id, + const PTString& module, + const PTString& rpc, + const RemoteControlParams& params) { + LOG4CXX_AUTO_TRACE(logger_); + LOG4CXX_DEBUG(logger_, "Module type: " << module); + + policy_table::ModuleType module_type; + bool is_valid = EnumFromJsonString(module, &module_type); + if (is_valid && access_remote_->CheckModuleType(app_id, module_type)) { + if (access_remote_->IsPrimaryDevice(device_id)) { + return TypeAccess::kAllowed; + } else { + Subject who = {device_id, app_id}; + Object what = {module_type}; + return CheckDriverConsent(who, what, rpc, params); + } + } + LOG4CXX_DEBUG(logger_, TypeAccess::kDisallowed); + return TypeAccess::kDisallowed; +} + +bool PolicyManagerImpl::CheckModule(const PTString& app_id, + const PTString& module) { + LOG4CXX_AUTO_TRACE(logger_); + policy_table::ModuleType module_type; + return EnumFromJsonString(module, &module_type) && + access_remote_->CheckModuleType(app_id, module_type); +} + +TypeAccess PolicyManagerImpl::CheckDriverConsent( + const Subject& who, + const Object& what, + const std::string& rpc, + const RemoteControlParams& params) { + LOG4CXX_AUTO_TRACE(logger_); + if (!access_remote_->IsEnabled()) { + return TypeAccess::kDisallowed; + } + + return access_remote_->Check(who, what); +} + +void PolicyManagerImpl::SetAccess(const PTString& dev_id, + const PTString& app_id, + const PTString& module, + bool allowed) { + LOG4CXX_AUTO_TRACE(logger_); + policy_table::ModuleType module_type; + bool is_valid = EnumFromJsonString(module, &module_type); + if (!is_valid) { + return; + } + + Subject who = {dev_id, app_id}; + Object what = {module_type}; + LOG4CXX_DEBUG(logger_, + "Driver's consent: " << who << ", " << what << " is " + << std::boolalpha << allowed); + if (allowed) { + access_remote_->Allow(who, what); + } else { + access_remote_->Deny(who, what); + } +} + +void PolicyManagerImpl::ResetAccess(const PTString& dev_id, + const PTString& app_id) { + LOG4CXX_AUTO_TRACE(logger_); + Subject who = {dev_id, app_id}; + access_remote_->Reset(who); +} + +void PolicyManagerImpl::ResetAccess(const PTString& module) { + LOG4CXX_AUTO_TRACE(logger_); + policy_table::ModuleType module_type; + bool is_valid = EnumFromJsonString(module, &module_type); + if (!is_valid) { + return; + } + + Object what = {module_type}; + access_remote_->Reset(what); +} + +void PolicyManagerImpl::SetPrimaryDevice(const PTString& dev_id) { + LOG4CXX_AUTO_TRACE(logger_); + access_remote_->SetPrimaryDevice(dev_id); +} + +void PolicyManagerImpl::ResetPrimaryDevice() { + LOG4CXX_AUTO_TRACE(logger_); + access_remote_->SetPrimaryDevice(""); +} + +PTString PolicyManagerImpl::PrimaryDevice() const { + LOG4CXX_AUTO_TRACE(logger_); + return access_remote_->PrimaryDevice(); +} + +void PolicyManagerImpl::SetRemoteControl(bool enabled) { + LOG4CXX_AUTO_TRACE(logger_); + if (enabled) { + access_remote_->Enable(); + } else { + access_remote_->Disable(); + } +} + +bool PolicyManagerImpl::GetRemoteControl() const { + return access_remote_->IsEnabled(); +} + +void PolicyManagerImpl::OnChangedPrimaryDevice( + const std::string& device_id, const std::string& application_id) { + LOG4CXX_AUTO_TRACE(logger_); + Subject who = {device_id, application_id}; + if (!access_remote_->IsAppRemoteControl(who)) { + LOG4CXX_INFO(logger_, "Application " << who << " isn't remote"); + return; + } + + const std::string rank = + access_remote_->IsPrimaryDevice(who.dev_id) ? "DRIVER" : "PASSENGER"; + UpdateDeviceRank(who, rank); + SendAppPermissionsChanged(who.dev_id, who.app_id); +} + +void PolicyManagerImpl::OnChangedRemoteControl( + const std::string& device_id, const std::string& application_id) { + LOG4CXX_AUTO_TRACE(logger_); + Subject who = {device_id, application_id}; + if (!access_remote_->IsAppRemoteControl(who)) { + LOG4CXX_INFO(logger_, "Application " << who << " isn't remote"); + return; + } + + if (access_remote_->IsPrimaryDevice(who.dev_id)) { + LOG4CXX_INFO(logger_, "Device " << who.dev_id << " is primary"); + return; + } + + if (!access_remote_->IsEnabled()) { + SendHMILevelChanged(who); + } + + SendAppPermissionsChanged(who.dev_id, who.app_id); +} + +void PolicyManagerImpl::UpdateDeviceRank(const Subject& who, + const std::string& rank) { + std::string default_hmi("NONE"); + if (GetDefaultHmi(who.app_id, &default_hmi)) { + access_remote_->Reset(who); + listener()->OnUpdateHMIStatus(who.dev_id, who.app_id, default_hmi, rank); + } else { + LOG4CXX_WARN(logger_, + "Couldn't get default HMI level for application " + << who.app_id); + } +} + +void PolicyManagerImpl::SendHMILevelChanged(const Subject& who) { + std::string default_hmi("NONE"); + if (GetDefaultHmi(who.app_id, &default_hmi)) { + access_remote_->Reset(who); + listener()->OnUpdateHMIStatus(who.dev_id, who.app_id, default_hmi); + } else { + LOG4CXX_WARN(logger_, + "Couldn't get default HMI level for application " + << who.app_id); + } +} + +void PolicyManagerImpl::GetPermissions(const std::string device_id, + const std::string application_id, + Permissions* data) { + LOG4CXX_AUTO_TRACE(logger_); + DCHECK(data); + std::vector<FunctionalGroupPermission> app_group_permissions; + GetPermissionsForApp(device_id, application_id, app_group_permissions); + + policy_table::FunctionalGroupings functional_groupings; + cache_->GetFunctionalGroupings(functional_groupings); + + policy_table::Strings app_groups; + std::vector<FunctionalGroupPermission>::const_iterator it = + app_group_permissions.begin(); + std::vector<FunctionalGroupPermission>::const_iterator it_end = + app_group_permissions.end(); + for (; it != it_end; ++it) { + app_groups.push_back((*it).group_name); + } + + PrepareNotificationData( + functional_groupings, app_groups, app_group_permissions, *data); +} + +void PolicyManagerImpl::SendAppPermissionsChanged( + const std::string& device_id, const std::string& application_id) { + Permissions notification_data; + GetPermissions(device_id, application_id, ¬ification_data); + listener()->OnPermissionsUpdated(application_id, notification_data); +} + +void PolicyManagerImpl::CheckPTUUpdatesChange( + const utils::SharedPtr<policy_table::Table> pt_update, + const utils::SharedPtr<policy_table::Table> snapshot) { + CheckPTURemoteCtrlChange(pt_update, snapshot); + CheckRemoteGroupsChange(pt_update, snapshot); +} + +bool PolicyManagerImpl::CheckPTURemoteCtrlChange( + const utils::SharedPtr<policy_table::Table> pt_update, + const utils::SharedPtr<policy_table::Table> snapshot) { + LOG4CXX_AUTO_TRACE(logger_); + + rpc::Optional<rpc::Boolean>& new_consent = + pt_update->policy_table.module_config.country_consent_passengersRC; + rpc::Optional<rpc::Boolean>& old_consent = + snapshot->policy_table.module_config.country_consent_passengersRC; + + if (!new_consent.is_initialized() && !old_consent.is_initialized()) { + return false; + } + + bool result = false; + if (new_consent.is_initialized() && old_consent.is_initialized()) { + result = (*new_consent != *old_consent); + } else { + bool not_changed_consent1 = !new_consent.is_initialized() && *old_consent; + bool not_changed_consent2 = !old_consent.is_initialized() && *new_consent; + + result = !(not_changed_consent1 || not_changed_consent2); + } + + if (result) { + listener()->OnRemoteAllowedChanged(result); + } + + return result; +} + +void PolicyManagerImpl::CheckRemoteGroupsChange( + const utils::SharedPtr<policy_table::Table> pt_update, + const utils::SharedPtr<policy_table::Table> snapshot) { + LOG4CXX_AUTO_TRACE(logger_); + + policy_table::ApplicationPolicies& new_apps = + pt_update->policy_table.app_policies_section.apps; + policy_table::ApplicationPolicies& old_apps = + snapshot->policy_table.app_policies_section.apps; + std::for_each( + old_apps.begin(), old_apps.end(), ProccessAppGroups(new_apps, this)); +} + +void PolicyManagerImpl::OnPrimaryGroupsChanged( + const std::string& application_id) { + const std::vector<std::string> devices = + listener()->GetDevicesIds(application_id); + for (std::vector<std::string>::const_iterator i = devices.begin(); + i != devices.end(); + ++i) { + const Subject who = {*i, application_id}; + if (access_remote_->IsAppRemoteControl(who) && + access_remote_->IsPrimaryDevice(who.dev_id)) { + SendAppPermissionsChanged(who.dev_id, who.app_id); + } + } +} + +void PolicyManagerImpl::OnNonPrimaryGroupsChanged( + const std::string& application_id) { + const std::vector<std::string> devices = + listener()->GetDevicesIds(application_id); + for (std::vector<std::string>::const_iterator i = devices.begin(); + i != devices.end(); + ++i) { + const Subject who = {*i, application_id}; + if (access_remote_->IsAppRemoteControl(who) && + !access_remote_->IsPrimaryDevice(who.dev_id) && + access_remote_->IsEnabled()) { + SendAppPermissionsChanged(who.dev_id, who.app_id); + } + } +} + +bool PolicyManagerImpl::GetModuleTypes( + const std::string& application_id, + std::vector<std::string>* modules) const { + return access_remote_->GetModuleTypes(application_id, modules); +} + +void PolicyManagerImpl::set_access_remote( + utils::SharedPtr<AccessRemote> access_remote) { + access_remote_ = access_remote; +} +#endif // SDL_REMOTE_CONTROL + } // namespace policy diff --git a/src/components/policy/policy_external/src/policy_table/enums.cc b/src/components/policy/policy_external/src/policy_table/enums.cc index 45db2cb469..fc108217c4 100644 --- a/src/components/policy/policy_external/src/policy_table/enums.cc +++ b/src/components/policy/policy_external/src/policy_table/enums.cc @@ -1,4 +1,3 @@ -// This file is generated, do not edit #include "policy/policy_table/enums.h" namespace rpc { @@ -440,6 +439,8 @@ bool IsValidEnum(AppHMIType val) { return true; case AHT_PROJECTION: return true; + case AHT_REMOTE_CONTROL: + return true; default: return false; } @@ -466,8 +467,6 @@ const char* EnumToJsonString(AppHMIType val) { return "TESTING"; case AHT_SYSTEM: return "SYSTEM"; - case AHT_PROJECTION: - return "PROJECTION"; default: return ""; } @@ -506,6 +505,9 @@ bool EnumFromJsonString(const std::string& literal, AppHMIType* result) { } else if ("PROJECTION" == literal) { *result = AHT_PROJECTION; return true; + } else if ("REMOTE_CONTROL" == literal) { + *result = AHT_REMOTE_CONTROL; + return true; } else { return false; } @@ -682,6 +684,10 @@ bool EnumFromJsonString(const std::string& literal, RequestType* result) { *result = RT_DRIVER_PROFILE; return true; } +} +else if ("REMOTE_CONTROL" == literal) { + *result = AHT_REMOTE_CONTROL; + return true; if ("VOICE_SEARCH" == literal) { *result = RT_VOICE_SEARCH; return true; @@ -722,6 +728,41 @@ bool EnumFromJsonString(const std::string& literal, RequestType* result) { } } +#ifdef SDL_REMOTE_CONTROL +bool IsValidEnum(ModuleType val) { + switch (val) { + case MT_CLIMATE: + return true; + case MT_RADIO: + return true; + default: + return false; + } +} +const char* EnumToJsonString(ModuleType val) { + switch (val) { + case MT_CLIMATE: + return "CLIMATE"; + case MT_RADIO: + return "RADIO"; + default: + return ""; + } +} + +bool EnumFromJsonString(const std::string& literal, ModuleType* result) { + if ("CLIMATE" == literal) { + *result = MT_CLIMATE; + return true; + } else if ("RADIO" == literal) { + *result = MT_RADIO; + return true; + } else { + return false; + } +} +#endif // SDL_REMOTE_CONTROL + const std::string kDefaultApp = "default"; const std::string kPreDataConsentApp = "pre_DataConsent"; const std::string kDeviceApp = "device"; diff --git a/src/components/policy/policy_external/src/policy_table/types.cc b/src/components/policy/policy_external/src/policy_table/types.cc index 528d70a426..5c962cc4da 100644 --- a/src/components/policy/policy_external/src/policy_table/types.cc +++ b/src/components/policy/policy_external/src/policy_table/types.cc @@ -239,8 +239,14 @@ ApplicationParams::ApplicationParams(const Json::Value* value__) , AppHMIType(impl::ValueMember(value__, "AppHMIType")) , RequestType(impl::ValueMember(value__, "RequestType")) , memory_kb(impl::ValueMember(value__, "memory_kb"), 0) - , heart_beat_timeout_ms( - impl::ValueMember(value__, "heart_beat_timeout_ms")) {} + , heart_beat_timeout_ms(impl::ValueMember(value__, "heart_beat_timeout_ms")) +#ifdef SDL_REMOTE_CONTROL + , groups_primaryRC(impl::ValueMember(value__, "groups_primaryRC")) + , groups_nonPrimaryRC(impl::ValueMember(value__, "groups_nonPrimaryRC")) + , moduleType(impl::ValueMember(value__, "moduleType")) +#endif // SDL_REMOTE_CONTROL +{ +} Json::Value ApplicationParams::ToJsonValue() const { Json::Value result__(PolicyBase::ToJsonValue()); @@ -250,6 +256,11 @@ Json::Value ApplicationParams::ToJsonValue() const { impl::WriteJsonField("memory_kb", memory_kb, &result__); impl::WriteJsonField( "heart_beat_timeout_ms", heart_beat_timeout_ms, &result__); +#ifdef SDL_REMOTE_CONTROL + impl::WriteJsonField("groups_primaryRC", groups_primaryRC, &result__); + impl::WriteJsonField("groups_nonPrimaryRC", groups_nonPrimaryRC, &result__); + impl::WriteJsonField("moduleType", moduleType, &result__); +#endif // SDL_REMOTE_CONTROL return result__; } @@ -271,6 +282,17 @@ bool ApplicationParams::is_valid() const { if (!heart_beat_timeout_ms.is_valid()) { return false; } +#ifdef SDL_REMOTE_CONTROL + if (!groups_primaryRC.is_valid()) { + return false; + } + if (!groups_nonPrimaryRC.is_valid()) { + return false; + } + if (!moduleType.is_valid()) { + return false; + } +#endif // SDL_REMOTE_CONTROL return Validate(); } @@ -297,6 +319,17 @@ bool ApplicationParams::struct_empty() const { if (heart_beat_timeout_ms.is_initialized()) { return false; } +#ifdef SDL_REMOTE_CONTROL + if (groups_primaryRC.is_initialized()) { + return false; + } + if (groups_nonPrimaryRC.is_initialized()) { + return false; + } + if (moduleType.is_initialized()) { + return false; + } +#endif // SDL_REMOTE_CONTROL return true; } @@ -339,6 +372,20 @@ void ApplicationParams::ReportErrors(rpc::ValidationReport* report__) const { heart_beat_timeout_ms.ReportErrors( &report__->ReportSubobject("heart_beat_timeout_ms")); } + +#ifdef SDL_REMOTE_CONTROL + if (!groups_primaryRC.is_valid()) { + groups_primaryRC.ReportErrors( + &report__->ReportSubobject("groups_primaryRC")); + } + if (!groups_nonPrimaryRC.is_valid()) { + groups_nonPrimaryRC.ReportErrors( + &report__->ReportSubobject("groups_nonPrimaryRC")); + } + if (!moduleType.is_valid()) { + moduleType.ReportErrors(&report__->ReportSubobject("moduleType")); + } +#endif // SDL_REMOTE_CONTROL } void ApplicationParams::SetPolicyTableType(PolicyTableType pt_type) { @@ -347,6 +394,11 @@ void ApplicationParams::SetPolicyTableType(PolicyTableType pt_type) { RequestType.SetPolicyTableType(pt_type); memory_kb.SetPolicyTableType(pt_type); heart_beat_timeout_ms.SetPolicyTableType(pt_type); +#ifdef SDL_REMOTE_CONTROL + groups_primaryRC.SetPolicyTableType(pt_type); + groups_nonPrimaryRC.SetPolicyTableType(pt_type); + moduleType.SetPolicyTableType(pt_type); +#endif // SDL_REMOTE_CONTROL } // RpcParameters methods @@ -549,7 +601,15 @@ ModuleConfig::ModuleConfig(const Json::Value* value__) , vehicle_year(impl::ValueMember(value__, "vehicle_year")) , preloaded_date(impl::ValueMember(value__, "preloaded_date")) , certificate(impl::ValueMember(value__, "certificate")) - , preloaded_pt(impl::ValueMember(value__, "preloaded_pt")) {} + , preloaded_pt(impl::ValueMember(value__, "preloaded_pt")) +#ifdef SDL_REMOTE_CONTROL + , user_consent_passengersRC( + impl::ValueMember(value__, "user_consent_passengersRC")) + , country_consent_passengersRC( + impl::ValueMember(value__, "country_consent_passengersRC")) +#endif // SDL_REMOTE_CONTROL +{ +} void ModuleConfig::SafeCopyFrom(const ModuleConfig& from) { exchange_after_x_days = from.exchange_after_x_days; @@ -566,6 +626,11 @@ void ModuleConfig::SafeCopyFrom(const ModuleConfig& from) { vehicle_make.assign_if_valid(from.vehicle_make); vehicle_model.assign_if_valid(from.vehicle_model); vehicle_year.assign_if_valid(from.vehicle_year); +#ifdef SDL_REMOTE_CONTROL + user_consent_passengersRC.assign_if_valid(from.user_consent_passengersRC); + country_consent_passengersRC.assign_if_valid( + from.country_consent_passengersRC); +#endif // SDL_REMOTE_CONTROL } Json::Value ModuleConfig::ToJsonValue() const { @@ -592,6 +657,12 @@ Json::Value ModuleConfig::ToJsonValue() const { impl::WriteJsonField("vehicle_year", vehicle_year, &result__); impl::WriteJsonField("certificate", certificate, &result__); impl::WriteJsonField("preloaded_date", preloaded_date, &result__); +#ifdef SDL_REMOTE_CONTROL + impl::WriteJsonField( + "user_consent_passengersRC", user_consent_passengersRC, &result__); + impl::WriteJsonField( + "country_consent_passengersRC", country_consent_passengersRC, &result__); +#endif // SDL_REMOTE_CONTROL return result__; } @@ -638,6 +709,14 @@ bool ModuleConfig::is_valid() const { if (!preloaded_date.is_valid()) { return false; } +#ifdef SDL_REMOTE_CONTROL + if (!user_consent_passengersRC.is_valid()) { + return false; + } + if (!country_consent_passengersRC.is_valid()) { + return false; + } +#endif // SDL_REMOTE_CONTROL return Validate(); } @@ -687,6 +766,14 @@ bool ModuleConfig::struct_empty() const { if (vehicle_year.is_initialized()) { return false; } +#ifdef SDL_REMOTE_CONTROL + if (user_consent_passengersRC.is_initialized()) { + return false; + } + if (country_consent_passengersRC.is_initialized()) { + return false; + } +#endif // SDL_REMOTE_CONTROL return true; } @@ -736,6 +823,16 @@ void ModuleConfig::ReportErrors(rpc::ValidationReport* report__) const { if (!vehicle_year.is_valid()) { vehicle_year.ReportErrors(&report__->ReportSubobject("vehicle_year")); } +#ifdef SDL_REMOTE_CONTROL + if (!user_consent_passengersRC.is_valid()) { + user_consent_passengersRC.ReportErrors( + &report__->ReportSubobject("user_consent_passengersRC")); + } + if (!country_consent_passengersRC.is_valid()) { + country_consent_passengersRC.ReportErrors( + &report__->ReportSubobject("country_consent_passengersRC")); + } +#endif // SDL_REMOTE_CONTROL const std::string validation_info = omitted_validation_info + PolicyTableTypeToString(GetPolicyTableType()); @@ -754,6 +851,13 @@ void ModuleConfig::ReportErrors(rpc::ValidationReport* report__) const { omitted_field_report = &report__->ReportSubobject("vehicle_model"); omitted_field_report->set_validation_info(validation_info); } +#ifdef SDL_REMOTE_CONTROL + if (user_consent_passengersRC.is_initialized()) { + omitted_field_report = + &report__->ReportSubobject("user_consent_passengersRC"); + omitted_field_report->set_validation_info(validation_info); + } +#endif // SDL_REMOTE_CONTROL break; } case PT_UPDATE: { @@ -787,6 +891,10 @@ void ModuleConfig::SetPolicyTableType(PolicyTableType pt_type) { vehicle_make.SetPolicyTableType(pt_type); vehicle_model.SetPolicyTableType(pt_type); vehicle_year.SetPolicyTableType(pt_type); +#ifdef SDL_REMOTE_CONTROL + user_consent_passengersRC.SetPolicyTableType(pt_type); + country_consent_passengersRC.SetPolicyTableType(pt_type); +#endif // SDL_REMOTE_CONTROL } // MessageString methods diff --git a/src/components/policy/policy_external/src/policy_table/validation.cc b/src/components/policy/policy_external/src/policy_table/validation.cc index b7e6dcc337..48a8578855 100644 --- a/src/components/policy/policy_external/src/policy_table/validation.cc +++ b/src/components/policy/policy_external/src/policy_table/validation.cc @@ -135,6 +135,39 @@ bool ApplicationPoliciesSection::Validate() const { return true; } + +#ifdef SDL_REMOTE_CONTROL +bool ApplicationParams::ValidateModuleTypes() const { + // moduleType is optional so see Optional<T>::is_valid() + bool is_initialized = moduleType->is_initialized(); + if (!is_initialized) { + // valid if not initialized + return true; + } + bool is_valid = moduleType->is_valid(); + if (is_valid) { + return true; + } + + struct IsInvalid { + bool operator()(Enum<ModuleType> item) const { + return !item.is_valid(); + } + }; + // cut invalid items + moduleType->erase( + std::remove_if(moduleType->begin(), moduleType->end(), IsInvalid()), + moduleType->end()); + bool empty = moduleType->empty(); + if (empty) { + // set non initialized value + ModuleTypes non_initialized; + moduleType = Optional<ModuleTypes>(non_initialized); + } + return true; +} +#endif // SDL_REMOTE_CONTROL + bool ApplicationParams::Validate() const { if (is_initialized()) { if (preconsented_groups.is_initialized()) { @@ -145,8 +178,13 @@ bool ApplicationParams::Validate() const { } } } +#ifdef SDL_REMOTE_CONTROL + return ValidateModuleTypes(); +#else // SDL_REMOTE_CONTROL return true; +#endif // SDL_REMOTE_CONTROL } + bool RpcParameters::Validate() const { return true; } diff --git a/src/components/policy/policy_external/src/sql_pt_queries.cc b/src/components/policy/policy_external/src/sql_pt_queries.cc index 1cd789f00d..6b3acd44ec 100644 --- a/src/components/policy/policy_external/src/sql_pt_queries.cc +++ b/src/components/policy/policy_external/src/sql_pt_queries.cc @@ -77,7 +77,7 @@ const std::string kCreateSchema = " `vehicle_year` VARCHAR(4), " " `preloaded_date` VARCHAR (10), " " `certificate` VARCHAR (45), " - " `user_consent_passengersRC` BOOL," + " `user_consent_passengersRC` BOOL, " " `country_consent_passengersRC` BOOL " "); " "CREATE TABLE IF NOT EXISTS `functional_group`( " @@ -392,31 +392,12 @@ const std::string kCreateSchema = "idx` " " ON `app_group_non_primary`(`application_id`); " - /* interior_zone */ - "CREATE TABLE `interior_zone`( " - " `id` INTEGER PRIMARY KEY NOT NULL, " - " `name` VARCHAR(100) NOT NULL, " - " `col` INTEGER NOT NULL, " - " `row` INTEGER NOT NULL, " - " `level` INTEGER NOT NULL " - "); " - "CREATE UNIQUE INDEX `interior_zone.room` ON " - "`interior_zone`(`col`,`row`,`level`); " - /* access_module */ "CREATE TABLE `access_module`( " " `id` INTEGER PRIMARY KEY NOT NULL, " " `name` VARCHAR(45) NOT NULL, " - " `zone_id` INTEGER NOT NULL, " - " `user_consent_needed` INTEGER NOT NULL, " - "CONSTRAINT `fk_module_1` " - " FOREIGN KEY(`zone_id`) " - " REFERENCES `interior_zone`(`id`) " + " `user_consent_needed` INTEGER NOT NULL " "); " - "CREATE INDEX `access_module.zone_module` ON " - "`access_module`(`name`,`zone_id`); " - "CREATE INDEX `access_module.fk_module_1_idx` ON " - "`access_module`(`zone_id`); " /* remote_rpc */ "CREATE TABLE `remote_rpc`( " @@ -522,24 +503,12 @@ const std::string kInsertAppGroupNonPrimary = const std::string kUpdateRemoteControlDenied = "UPDATE `application` SET `remote_control_denied` = ? WHERE `id` = ?"; -const std::string kCountInteriorZones = - "SELECT COUNT(`id`) FROM `interior_zone`"; - -const std::string kDeleteInteriorZones = "DELETE FROM `interior_zone`"; - const std::string kDeleteAccessModules = "DELETE FROM `access_module`"; const std::string kDeleteRemoteRpc = "DELETE FROM `remote_rpc`"; -const std::string kInsertInteriorZone = - "INSERT INTO `interior_zone` (`name`, `col`, `row`, `level`) " - " VALUES(?, ?, ?, ?)"; - -const std::string kSelectInteriorZones = - "SELECT `id`, `name`, `col`, `row`, `level` FROM `interior_zone`"; - const std::string kInsertAccessModule = - "INSERT INTO `access_module` (`name`, `zone_id`, `user_consent_needed`) " + "INSERT INTO `access_module` (`name`, `user_consent_needed`) " " VALUES(?, ?, ?)"; const std::string kDeleteAppGroupPrimaryByApplicationId = @@ -550,7 +519,7 @@ const std::string kDeleteAppGroupNonPrimaryByApplicationId = const std::string kSelectAccessModules = "SELECT `id`, `name` FROM `access_module` " - " WHERE `zone_id` = ? AND `user_consent_needed` = ?"; + " WHERE `user_consent_needed` = ?"; const std::string kInsertRemoteRpc = "INSERT INTO `remote_rpc` (`module_id`, `name`, `parameter`) " @@ -619,9 +588,7 @@ const std::string kDropSchema = "`app_group_non_primary.fk_application_has_functional_group_functional_" "group1_idx`; " "DROP TABLE IF EXISTS `app_group_non_primary`; " - "DROP TABLE IF EXISTS `interior_zone`; " "DROP TABLE IF EXISTS `access_module`; " - "DROP INDEX IF EXISTS `access_module.zone_module`; " "DROP INDEX IF EXISTS `access_module.fk_module_1_idx`; " "DROP INDEX IF EXISTS " "`app_group.fk_application_has_functional_group_application1_idx`; " @@ -674,7 +641,6 @@ const std::string kDeleteData = "DELETE FROM `rpc`; " "DELETE FROM `app_group_primary`; " "DELETE FROM `app_group_non_primary`; " - "DELETE FROM `interior_zone`; " "DELETE FROM `access_module`; " "DELETE FROM `version`; " "DELETE FROM `message_type`; " diff --git a/src/components/policy/policy_external/src/sql_pt_representation.cc b/src/components/policy/policy_external/src/sql_pt_representation.cc index 1732f3c774..1960fb6e03 100644 --- a/src/components/policy/policy_external/src/sql_pt_representation.cc +++ b/src/components/policy/policy_external/src/sql_pt_representation.cc @@ -552,6 +552,12 @@ void SQLPTRepresentation::GatherModuleConfig( *config->vehicle_year = query.GetString(7); *config->preloaded_date = query.GetString(8); *config->certificate = query.GetString(9); +#ifdef SDL_REMOTE_CONTROL + *config->user_consent_passengersRC = + query.IsNull(8) ? true : query.GetBoolean(10); + *config->country_consent_passengersRC = + query.IsNull(9) ? true : query.GetBoolean(11); +#endif // SDL_REMOTE_CONTROL } utils::dbms::SQLQuery endpoints(db()); @@ -764,6 +770,25 @@ bool SQLPTRepresentation::GatherApplicationPoliciesSection( if (!GatherAppGroup(app_id, ¶ms.groups)) { return false; } + +#ifdef SDL_REMOTE_CONTROL + if (!GatherAppGroupPrimary(app_id, &*params.groups_primaryRC)) { + return false; + } + if (!GatherAppGroupNonPrimary(app_id, &*params.groups_nonPrimaryRC)) { + return false; + } + bool denied = false; + if (!GatherRemoteControlDenied(app_id, &denied)) { + return false; + } + if (!denied) { + if (!GatherModuleType(app_id, &*params.moduleType)) { + return false; + } + } +#endif // SDL_REMOTE_CONTROL + if (!GatherNickName(app_id, &*params.nicknames)) { return false; } @@ -953,6 +978,22 @@ bool SQLPTRepresentation::SaveApplicationPoliciesSection( LOG4CXX_WARN(logger_, "Incorrect delete from app_group."); return false; } + +#ifdef SDL_REMOTE_CONTROL + if (!query_delete.Exec(sql_pt::kDeleteAppGroupPrimary)) { + LOG4CXX_WARN(logger_, "Incorrect delete from app_group_primary."); + return false; + } + if (!query_delete.Exec(sql_pt::kDeleteAppGroupNonPrimary)) { + LOG4CXX_WARN(logger_, "Incorrect delete from app_group_non_primary."); + return false; + } + if (!query_delete.Exec(sql_pt::kDeleteModuleTypes)) { + LOG4CXX_WARN(logger_, "Incorrect delete from module_type."); + return false; + } +#endif // SDL_REMOTE_CONTROL + if (!query_delete.Exec(sql_pt::kDeleteApplication)) { LOG4CXX_WARN(logger_, "Incorrect delete from application."); return false; @@ -1033,6 +1074,22 @@ bool SQLPTRepresentation::SaveSpecificAppPolicy( if (!SaveAppGroup(app.first, app.second.groups)) { return false; } + +#ifdef SDL_REMOTE_CONTROL + if (!SaveAppGroupPrimary(app.first, *app.second.groups_primaryRC)) { + return false; + } + if (!SaveAppGroupNonPrimary(app.first, *app.second.groups_nonPrimaryRC)) { + return false; + } + + bool denied = !app.second.moduleType->is_initialized(); + if (!SaveRemoteControlDenied(app.first, denied) || + !SaveModuleType(app.first, *app.second.moduleType)) { + return false; + } +#endif // SDL_REMOTE_CONTROL + if (!SaveNickname(app.first, *app.second.nicknames)) { return false; } @@ -1195,6 +1252,14 @@ bool SQLPTRepresentation::SaveModuleConfig( : query.Bind(8); config.certificate.is_initialized() ? query.Bind(9, *(config.certificate)) : query.Bind(9); +#ifdef SDL_REMOTE_CONTROL + config.user_consent_passengersRC.is_initialized() + ? query.Bind(10, *(config.user_consent_passengersRC)) + : query.Bind(10); + config.country_consent_passengersRC.is_initialized() + ? query.Bind(11, *(config.country_consent_passengersRC)) + : query.Bind(11); +#endif // SDL_REMOTE_CONTROL if (!query.Exec()) { LOG4CXX_WARN(logger_, "Incorrect update module config"); @@ -1596,6 +1661,280 @@ bool SQLPTRepresentation::GatherAppGroup( return true; } +#ifdef SDL_REMOTE_CONTROL +bool SQLPTRepresentation::GatherAppGroupPrimary( + const std::string& app_id, policy_table::Strings* app_groups) const { + dbms::SQLQuery query(db()); + if (!query.Prepare(sql_pt::kSelectAppGroupsPrimary)) { + LOG4CXX_WARN(logger_, "Incorrect select from app groups for primary RC"); + return false; + } + + query.Bind(0, app_id); + while (query.Next()) { + app_groups->push_back(query.GetString(0)); + } + return true; +} + +bool SQLPTRepresentation::GatherAppGroupNonPrimary( + const std::string& app_id, policy_table::Strings* app_groups) const { + dbms::SQLQuery query(db()); + if (!query.Prepare(sql_pt::kSelectAppGroupsNonPrimary)) { + LOG4CXX_WARN(logger_, + "Incorrect select from app groups for non primary RC"); + return false; + } + + query.Bind(0, app_id); + while (query.Next()) { + app_groups->push_back(query.GetString(0)); + } + return true; +} + +bool SQLPTRepresentation::GatherRemoteControlDenied(const std::string& app_id, + bool* denied) const { + LOG4CXX_AUTO_TRACE(logger_); + dbms::SQLQuery query(db()); + if (!query.Prepare(sql_pt::kSelectRemoteControlDenied)) { + LOG4CXX_WARN(logger_, "Incorrect select remote control flag"); + return false; + } + query.Bind(0, app_id); + if (query.Next()) { + *denied = query.GetBoolean(0); + } else { + return false; + } + return true; +} + +bool SQLPTRepresentation::GatherModuleType( + const std::string& app_id, policy_table::ModuleTypes* app_types) const { + dbms::SQLQuery query(db()); + if (!query.Prepare(sql_pt::kSelectModuleTypes)) { + LOG4CXX_WARN(logger_, "Incorrect select from app types"); + return false; + } + + query.Bind(0, app_id); + while (query.Next()) { + policy_table::ModuleType type; + if (!policy_table::EnumFromJsonString(query.GetString(0), &type)) { + return false; + } + app_types->push_back(type); + } + return true; +} + +bool SQLPTRepresentation::SaveAppGroupPrimary( + const std::string& app_id, const policy_table::Strings& app_groups) { + LOG4CXX_AUTO_TRACE(logger_); + dbms::SQLQuery query(db()); + if (!query.Prepare(sql_pt::kInsertAppGroupPrimary)) { + LOG4CXX_WARN(logger_, "Incorrect insert statement for app group primary"); + return false; + } + policy_table::Strings::const_iterator it; + for (it = app_groups.begin(); it != app_groups.end(); ++it) { + std::string ssss = *it; + LOG4CXX_INFO(logger_, "Group: " << ssss); + query.Bind(0, app_id); + query.Bind(1, *it); + if (!query.Exec() || !query.Reset()) { + LOG4CXX_WARN(logger_, + "Incorrect insert into app group primary." + << query.LastError().text()); + return false; + } + } + + return true; +} + +bool SQLPTRepresentation::SaveAppGroupNonPrimary( + const std::string& app_id, const policy_table::Strings& app_groups) { + LOG4CXX_AUTO_TRACE(logger_); + dbms::SQLQuery query(db()); + if (!query.Prepare(sql_pt::kInsertAppGroupNonPrimary)) { + LOG4CXX_WARN(logger_, + "Incorrect insert statement for app group non primary"); + return false; + } + policy_table::Strings::const_iterator it; + for (it = app_groups.begin(); it != app_groups.end(); ++it) { + std::string ssss = *it; + LOG4CXX_INFO(logger_, "Group: " << ssss); + query.Bind(0, app_id); + query.Bind(1, *it); + if (!query.Exec() || !query.Reset()) { + LOG4CXX_WARN(logger_, + "Incorrect insert into app group non primary." + << query.LastError().text()); + return false; + } + } + + return true; +} + +bool SQLPTRepresentation::SaveRemoteControlDenied(const std::string& app_id, + bool deny) { + LOG4CXX_AUTO_TRACE(logger_); + dbms::SQLQuery query(db()); + if (!query.Prepare(sql_pt::kUpdateRemoteControlDenied)) { + LOG4CXX_WARN(logger_, "Incorrect update statement for remote control flag"); + return false; + } + LOG4CXX_DEBUG(logger_, "App: " << app_id << std::boolalpha << " - " << deny); + query.Bind(0, deny); + query.Bind(1, app_id); + if (!query.Exec()) { + LOG4CXX_WARN(logger_, "Incorrect update remote control flag."); + return false; + } + return true; +} + +bool SQLPTRepresentation::SaveModuleType( + const std::string& app_id, const policy_table::ModuleTypes& types) { + dbms::SQLQuery query(db()); + if (!query.Prepare(sql_pt::kInsertModuleType)) { + LOG4CXX_WARN(logger_, "Incorrect insert statement for module type"); + return false; + } + + policy_table::ModuleTypes::const_iterator it; + for (it = types.begin(); it != types.end(); ++it) { + query.Bind(0, app_id); + std::string module(policy_table::EnumToJsonString(*it)); + query.Bind(1, module); + LOG4CXX_DEBUG(logger_, + "Module(app: " << app_id << ", type: " << module << ")"); + if (!query.Exec() || !query.Reset()) { + LOG4CXX_WARN(logger_, "Incorrect insert into module type."); + return false; + } + } + + return true; +} + +bool SQLPTRepresentation::SaveAccessModule( + TypeAccess access, const policy_table::AccessModules& modules) { + LOG4CXX_AUTO_TRACE(logger_); + dbms::SQLQuery query(db()); + if (!query.Prepare(sql_pt::kInsertAccessModule)) { + LOG4CXX_WARN(logger_, "Incorrect insert statement for access module"); + return false; + } + + policy_table::AccessModules::const_iterator i; + for (i = modules.begin(); i != modules.end(); ++i) { + const std::string& name = i->first; + const policy_table::RemoteRpcs& rpcs = i->second; + query.Bind(0, name); + query.Bind(1, access); + if (!query.Exec()) { + LOG4CXX_WARN(logger_, "Incorrect insert into access module."); + return false; + } + int id = query.LastInsertId(); + if (!query.Reset()) { + LOG4CXX_WARN(logger_, "Couldn't reset query access module."); + return false; + } + if (!SaveRemoteRpc(id, rpcs)) { + return false; + } + } + return true; +} + +bool SQLPTRepresentation::GatherAccessModule( + TypeAccess access, policy_table::AccessModules* modules) const { + LOG4CXX_AUTO_TRACE(logger_); + dbms::SQLQuery query(db()); + if (!query.Prepare(sql_pt::kSelectAccessModules)) { + LOG4CXX_WARN(logger_, "Incorrect select from access module"); + return false; + } + + query.Bind(0, access); + while (query.Next()) { + int id = query.GetInteger(0); + std::string name = query.GetString(1); + policy_table::RemoteRpcs rpcs; + if (!GatherRemoteRpc(id, &rpcs)) { + return false; + } + modules->insert(std::make_pair(name, rpcs)); + } + return true; +} + +bool SQLPTRepresentation::SaveRemoteRpc(int module_id, + const policy_table::RemoteRpcs& rpcs) { + LOG4CXX_AUTO_TRACE(logger_); + dbms::SQLQuery query(db()); + if (!query.Prepare(sql_pt::kInsertRemoteRpc)) { + LOG4CXX_WARN(logger_, "Incorrect insert statement for remote rpc"); + return false; + } + policy_table::RemoteRpcs::const_iterator i; + for (i = rpcs.begin(); i != rpcs.end(); ++i) { + const std::string& name = i->first; + const policy_table::Strings& params = i->second; + policy_table::Strings::const_iterator j; + if (params.empty()) { + query.Bind(0, module_id); + query.Bind(1, name); + query.Bind(2); + if (!query.Exec() || !query.Reset()) { + LOG4CXX_WARN(logger_, "Incorrect insert into remote rpc."); + return false; + } + } else { + for (j = params.begin(); j != params.end(); ++j) { + const std::string& param = *j; + query.Bind(0, module_id); + query.Bind(1, name); + query.Bind(2, param); + if (!query.Exec() || !query.Reset()) { + LOG4CXX_WARN(logger_, "Incorrect insert into remote rpc."); + return false; + } + } + } + } + return true; +} + +bool SQLPTRepresentation::GatherRemoteRpc( + int module_id, policy_table::RemoteRpcs* rpcs) const { + LOG4CXX_AUTO_TRACE(logger_); + dbms::SQLQuery query(db()); + if (!query.Prepare(sql_pt::kSelectRemoteRpcs)) { + LOG4CXX_WARN(logger_, "Incorrect select from remote rpc"); + return false; + } + + query.Bind(0, module_id); + while (query.Next()) { + std::string name = query.GetString(0); + if (!query.IsNull(1)) { + std::string parameter = query.GetString(1); + (*rpcs)[name].push_back(parameter); + } else { + rpcs->insert(std::make_pair(name, policy_table::Strings())); + } + } + return true; +} +#endif // SDL_REMOTE_CONTROL + bool SQLPTRepresentation::SaveApplicationCustomData(const std::string& app_id, bool is_revoked, bool is_default, @@ -1681,6 +2020,32 @@ bool SQLPTRepresentation::SetDefaultPolicy(const std::string& app_id) { return false; } +#ifdef SDL_REMOTE_CONTROL + dbms::SQLQuery query_p(db()); + if (!query_p.Prepare(sql_pt::kDeleteAppGroupPrimaryByApplicationId)) { + LOG4CXX_ERROR(logger_, + "Incorrect statement to delete from app_group_primary."); + return false; + } + query_p.Bind(0, app_id); + if (!query_p.Exec()) { + LOG4CXX_ERROR(logger_, "Failed deleting from app_group_primary."); + return false; + } + + dbms::SQLQuery query_np(db()); + if (!query_np.Prepare(sql_pt::kDeleteAppGroupNonPrimaryByApplicationId)) { + LOG4CXX_ERROR(logger_, + "Incorrect statement to delete from app_group_non_primary."); + return false; + } + query_np.Bind(0, app_id); + if (!query_np.Exec()) { + LOG4CXX_ERROR(logger_, "Failed deleting from app_group_non_primary."); + return false; + } +#endif // SDL_REMOTE_CONTROL + if (!CopyApplication(kDefaultId, app_id)) { return false; } @@ -1699,8 +2064,18 @@ bool SQLPTRepresentation::SetDefaultPolicy(const std::string& app_id) { } policy_table::Strings default_groups; - if (GatherAppGroup(kDefaultId, &default_groups) && - SaveAppGroup(app_id, default_groups)) { + bool ret = (GatherAppGroup(kDefaultId, &default_groups) && + SaveAppGroup(app_id, default_groups)); +#ifdef SDL_REMOTE_CONTROL + policy_table::Strings groups_primary; + ret = ret && (GatherAppGroupPrimary(kDefaultId, &groups_primary) && + SaveAppGroupPrimary(app_id, groups_primary)); + policy_table::Strings groups_non_primary; + ret = ret && (GatherAppGroupNonPrimary(kDefaultId, &groups_non_primary) && + SaveAppGroupNonPrimary(app_id, groups_non_primary)); +#endif // SDL_REMOTE_CONTROL + + if (ret) { return SetIsDefault(app_id, true); } return false; diff --git a/src/components/policy/policy_external/test/CMakeLists.txt b/src/components/policy/policy_external/test/CMakeLists.txt index 8b77c90dd2..a455d43b91 100644 --- a/src/components/policy/policy_external/test/CMakeLists.txt +++ b/src/components/policy/policy_external/test/CMakeLists.txt @@ -55,6 +55,12 @@ file (GLOB POLICY_TEST_SOURCES list (REMOVE_ITEM POLICY_TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/policy_manager_impl_stress_test.cc) +if (REMOTE_CONTROL) + list (APPEND testSources + access_remote_impl_test.cc + ) +endif () + create_test("policy_test" "${POLICY_TEST_SOURCES}" "${testLibraries}") #Additional test files (json) diff --git a/src/components/policy/policy_external/test/include/policy/mock_access_remote.h b/src/components/policy/policy_external/test/include/policy/mock_access_remote.h new file mode 100644 index 0000000000..01e48805b6 --- /dev/null +++ b/src/components/policy/policy_external/test/include/policy/mock_access_remote.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2015, 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_POLICY_POLICY_EXTERNAL_TEST_INCLUDE_POLICY_MOCK_ACCESS_REMOTE_H_ +#define SRC_COMPONENTS_POLICY_POLICY_EXTERNAL_TEST_INCLUDE_POLICY_MOCK_ACCESS_REMOTE_H_ + +#include "gmock/gmock.h" +#include "policy/access_remote.h" + +namespace test { +namespace components { +namespace access_remote_test { + +class MockSubject : public policy::Subject { + public: +}; + +class MockObject : public policy::Object { + public: +}; + +class MockAccessRemote : public policy::AccessRemote { + public: + MOCK_METHOD0(Init, void()); + MOCK_METHOD0(Enable, void()); + MOCK_METHOD0(Disable, void()); + MOCK_CONST_METHOD0(IsEnabled, bool()); + MOCK_CONST_METHOD1(IsPrimaryDevice, bool(const policy::PTString& dev_id)); + MOCK_METHOD1(SetPrimaryDevice, void(const policy::PTString& dev_id)); + MOCK_CONST_METHOD0(PrimaryDevice, policy::PTString()); + + MOCK_METHOD2(Allow, + void(const policy::Subject& who, const policy::Object& what)); + MOCK_METHOD2(Deny, + void(const policy::Subject& who, const policy::Object& what)); + MOCK_METHOD1(Reset, void(const policy::Subject& who)); + MOCK_METHOD1(Reset, void(const policy::Object& what)); + MOCK_CONST_METHOD2(Check, + policy::TypeAccess(const policy::Subject& who, + const policy::Object& what)); + MOCK_CONST_METHOD3( + FindGroup, + policy::PTString(const policy::Subject& who, + const policy::PTString& rpc, + const policy::RemoteControlParams& params)); + MOCK_METHOD2(SetDefaultHmiTypes, + void(const policy::Subject& who, + const std::vector<int>& hmi_types)); + MOCK_METHOD1(GetGroups, + const policy_table::Strings&(const policy::Subject& who)); + MOCK_METHOD3(GetPermissionsForApp, + bool(const std::string& device_id, + const std::string& app_id, + policy::FunctionalIdType& group_types)); + MOCK_CONST_METHOD2(CheckModuleType, + bool(const policy::PTString& app_id, + policy_table::ModuleType module)); + MOCK_METHOD1(IsAppRemoteControl, bool(const policy::Subject& who)); + MOCK_METHOD0(Reset, void()); + MOCK_METHOD2(GetModuleTypes, + bool(const std::string& application_id, + std::vector<std::string>* modules)); +}; + +} // namespace access_remote_test +} // namespace components +} // namespace test + +#endif // SRC_COMPONENTS_POLICY_POLICY_EXTERNAL_TEST_INCLUDE_POLICY_MOCK_ACCESS_REMOTE_H_ diff --git a/src/components/policy/policy_external/test/include/policy/mock_app_stopwatch.h b/src/components/policy/policy_external/test/include/policy/mock_app_stopwatch.h new file mode 100644 index 0000000000..397201ce40 --- /dev/null +++ b/src/components/policy/policy_external/test/include/policy/mock_app_stopwatch.h @@ -0,0 +1,53 @@ +/* Copyright (c) 2016, 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_POLICY_POLICY_EXTERNAL_TEST_INCLUDE_POLICY_MOCK_APP_STOPWATCH_H_ +#define SRC_COMPONENTS_POLICY_POLICY_EXTERNAL_TEST_INCLUDE_POLICY_MOCK_APP_STOPWATCH_H_ + +#include "gmock/gmock.h" +#include "policy/usage_statistics/app_stopwatch.h" + +namespace test { +namespace components { +namespace usage_statistics_test { + +class MockAppStopwatch : public usage_statistics::AppStopwatch { + public: + MOCK_METHOD1(Start, void(usage_statistics::AppStopwatchId stopwatch_type)); + MOCK_METHOD1(Switch, void(usage_statistics::AppStopwatchId stopwatch_type)); + MOCK_METHOD0(WriteTime, void()); +}; + +} // namespace usage_statistics_test +} // namespace components +} // namespace test + +#endif // SRC_COMPONENTS_POLICY_POLICY_EXTERNAL_TEST_INCLUDE_POLICY_MOCK_APP_STOPWATCH_H_ diff --git a/src/components/policy/policy_external/test/sql_pt_ext_representation_test.cc b/src/components/policy/policy_external/test/sql_pt_ext_representation_test.cc index 92525c646d..1ece673711 100644 --- a/src/components/policy/policy_external/test/sql_pt_ext_representation_test.cc +++ b/src/components/policy/policy_external/test/sql_pt_ext_representation_test.cc @@ -323,6 +323,8 @@ TEST_F(SQLPTExtRepresentationTest, module_config["vehicle_model"] = Json::Value("ModelT"); module_config["vehicle_year"] = Json::Value("2014"); module_config["certificate"] = Json::Value("my_cert"); + module_config["country_consent_passengersRC"] = Json::Value(false); + module_config["user_consent_passengersRC"] = Json::Value(false); Json::Value& functional_groupings = policy_table["functional_groupings"]; functional_groupings["default"] = Json::Value(Json::objectValue); diff --git a/src/components/policy/policy_external/test/sql_pt_representation_test.cc b/src/components/policy/policy_external/test/sql_pt_representation_test.cc index a0a544deeb..d835a5c389 100644 --- a/src/components/policy/policy_external/test/sql_pt_representation_test.cc +++ b/src/components/policy/policy_external/test/sql_pt_representation_test.cc @@ -85,7 +85,7 @@ class SQLPTRepresentationTest : public SQLPTRepresentation, policy_settings_; static void SetUpTestCase() { - const std::string kAppStorageFolder = "storage1"; + const std::string kAppStorageFolder = "storage_SQLPTRepresentationTest"; reps = new SQLPTRepresentation(in_memory_); ASSERT_TRUE(reps != NULL); policy_settings_ = std::auto_ptr<policy_handler_test::MockPolicySettings>( @@ -407,7 +407,7 @@ TEST_F(SQLPTRepresentationTest, query.Prepare(query_select); query.Next(); - const int policy_tables_number = 35; + const int policy_tables_number = 34; ASSERT_EQ(policy_tables_number, query.GetInteger(0)); const std::string query_select_count_of_iap_buffer_full = @@ -1607,6 +1607,10 @@ TEST_F(SQLPTRepresentationTest, table["policy_table"]["device_data"] = Json::Value(Json::objectValue); table["policy_table"]["module_meta"] = Json::Value(Json::objectValue); table["policy_table"]["module_config"]["preloaded_pt"] = Json::Value(false); + table["policy_table"]["module_config"]["country_consent_passengersRC"] = + Json::Value(false); + table["policy_table"]["module_config"]["user_consent_passengersRC"] = + Json::Value(false); policy_table::Table expected(&table); Json::StyledWriter writer; // Checks diff --git a/src/components/policy/policy_regular/CMakeLists.txt b/src/components/policy/policy_regular/CMakeLists.txt index 76e10a58b0..c7b9c068b9 100644 --- a/src/components/policy/policy_regular/CMakeLists.txt +++ b/src/components/policy/policy_regular/CMakeLists.txt @@ -65,12 +65,17 @@ set(EXCLUDE_PATHS ) set(PATHS - ${CMAKE_CURRENT_SOURCE_DIR}/include/ - ${CMAKE_CURRENT_SOURCE_DIR}/src/ + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/src ${COMPONENTS_DIR}/rpc_base/src/rpc_base/rpc_base.cc ) collect_sources(SOURCES "${PATHS}" "${EXCLUDE_PATHS}") +if (NOT REMOTE_CONTROL) + list(REMOVE_ITEM SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/src/access_remote_impl.cc) +endif() + set(LIBRARIES ConfigProfile policy_struct diff --git a/src/components/policy/policy_regular/include/policy/access_remote.h b/src/components/policy/policy_regular/include/policy/access_remote.h new file mode 100644 index 0000000000..b9fd8862e9 --- /dev/null +++ b/src/components/policy/policy_regular/include/policy/access_remote.h @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2015, 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_POLICY_SRC_POLICY_INCLUDE_POLICY_ACCESS_REMOTE_H_ +#define SRC_COMPONENTS_POLICY_SRC_POLICY_INCLUDE_POLICY_ACCESS_REMOTE_H_ + +#include <vector> +#include <ostream> +#include <string> +#include "policy/policy_table/types.h" +#include "policy/policy_types.h" + +namespace policy_table = ::rpc::policy_table_interface_base; + +namespace policy { + +enum TypeAccess { kDisallowed, kAllowed, kManual }; +inline std::ostream& operator<<(std::ostream& output, TypeAccess x) { + output << "Access: "; + switch (x) { + case kDisallowed: + output << "DISALLOWED"; + break; + case kAllowed: + output << "ALLOWED"; + break; + case kManual: + output << "MANUAL"; + break; + default: + output << "Error: Unknown type"; + } + return output; +} + +struct Subject { + PTString dev_id; + PTString app_id; +}; +inline bool operator<(const Subject& x, const Subject& y) { + return x.dev_id < y.dev_id || (x.dev_id == y.dev_id && x.app_id < y.app_id); +} +inline bool operator==(const Subject& x, const Subject& y) { + return x.dev_id == y.dev_id && x.app_id == y.app_id; +} +inline std::ostream& operator<<(std::ostream& output, const Subject& who) { + output << "Subject(dev:" << who.dev_id << ", app:" << who.app_id << ")"; + return output; +} + +struct Object { + policy_table::ModuleType module; +}; +inline bool operator<(const Object& x, const Object& y) { + return x.module < y.module; +} +inline bool operator==(const Object& x, const Object& y) { + return x.module == y.module; +} +inline std::ostream& operator<<(std::ostream& output, const Object& what) { + output << "Object(module:" << EnumToJsonString(what.module) << ")"; + return output; +} + +typedef std::vector<PTString> RemoteControlParams; + +class AccessRemote { + public: + virtual ~AccessRemote() {} + + /** + * Initializes oneself + */ + virtual void Init() = 0; + + /** + * Enables remote control + */ + virtual void Enable() = 0; + + /** + * Disables remote control + */ + virtual void Disable() = 0; + + /** + * Checks if remote control is enabled + * @return true if enabled + */ + virtual bool IsEnabled() const = 0; + + /** + * Checks whether device is driver's device + * @param dev_id unique device id + * @return true if device is have driver + */ + virtual bool IsPrimaryDevice(const PTString& dev_id) const = 0; + + /** + * Sets device as driver's device + * @param dev_id ID device + */ + virtual void SetPrimaryDevice(const PTString& dev_id) = 0; + + /** + * Gets current primary device + * @return ID device + */ + virtual PTString PrimaryDevice() const = 0; + + /** + * Allows access subject to object + * @param who subject is dev_id and app_id + * @param what object is group_id + */ + virtual void Allow(const Subject& who, const Object& what) = 0; + + /** + * Denies access subject to object + * @param who subject is dev_id and app_id + * @param what object is group_id + */ + virtual void Deny(const Subject& who, const Object& what) = 0; + + /** + * Resets access subject to all object + * @param who subject is dev_id and app_id + */ + virtual void Reset(const Subject& who) = 0; + + /** + * Resets access to object for all subjects + * @param what object is group + */ + virtual void Reset(const Object& what) = 0; + + /* + * Resets all stored consents + */ + virtual void Reset() = 0; + + /** + * Checks access subject to object + * @param who subject is dev_id and app_id + * @param what object is group_id + * @return allowed if access was given, disallowed if access was denied + * manual if need to ask driver + */ + virtual TypeAccess Check(const Subject& who, const Object& what) const = 0; + + /** + * Checks permissions for module + * @param app_id application ID + * @param module type + * @return true if allowed + */ + virtual bool CheckModuleType(const PTString& app_id, + policy_table::ModuleType module) const = 0; + + /** + * Sets HMI types if application has default policy permissions + * @param who subject + * @param hmi_types list of HMI types + */ + virtual void SetDefaultHmiTypes(const Subject& who, + const std::vector<int>& hmi_types) = 0; + + /** + * Gets groups + * @param who subject + * @return list of groups + */ + virtual const policy_table::Strings& GetGroups(const Subject& who) = 0; + + /** + * Gets permissions for application + * @param device_id + * @param app_id + * @param group_types + * @return true if success + */ + virtual bool GetPermissionsForApp(const std::string& device_id, + const std::string& app_id, + FunctionalIdType& group_types) = 0; + + /** + * Checks if application has remote functionality + * @param who subject + * @return true if application uses remote control + */ + virtual bool IsAppRemoteControl(const Subject& who) = 0; + + /** + * Gets all allowed module types + * @param app_id unique identifier of application + * @param list of allowed module types + * @return true if application has allowed modules + */ + virtual bool GetModuleTypes(const std::string& policy_app_id, + std::vector<std::string>* modules) = 0; +}; + +} // namespace policy + +#endif // SRC_COMPONENTS_POLICY_SRC_POLICY_INCLUDE_POLICY_ACCESS_REMOTE_H_ diff --git a/src/components/policy/policy_regular/include/policy/access_remote_impl.h b/src/components/policy/policy_regular/include/policy/access_remote_impl.h new file mode 100644 index 0000000000..03427d2501 --- /dev/null +++ b/src/components/policy/policy_regular/include/policy/access_remote_impl.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2015, 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_POLICY_SRC_POLICY_INCLUDE_POLICY_ACCESS_REMOTE_IMPL_H_ +#define SRC_COMPONENTS_POLICY_SRC_POLICY_INCLUDE_POLICY_ACCESS_REMOTE_IMPL_H_ + +#include <map> +#include "policy/policy_table/types.h" +#include "utils/macro.h" +#include "utils/shared_ptr.h" +#include "policy/access_remote.h" +#include "policy/cache_manager.h" + +using policy_table::FunctionalGroupings; + +namespace policy { + +class AccessRemoteImpl : public AccessRemote { + public: + typedef std::map<Subject, TypeAccess> AccessControlRow; + typedef std::map<Object, AccessControlRow> AccessControlList; + typedef std::map<Subject, policy_table::AppHMITypes> HMIList; + + AccessRemoteImpl(); + explicit AccessRemoteImpl(utils::SharedPtr<CacheManager> cache); + + virtual void Init(); + virtual void Enable(); + virtual void Disable(); + virtual bool IsEnabled() const; + + virtual bool IsPrimaryDevice(const PTString& dev_id) const; + virtual void SetPrimaryDevice(const PTString& dev_id); + virtual PTString PrimaryDevice() const; + + virtual void Allow(const Subject& who, const Object& what); + virtual void Deny(const Subject& who, const Object& what); + virtual void Reset(const Subject& who); + virtual void Reset(const Object& what); + virtual void Reset(); + virtual TypeAccess Check(const Subject& who, const Object& what) const; + virtual bool CheckModuleType(const PTString& app_id, + policy_table::ModuleType module) const; + virtual void SetDefaultHmiTypes(const Subject& who, + const std::vector<int>& hmi_types); + virtual const policy_table::Strings& GetGroups(const Subject& who); + virtual bool GetPermissionsForApp(const std::string& device_id, + const std::string& app_id, + FunctionalIdType& group_types); + virtual bool IsAppRemoteControl(const Subject& who); + virtual bool GetModuleTypes(const std::string& policy_app_id, + std::vector<std::string>* modules); + + private: + inline void set_enabled(bool value); + inline bool country_consent() const; + const policy_table::AppHMITypes& HmiTypes(const Subject& who); + void GetGroupsIds(const std::string& device_id, + const std::string& app_id, + FunctionalGroupIDs& grops_ids); + bool IsAllowed(const policy_table::AccessModules& modules, + const std::string& module_name, + const std::string& rpc_name, + RemoteControlParams* input) const; + bool CompareParameters(const policy_table::Strings& parameters, + RemoteControlParams* input) const; + utils::SharedPtr<CacheManager> cache_; + PTString primary_device_; + bool enabled_; + AccessControlList acl_; + HMIList hmi_types_; + +#ifdef BUILD_TESTS + friend struct Erase; + friend struct IsTypeAccess; + + FRIEND_TEST(AccessRemoteImplTest, KeyMapTest); + FRIEND_TEST(AccessRemoteImplTest, Allow); + FRIEND_TEST(AccessRemoteImplTest, Deny); + FRIEND_TEST(AccessRemoteImplTest, ChangeAccess); + FRIEND_TEST(AccessRemoteImplTest, ResetBySubject); + FRIEND_TEST(AccessRemoteImplTest, ResetByObject); + FRIEND_TEST(AccessRemoteImplTest, CheckAllowed); + FRIEND_TEST(AccessRemoteImplTest, CheckDisallowed); + FRIEND_TEST(AccessRemoteImplTest, CheckManual); + FRIEND_TEST(AccessRemoteImplTest, CheckModuleType); + FRIEND_TEST(AccessRemoteImplTest, EnableDisable); + FRIEND_TEST(AccessRemoteImplTest, SetDefaultHmiTypes); + FRIEND_TEST(AccessRemoteImplTest, GetGroups); +#endif // BUILD_TESTS +}; + +} // namespace policy + +#endif // SRC_COMPONENTS_POLICY_SRC_POLICY_INCLUDE_POLICY_ACCESS_REMOTE_IMPL_H_ diff --git a/src/components/policy/policy_regular/include/policy/cache_manager.h b/src/components/policy/policy_regular/include/policy/cache_manager.h index 73c010ce33..c5d4c848f4 100644 --- a/src/components/policy/policy_regular/include/policy/cache_manager.h +++ b/src/components/policy/policy_regular/include/policy/cache_manager.h @@ -325,6 +325,13 @@ class CacheManager : public CacheManagerInterface { bool GetDefaultHMI(const std::string& app_id, std::string& default_hmi) const; /** + * Gets HMI types from specific policy + * @param app_id ID application + * @return list of HMI types + */ + const policy_table::AppHMITypes* GetHMITypes(const std::string& app_id); + + /** * @brief Reset user consent for device data and applications permissions * @return */ @@ -690,11 +697,9 @@ class CacheManager : public CacheManagerInterface { const PolicySettings& get_settings() const; -#ifdef BUILD_TESTS - utils::SharedPtr<policy_table::Table> GetPT() const { + utils::SharedPtr<policy_table::Table> pt() const { return pt_; } -#endif private: std::string currentDateTime(); @@ -767,6 +772,13 @@ class CacheManager : public CacheManagerInterface { sync_primitives::Lock backuper_locker_; BackgroundBackuper* backuper_; const PolicySettings* settings_; + +#ifdef BUILD_TESTS + friend class AccessRemoteImpl; + FRIEND_TEST(AccessRemoteImplTest, CheckModuleType); + FRIEND_TEST(AccessRemoteImplTest, EnableDisable); + FRIEND_TEST(AccessRemoteImplTest, GetGroups); +#endif // BUILD_TESTS }; } // namespace policy #endif // SRC_COMPONENTS_POLICY_POLICY_REGULAR_INCLUDE_POLICY_CACHE_MANAGER_H_ diff --git a/src/components/policy/policy_regular/include/policy/cache_manager_interface.h b/src/components/policy/policy_regular/include/policy/cache_manager_interface.h index 50896bb8f1..9712b799dc 100644 --- a/src/components/policy/policy_regular/include/policy/cache_manager_interface.h +++ b/src/components/policy/policy_regular/include/policy/cache_manager_interface.h @@ -323,6 +323,14 @@ class CacheManagerInterface { std::string& default_hmi) const = 0; /** + * Gets HMI types from specific policy + * @param app_id ID application + * @return list of HMI types + */ + virtual const policy_table::AppHMITypes* GetHMITypes( + const std::string& app_id) = 0; + + /** * @brief Reset user consent for device data and applications permissions * @return */ @@ -626,15 +634,13 @@ class CacheManagerInterface { */ virtual std::string GetCertificate() const = 0; -#ifdef BUILD_TESTS /** - * @brief GetPT allows to obtain SharedPtr to PT. + * @brief pt allows to obtain SharedPtr to PT. * Used ONLY in Unit tests * @return SharedPTR to PT * */ - virtual utils::SharedPtr<policy_table::Table> GetPT() const = 0; -#endif + virtual utils::SharedPtr<policy_table::Table> pt() const = 0; }; typedef utils::SharedPtr<CacheManagerInterface> CacheManagerInterfaceSPtr; diff --git a/src/components/policy/policy_regular/include/policy/policy_helper.h b/src/components/policy/policy_regular/include/policy/policy_helper.h index 996c2917d0..ce1288fa1b 100644 --- a/src/components/policy/policy_regular/include/policy/policy_helper.h +++ b/src/components/policy/policy_regular/include/policy/policy_helper.h @@ -243,6 +243,22 @@ FunctionalGroupIDs FindSame(const FunctionalGroupIDs& first, * @return true, if succeded, otherwise - false */ bool UnwrapAppPolicies(policy_table::ApplicationPolicies& app_policies); + +#ifdef SDL_REMOTE_CONTROL + +struct ProccessAppGroups { + ProccessAppGroups(const policy_table::ApplicationPolicies& apps, + PolicyManagerImpl* pm) + : new_apps_(apps), pm_(pm), default_(new_apps_.find(kDefaultId)) {} + void operator()(const policy_table::ApplicationPolicies::value_type& app); + + private: + const policy_table::ApplicationPolicies& new_apps_; + PolicyManagerImpl* pm_; + policy_table::ApplicationPolicies::const_iterator default_; +}; + +#endif // SDL_REMOTE_CONTROL } #endif // SRC_COMPONENTS_POLICY_POLICY_REGULAR_INCLUDE_POLICY_POLICY_HELPER_H_ diff --git a/src/components/policy/policy_regular/include/policy/policy_manager_impl.h b/src/components/policy/policy_regular/include/policy/policy_manager_impl.h index 3ca9994a8a..868328bcb4 100644 --- a/src/components/policy/policy_regular/include/policy/policy_manager_impl.h +++ b/src/components/policy/policy_regular/include/policy/policy_manager_impl.h @@ -47,6 +47,10 @@ #include "policy/usage_statistics/statistics_manager.h" #include "policy/policy_helper.h" #include "utils/timer.h" +#ifdef SDL_REMOTE_CONTROL +#include "policy/access_remote.h" +#include "policy/access_remote_impl.h" +#endif // SDL_REMOTE_CONTROL namespace policy_table = rpc::policy_table_interface_base; @@ -176,6 +180,39 @@ class PolicyManagerImpl : public PolicyManager { StatusNotifier AddApplication( const std::string& application_id, const rpc::policy_table_interface_base::AppHmiTypes& hmi_types); +#ifdef SDL_REMOTE_CONTROL + void SetDefaultHmiTypes(const std::string& application_id, + const std::vector<int>& hmi_types); + /** + * Gets HMI types + * @param application_id ID application + * @param app_types list to save HMI types + * @return true if policy has specific policy for this application + */ + virtual bool GetHMITypes(const std::string& application_id, + std::vector<int>* app_types) OVERRIDE; + virtual void set_access_remote(utils::SharedPtr<AccessRemote> access_remote); + TypeAccess CheckDriverConsent(const Subject& who, + const Object& what, + const std::string& rpc, + const RemoteControlParams& params); + void CheckPTUUpdatesChange( + const utils::SharedPtr<policy_table::Table> pt_update, + const utils::SharedPtr<policy_table::Table> snapshot); + bool CheckPTURemoteCtrlChange( + const utils::SharedPtr<policy_table::Table> pt_update, + const utils::SharedPtr<policy_table::Table> snapshot); + + void CheckRemoteGroupsChange( + const utils::SharedPtr<policy_table::Table> pt_update, + const utils::SharedPtr<policy_table::Table> snapshot); + + void SendHMILevelChanged(const Subject& who); + void UpdateDeviceRank(const Subject& who, const std::string& rank); + + void OnPrimaryGroupsChanged(const std::string& application_id); + void OnNonPrimaryGroupsChanged(const std::string& application_id); +#endif // SDL_REMOTE_CONTROL virtual void RemoveAppConsentForGroup(const std::string& app_id, const std::string& group_name); @@ -319,10 +356,43 @@ class PolicyManagerImpl : public PolicyManager { void RetrySequence(); private: +#ifdef SDL_REMOTE_CONTROL + void GetPermissions(const std::string device_id, + const std::string application_id, + Permissions* data); + virtual TypeAccess CheckAccess(const PTString& device_id, + const PTString& app_id, + const PTString& module, + const PTString& rpc, + const RemoteControlParams& params); + virtual bool CheckModule(const PTString& app_id, const PTString& module); + virtual void SetAccess(const PTString& dev_id, + const PTString& app_id, + const PTString& module, + bool allowed); + virtual void ResetAccess(const PTString& dev_id, const PTString& app_id); + virtual void ResetAccess(const PTString& module); + virtual void SetPrimaryDevice(const PTString& dev_id); + virtual void ResetPrimaryDevice(); + virtual PTString PrimaryDevice() const; + virtual void SetRemoteControl(bool enabled); + virtual bool GetRemoteControl() const; + virtual void OnChangedPrimaryDevice(const std::string& device_id, + const std::string& application_id); + virtual void OnChangedRemoteControl(const std::string& device_id, + const std::string& application_id); + virtual void SendAppPermissionsChanged(const std::string& device_id, + const std::string& application_id); + virtual bool GetModuleTypes(const std::string& policy_app_id, + std::vector<std::string>* modules) const; +#endif // SDL_REMOTE_CONTROL PolicyListener* listener_; UpdateStatusManager update_status_manager_; CacheManagerInterfaceSPtr cache_; +#ifdef SDL_REMOTE_CONTROL + utils::SharedPtr<AccessRemote> access_remote_; +#endif sync_primitives::Lock apps_registration_lock_; sync_primitives::Lock app_permissions_diff_lock_; std::map<std::string, AppPermissions> app_permissions_diff_; diff --git a/src/components/policy/policy_regular/include/policy/policy_table/types.h b/src/components/policy/policy_regular/include/policy/policy_table/types.h index 8b9a872a5b..d9d2ad34eb 100644 --- a/src/components/policy/policy_regular/include/policy/policy_table/types.h +++ b/src/components/policy/policy_regular/include/policy/policy_table/types.h @@ -96,6 +96,12 @@ typedef Map<DeviceParams, 0, 255> DeviceData; typedef Array<Enum<RequestType>, 0, 255> RequestTypes; +#ifdef SDL_REMOTE_CONTROL +typedef Map<Strings, 0, 255> RemoteRpcs; +typedef Map<RemoteRpcs, 0, 255> AccessModules; +typedef Array<Enum<ModuleType>, 0, 255> ModuleTypes; +#endif // SDL_REMOTE_CONTROL + typedef AppHMIType AppHmiType; typedef std::vector<AppHMIType> AppHmiTypes; @@ -136,6 +142,11 @@ struct ApplicationParams : PolicyBase { Optional<Integer<uint16_t, 0, 65225> > memory_kb; Optional<Integer<uint32_t, 0, UINT_MAX> > heart_beat_timeout_ms; Optional<String<0, 255> > certificate; +#ifdef SDL_REMOTE_CONTROL + Optional<Strings> groups_primaryRC; + Optional<Strings> groups_nonPrimaryRC; + mutable Optional<ModuleTypes> moduleType; +#endif // SDL_REMOTE_CONTROL public: ApplicationParams(); @@ -151,6 +162,9 @@ struct ApplicationParams : PolicyBase { private: bool Validate() const; +#ifdef SDL_REMOTE_CONTROL + bool ValidateModuleTypes() const; +#endif // SDL_REMOTE_CONTROL }; struct ApplicationPoliciesSection : CompositeType { @@ -233,6 +247,10 @@ struct ModuleConfig : CompositeType { Optional<String<4, 4> > vehicle_year; Optional<String<0, 10> > preloaded_date; Optional<String<0, 65535> > certificate; +#ifdef SDL_REMOTE_CONTROL + Optional<Boolean> user_consent_passengersRC; + Optional<Boolean> country_consent_passengersRC; +#endif // SDL_REMOTE_CONTROL public: ModuleConfig(); diff --git a/src/components/policy/policy_regular/include/policy/policy_types.h b/src/components/policy/policy_regular/include/policy/policy_types.h index 25aa126a03..09df043197 100644 --- a/src/components/policy/policy_regular/include/policy/policy_types.h +++ b/src/components/policy/policy_regular/include/policy/policy_types.h @@ -56,6 +56,7 @@ const std::string kDefaultDeviceConnectionType = "UNKNOWN"; */ const std::string kPreDataConsentId = "pre_DataConsent"; const std::string kDefaultId = "default"; +const std::string kPreConsentPassengersRC = "pre_consent_passengersRC"; const std::string kDeviceId = "device"; /* diff --git a/src/components/policy/policy_regular/include/policy/sql_pt_queries.h b/src/components/policy/policy_regular/include/policy/sql_pt_queries.h index 79a66ba41a..20f5d5aed4 100644 --- a/src/components/policy/policy_regular/include/policy/sql_pt_queries.h +++ b/src/components/policy/policy_regular/include/policy/sql_pt_queries.h @@ -114,6 +114,27 @@ extern const std::string kInsertApplicationFull; extern const std::string kDeletePreconsentedGroupsByApplicationId; extern const std::string kSelectApplicationFull; extern const std::string kUpdatePreloaded; +extern const std::string kUpdateRemoteControlDenied; +extern const std::string kSelectRemoteControlDenied; +extern const std::string kDeleteAppGroupPrimaryByApplicationId; +extern const std::string kDeleteAppGroupNonPrimaryByApplicationId; +extern const std::string kCollectFriendlyMsg; +extern const std::string kSelectAppGroupsPrimary; +extern const std::string kSelectAppGroupsNonPrimary; +extern const std::string kSelectModuleTypes; +extern const std::string kInsertAppGroupPrimary; +extern const std::string kInsertAppGroupNonPrimary; +extern const std::string kInsertModuleType; +extern const std::string kInsertAccessModule; +extern const std::string kSelectAccessModules; +extern const std::string kDeleteAccessModules; +extern const std::string kInsertRemoteRpc; +extern const std::string kSelectRemoteRpcs; +extern const std::string kDeleteRemoteRpc; +extern const std::string kDeleteAppGroupPrimary; +extern const std::string kDeleteAppGroupNonPrimary; +extern const std::string kDeleteModuleTypes; +extern const std::string kDeleteAllDevices; extern const std::string kSelectDBVersion; extern const std::string kUpdateDBVersion; extern const std::string kSaveModuleMeta; diff --git a/src/components/policy/policy_regular/include/policy/sql_pt_representation.h b/src/components/policy/policy_regular/include/policy/sql_pt_representation.h index bd867389ab..e152c040b1 100644 --- a/src/components/policy/policy_regular/include/policy/sql_pt_representation.h +++ b/src/components/policy/policy_regular/include/policy/sql_pt_representation.h @@ -97,6 +97,31 @@ class SQLPTRepresentation : public virtual PTRepresentation { } #endif // BUILD_TESTS protected: +#ifdef SDL_REMOTE_CONTROL + enum TypeAccess { kAllowed, kManual }; + bool GatherAppGroupPrimary(const std::string& app_id, + policy_table::Strings* app_groups) const; + bool GatherAppGroupNonPrimary(const std::string& app_id, + policy_table::Strings* app_groups) const; + bool GatherModuleType(const std::string& app_id, + policy_table::ModuleTypes* module_types) const; + bool GatherRemoteControlDenied(const std::string& app_id, bool* denied) const; + bool GatherAccessModule(TypeAccess access, + policy_table::AccessModules* modules) const; + bool GatherRemoteRpc(int module_id, policy_table::RemoteRpcs* rpcs) const; + bool SaveAppGroupPrimary(const std::string& app_id, + const policy_table::Strings& app_groups); + bool SaveAppGroupNonPrimary(const std::string& app_id, + const policy_table::Strings& app_groups); + bool SaveModuleType(const std::string& app_id, + const policy_table::ModuleTypes& types); + bool SaveRemoteControlDenied(const std::string& app_id, bool deny); + + bool SaveAccessModule(TypeAccess access, + const policy_table::AccessModules& modules); + bool SaveRemoteRpc(int module_id, const policy_table::RemoteRpcs& rpcs); +#endif // SDL_REMOTE_CONTROL + virtual void GatherModuleMeta(policy_table::ModuleMeta* meta) const; virtual void GatherModuleConfig(policy_table::ModuleConfig* config) const; virtual bool GatherUsageAndErrorCounts( diff --git a/src/components/policy/policy_regular/src/access_remote_impl.cc b/src/components/policy/policy_regular/src/access_remote_impl.cc new file mode 100644 index 0000000000..9ae76fc19a --- /dev/null +++ b/src/components/policy/policy_regular/src/access_remote_impl.cc @@ -0,0 +1,377 @@ +/* + * Copyright (c) 2015, 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 "policy/access_remote_impl.h" + +#include <algorithm> +#include <iterator> +#include "policy/cache_manager.h" +#include "utils/logger.h" + +CREATE_LOGGERPTR_GLOBAL(logger_, "PolicyManagerImpl") + +using policy_table::DeviceData; +using policy_table::FunctionalGroupings; +using rpc::policy_table_interface_base::EnumFromJsonString; + +namespace policy { + +struct Erase { + private: + const Subject& who_; + + public: + explicit Erase(const Subject& who) : who_(who) {} + void operator()(AccessRemoteImpl::AccessControlList::value_type& row) const { + row.second.erase(who_); + } +}; + +struct IsTypeAccess { + private: + const TypeAccess& type_; + + public: + explicit IsTypeAccess(const TypeAccess& type) : type_(type) {} + bool operator()( + const AccessRemoteImpl::AccessControlRow::value_type& item) const { + return item.second == type_; + } +}; + +struct ToHMIType { + policy_table::AppHMITypes::value_type operator()(int item) const { + policy_table::AppHMIType type = static_cast<policy_table::AppHMIType>(item); + if (!IsValidEnum(type)) { + LOG4CXX_WARN(logger_, "HMI type isn't known " << item); + type = policy_table::AHT_DEFAULT; + } + LOG4CXX_DEBUG(logger_, + "HMI type: " << item << " - " << EnumToJsonString(type)); + return policy_table::AppHMITypes::value_type(type); + } +}; + +struct Contained { + private: + const policy_table::Strings& params_; + + public: + explicit Contained(const policy_table::Strings& params) : params_(params) {} + bool operator()(const RemoteControlParams::value_type& item) const { + return std::find_if(params_.begin(), params_.end(), CompareString(item)) != + params_.end(); + } + struct CompareString { + private: + const RemoteControlParams::value_type& value_; + + public: + explicit CompareString(const RemoteControlParams::value_type& value) + : value_(value) {} + bool operator()(const policy_table::Strings::value_type& item) const { + return value_ == static_cast<std::string>(item); + } + }; +}; + +struct ToModuleType { + std::string operator()(policy_table::ModuleTypes::value_type item) const { + policy_table::ModuleType type = static_cast<policy_table::ModuleType>(item); + return EnumToJsonString(type); + } +}; + +AccessRemoteImpl::AccessRemoteImpl() + : cache_(new CacheManager()), primary_device_(), enabled_(true), acl_() {} + +AccessRemoteImpl::AccessRemoteImpl(utils::SharedPtr<CacheManager> cache) + : cache_(cache), primary_device_(), enabled_(true), acl_() {} + +void AccessRemoteImpl::Init() { + LOG4CXX_AUTO_TRACE(logger_); + DCHECK(cache_->pt()); + + policy_table::ModuleConfig& config = cache_->pt()->policy_table.module_config; + enabled_ = country_consent() && + (!config.user_consent_passengersRC.is_initialized() || + *config.user_consent_passengersRC); +} + +bool AccessRemoteImpl::IsPrimaryDevice(const PTString& dev_id) const { + LOG4CXX_AUTO_TRACE(logger_); + return primary_device_ == dev_id; +} + +TypeAccess AccessRemoteImpl::Check(const Subject& who, + const Object& what) const { + LOG4CXX_AUTO_TRACE(logger_); + AccessControlList::const_iterator i = acl_.find(what); + if (i != acl_.end()) { + const AccessControlRow& row = i->second; + AccessControlRow::const_iterator j = row.find(who); + if (j != row.end()) { + // who has permissions + TypeAccess ret = j->second; + LOG4CXX_TRACE(logger_, + "Subject " << who << " has permissions " << ret + << " to object " << what); + return ret; + } + } + return TypeAccess::kManual; +} + +bool AccessRemoteImpl::CheckModuleType(const PTString& app_id, + policy_table::ModuleType module) const { + LOG4CXX_AUTO_TRACE(logger_); + if (!cache_->IsApplicationRepresented(app_id)) { + return false; + } + + const policy_table::ApplicationParams& app = + cache_->pt()->policy_table.app_policies_section.apps[app_id]; + if (!app.moduleType.is_initialized()) { + return false; + } + + const policy_table::ModuleTypes& modules = *app.moduleType; + if (modules.empty()) { + return true; + } + + return std::find(modules.begin(), modules.end(), module) != modules.end(); +} + +bool AccessRemoteImpl::IsAllowed(const policy_table::AccessModules& modules, + const std::string& module_name, + const std::string& rpc_name, + RemoteControlParams* input) const { + LOG4CXX_AUTO_TRACE(logger_); + policy_table::AccessModules::const_iterator i = modules.find(module_name); + if (i == modules.end()) { + LOG4CXX_DEBUG(logger_, "Module " << module_name << " wasn't found"); + return false; + } + + const policy_table::RemoteRpcs& rpcs = i->second; + if (rpcs.empty()) { + return true; + } + policy_table::RemoteRpcs::const_iterator j = rpcs.find(rpc_name); + if (j != rpcs.end()) { + const policy_table::Strings& parameters = j->second; + return CompareParameters(parameters, input); + } + LOG4CXX_DEBUG(logger_, "RPC " << rpc_name << " wasn't found"); + return false; +} + +bool AccessRemoteImpl::CompareParameters( + const policy_table::Strings& parameters, RemoteControlParams* input) const { + LOG4CXX_AUTO_TRACE(logger_); + if (parameters.empty()) { + return true; + } + + if (input->empty()) { + LOG4CXX_DEBUG(logger_, "Input is empty"); + return false; + } + + input->erase( + std::remove_if(input->begin(), input->end(), Contained(parameters)), + input->end()); + return input->empty(); +} + +void AccessRemoteImpl::Allow(const Subject& who, const Object& what) { + LOG4CXX_AUTO_TRACE(logger_); + acl_[what][who] = TypeAccess::kAllowed; +} + +void AccessRemoteImpl::Deny(const Subject& who, const Object& what) { + LOG4CXX_AUTO_TRACE(logger_); + acl_[what][who] = TypeAccess::kDisallowed; +} + +void AccessRemoteImpl::Reset(const Subject& who) { + LOG4CXX_AUTO_TRACE(logger_); + std::for_each(acl_.begin(), acl_.end(), Erase(who)); +} + +void AccessRemoteImpl::Reset(const Object& what) { + LOG4CXX_AUTO_TRACE(logger_); + acl_.erase(what); +} + +void AccessRemoteImpl::Reset() { + acl_.clear(); +} + +void AccessRemoteImpl::SetPrimaryDevice(const PTString& dev_id) { + LOG4CXX_AUTO_TRACE(logger_); + primary_device_ = dev_id; +} + +PTString AccessRemoteImpl::PrimaryDevice() const { + return primary_device_; +} + +void AccessRemoteImpl::Enable() { + LOG4CXX_AUTO_TRACE(logger_); + set_enabled(true); +} + +void AccessRemoteImpl::Disable() { + LOG4CXX_AUTO_TRACE(logger_); + set_enabled(false); +} + +void AccessRemoteImpl::set_enabled(bool value) { + enabled_ = country_consent() && value; + *cache_->pt()->policy_table.module_config.user_consent_passengersRC = value; + cache_->Backup(); +} + +bool AccessRemoteImpl::country_consent() const { + policy_table::ModuleConfig& config = cache_->pt()->policy_table.module_config; + return !config.country_consent_passengersRC.is_initialized() || + *config.country_consent_passengersRC; +} + +bool AccessRemoteImpl::IsEnabled() const { + LOG4CXX_AUTO_TRACE(logger_); + return enabled_; +} + +void AccessRemoteImpl::SetDefaultHmiTypes(const Subject& who, + const std::vector<int>& hmi_types) { + LOG4CXX_AUTO_TRACE(logger_); + HMIList::mapped_type types; + std::transform(hmi_types.begin(), + hmi_types.end(), + std::back_inserter(types), + ToHMIType()); + hmi_types_[who] = types; +} + +const policy_table::AppHMITypes& AccessRemoteImpl::HmiTypes( + const Subject& who) { + LOG4CXX_AUTO_TRACE(logger_); + if (cache_->IsDefaultPolicy(who.app_id)) { + return hmi_types_[who]; + } else { + return *cache_->pt() + ->policy_table.app_policies_section.apps[who.app_id] + .AppHMIType; + } +} + +const policy_table::Strings& AccessRemoteImpl::GetGroups(const Subject& who) { + LOG4CXX_AUTO_TRACE(logger_); + if (IsAppRemoteControl(who)) { + if (IsPrimaryDevice(who.dev_id)) { + return *cache_->pt() + ->policy_table.app_policies_section.apps[who.app_id] + .groups_primaryRC; + } else if (IsEnabled()) { + return *cache_->pt() + ->policy_table.app_policies_section.apps[who.app_id] + .groups_nonPrimaryRC; + } else { + return cache_->GetGroups(kPreConsentPassengersRC); + } + } + return cache_->GetGroups(who.app_id); +} + +bool AccessRemoteImpl::IsAppRemoteControl(const Subject& who) { + LOG4CXX_AUTO_TRACE(logger_); + const policy_table::AppHMITypes& hmi_types = HmiTypes(who); + return std::find(hmi_types.begin(), + hmi_types.end(), + policy_table::AHT_REMOTE_CONTROL) != hmi_types.end(); +} + +bool AccessRemoteImpl::GetPermissionsForApp(const std::string& device_id, + const std::string& app_id, + FunctionalIdType& group_types) { + LOG4CXX_AUTO_TRACE(logger_); + GetGroupsIds(device_id, app_id, group_types[kTypeGeneral]); + GetGroupsIds(device_id, kDefaultId, group_types[kTypeDefault]); + GetGroupsIds( + device_id, kPreDataConsentId, group_types[kTypePreDataConsented]); + return true; +} + +std::ostream& operator<<(std::ostream& output, + const FunctionalGroupIDs& types) { + std::copy(types.begin(), + types.end(), + std::ostream_iterator<FunctionalGroupIDs::value_type>(output, " ")); + return output; +} + +void AccessRemoteImpl::GetGroupsIds(const std::string& device_id, + const std::string& app_id, + FunctionalGroupIDs& groups_ids) { + Subject who = {device_id, app_id}; + const policy_table::Strings& groups = GetGroups(who); + groups_ids.resize(groups.size()); + std::transform(groups.begin(), + groups.end(), + groups_ids.begin(), + &CacheManager::GenerateHash); + LOG4CXX_DEBUG(logger_, "Groups Ids: " << groups_ids); +} + +bool AccessRemoteImpl::GetModuleTypes(const std::string& application_id, + std::vector<std::string>* modules) { + DCHECK(modules); + policy_table::ApplicationPolicies& apps = + cache_->pt()->policy_table.app_policies_section.apps; + policy_table::ApplicationPolicies::iterator i = apps.find(application_id); + if (i == apps.end()) { + return false; + } + rpc::Optional<policy_table::ModuleTypes> moduleTypes = i->second.moduleType; + if (!moduleTypes.is_initialized()) { + return false; + } + std::transform(moduleTypes->begin(), + moduleTypes->end(), + std::back_inserter(*modules), + ToModuleType()); + return true; +} + +} // namespace policy diff --git a/src/components/policy/policy_regular/src/cache_manager.cc b/src/components/policy/policy_regular/src/cache_manager.cc index 6184320306..decf526677 100644 --- a/src/components/policy/policy_regular/src/cache_manager.cc +++ b/src/components/policy/policy_regular/src/cache_manager.cc @@ -127,6 +127,17 @@ uint32_t CacheManager::HeartBeatTimeout(const std::string& app_id) const { return result; } +const policy_table::AppHMITypes* CacheManager::GetHMITypes( + const std::string& app_id) { + const policy_table::ApplicationPolicies& apps = + pt_->policy_table.app_policies_section.apps; + policy_table::ApplicationPolicies::const_iterator i = apps.find(app_id); + if (i != apps.end()) { + return &(*i->second.AppHMIType); + } + return NULL; +} + bool CacheManager::CanAppStealFocus(const std::string& app_id) const { CACHE_MANAGER_CHECK(false); bool result = true; @@ -136,8 +147,8 @@ bool CacheManager::CanAppStealFocus(const std::string& app_id) const { bool CacheManager::GetDefaultHMI(const std::string& app_id, std::string& default_hmi) const { CACHE_MANAGER_CHECK(false); - bool result = true; - return result; + default_hmi = "NONE"; + return true; } bool CacheManager::ResetUserConsent() { diff --git a/src/components/policy/policy_regular/src/policy_helper.cc b/src/components/policy/policy_regular/src/policy_helper.cc index b72a041a83..7ee8153e8b 100644 --- a/src/components/policy/policy_regular/src/policy_helper.cc +++ b/src/components/policy/policy_regular/src/policy_helper.cc @@ -802,4 +802,53 @@ bool UnwrapAppPolicies(policy_table::ApplicationPolicies& app_policies) { return true; } + +#ifdef SDL_REMOTE_CONTROL +bool HaveGroupsChanged(const rpc::Optional<policy_table::Strings>& old_groups, + const rpc::Optional<policy_table::Strings>& new_groups) { + if (!old_groups.is_initialized() && !new_groups.is_initialized()) { + return false; + } + if (!old_groups.is_initialized() || !new_groups.is_initialized()) { + return true; + } + policy_table::Strings old_groups_abs = *old_groups; + policy_table::Strings new_groups_abs = *new_groups; + if (old_groups_abs.size() != new_groups_abs.size()) { + return true; + } + std::sort(new_groups_abs.begin(), new_groups_abs.end(), Compare); + std::sort(old_groups_abs.begin(), old_groups_abs.end(), Compare); + + return std::equal(new_groups_abs.begin(), + new_groups_abs.end(), + old_groups_abs.begin(), + Compare); +} + +void ProccessAppGroups::operator()( + const policy_table::ApplicationPolicies::value_type& app) { + policy_table::ApplicationPolicies::const_iterator i = + new_apps_.find(app.first); + if (i == new_apps_.end() && default_ != new_apps_.end()) { + i = default_; + } + if (i != new_apps_.end()) { + if (HaveGroupsChanged(i->second.groups_primaryRC, + app.second.groups_primaryRC)) { + LOG4CXX_DEBUG(logger_, + "Primary groups for " << app.first << " have changed"); + + pm_->OnPrimaryGroupsChanged(app.first); + } + if (HaveGroupsChanged(i->second.groups_nonPrimaryRC, + app.second.groups_nonPrimaryRC)) { + LOG4CXX_DEBUG(logger_, + "Non-primary groups for " << app.first << " have changed"); + pm_->OnNonPrimaryGroupsChanged(app.first); + } + } +} + +#endif // SDL_REMOTE_CONTROL } diff --git a/src/components/policy/policy_regular/src/policy_manager_impl.cc b/src/components/policy/policy_regular/src/policy_manager_impl.cc index f05ac9cb67..562539eb0c 100644 --- a/src/components/policy/policy_regular/src/policy_manager_impl.cc +++ b/src/components/policy/policy_regular/src/policy_manager_impl.cc @@ -51,6 +51,11 @@ #include "utils/timer_task_impl.h" #include "utils/make_shared.h" +#ifdef SDL_REMOTE_CONTROL +#include "policy/access_remote.h" +#include "policy/access_remote_impl.h" +#endif // SDL_REMOTE_CONTROL + policy::PolicyManager* CreateManager() { return new policy::PolicyManagerImpl(); } @@ -71,6 +76,10 @@ PolicyManagerImpl::PolicyManagerImpl() : PolicyManager() , listener_(NULL) , cache_(new CacheManager) +#ifdef SDL_REMOTE_CONTROL + , access_remote_(new AccessRemoteImpl( + CacheManagerInterfaceSPtr::static_pointer_cast<CacheManager>(cache_))) +#endif // SDL_REMOTE_CONTROL , retry_sequence_timeout_(kDefaultRetryTimeoutInMSec) , retry_sequence_index_(0) , timer_retry_sequence_("Retry sequence timer", @@ -80,7 +89,8 @@ PolicyManagerImpl::PolicyManagerImpl() , retry_sequence_url_(0, 0, "") , wrong_ptu_update_received_(false) , send_on_update_sent_out_(false) - , trigger_ptu_(false) {} + , trigger_ptu_(false) { +} void PolicyManagerImpl::set_listener(PolicyListener* listener) { listener_ = listener; @@ -204,6 +214,10 @@ bool PolicyManagerImpl::LoadPT(const std::string& file, listener_->OnCertificateUpdated( *(pt_update->policy_table.module_config.certificate)); } +#ifdef SDL_REMOTE_CONTROL + access_remote_->Init(); + CheckPTUUpdatesChange(pt_update, policy_table_snapshot); +#endif // SDL_REMOTE_CONTROL std::map<std::string, StringArray> app_hmi_types; cache_->GetHMIAppTypeAfterUpdate(app_hmi_types); @@ -381,7 +395,13 @@ void PolicyManagerImpl::CheckPermissions(const PTString& device_id, "CheckPermissions for " << app_id << " and rpc " << rpc << " for " << hmi_level << " level."); +#ifdef SDL_REMOTE_CONTROL + Subject who = {device_id, app_id}; + const policy_table::Strings& groups = access_remote_->GetGroups(who); +#else // SDL_REMOTE_CONTROL const policy_table::Strings& groups = cache_->GetGroups(app_id); +#endif // SDL_REMOTE_CONTROL + cache_->CheckPermissions(groups, hmi_level, rpc, result); if (cache_->IsApplicationRevoked(app_id)) { // SDL must be able to notify mobile side with its status after app has @@ -438,6 +458,17 @@ void PolicyManagerImpl::SendNotificationOnPermissionsUpdated( std::string default_hmi; default_hmi = "NONE"; +#ifdef SDL_REMOTE_CONTROL + const Subject who = {device_id, application_id}; + if (access_remote_->IsAppRemoteControl(who)) { + const std::string rank = + access_remote_->IsPrimaryDevice(who.dev_id) ? "DRIVER" : "PASSENGER"; + UpdateDeviceRank(who, rank); + listener()->OnPermissionsUpdated(application_id, notification_data); + return; + } +#endif // SDL_REMOTE_CONTROL + listener()->OnPermissionsUpdated( application_id, notification_data, default_hmi); } @@ -674,7 +705,16 @@ void PolicyManagerImpl::GetPermissionsForApp( } FunctionalIdType group_types; - if (!cache_->GetPermissionsForApp(device_id, app_id_to_check, group_types)) { +#ifdef SDL_REMOTE_CONTROL + allowed_by_default = false; + bool ret = access_remote_->GetPermissionsForApp( + device_id, policy_app_id, group_types); +#else + bool ret = + cache_->GetPermissionsForApp(device_id, app_id_to_check, group_types); +#endif // REMOTE_CONTROL + + if (!ret) { LOG4CXX_WARN(logger_, "Can't get user permissions for app " << policy_app_id); return; @@ -1020,6 +1060,7 @@ StatusNotifier PolicyManagerImpl::AddApplication( return utils::MakeShared<utils::CallNothing>(); } } + void PolicyManagerImpl::RemoveAppConsentForGroup( const std::string& app_id, const std::string& group_name) { cache_->RemoveAppConsentForGroup(app_id, group_name); @@ -1093,6 +1134,9 @@ bool PolicyManagerImpl::InitPT(const std::string& file_name, if (ret) { RefreshRetrySequence(); update_status_manager_.OnPolicyInit(cache_->UpdateRequired()); +#ifdef SDL_REMOTE_CONTROL + access_remote_->Init(); +#endif // SDL_REMOTE_CONTROL } return ret; } @@ -1127,4 +1171,336 @@ void PolicyManagerImpl::RetrySequence() { timer_retry_sequence_.Start(timeout_msec, timer::kPeriodic); } +#ifdef SDL_REMOTE_CONTROL +void PolicyManagerImpl::SetDefaultHmiTypes(const std::string& application_id, + const std::vector<int>& hmi_types) { + LOG4CXX_INFO(logger_, "SetDefaultHmiTypes"); + const std::string device_id = GetCurrentDeviceId(application_id); + Subject who = {device_id, application_id}; + access_remote_->SetDefaultHmiTypes(who, hmi_types); +} + +struct HMITypeToInt { + int operator()(const policy_table::AppHMITypes::value_type item) { + return policy_table::AppHMIType(item); + } +}; + +bool PolicyManagerImpl::GetHMITypes(const std::string& application_id, + std::vector<int>* app_types) { + LOG4CXX_AUTO_TRACE(logger_); + if (cache_->IsDefaultPolicy(application_id)) { + return false; + } + const policy_table::AppHMITypes* hmi_types = + cache_->GetHMITypes(application_id); + if (hmi_types) { + std::transform(hmi_types->begin(), + hmi_types->end(), + std::back_inserter(*app_types), + HMITypeToInt()); + } + return hmi_types; +} + +TypeAccess PolicyManagerImpl::CheckAccess(const PTString& device_id, + const PTString& app_id, + const PTString& module, + const PTString& rpc, + const RemoteControlParams& params) { + LOG4CXX_AUTO_TRACE(logger_); + LOG4CXX_DEBUG(logger_, "Module type: " << module); + + policy_table::ModuleType module_type; + bool is_valid = EnumFromJsonString(module, &module_type); + if (is_valid && access_remote_->CheckModuleType(app_id, module_type)) { + if (access_remote_->IsPrimaryDevice(device_id)) { + return TypeAccess::kAllowed; + } else { + Subject who = {device_id, app_id}; + Object what = {module_type}; + return CheckDriverConsent(who, what, rpc, params); + } + } + LOG4CXX_DEBUG(logger_, TypeAccess::kDisallowed); + return TypeAccess::kDisallowed; +} + +bool PolicyManagerImpl::CheckModule(const PTString& app_id, + const PTString& module) { + LOG4CXX_AUTO_TRACE(logger_); + policy_table::ModuleType module_type; + return EnumFromJsonString(module, &module_type) && + access_remote_->CheckModuleType(app_id, module_type); +} + +TypeAccess PolicyManagerImpl::CheckDriverConsent( + const Subject& who, + const Object& what, + const std::string& rpc, + const RemoteControlParams& params) { + LOG4CXX_AUTO_TRACE(logger_); + if (!access_remote_->IsEnabled()) { + return TypeAccess::kDisallowed; + } + + return access_remote_->Check(who, what); +} + +void PolicyManagerImpl::SetAccess(const PTString& dev_id, + const PTString& app_id, + const PTString& module, + bool allowed) { + LOG4CXX_AUTO_TRACE(logger_); + policy_table::ModuleType module_type; + bool is_valid = EnumFromJsonString(module, &module_type); + if (!is_valid) { + return; + } + + Subject who = {dev_id, app_id}; + Object what = {module_type}; + LOG4CXX_DEBUG(logger_, + "Driver's consent: " << who << ", " << what << " is " + << std::boolalpha << allowed); + if (allowed) { + access_remote_->Allow(who, what); + } else { + access_remote_->Deny(who, what); + } +} + +void PolicyManagerImpl::ResetAccess(const PTString& dev_id, + const PTString& app_id) { + LOG4CXX_AUTO_TRACE(logger_); + Subject who = {dev_id, app_id}; + access_remote_->Reset(who); +} + +void PolicyManagerImpl::ResetAccess(const PTString& module) { + LOG4CXX_AUTO_TRACE(logger_); + policy_table::ModuleType module_type; + bool is_valid = EnumFromJsonString(module, &module_type); + if (!is_valid) { + return; + } + + Object what = {module_type}; + access_remote_->Reset(what); +} + +void PolicyManagerImpl::SetPrimaryDevice(const PTString& dev_id) { + LOG4CXX_AUTO_TRACE(logger_); + access_remote_->SetPrimaryDevice(dev_id); +} + +void PolicyManagerImpl::ResetPrimaryDevice() { + LOG4CXX_AUTO_TRACE(logger_); + access_remote_->SetPrimaryDevice(""); +} + +PTString PolicyManagerImpl::PrimaryDevice() const { + LOG4CXX_AUTO_TRACE(logger_); + return access_remote_->PrimaryDevice(); +} + +void PolicyManagerImpl::SetRemoteControl(bool enabled) { + LOG4CXX_AUTO_TRACE(logger_); + if (enabled) { + access_remote_->Enable(); + } else { + access_remote_->Disable(); + } +} + +bool PolicyManagerImpl::GetRemoteControl() const { + return access_remote_->IsEnabled(); +} + +void PolicyManagerImpl::OnChangedPrimaryDevice( + const std::string& device_id, const std::string& application_id) { + LOG4CXX_AUTO_TRACE(logger_); + Subject who = {device_id, application_id}; + if (!access_remote_->IsAppRemoteControl(who)) { + LOG4CXX_INFO(logger_, "Application " << who << " isn't remote"); + return; + } + + const std::string rank = + access_remote_->IsPrimaryDevice(who.dev_id) ? "DRIVER" : "PASSENGER"; + UpdateDeviceRank(who, rank); + SendAppPermissionsChanged(who.dev_id, who.app_id); +} + +void PolicyManagerImpl::OnChangedRemoteControl( + const std::string& device_id, const std::string& application_id) { + LOG4CXX_AUTO_TRACE(logger_); + Subject who = {device_id, application_id}; + if (!access_remote_->IsAppRemoteControl(who)) { + LOG4CXX_INFO(logger_, "Application " << who << " isn't remote"); + return; + } + + if (access_remote_->IsPrimaryDevice(who.dev_id)) { + LOG4CXX_INFO(logger_, "Device " << who.dev_id << " is primary"); + return; + } + + if (!access_remote_->IsEnabled()) { + SendHMILevelChanged(who); + } + + SendAppPermissionsChanged(who.dev_id, who.app_id); +} + +void PolicyManagerImpl::UpdateDeviceRank(const Subject& who, + const std::string& rank) { + std::string default_hmi("NONE"); + if (GetDefaultHmi(who.app_id, &default_hmi)) { + access_remote_->Reset(who); + listener()->OnUpdateHMIStatus(who.dev_id, who.app_id, default_hmi, rank); + } else { + LOG4CXX_WARN(logger_, + "Couldn't get default HMI level for application " + << who.app_id); + } +} + +void PolicyManagerImpl::SendHMILevelChanged(const Subject& who) { + std::string default_hmi("NONE"); + if (GetDefaultHmi(who.app_id, &default_hmi)) { + access_remote_->Reset(who); + listener()->OnUpdateHMIStatus(who.dev_id, who.app_id, default_hmi); + } else { + LOG4CXX_WARN(logger_, + "Couldn't get default HMI level for application " + << who.app_id); + } +} + +void PolicyManagerImpl::GetPermissions(const std::string device_id, + const std::string application_id, + Permissions* data) { + LOG4CXX_AUTO_TRACE(logger_); + DCHECK(data); + std::vector<FunctionalGroupPermission> app_group_permissions; + GetPermissionsForApp(device_id, application_id, app_group_permissions); + + policy_table::FunctionalGroupings functional_groupings; + cache_->GetFunctionalGroupings(functional_groupings); + + policy_table::Strings app_groups; + std::vector<FunctionalGroupPermission>::const_iterator it = + app_group_permissions.begin(); + std::vector<FunctionalGroupPermission>::const_iterator it_end = + app_group_permissions.end(); + for (; it != it_end; ++it) { + app_groups.push_back((*it).group_name); + } + + PrepareNotificationData( + functional_groupings, app_groups, app_group_permissions, *data); +} + +void PolicyManagerImpl::SendAppPermissionsChanged( + const std::string& device_id, const std::string& application_id) { + Permissions notification_data; + GetPermissions(device_id, application_id, ¬ification_data); + listener()->OnPermissionsUpdated(application_id, notification_data); +} + +void PolicyManagerImpl::CheckPTUUpdatesChange( + const utils::SharedPtr<policy_table::Table> pt_update, + const utils::SharedPtr<policy_table::Table> snapshot) { + CheckPTURemoteCtrlChange(pt_update, snapshot); + CheckRemoteGroupsChange(pt_update, snapshot); +} + +bool PolicyManagerImpl::CheckPTURemoteCtrlChange( + const utils::SharedPtr<policy_table::Table> pt_update, + const utils::SharedPtr<policy_table::Table> snapshot) { + LOG4CXX_AUTO_TRACE(logger_); + + rpc::Optional<rpc::Boolean>& new_consent = + pt_update->policy_table.module_config.country_consent_passengersRC; + rpc::Optional<rpc::Boolean>& old_consent = + snapshot->policy_table.module_config.country_consent_passengersRC; + + if (!new_consent.is_initialized() && !old_consent.is_initialized()) { + return false; + } + + bool result = false; + if (new_consent.is_initialized() && old_consent.is_initialized()) { + result = (*new_consent != *old_consent); + } else { + bool not_changed_consent1 = !new_consent.is_initialized() && *old_consent; + bool not_changed_consent2 = !old_consent.is_initialized() && *new_consent; + + result = !(not_changed_consent1 || not_changed_consent2); + } + + if (result) { + listener()->OnRemoteAllowedChanged(result); + } + + return result; +} + +void PolicyManagerImpl::CheckRemoteGroupsChange( + const utils::SharedPtr<policy_table::Table> pt_update, + const utils::SharedPtr<policy_table::Table> snapshot) { + LOG4CXX_AUTO_TRACE(logger_); + + policy_table::ApplicationPolicies& new_apps = + pt_update->policy_table.app_policies_section.apps; + policy_table::ApplicationPolicies& old_apps = + snapshot->policy_table.app_policies_section.apps; + std::for_each( + old_apps.begin(), old_apps.end(), ProccessAppGroups(new_apps, this)); +} + +void PolicyManagerImpl::OnPrimaryGroupsChanged( + const std::string& application_id) { + const std::vector<std::string> devices = + listener()->GetDevicesIds(application_id); + for (std::vector<std::string>::const_iterator i = devices.begin(); + i != devices.end(); + ++i) { + const Subject who = {*i, application_id}; + if (access_remote_->IsAppRemoteControl(who) && + access_remote_->IsPrimaryDevice(who.dev_id)) { + SendAppPermissionsChanged(who.dev_id, who.app_id); + } + } +} + +void PolicyManagerImpl::OnNonPrimaryGroupsChanged( + const std::string& application_id) { + const std::vector<std::string> devices = + listener()->GetDevicesIds(application_id); + for (std::vector<std::string>::const_iterator i = devices.begin(); + i != devices.end(); + ++i) { + const Subject who = {*i, application_id}; + if (access_remote_->IsAppRemoteControl(who) && + !access_remote_->IsPrimaryDevice(who.dev_id) && + access_remote_->IsEnabled()) { + SendAppPermissionsChanged(who.dev_id, who.app_id); + } + } +} + +bool PolicyManagerImpl::GetModuleTypes( + const std::string& application_id, + std::vector<std::string>* modules) const { + return access_remote_->GetModuleTypes(application_id, modules); +} + +void PolicyManagerImpl::set_access_remote( + utils::SharedPtr<AccessRemote> access_remote) { + access_remote_ = access_remote; +} +#endif // SDL_REMOTE_CONTROL + } // namespace policy diff --git a/src/components/policy/policy_regular/src/policy_table/enums.cc b/src/components/policy/policy_regular/src/policy_table/enums.cc index 6de065148a..e0f77be989 100644 --- a/src/components/policy/policy_regular/src/policy_table/enums.cc +++ b/src/components/policy/policy_regular/src/policy_table/enums.cc @@ -326,6 +326,8 @@ bool IsValidEnum(AppHMIType val) { return true; case AHT_PROJECTION: return true; + case AHT_REMOTE_CONTROL: + return true; default: return false; } @@ -354,6 +356,8 @@ const char* EnumToJsonString(AppHMIType val) { return "SYSTEM"; case AHT_PROJECTION: return "PROJECTION"; + case AHT_REMOTE_CONTROL: + return "REMOTE_CONTROL"; default: return ""; } @@ -392,6 +396,9 @@ bool EnumFromJsonString(const std::string& literal, AppHMIType* result) { } else if ("PROJECTION" == literal) { *result = AHT_PROJECTION; return true; + } else if ("REMOTE_CONTROL" == literal) { + *result = AHT_REMOTE_CONTROL; + return true; } else { return false; } @@ -576,6 +583,41 @@ bool EnumFromJsonString(const std::string& literal, RequestType* result) { } } +#ifdef SDL_REMOTE_CONTROL +bool IsValidEnum(ModuleType val) { + switch (val) { + case MT_CLIMATE: + return true; + case MT_RADIO: + return true; + default: + return false; + } +} +const char* EnumToJsonString(ModuleType val) { + switch (val) { + case MT_CLIMATE: + return "CLIMATE"; + case MT_RADIO: + return "RADIO"; + default: + return ""; + } +} + +bool EnumFromJsonString(const std::string& literal, ModuleType* result) { + if ("CLIMATE" == literal) { + *result = MT_CLIMATE; + return true; + } else if ("RADIO" == literal) { + *result = MT_RADIO; + return true; + } else { + return false; + } +} +#endif // SDL_REMOTE_CONTROL + const std::string kDefaultApp = "default"; const std::string kPreDataConsentApp = "pre_DataConsent"; const std::string kDeviceApp = "device"; diff --git a/src/components/policy/policy_regular/src/policy_table/types.cc b/src/components/policy/policy_regular/src/policy_table/types.cc index 7928973919..2c445d4bff 100644 --- a/src/components/policy/policy_regular/src/policy_table/types.cc +++ b/src/components/policy/policy_regular/src/policy_table/types.cc @@ -166,7 +166,14 @@ ApplicationParams::ApplicationParams(const Json::Value* value__) , RequestType(impl::ValueMember(value__, "RequestType")) , memory_kb(impl::ValueMember(value__, "memory_kb"), 0) , heart_beat_timeout_ms(impl::ValueMember(value__, "heart_beat_timeout_ms")) - , certificate(impl::ValueMember(value__, "certificate"), "not_specified") {} + , certificate(impl::ValueMember(value__, "certificate"), "not_specified") +#ifdef SDL_REMOTE_CONTROL + , groups_primaryRC(impl::ValueMember(value__, "groups_primaryRC")) + , groups_nonPrimaryRC(impl::ValueMember(value__, "groups_nonPrimaryRC")) + , moduleType(impl::ValueMember(value__, "moduleType")) +#endif // SDL_REMOTE_CONTROL +{ +} Json::Value ApplicationParams::ToJsonValue() const { Json::Value result__(PolicyBase::ToJsonValue()); @@ -177,6 +184,11 @@ Json::Value ApplicationParams::ToJsonValue() const { impl::WriteJsonField("memory_kb", memory_kb, &result__); impl::WriteJsonField( "heart_beat_timeout_ms", heart_beat_timeout_ms, &result__); +#ifdef SDL_REMOTE_CONTROL + impl::WriteJsonField("groups_primaryRC", groups_primaryRC, &result__); + impl::WriteJsonField("groups_nonPrimaryRC", groups_nonPrimaryRC, &result__); + impl::WriteJsonField("moduleType", moduleType, &result__); +#endif // SDL_REMOTE_CONTROL return result__; } @@ -204,6 +216,17 @@ bool ApplicationParams::is_valid() const { if (!certificate.is_valid()) { return false; } +#ifdef SDL_REMOTE_CONTROL + if (!groups_primaryRC.is_valid()) { + return false; + } + if (!groups_nonPrimaryRC.is_valid()) { + return false; + } + if (!moduleType.is_valid()) { + return false; + } +#endif // SDL_REMOTE_CONTROL return Validate(); } @@ -236,6 +259,17 @@ bool ApplicationParams::struct_empty() const { if (certificate.is_initialized()) { return false; } +#ifdef SDL_REMOTE_CONTROL + if (groups_primaryRC.is_initialized()) { + return false; + } + if (groups_nonPrimaryRC.is_initialized()) { + return false; + } + if (moduleType.is_initialized()) { + return false; + } +#endif // SDL_REMOTE_CONTROL return true; } @@ -268,6 +302,19 @@ void ApplicationParams::ReportErrors(rpc::ValidationReport* report__) const { if (!certificate.is_valid()) { certificate.ReportErrors(&report__->ReportSubobject("certificate")); } +#ifdef SDL_REMOTE_CONTROL + if (!groups_primaryRC.is_valid()) { + groups_primaryRC.ReportErrors( + &report__->ReportSubobject("groups_primaryRC")); + } + if (!groups_nonPrimaryRC.is_valid()) { + groups_nonPrimaryRC.ReportErrors( + &report__->ReportSubobject("groups_nonPrimaryRC")); + } + if (!moduleType.is_valid()) { + moduleType.ReportErrors(&report__->ReportSubobject("moduleType")); + } +#endif // SDL_REMOTE_CONTROL } void ApplicationParams::SetPolicyTableType(PolicyTableType pt_type) { @@ -278,6 +325,11 @@ void ApplicationParams::SetPolicyTableType(PolicyTableType pt_type) { memory_kb.SetPolicyTableType(pt_type); heart_beat_timeout_ms.SetPolicyTableType(pt_type); certificate.SetPolicyTableType(pt_type); +#ifdef SDL_REMOTE_CONTROL + groups_primaryRC.SetPolicyTableType(pt_type); + groups_nonPrimaryRC.SetPolicyTableType(pt_type); + moduleType.SetPolicyTableType(pt_type); +#endif // SDL_REMOTE_CONTROL } // RpcParameters methods @@ -430,7 +482,15 @@ ModuleConfig::ModuleConfig(const Json::Value* value__) , vehicle_model(impl::ValueMember(value__, "vehicle_model")) , vehicle_year(impl::ValueMember(value__, "vehicle_year")) , preloaded_date(impl::ValueMember(value__, "preloaded_date")) - , certificate(impl::ValueMember(value__, "certificate")) {} + , certificate(impl::ValueMember(value__, "certificate")) +#ifdef SDL_REMOTE_CONTROL + , user_consent_passengersRC( + impl::ValueMember(value__, "user_consent_passengersRC")) + , country_consent_passengersRC( + impl::ValueMember(value__, "country_consent_passengersRC")) +#endif // SDL_REMOTE_CONTROL +{ +} void ModuleConfig::SafeCopyFrom(const ModuleConfig& from) { // device_certificates = from.device_certificates; // According to the @@ -448,6 +508,11 @@ void ModuleConfig::SafeCopyFrom(const ModuleConfig& from) { vehicle_model.assign_if_valid(from.vehicle_model); vehicle_year.assign_if_valid(from.vehicle_year); certificate.assign_if_valid(from.certificate); +#ifdef SDL_REMOTE_CONTROL + user_consent_passengersRC.assign_if_valid(from.user_consent_passengersRC); + country_consent_passengersRC.assign_if_valid( + from.country_consent_passengersRC); +#endif // SDL_REMOTE_CONTROL } Json::Value ModuleConfig::ToJsonValue() const { @@ -473,6 +538,12 @@ Json::Value ModuleConfig::ToJsonValue() const { impl::WriteJsonField("vehicle_year", vehicle_year, &result__); impl::WriteJsonField("certificate", certificate, &result__); impl::WriteJsonField("preloaded_date", preloaded_date, &result__); +#ifdef SDL_REMOTE_CONTROL + impl::WriteJsonField( + "user_consent_passengersRC", user_consent_passengersRC, &result__); + impl::WriteJsonField( + "country_consent_passengersRC", country_consent_passengersRC, &result__); +#endif // SDL_REMOTE_CONTROL return result__; } bool ModuleConfig::is_valid() const { @@ -515,6 +586,14 @@ bool ModuleConfig::is_valid() const { if (!preloaded_date.is_valid()) { return false; } +#ifdef SDL_REMOTE_CONTROL + if (!user_consent_passengersRC.is_valid()) { + return false; + } + if (!country_consent_passengersRC.is_valid()) { + return false; + } +#endif // SDL_REMOTE_CONTROL return Validate(); } bool ModuleConfig::is_initialized() const { @@ -559,7 +638,14 @@ bool ModuleConfig::struct_empty() const { if (vehicle_year.is_initialized()) { return false; } - +#ifdef SDL_REMOTE_CONTROL + if (user_consent_passengersRC.is_initialized()) { + return false; + } + if (country_consent_passengersRC.is_initialized()) { + return false; + } +#endif // SDL_REMOTE_CONTROL return true; } void ModuleConfig::ReportErrors(rpc::ValidationReport* report__) const { @@ -609,6 +695,16 @@ void ModuleConfig::ReportErrors(rpc::ValidationReport* report__) const { if (!vehicle_year.is_valid()) { vehicle_year.ReportErrors(&report__->ReportSubobject("vehicle_year")); } +#ifdef SDL_REMOTE_CONTROL + if (!user_consent_passengersRC.is_valid()) { + user_consent_passengersRC.ReportErrors( + &report__->ReportSubobject("user_consent_passengersRC")); + } + if (!country_consent_passengersRC.is_valid()) { + country_consent_passengersRC.ReportErrors( + &report__->ReportSubobject("country_consent_passengersRC")); + } +#endif // SDL_REMOTE_CONTROL if (PT_PRELOADED == GetPolicyTableType()) { std::string validation_info = omitted_validation_info + PolicyTableTypeToString(GetPolicyTableType()); @@ -625,6 +721,13 @@ void ModuleConfig::ReportErrors(rpc::ValidationReport* report__) const { omitted_field_report = &report__->ReportSubobject("vehicle_model"); omitted_field_report->set_validation_info(validation_info); } +#ifdef SDL_REMOTE_CONTROL + if (user_consent_passengersRC.is_initialized()) { + omitted_field_report = + &report__->ReportSubobject("user_consent_passengersRC"); + omitted_field_report->set_validation_info(validation_info); + } +#endif // SDL_REMOTE_CONTROL } } @@ -641,6 +744,10 @@ void ModuleConfig::SetPolicyTableType(PolicyTableType pt_type) { vehicle_make.SetPolicyTableType(pt_type); vehicle_model.SetPolicyTableType(pt_type); vehicle_year.SetPolicyTableType(pt_type); +#ifdef SDL_REMOTE_CONTROL + user_consent_passengersRC.SetPolicyTableType(pt_type); + country_consent_passengersRC.SetPolicyTableType(pt_type); +#endif // SDL_REMOTE_CONTROL } // MessageString methods diff --git a/src/components/policy/policy_regular/src/policy_table/validation.cc b/src/components/policy/policy_regular/src/policy_table/validation.cc index 18a30d9f77..10b8e4bf7c 100644 --- a/src/components/policy/policy_regular/src/policy_table/validation.cc +++ b/src/components/policy/policy_regular/src/policy_table/validation.cc @@ -114,14 +114,46 @@ bool ApplicationPoliciesSection::Validate() const { return true; } -bool ApplicationParams::Validate() const { - // Check for empty "groups" sub-sections - if (groups.empty()) { - return false; +#ifdef SDL_REMOTE_CONTROL +bool ApplicationParams::ValidateModuleTypes() const { + // moduleType is optional so see Optional<T>::is_valid() + bool is_initialized = moduleType->is_initialized(); + if (!is_initialized) { + // valid if not initialized + return true; + } + bool is_valid = moduleType->is_valid(); + if (is_valid) { + return true; + } + + struct IsInvalid { + bool operator()(Enum<ModuleType> item) const { + return !item.is_valid(); + } + }; + // cut invalid items + moduleType->erase( + std::remove_if(moduleType->begin(), moduleType->end(), IsInvalid()), + moduleType->end()); + bool empty = moduleType->empty(); + if (empty) { + // set non initialized value + ModuleTypes non_initialized; + moduleType = Optional<ModuleTypes>(non_initialized); } return true; } +bool ApplicationParams::Validate() const { + return ValidateModuleTypes(); +} +#else // SDL_REMOTE_CONTROL +bool ApplicationParams::Validate() const { + return true; +} +#endif // SDL_REMOTE_CONTROL + bool RpcParameters::Validate() const { return true; } diff --git a/src/components/policy/policy_regular/src/sql_pt_queries.cc b/src/components/policy/policy_regular/src/sql_pt_queries.cc index df4bc74cc2..d573e79816 100644 --- a/src/components/policy/policy_regular/src/sql_pt_queries.cc +++ b/src/components/policy/policy_regular/src/sql_pt_queries.cc @@ -71,7 +71,9 @@ const std::string kCreateSchema = " `certificate` TEXT, " " `vehicle_make` VARCHAR(45), " " `vehicle_model` VARCHAR(45), " - " `vehicle_year` VARCHAR(4) " + " `vehicle_year` VARCHAR(4), " + " `user_consent_passengersRC` BOOL, " + " `country_consent_passengersRC` BOOL " "); " "CREATE TABLE IF NOT EXISTS `functional_group`( " " `id` INTEGER PRIMARY KEY NOT NULL, " @@ -134,6 +136,7 @@ const std::string kCreateSchema = " `memory_kb` INTEGER NOT NULL, " " `heart_beat_timeout_ms` INTEGER NOT NULL, " " `certificate` VARCHAR(45), " + " `remote_control_denied` BOOLEAN NOT NULL DEFAULT 0, " " CONSTRAINT `fk_application_hmi_level1` " " FOREIGN KEY(`default_hmi`) " " REFERENCES `hmi_level`(`value`), " @@ -316,6 +319,78 @@ const std::string kCreateSchema = " FOREIGN KEY(`message_type_name`) " " REFERENCES `message_type`(`name`) " "); " + + "CREATE TABLE IF NOT EXISTS `app_group_primary`( " + " `application_id` VARCHAR(45) NOT NULL, " + " `functional_group_id` INTEGER NOT NULL, " + " PRIMARY KEY(`application_id`,`functional_group_id`), " + " CONSTRAINT `fk_application_has_functional_group_application1` " + " FOREIGN KEY(`application_id`) " + " REFERENCES `application`(`id`), " + " CONSTRAINT `fk_application_has_functional_group_functional_group1` " + " FOREIGN KEY(`functional_group_id`) " + " REFERENCES `functional_group`(`id`) " + "); " + "CREATE INDEX IF NOT EXISTS " + "`app_group_primary.fk_application_has_functional_group_functional_group1_" + "idx` " + " ON `app_group_primary`(`functional_group_id`); " + "CREATE INDEX IF NOT EXISTS " + "`app_group_primary.fk_application_has_functional_group_application1_idx` " + " ON `app_group_primary`(`application_id`); " + + "CREATE TABLE IF NOT EXISTS `app_group_non_primary`( " + " `application_id` VARCHAR(45) NOT NULL, " + " `functional_group_id` INTEGER NOT NULL, " + " PRIMARY KEY(`application_id`,`functional_group_id`), " + " CONSTRAINT `fk_application_has_functional_group_application1` " + " FOREIGN KEY(`application_id`) " + " REFERENCES `application`(`id`), " + " CONSTRAINT `fk_application_has_functional_group_functional_group1` " + " FOREIGN KEY(`functional_group_id`) " + " REFERENCES `functional_group`(`id`) " + "); " + "CREATE INDEX IF NOT EXISTS " + "`app_group_non_primary.fk_application_has_functional_group_functional_" + "group1_idx` " + " ON `app_group_non_primary`(`functional_group_id`); " + "CREATE INDEX IF NOT EXISTS " + "`app_group_non_primary.fk_application_has_functional_group_application1_" + "idx` " + " ON `app_group_non_primary`(`application_id`); " + + /* access_module */ + "CREATE TABLE `access_module`( " + " `id` INTEGER PRIMARY KEY NOT NULL, " + " `name` VARCHAR(45) NOT NULL, " + " `user_consent_needed` INTEGER NOT NULL " + "); " + + /* remote_rpc */ + "CREATE TABLE `remote_rpc`( " + " `id` INTEGER PRIMARY KEY NOT NULL, " + " `name` VARCHAR(255) NOT NULL, " + " `parameter` VARCHAR(45), " + " `module_id` INTEGER NOT NULL, " + "CONSTRAINT `fk_remote_rpc_1` " + " FOREIGN KEY(`module_id`) " + " REFERENCES `access_module`(`id`) " + "); " + "CREATE INDEX `remote_rpc.fk_remote_rpc_1_idx` ON " + "`remote_rpc`(`module_id`); " + + /* module type */ + "CREATE TABLE IF NOT EXISTS `module_type`( " + " `name` VARCHAR(50) NOT NULL, " + " `application_id` VARCHAR(45) NOT NULL, " + " PRIMARY KEY(`name`,`application_id`), " + " CONSTRAINT `fk_module_type_application1` " + " FOREIGN KEY(`application_id`) " + " REFERENCES `application`(`id`) " + "); " + "CREATE INDEX IF NOT EXISTS `module_type.fk_module_type_application1_idx` " + " ON `module_type`(`application_id`); " + "CREATE INDEX IF NOT EXISTS `message.fk_messages_languages1_idx` " " ON `message`(`language_code`);" "CREATE INDEX IF NOT EXISTS " @@ -353,8 +428,79 @@ const std::string kInsertInitData = "INSERT OR IGNORE INTO `_internal_data` (`db_version_hash`) VALUES(0); " ""; +const std::string kDeleteAppGroupPrimary = "DELETE FROM `app_group_primary`"; + +const std::string kDeleteAppGroupNonPrimary = + "DELETE FROM `app_group_non_primary`"; + +const std::string kDeleteModuleTypes = "DELETE FROM `module_type`"; + +const std::string kDeleteAllDevices = "DELETE FROM `device`;"; + +const std::string kSelectAppGroupsPrimary = + "SELECT `f`.`name` FROM `app_group_primary` AS `a`" + " LEFT JOIN `functional_group` AS `f` " + " ON (`f`.`id` = `a`.`functional_group_id`)" + " WHERE `a`.`application_id` = ?"; + +const std::string kSelectAppGroupsNonPrimary = + "SELECT `f`.`name` FROM `app_group_non_primary` AS `a`" + " LEFT JOIN `functional_group` AS `f` " + " ON (`f`.`id` = `a`.`functional_group_id`)" + " WHERE `a`.`application_id` = ?"; + +const std::string kSelectRemoteControlDenied = + "SELECT `remote_control_denied` FROM `application` WHERE `id` = ? LIMIT 1"; + +const std::string kInsertAppGroupPrimary = + "INSERT INTO `app_group_primary` (`application_id`, `functional_group_id`)" + " SELECT ?, `id` FROM `functional_group` WHERE `name` = ? LIMIT 1"; + +const std::string kInsertAppGroupNonPrimary = + "INSERT INTO `app_group_non_primary` (`application_id`, " + "`functional_group_id`)" + " SELECT ?, `id` FROM `functional_group` WHERE `name` = ? LIMIT 1"; + +const std::string kUpdateRemoteControlDenied = + "UPDATE `application` SET `remote_control_denied` = ? WHERE `id` = ?"; + +const std::string kDeleteAccessModules = "DELETE FROM `access_module`"; + +const std::string kDeleteRemoteRpc = "DELETE FROM `remote_rpc`"; + +const std::string kInsertAccessModule = + "INSERT INTO `access_module` (`name`, `user_consent_needed`) " + " VALUES(?, ?, ?)"; + +const std::string kDeleteAppGroupPrimaryByApplicationId = + "DELETE FROM `app_group_primary` WHERE `application_id` = ?"; + +const std::string kDeleteAppGroupNonPrimaryByApplicationId = + "DELETE FROM `app_group_non_primary` WHERE `application_id` = ?"; + +const std::string kSelectAccessModules = + "SELECT `id`, `name` FROM `access_module` " + " WHERE `user_consent_needed` = ?"; + +const std::string kInsertRemoteRpc = + "INSERT INTO `remote_rpc` (`module_id`, `name`, `parameter`) " + " VALUES(?, ?, ?)"; + +const std::string kSelectRemoteRpcs = + "SELECT `name`, `parameter` FROM `remote_rpc` " + " WHERE `module_id` = ?"; + +const std::string kInsertModuleType = + "INSERT OR IGNORE INTO `module_type` (`application_id`, `name`) VALUES (?, " + "?)"; + +const std::string kSelectModuleTypes = + "SELECT DISTINCT `name` FROM `module_type` WHERE `application_id` = ?"; + const std::string kDropSchema = "BEGIN; " + "DROP INDEX IF EXISTS `module_type.fk_module_type_application1_idx`; " + "DROP TABLE IF EXISTS `module_type`; " "DROP INDEX IF EXISTS `message.fk_messages_languages1_idx`; " "DROP INDEX IF EXISTS " "`message.fk_message_consumer_friendly_messages1_idx`; " @@ -388,6 +534,21 @@ const std::string kDropSchema = "idx`; " "DROP TABLE IF EXISTS `preconsented_group`; " "DROP INDEX IF EXISTS " + "`app_group_primary.fk_application_has_functional_group_application1_idx`; " + "DROP INDEX IF EXISTS " + "`app_group_primary.fk_application_has_functional_group_functional_group1_" + "idx`; " + "DROP TABLE IF EXISTS `app_group_primary`; " + "DROP INDEX IF EXISTS " + "`app_group_non_primary.fk_application_has_functional_group_application1_" + "idx`; " + "DROP INDEX IF EXISTS " + "`app_group_non_primary.fk_application_has_functional_group_functional_" + "group1_idx`; " + "DROP TABLE IF EXISTS `app_group_non_primary`; " + "DROP TABLE IF EXISTS `access_module`; " + "DROP INDEX IF EXISTS `access_module.fk_module_1_idx`; " + "DROP INDEX IF EXISTS " "`app_group.fk_application_has_functional_group_application1_idx`; " "DROP INDEX IF EXISTS " "`app_group.fk_application_has_functional_group_functional_group1_idx`; " @@ -409,6 +570,8 @@ const std::string kDropSchema = "DROP TABLE IF EXISTS `priority`; " "DROP TABLE IF EXISTS `functional_group`; " "DROP TABLE IF EXISTS `module_config`; " + "DROP TABLE IF EXISTS `remote_rpc`; " + "DROP INDEX IF EXISTS `remote_rpc.fk_remote_rpc_1_idx`; " "DROP TABLE IF EXISTS `module_meta`; " "DROP TABLE IF EXISTS `usage_and_error_count`; " "DROP TABLE IF EXISTS `device`; " @@ -419,6 +582,7 @@ const std::string kDropSchema = const std::string kDeleteData = "BEGIN; " "DELETE FROM `message`; " + "DELETE FROM `module_type`; " "DELETE FROM `endpoint`; " "DELETE FROM `consent_group`; " "DELETE FROM `app_type`; " @@ -430,6 +594,9 @@ const std::string kDeleteData = "DELETE FROM `app_group`; " "DELETE FROM `application`; " "DELETE FROM `rpc`; " + "DELETE FROM `app_group_primary`; " + "DELETE FROM `app_group_non_primary`; " + "DELETE FROM `access_module`; " "DELETE FROM `version`; " "DELETE FROM `message_type`; " "DELETE FROM `language`; " @@ -439,6 +606,7 @@ const std::string kDeleteData = "DELETE FROM `functional_group`; " "DELETE FROM `module_config`; " "DELETE FROM `module_meta`; " + "DELETE FROM `remote_rpc`; " "DELETE FROM `usage_and_error_count`; " "DELETE FROM `device`; " "COMMIT; " @@ -522,7 +690,8 @@ const std::string kUpdateModuleConfig = " `exchange_after_x_ignition_cycles` = ?," " `exchange_after_x_kilometers` = ?, `exchange_after_x_days` = ?, " " `timeout_after_x_seconds` = ?, `certificate` = ?, `vehicle_make` = ?, " - " `vehicle_model` = ?, `vehicle_year` = ?"; + " `vehicle_model` = ?, `vehicle_year` = ?, " + " `user_consent_passengersRC` = ?, `country_consent_passengersRC` = ?"; const std::string kInsertEndpoint = "INSERT INTO `endpoint` (`service`, `url`, `application_id`) " @@ -562,7 +731,8 @@ const std::string kSelectModuleConfig = "SELECT `preloaded_pt`, `exchange_after_x_ignition_cycles`, " " `exchange_after_x_kilometers`, `exchange_after_x_days`, " " `timeout_after_x_seconds`, `certificate`, `vehicle_make`," - " `vehicle_model`, `vehicle_year` " + " `vehicle_model`, `vehicle_year`, " + " `user_consent_passengersRC` , `country_consent_passengersRC` " " FROM `module_config`"; const std::string kSelectEndpoints = diff --git a/src/components/policy/policy_regular/src/sql_pt_representation.cc b/src/components/policy/policy_regular/src/sql_pt_representation.cc index e94c853414..854b6e4804 100644 --- a/src/components/policy/policy_regular/src/sql_pt_representation.cc +++ b/src/components/policy/policy_regular/src/sql_pt_representation.cc @@ -526,6 +526,12 @@ void SQLPTRepresentation::GatherModuleConfig( *config->vehicle_model = query.GetString(7); *config->vehicle_year = query.GetString(8); *config->preloaded_date = query.GetString(9); +#ifdef SDL_REMOTE_CONTROL + *config->user_consent_passengersRC = + query.IsNull(8) ? true : query.GetBoolean(8); + *config->country_consent_passengersRC = + query.IsNull(9) ? true : query.GetBoolean(9); +#endif // SDL_REMOTE_CONTROL } utils::dbms::SQLQuery endpoints(db()); @@ -705,6 +711,23 @@ bool SQLPTRepresentation::GatherApplicationPoliciesSection( if (!GatherAppGroup(app_id, ¶ms.groups)) { return false; } +#ifdef SDL_REMOTE_CONTROL + if (!GatherAppGroupPrimary(app_id, &*params.groups_primaryRC)) { + return false; + } + if (!GatherAppGroupNonPrimary(app_id, &*params.groups_nonPrimaryRC)) { + return false; + } + bool denied = false; + if (!GatherRemoteControlDenied(app_id, &denied)) { + return false; + } + if (!denied) { + if (!GatherModuleType(app_id, &*params.moduleType)) { + return false; + } + } +#endif // SDL_REMOTE_CONTROL if (!GatherNickName(app_id, &*params.nicknames)) { return false; } @@ -859,6 +882,20 @@ bool SQLPTRepresentation::SaveApplicationPoliciesSection( LOG4CXX_WARN(logger_, "Incorrect delete from app_group."); return false; } +#ifdef SDL_REMOTE_CONTROL + if (!query_delete.Exec(sql_pt::kDeleteAppGroupPrimary)) { + LOG4CXX_WARN(logger_, "Incorrect delete from app_group_primary."); + return false; + } + if (!query_delete.Exec(sql_pt::kDeleteAppGroupNonPrimary)) { + LOG4CXX_WARN(logger_, "Incorrect delete from app_group_non_primary."); + return false; + } + if (!query_delete.Exec(sql_pt::kDeleteModuleTypes)) { + LOG4CXX_WARN(logger_, "Incorrect delete from module_type."); + return false; + } +#endif // SDL_REMOTE_CONTROL if (!query_delete.Exec(sql_pt::kDeleteApplication)) { LOG4CXX_WARN(logger_, "Incorrect delete from application."); return false; @@ -941,6 +978,20 @@ bool SQLPTRepresentation::SaveSpecificAppPolicy( if (!SaveAppGroup(app.first, app.second.groups)) { return false; } +#ifdef SDL_REMOTE_CONTROL + if (!SaveAppGroupPrimary(app.first, *app.second.groups_primaryRC)) { + return false; + } + if (!SaveAppGroupNonPrimary(app.first, *app.second.groups_nonPrimaryRC)) { + return false; + } + + bool denied = !app.second.moduleType->is_initialized(); + if (!SaveRemoteControlDenied(app.first, denied) || + !SaveModuleType(app.first, *app.second.moduleType)) { + return false; + } +#endif // SDL_REMOTE_CONTROL if (!SaveNickname(app.first, *app.second.nicknames)) { return false; } @@ -1111,7 +1162,14 @@ bool SQLPTRepresentation::SaveModuleConfig( : query.Bind(7); config.vehicle_year.is_initialized() ? query.Bind(8, *(config.vehicle_year)) : query.Bind(8); - +#ifdef SDL_REMOTE_CONTROL + config.user_consent_passengersRC.is_initialized() + ? query.Bind(9, *(config.user_consent_passengersRC)) + : query.Bind(9); + config.country_consent_passengersRC.is_initialized() + ? query.Bind(10, *(config.country_consent_passengersRC)) + : query.Bind(10); +#endif // SDL_REMOTE_CONTROL if (!query.Exec()) { LOG4CXX_WARN(logger_, "Incorrect update module config"); return false; @@ -1506,6 +1564,280 @@ bool SQLPTRepresentation::GatherAppGroup( return true; } +#ifdef SDL_REMOTE_CONTROL +bool SQLPTRepresentation::GatherAppGroupPrimary( + const std::string& app_id, policy_table::Strings* app_groups) const { + utils::dbms::SQLQuery query(db()); + if (!query.Prepare(sql_pt::kSelectAppGroupsPrimary)) { + LOG4CXX_WARN(logger_, "Incorrect select from app groups for primary RC"); + return false; + } + + query.Bind(0, app_id); + while (query.Next()) { + app_groups->push_back(query.GetString(0)); + } + return true; +} + +bool SQLPTRepresentation::GatherAppGroupNonPrimary( + const std::string& app_id, policy_table::Strings* app_groups) const { + utils::dbms::SQLQuery query(db()); + if (!query.Prepare(sql_pt::kSelectAppGroupsNonPrimary)) { + LOG4CXX_WARN(logger_, + "Incorrect select from app groups for non primary RC"); + return false; + } + + query.Bind(0, app_id); + while (query.Next()) { + app_groups->push_back(query.GetString(0)); + } + return true; +} + +bool SQLPTRepresentation::GatherRemoteControlDenied(const std::string& app_id, + bool* denied) const { + LOG4CXX_AUTO_TRACE(logger_); + utils::dbms::SQLQuery query(db()); + if (!query.Prepare(sql_pt::kSelectRemoteControlDenied)) { + LOG4CXX_WARN(logger_, "Incorrect select remote control flag"); + return false; + } + query.Bind(0, app_id); + if (query.Next()) { + *denied = query.GetBoolean(0); + } else { + return false; + } + return true; +} + +bool SQLPTRepresentation::GatherModuleType( + const std::string& app_id, policy_table::ModuleTypes* app_types) const { + utils::dbms::SQLQuery query(db()); + if (!query.Prepare(sql_pt::kSelectModuleTypes)) { + LOG4CXX_WARN(logger_, "Incorrect select from app types"); + return false; + } + + query.Bind(0, app_id); + while (query.Next()) { + policy_table::ModuleType type; + if (!policy_table::EnumFromJsonString(query.GetString(0), &type)) { + return false; + } + app_types->push_back(type); + } + return true; +} + +bool SQLPTRepresentation::SaveAppGroupPrimary( + const std::string& app_id, const policy_table::Strings& app_groups) { + LOG4CXX_AUTO_TRACE(logger_); + utils::dbms::SQLQuery query(db()); + if (!query.Prepare(sql_pt::kInsertAppGroupPrimary)) { + LOG4CXX_WARN(logger_, "Incorrect insert statement for app group primary"); + return false; + } + policy_table::Strings::const_iterator it; + for (it = app_groups.begin(); it != app_groups.end(); ++it) { + std::string ssss = *it; + LOG4CXX_INFO(logger_, "Group: " << ssss); + query.Bind(0, app_id); + query.Bind(1, *it); + if (!query.Exec() || !query.Reset()) { + LOG4CXX_WARN(logger_, + "Incorrect insert into app group primary." + << query.LastError().text()); + return false; + } + } + + return true; +} + +bool SQLPTRepresentation::SaveAppGroupNonPrimary( + const std::string& app_id, const policy_table::Strings& app_groups) { + LOG4CXX_AUTO_TRACE(logger_); + utils::dbms::SQLQuery query(db()); + if (!query.Prepare(sql_pt::kInsertAppGroupNonPrimary)) { + LOG4CXX_WARN(logger_, + "Incorrect insert statement for app group non primary"); + return false; + } + policy_table::Strings::const_iterator it; + for (it = app_groups.begin(); it != app_groups.end(); ++it) { + std::string ssss = *it; + LOG4CXX_INFO(logger_, "Group: " << ssss); + query.Bind(0, app_id); + query.Bind(1, *it); + if (!query.Exec() || !query.Reset()) { + LOG4CXX_WARN(logger_, + "Incorrect insert into app group non primary." + << query.LastError().text()); + return false; + } + } + + return true; +} + +bool SQLPTRepresentation::SaveRemoteControlDenied(const std::string& app_id, + bool deny) { + LOG4CXX_AUTO_TRACE(logger_); + utils::dbms::SQLQuery query(db()); + if (!query.Prepare(sql_pt::kUpdateRemoteControlDenied)) { + LOG4CXX_WARN(logger_, "Incorrect update statement for remote control flag"); + return false; + } + LOG4CXX_DEBUG(logger_, "App: " << app_id << std::boolalpha << " - " << deny); + query.Bind(0, deny); + query.Bind(1, app_id); + if (!query.Exec()) { + LOG4CXX_WARN(logger_, "Incorrect update remote control flag."); + return false; + } + return true; +} + +bool SQLPTRepresentation::SaveModuleType( + const std::string& app_id, const policy_table::ModuleTypes& types) { + utils::dbms::SQLQuery query(db()); + if (!query.Prepare(sql_pt::kInsertModuleType)) { + LOG4CXX_WARN(logger_, "Incorrect insert statement for module type"); + return false; + } + + policy_table::ModuleTypes::const_iterator it; + for (it = types.begin(); it != types.end(); ++it) { + query.Bind(0, app_id); + std::string module(policy_table::EnumToJsonString(*it)); + query.Bind(1, module); + LOG4CXX_DEBUG(logger_, + "Module(app: " << app_id << ", type: " << module << ")"); + if (!query.Exec() || !query.Reset()) { + LOG4CXX_WARN(logger_, "Incorrect insert into module type."); + return false; + } + } + + return true; +} + +bool SQLPTRepresentation::SaveAccessModule( + TypeAccess access, const policy_table::AccessModules& modules) { + LOG4CXX_AUTO_TRACE(logger_); + utils::dbms::SQLQuery query(db()); + if (!query.Prepare(sql_pt::kInsertAccessModule)) { + LOG4CXX_WARN(logger_, "Incorrect insert statement for access module"); + return false; + } + + policy_table::AccessModules::const_iterator i; + for (i = modules.begin(); i != modules.end(); ++i) { + const std::string& name = i->first; + const policy_table::RemoteRpcs& rpcs = i->second; + query.Bind(0, name); + query.Bind(1, access); + if (!query.Exec()) { + LOG4CXX_WARN(logger_, "Incorrect insert into access module."); + return false; + } + int id = query.LastInsertId(); + if (!query.Reset()) { + LOG4CXX_WARN(logger_, "Couldn't reset query access module."); + return false; + } + if (!SaveRemoteRpc(id, rpcs)) { + return false; + } + } + return true; +} + +bool SQLPTRepresentation::GatherAccessModule( + TypeAccess access, policy_table::AccessModules* modules) const { + LOG4CXX_AUTO_TRACE(logger_); + utils::dbms::SQLQuery query(db()); + if (!query.Prepare(sql_pt::kSelectAccessModules)) { + LOG4CXX_WARN(logger_, "Incorrect select from access module"); + return false; + } + + query.Bind(0, access); + while (query.Next()) { + int id = query.GetInteger(0); + std::string name = query.GetString(1); + policy_table::RemoteRpcs rpcs; + if (!GatherRemoteRpc(id, &rpcs)) { + return false; + } + modules->insert(std::make_pair(name, rpcs)); + } + return true; +} + +bool SQLPTRepresentation::SaveRemoteRpc(int module_id, + const policy_table::RemoteRpcs& rpcs) { + LOG4CXX_AUTO_TRACE(logger_); + utils::dbms::SQLQuery query(db()); + if (!query.Prepare(sql_pt::kInsertRemoteRpc)) { + LOG4CXX_WARN(logger_, "Incorrect insert statement for remote rpc"); + return false; + } + policy_table::RemoteRpcs::const_iterator i; + for (i = rpcs.begin(); i != rpcs.end(); ++i) { + const std::string& name = i->first; + const policy_table::Strings& params = i->second; + policy_table::Strings::const_iterator j; + if (params.empty()) { + query.Bind(0, module_id); + query.Bind(1, name); + query.Bind(2); + if (!query.Exec() || !query.Reset()) { + LOG4CXX_WARN(logger_, "Incorrect insert into remote rpc."); + return false; + } + } else { + for (j = params.begin(); j != params.end(); ++j) { + const std::string& param = *j; + query.Bind(0, module_id); + query.Bind(1, name); + query.Bind(2, param); + if (!query.Exec() || !query.Reset()) { + LOG4CXX_WARN(logger_, "Incorrect insert into remote rpc."); + return false; + } + } + } + } + return true; +} + +bool SQLPTRepresentation::GatherRemoteRpc( + int module_id, policy_table::RemoteRpcs* rpcs) const { + LOG4CXX_AUTO_TRACE(logger_); + utils::dbms::SQLQuery query(db()); + if (!query.Prepare(sql_pt::kSelectRemoteRpcs)) { + LOG4CXX_WARN(logger_, "Incorrect select from remote rpc"); + return false; + } + + query.Bind(0, module_id); + while (query.Next()) { + std::string name = query.GetString(0); + if (!query.IsNull(1)) { + std::string parameter = query.GetString(1); + (*rpcs)[name].push_back(parameter); + } else { + rpcs->insert(std::make_pair(name, policy_table::Strings())); + } + } + return true; +} +#endif // SDL_REMOTE_CONTROL + bool SQLPTRepresentation::SaveApplicationCustomData(const std::string& app_id, bool is_revoked, bool is_default, @@ -1590,6 +1922,31 @@ bool SQLPTRepresentation::SetDefaultPolicy(const std::string& app_id) { LOG4CXX_ERROR(logger_, "Failed deleting from app_group."); return false; } +#ifdef SDL_REMOTE_CONTROL + utils::dbms::SQLQuery query_p(db()); + if (!query_p.Prepare(sql_pt::kDeleteAppGroupPrimaryByApplicationId)) { + LOG4CXX_ERROR(logger_, + "Incorrect statement to delete from app_group_primary."); + return false; + } + query_p.Bind(0, app_id); + if (!query_p.Exec()) { + LOG4CXX_ERROR(logger_, "Failed deleting from app_group_primary."); + return false; + } + + utils::dbms::SQLQuery query_np(db()); + if (!query_np.Prepare(sql_pt::kDeleteAppGroupNonPrimaryByApplicationId)) { + LOG4CXX_ERROR(logger_, + "Incorrect statement to delete from app_group_non_primary."); + return false; + } + query_np.Bind(0, app_id); + if (!query_np.Exec()) { + LOG4CXX_ERROR(logger_, "Failed deleting from app_group_non_primary."); + return false; + } +#endif // SDL_REMOTE_CONTROL if (!CopyApplication(kDefaultId, app_id)) { return false; @@ -1612,7 +1969,22 @@ bool SQLPTRepresentation::SetDefaultPolicy(const std::string& app_id) { !SaveAppType(app_id, app_types)) { return false; } - return SetIsDefault(app_id, true); + + bool ret = (GatherAppGroup(kDefaultId, &default_groups) && + SaveAppGroup(app_id, default_groups)); +#ifdef SDL_REMOTE_CONTROL + policy_table::Strings groups_primary; + ret = ret && (GatherAppGroupPrimary(kDefaultId, &groups_primary) && + SaveAppGroupPrimary(app_id, groups_primary)); + policy_table::Strings groups_non_primary; + ret = ret && (GatherAppGroupNonPrimary(kDefaultId, &groups_non_primary) && + SaveAppGroupNonPrimary(app_id, groups_non_primary)); +#endif // SDL_REMOTE_CONTROL + + if (ret) { + return SetIsDefault(app_id, true); + } + return false; } bool SQLPTRepresentation::SetIsDefault(const std::string& app_id, diff --git a/src/components/policy/policy_regular/test/CMakeLists.txt b/src/components/policy/policy_regular/test/CMakeLists.txt index 997c3637e8..62ff691f83 100644 --- a/src/components/policy/policy_regular/test/CMakeLists.txt +++ b/src/components/policy/policy_regular/test/CMakeLists.txt @@ -39,11 +39,17 @@ include_directories( ${COMPONENTS_DIR}/rpc_base/include ${COMPONENTS_DIR}/config_profile/include ${COMPONENTS_DIR}/utils/include/ + ${COMPONENTS_DIR}/include/test/policy/policy_regular/ ${POLICY_PATH}/test/include/ ${POLICY_MOCK_INCLUDE_PATH}/ ) collect_sources(SOURCES "${CMAKE_CURRENT_SOURCE_DIR}") +if (NOT REMOTE_CONTROL) + list (REMOVE_ITEM SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/access_remote_impl_test.cc + ) +endif () set(LIBRARIES gmock diff --git a/src/components/policy/policy_regular/test/access_remote_impl_test.cc b/src/components/policy/policy_regular/test/access_remote_impl_test.cc new file mode 100644 index 0000000000..4b2a9b02eb --- /dev/null +++ b/src/components/policy/policy_regular/test/access_remote_impl_test.cc @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2015, 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 "policy/access_remote_impl.h" + +namespace policy { + +TEST(AccessRemoteImplTest, Allow) { + AccessRemoteImpl access_remote; + Subject who = {"dev1", "12345"}; + Object what = {policy_table::MT_RADIO}; + access_remote.Allow(who, what); + AccessRemoteImpl::AccessControlList::const_iterator i = + access_remote.acl_.find(what); + ASSERT_NE(access_remote.acl_.end(), i); + AccessRemoteImpl::AccessControlRow::const_iterator j = i->second.find(who); + ASSERT_NE(i->second.end(), j); + EXPECT_EQ(TypeAccess::kAllowed, j->second); +} + +TEST(AccessRemoteImplTest, KeyMapTest) { + // Testing operator < to use as key of map + AccessRemoteImpl access_remote; + Subject who = {"dev1", "12345"}; + Object what1 = {policy_table::MT_RADIO}; + Object what2 = {policy_table::MT_CLIMATE}; + access_remote.Allow(who, what1); + access_remote.Allow(who, what2); + ASSERT_EQ(2u, access_remote.acl_.size()); +} + +TEST(AccessRemoteImplTest, Deny) { + AccessRemoteImpl access_remote; + Subject who = {"dev1", "12345"}; + Object what = {policy_table::MT_RADIO}; + access_remote.Deny(who, what); + AccessRemoteImpl::AccessControlList::const_iterator i = + access_remote.acl_.find(what); + ASSERT_NE(access_remote.acl_.end(), i); + AccessRemoteImpl::AccessControlRow::const_iterator j = i->second.find(who); + ASSERT_NE(i->second.end(), j); + EXPECT_EQ(TypeAccess::kDisallowed, j->second); +} + +TEST(AccessRemoteImplTest, ChangeAccess) { + AccessRemoteImpl access_remote; + Subject who = {"dev1", "12345"}; + Object what = {policy_table::MT_RADIO}; + access_remote.Allow(who, what); + ASSERT_EQ(TypeAccess::kAllowed, access_remote.acl_[what][who]); + access_remote.Deny(who, what); + ASSERT_EQ(TypeAccess::kDisallowed, access_remote.acl_[what][who]); + access_remote.Allow(who, what); + EXPECT_EQ(TypeAccess::kAllowed, access_remote.acl_[what][who]); +} + +TEST(AccessRemoteImplTest, ResetBySubject) { + AccessRemoteImpl access_remote; + Subject who = {"dev1", "12345"}; + Object what1 = {policy_table::MT_RADIO}; + Object what2 = {policy_table::MT_CLIMATE}; + access_remote.Allow(who, what1); + access_remote.Deny(who, what2); + ASSERT_EQ(2u, access_remote.acl_.size()); + ASSERT_EQ(1u, access_remote.acl_[what1].size()); + ASSERT_EQ(1u, access_remote.acl_[what2].size()); + + access_remote.Reset(who); + ASSERT_EQ(2u, access_remote.acl_.size()); + EXPECT_TRUE(access_remote.acl_[what1].empty()); + EXPECT_TRUE(access_remote.acl_[what2].empty()); +} + +TEST(AccessRemoteImplTest, ResetByObject) { + AccessRemoteImpl access_remote; + Subject who1 = {"dev1", "12345"}; + Subject who2 = {"dev2", "123456"}; + Object what = {policy_table::MT_RADIO}; + access_remote.Allow(who1, what); + access_remote.Deny(who2, what); + ASSERT_EQ(1u, access_remote.acl_.size()); + ASSERT_EQ(2u, access_remote.acl_[what].size()); + + access_remote.Reset(what); + EXPECT_TRUE(access_remote.acl_.empty()); +} + +TEST(AccessRemoteImplTest, CheckAllowed) { + AccessRemoteImpl access_remote; + Subject who = {"dev1", "12345"}; + Object what = {policy_table::MT_RADIO}; + access_remote.Allow(who, what); + + EXPECT_EQ(TypeAccess::kAllowed, access_remote.Check(who, what)); +} + +TEST(AccessRemoteImplTest, CheckDisallowed) { + AccessRemoteImpl access_remote; + Subject who = {"dev1", "12345"}; + Subject who1 = {"dev1", "123456"}; + Object what = {policy_table::MT_RADIO}; + + access_remote.Allow(who, what); + EXPECT_EQ(TypeAccess::kManual, access_remote.Check(who1, what)); + + access_remote.Reset(who); + access_remote.Deny(who1, what); + EXPECT_EQ(TypeAccess::kDisallowed, access_remote.Check(who1, what)); +} + +TEST(AccessRemoteImplTest, CheckManual) { + AccessRemoteImpl access_remote; + Subject who = {"dev1", "12345"}; + Subject who1 = {"dev1", "123456"}; + Object what = {policy_table::MT_RADIO}; + + EXPECT_EQ(TypeAccess::kManual, access_remote.Check(who, what)); + + access_remote.Deny(who1, what); + EXPECT_EQ(TypeAccess::kManual, access_remote.Check(who, what)); +} + +TEST(AccessRemoteImplTest, CheckModuleType) { + AccessRemoteImpl access_remote; + access_remote.cache_->pt_ = new policy_table::Table(); + + // No application + EXPECT_FALSE(access_remote.CheckModuleType("1234", policy_table::MT_RADIO)); + + // No modules + policy_table::ApplicationPolicies& apps = + access_remote.cache_->pt_->policy_table.app_policies_section.apps; + apps["1234"]; + EXPECT_FALSE(access_remote.CheckModuleType("1234", policy_table::MT_RADIO)); + + // Empty modules + policy_table::ModuleTypes& modules = *apps["1234"].moduleType; + modules.mark_initialized(); + EXPECT_TRUE(access_remote.CheckModuleType("1234", policy_table::MT_RADIO)); + EXPECT_TRUE(access_remote.CheckModuleType("1234", policy_table::MT_CLIMATE)); + + // Specific modules + modules.push_back(policy_table::MT_RADIO); + EXPECT_TRUE(access_remote.CheckModuleType("1234", policy_table::MT_RADIO)); + EXPECT_FALSE(access_remote.CheckModuleType("1234", policy_table::MT_CLIMATE)); +} + +TEST(AccessRemoteImplTest, EnableDisable) { + AccessRemoteImpl access_remote; + access_remote.cache_->pt_ = new policy_table::Table(); + policy_table::ModuleConfig& config = + access_remote.cache_->pt_->policy_table.module_config; + + // Country is enabled + access_remote.enabled_ = true; + *config.country_consent_passengersRC = true; + access_remote.Enable(); + EXPECT_TRUE(*config.user_consent_passengersRC); + EXPECT_TRUE(*config.country_consent_passengersRC); + EXPECT_TRUE(access_remote.IsEnabled()); + + access_remote.Disable(); + EXPECT_FALSE(*config.user_consent_passengersRC); + EXPECT_TRUE(*config.country_consent_passengersRC); + EXPECT_FALSE(access_remote.IsEnabled()); + + // Country is disabled + access_remote.enabled_ = false; + *config.country_consent_passengersRC = false; + access_remote.Enable(); + EXPECT_TRUE(*config.user_consent_passengersRC); + EXPECT_FALSE(*config.country_consent_passengersRC); + EXPECT_FALSE(access_remote.IsEnabled()); + + access_remote.Disable(); + EXPECT_FALSE(*config.user_consent_passengersRC); + EXPECT_FALSE(*config.country_consent_passengersRC); + EXPECT_FALSE(access_remote.IsEnabled()); +} + +TEST(AccessRemoteImplTest, SetDefaultHmiTypes) { + AccessRemoteImpl access_remote; + + std::vector<int> hmi_expected; + hmi_expected.push_back(2); + hmi_expected.push_back(6); + Subject who = {"dev1", "1234"}; + access_remote.SetDefaultHmiTypes(who, hmi_expected); + + EXPECT_NE(access_remote.hmi_types_.end(), access_remote.hmi_types_.find(who)); + policy_table::AppHMITypes& hmi_output = access_remote.hmi_types_[who]; + EXPECT_EQ(2u, hmi_output.size()); + EXPECT_EQ(policy_table::AHT_MEDIA, hmi_output[0]); + EXPECT_EQ(policy_table::AHT_SOCIAL, hmi_output[1]); +} + +TEST(AccessRemoteImplTest, GetGroups) { + AccessRemoteImpl access_remote; + access_remote.primary_device_ = "dev1"; + access_remote.enabled_ = true; + Subject who = {"dev1", "1234"}; + access_remote.hmi_types_[who].push_back(policy_table::AHT_REMOTE_CONTROL); + + access_remote.cache_->pt_ = new policy_table::Table(); + policy_table::ApplicationPolicies& apps = + access_remote.cache_->pt_->policy_table.app_policies_section.apps; + apps["1234"].groups.push_back("group_default"); + apps["1234"].groups_nonPrimaryRC->push_back("group_non_primary"); + apps["1234"].groups_primaryRC->push_back("group_primary"); + apps["1234"].AppHMIType->push_back(policy_table::AHT_MEDIA); + + // Default groups + const policy_table::Strings& groups1 = access_remote.GetGroups(who); + EXPECT_EQ(std::string("group_default"), std::string(groups1[0])); + + // Primary groups + apps["1234"].set_to_string(policy::kDefaultId); + const policy_table::Strings& groups2 = access_remote.GetGroups(who); + EXPECT_EQ(std::string("group_primary"), std::string(groups2[0])); + + // Non primary groups + apps["1234"].set_to_string(policy::kDefaultId); + Subject who2 = {"dev2", "1234"}; + access_remote.hmi_types_[who2].push_back(policy_table::AHT_REMOTE_CONTROL); + const policy_table::Strings& groups3 = access_remote.GetGroups(who2); + EXPECT_EQ(std::string("group_non_primary"), std::string(groups3[0])); + + // Empty groups + access_remote.enabled_ = false; + apps["1234"].set_to_string(policy::kDefaultId); + const policy_table::Strings& groups4 = access_remote.GetGroups(who2); + EXPECT_TRUE(groups4.empty()); +} + +} // namespace policy diff --git a/src/components/policy/policy_regular/test/include/policy/mock_access_remote.h b/src/components/policy/policy_regular/test/include/policy/mock_access_remote.h new file mode 100644 index 0000000000..8c5bf75ba5 --- /dev/null +++ b/src/components/policy/policy_regular/test/include/policy/mock_access_remote.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2015, 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_POLICY_TEST_INCLUDE_MOCK_ACCESS_REMOTE_H_ +#define SRC_COMPONENTS_POLICY_TEST_INCLUDE_MOCK_ACCESS_REMOTE_H_ + +#include "gmock/gmock.h" +#include "policy/access_remote.h" + +namespace test { +namespace components { +namespace access_remote_test { + +class MockSubject : public policy::Subject { + public: +}; + +class MockObject : public policy::Object { + public: +}; + +class MockAccessRemote : public policy::AccessRemote { + public: + MOCK_METHOD0(Init, void()); + MOCK_METHOD0(Enable, void()); + MOCK_METHOD0(Disable, void()); + MOCK_CONST_METHOD0(IsEnabled, bool()); + MOCK_CONST_METHOD1(IsPrimaryDevice, bool(const policy::PTString& dev_id)); + MOCK_METHOD1(SetPrimaryDevice, void(const policy::PTString& dev_id)); + MOCK_CONST_METHOD0(PrimaryDevice, policy::PTString()); + + MOCK_METHOD2(Allow, + void(const policy::Subject& who, const policy::Object& what)); + MOCK_METHOD2(Deny, + void(const policy::Subject& who, const policy::Object& what)); + MOCK_METHOD1(Reset, void(const policy::Subject& who)); + MOCK_METHOD1(Reset, void(const policy::Object& what)); + MOCK_CONST_METHOD2(Check, + policy::TypeAccess(const policy::Subject& who, + const policy::Object& what)); + MOCK_CONST_METHOD3( + FindGroup, + policy::PTString(const policy::Subject& who, + const policy::PTString& rpc, + const policy::RemoteControlParams& params)); + MOCK_METHOD2(SetDefaultHmiTypes, + void(const policy::Subject& who, + const std::vector<int>& hmi_types)); + MOCK_METHOD1(GetGroups, + const policy_table::Strings&(const policy::Subject& who)); + MOCK_METHOD3(GetPermissionsForApp, + bool(const std::string& device_id, + const std::string& app_id, + policy::FunctionalIdType& group_types)); + MOCK_CONST_METHOD2(CheckModuleType, + bool(const policy::PTString& app_id, + policy_table::ModuleType module)); + MOCK_METHOD1(IsAppRemoteControl, bool(const policy::Subject& who)); + MOCK_METHOD0(Reset, void()); + MOCK_METHOD2(GetModuleTypes, + bool(const std::string& application_id, + std::vector<std::string>* modules)); +}; + +} // namespace access_remote_test +} // namespace components +} // namespace test + +#endif // SRC_COMPONENTS_POLICY_TEST_INCLUDE_MOCK_ACCESS_REMOTE_H_ diff --git a/src/components/policy/policy_regular/test/include/policy/mock_policy_manager.h b/src/components/policy/policy_regular/test/include/policy/mock_policy_manager.h deleted file mode 100644 index 7ab4b518cd..0000000000 --- a/src/components/policy/policy_regular/test/include/policy/mock_policy_manager.h +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (c) 2016, 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_POLICY_POLICY_REGULAR_TEST_INCLUDE_MOCK_POLICY_MANAGER_H_ -#define SRC_COMPONENTS_POLICY_POLICY_REGULAR_TEST_INCLUDE_MOCK_POLICY_MANAGER_H_ - -#include <string> -#include <vector> -#include "gmock/gmock.h" -#include "policy/policy_listener.h" -#include "policy/policy_types.h" -#include "policy/usage_statistics/statistics_manager.h" - -#include "rpc_base/rpc_base.h" -#include "policy/policy_table/types.h" -#include "policy/policy_manager.h" - -namespace policy_table = ::rpc::policy_table_interface_base; - -namespace policy_manager { - -using namespace policy; - -class MockPolicyManager : public PolicyManager { - public: - MOCK_METHOD1(set_listener, void(PolicyListener* listener)); - MOCK_METHOD2(InitPT, - bool(const std::string& file_name, - const PolicySettings* settings)); - MOCK_METHOD2(LoadPT, - bool(const std::string& file, const BinaryMessage& pt_content)); - MOCK_METHOD1(ResetPT, bool(const std::string& file_name)); - MOCK_METHOD2(GetUpdateUrls, - void(const uint32_t service_type, EndpointUrls& out_end_points)); - MOCK_METHOD2(GetUpdateUrls, - void(const std::string& service_type, - EndpointUrls& out_end_points)); - MOCK_METHOD0(RequestPTUpdate, bool()); - - MOCK_METHOD6(CheckPermissions, - void(const PTString& device_id, - const PTString& app_id, - const PTString& hmi_level, - const PTString& rpc, - const RPCParams& rpc_params, - CheckPermissionResult& result)); - MOCK_METHOD0(ResetUserConsent, bool()); - MOCK_CONST_METHOD0(GetPolicyTableStatus, std::string()); - MOCK_METHOD1(KmsChanged, void(int kilometers)); - MOCK_METHOD0(IncrementIgnitionCycles, void()); - MOCK_METHOD0(ForcePTExchange, std::string()); - MOCK_METHOD0(ResetRetrySequence, void()); - MOCK_METHOD0(NextRetryTimeout, int()); - MOCK_METHOD0(TimeoutExchangeMSec, uint32_t()); - MOCK_METHOD0(RetrySequenceDelaysSeconds, const std::vector<int>()); - MOCK_METHOD0(OnExceededTimeout, void()); - MOCK_METHOD0(OnUpdateStarted, void()); - MOCK_CONST_METHOD1(GetUserConsentForDevice, - DeviceConsent(const std::string& device_id)); - MOCK_METHOD3( - GetUserConsentForApp, - void(const std::string& device_id, - const std::string& policy_app_id, - std::vector<policy::FunctionalGroupPermission>& permissions)); - MOCK_METHOD2(SetUserConsentForDevice, - void(const std::string& device_id, bool is_allowed)); - MOCK_METHOD2(ReactOnUserDevConsentForApp, - bool(const std::string app_id, bool is_device_allowed)); - MOCK_METHOD2(PTUpdatedAt, void(policy::Counters counter, int value)); - - MOCK_METHOD3(GetInitialAppData, - bool(const std::string&, - policy::StringArray*, - policy::StringArray*)); - - MOCK_METHOD2(AddDevice, - void(const std::string& device_id, - const std::string& connection_type)); - MOCK_METHOD2(SetDeviceInfo, - void(const std::string& device_id, - const policy::DeviceInfo& device_info)); - MOCK_METHOD1(SetUserConsentForApp, - void(const policy::PermissionConsent& permissions)); - MOCK_CONST_METHOD2(GetDefaultHmi, - bool(const std::string& policy_app_id, - std::string* default_hmi)); - MOCK_CONST_METHOD2(GetPriority, - bool(const std::string& policy_app_id, - std::string* priority)); - MOCK_METHOD2(GetUserFriendlyMessages, - std::vector<policy::UserFriendlyMessage>( - const std::vector<std::string>& message_code, - const std::string& language)); - MOCK_CONST_METHOD1(IsApplicationRevoked, bool(const std::string& app_id)); - MOCK_METHOD3( - GetPermissionsForApp, - void(const std::string& device_id, - const std::string& policy_app_id, - std::vector<policy::FunctionalGroupPermission>& permissions)); - MOCK_METHOD1(GetAppPermissionsChanges, - policy::AppPermissions(const std::string& policy_app_id)); - MOCK_METHOD1(RemovePendingPermissionChanges, void(const std::string& app_id)); - MOCK_CONST_METHOD1(GetCurrentDeviceId, - std::string&(const std::string& policy_app_id)); - MOCK_METHOD1(SetSystemLanguage, void(const std::string& language)); - MOCK_METHOD3(SetSystemInfo, - void(const std::string& ccpu_version, - const std::string& wers_country_code, - const std::string& language)); - MOCK_METHOD1(SendNotificationOnPermissionsUpdated, - void(const std::string& application_id)); - MOCK_METHOD1(MarkUnpairedDevice, void(const std::string& device_id)); - MOCK_METHOD1(AddApplication, - StatusNotifier(const std::string& application_id)); - MOCK_METHOD0(CleanupUnpairedDevices, bool()); - MOCK_CONST_METHOD1(CanAppKeepContext, bool(const std::string& app_id)); - MOCK_CONST_METHOD1(CanAppStealFocus, bool(const std::string& app_id)); - MOCK_METHOD0(OnSystemReady, void()); - MOCK_CONST_METHOD1(GetNotificationsNumber, - uint32_t(const std::string& priority)); - MOCK_METHOD1(SetVINValue, void(const std::string& value)); - MOCK_CONST_METHOD1(IsPredataPolicy, bool(const std::string& policy_app_id)); - MOCK_CONST_METHOD1(HeartBeatTimeout, uint32_t(const std::string& app_id)); - MOCK_METHOD1(SaveUpdateStatusRequired, void(bool is_update_needed)); - MOCK_METHOD0(OnAppsSearchStarted, void()); - MOCK_METHOD0(OnAppsSearchCompleted, void()); - MOCK_METHOD1(OnAppRegisteredOnMobile, - void(const std::string& application_id)); - MOCK_CONST_METHOD1( - GetAppRequestTypes, - const std::vector<std::string>(const std::string policy_app_id)); - MOCK_CONST_METHOD0(GetVehicleInfo, const policy::VehicleInfo()); - MOCK_CONST_METHOD0(RetrieveCertificate, std::string()); - MOCK_METHOD1(SetDecryptedCertificate, void(const std::string&)); - MOCK_METHOD0(ExceededIgnitionCycles, bool()); - MOCK_METHOD0(ExceededDays, bool()); - MOCK_METHOD0(StartPTExchange, void()); - MOCK_METHOD1(Increment, void(usage_statistics::GlobalCounterId type)); - MOCK_METHOD2(Increment, - void(const std::string& app_id, - usage_statistics::AppCounterId type)); - MOCK_METHOD3(Set, - void(const std::string& app_id, - usage_statistics::AppInfoId type, - const std::string& value)); - MOCK_METHOD3(Add, - void(const std::string& app_id, - usage_statistics::AppStopwatchId type, - int32_t timespan_seconds)); - MOCK_CONST_METHOD0(get_settings, const PolicySettings&()); - MOCK_METHOD1(set_settings, void(const PolicySettings* get_settings)); -}; - -} // namespace policy_manager - -#endif // SRC_COMPONENTS_POLICY_POLICY_REGULAR_TEST_INCLUDE_MOCK_POLICY_MANAGER_H_ diff --git a/src/components/policy/policy_regular/test/policy_manager_impl_test.cc b/src/components/policy/policy_regular/test/policy_manager_impl_test.cc index e8bca3061f..799b6c2999 100644 --- a/src/components/policy/policy_regular/test/policy_manager_impl_test.cc +++ b/src/components/policy/policy_regular/test/policy_manager_impl_test.cc @@ -53,7 +53,9 @@ #include "utils/date_time.h" #include "utils/make_shared.h" #include "utils/gen_hash.h" - +#ifdef SDL_REMOTE_CONTROL +#include "policy/mock_access_remote.h" +#endif // SDL_REMOTE_CONTROL using ::testing::ReturnRef; using ::testing::DoAll; using ::testing::SetArgReferee; @@ -144,12 +146,20 @@ class PolicyManagerImplTest : public ::testing::Test { MockCacheManagerInterface* cache_manager; NiceMock<MockPolicyListener> listener; const std::string device_id; +#ifdef SDL_REMOTE_CONTROL + utils::SharedPtr<access_remote_test::MockAccessRemote> access_remote; +#endif // SDL_REMOTE_CONTROL void SetUp() OVERRIDE { manager = new PolicyManagerImpl(); manager->set_listener(&listener); cache_manager = new MockCacheManagerInterface(); manager->set_cache_manager(cache_manager); + +#ifdef SDL_REMOTE_CONTROL + access_remote = new access_remote_test::MockAccessRemote(); + manager->set_access_remote(access_remote); +#endif // SDL_REMOTE_CONTROL } void TearDown() OVERRIDE { @@ -165,6 +175,15 @@ class PolicyManagerImplTest : public ::testing::Test { return ::testing::AssertionFailure() << ::rpc::PrettyFormat(report); } } + +#ifdef SDL_REMOTE_CONTROL + public: + bool CheckPTURemoteCtrlChange( + const utils::SharedPtr<policy_table::Table> pt_update, + const utils::SharedPtr<policy_table::Table> snapshot) { + return manager->CheckPTURemoteCtrlChange(pt_update, snapshot); + } +#endif // SDL_REMOTE_CONTROL }; class PolicyManagerImplTest2 : public ::testing::Test { @@ -189,10 +208,10 @@ class PolicyManagerImplTest2 : public ::testing::Test { const std::string dev_id2; Json::Value PTU_request_types; NiceMock<policy_handler_test::MockPolicySettings> policy_settings_; - const std::string kAppStorageFolder = "storage1"; + const std::string kAppStorageFolder = "storage_PolicyManagerImplTest2"; void SetUp() OVERRIDE { - file_system::CreateDirectory("storage1"); + file_system::CreateDirectory(kAppStorageFolder); file_system::DeleteFile("policy.sqlite"); manager = new PolicyManagerImpl(); @@ -231,7 +250,7 @@ class PolicyManagerImplTest2 : public ::testing::Test { } void CreateLocalPT(const std::string& file_name) { - file_system::remove_directory_content("storage1"); + file_system::remove_directory_content(kAppStorageFolder); ON_CALL(policy_settings_, app_storage_folder()) .WillByDefault(ReturnRef(kAppStorageFolder)); ASSERT_TRUE(manager->InitPT(file_name, &policy_settings_)); @@ -355,6 +374,8 @@ class PolicyManagerImplTest2 : public ::testing::Test { void TearDown() OVERRIDE { delete manager; + file_system::remove_directory_content(kAppStorageFolder); + file_system::RemoveDirectory(kAppStorageFolder, true); } }; @@ -1247,7 +1268,7 @@ TEST_F(PolicyManagerImplTest2, // Arrange CreateLocalPT("sdl_preloaded_pt.json"); GetPTU("valid_sdl_pt_update.json"); - utils::SharedPtr<policy_table::Table> pt = (manager->GetCache())->GetPT(); + utils::SharedPtr<policy_table::Table> pt = (manager->GetCache())->pt(); policy_table::ModuleConfig& module_config = pt->policy_table.module_config; ::policy::VehicleInfo vehicle_info = manager->GetVehicleInfo(); @@ -1328,7 +1349,7 @@ TEST_F( HertBeatTimeout_AddApp_UpdateAppPolicies_ExpectReceivedHertBeatTimeoutCorrect) { // Arrange CreateLocalPT("sdl_preloaded_pt.json"); - utils::SharedPtr<policy_table::Table> pt = (manager->GetCache())->GetPT(); + utils::SharedPtr<policy_table::Table> pt = (manager->GetCache())->pt(); ::policy_table::PolicyTableType type1 = ::policy_table::PolicyTableType::PT_PRELOADED; pt->SetPolicyTableType(type1); diff --git a/src/components/policy/policy_regular/test/sql_pt_representation_test.cc b/src/components/policy/policy_regular/test/sql_pt_representation_test.cc index a313ce6d7f..cef5cdeb38 100644 --- a/src/components/policy/policy_regular/test/sql_pt_representation_test.cc +++ b/src/components/policy/policy_regular/test/sql_pt_representation_test.cc @@ -68,22 +68,23 @@ namespace test { namespace components { namespace policy_test { +using policy_handler_test::MockPolicySettings; + class SQLPTRepresentationTest : public SQLPTRepresentation, public ::testing::Test { protected: - static DBMS* dbms; - static SQLPTRepresentation* reps; + DBMS* dbms; + SQLPTRepresentation* reps; static const std::string kDatabaseName; static const std::string kAppStorageFolder; // Gtest can show message that this object doesn't destroyed - static std::auto_ptr<policy_handler_test::MockPolicySettings> - policy_settings_; + std::auto_ptr<NiceMock<MockPolicySettings> > policy_settings_; - static void SetUpTestCase() { - file_system::DeleteFile(kAppStorageFolder + "/policy.sqlite"); + void SetUp() OVERRIDE { + file_system::CreateDirectory(kAppStorageFolder); reps = new SQLPTRepresentation; - policy_settings_ = std::auto_ptr<policy_handler_test::MockPolicySettings>( - new policy_handler_test::MockPolicySettings()); + policy_settings_ = std::auto_ptr<NiceMock<MockPolicySettings> >( + new NiceMock<MockPolicySettings>()); ON_CALL(*policy_settings_, app_storage_folder()) .WillByDefault(ReturnRef(kAppStorageFolder)); EXPECT_EQ(::policy::SUCCESS, reps->Init(policy_settings_.get())); @@ -93,15 +94,13 @@ class SQLPTRepresentationTest : public SQLPTRepresentation, void TearDown() OVERRIDE { EXPECT_TRUE(reps->Clear()); - } - - static void TearDownTestCase() { EXPECT_TRUE(reps->Drop()); EXPECT_TRUE(reps->Close()); reps->RemoveDB(); delete reps; dbms->Close(); - file_system::RemoveDirectory(kAppStorageFolder); + file_system::remove_directory_content(kAppStorageFolder); + file_system::RemoveDirectory(kAppStorageFolder, true); policy_settings_.reset(); } @@ -346,12 +345,9 @@ class SQLPTRepresentationTest : public SQLPTRepresentation, } }; -DBMS* SQLPTRepresentationTest::dbms = 0; -SQLPTRepresentation* SQLPTRepresentationTest::reps = 0; const std::string SQLPTRepresentationTest::kDatabaseName = "policy.sqlite"; -const std::string SQLPTRepresentationTest::kAppStorageFolder = "storage1"; -std::auto_ptr<policy_handler_test::MockPolicySettings> - SQLPTRepresentationTest::policy_settings_; +const std::string SQLPTRepresentationTest::kAppStorageFolder = + "storage_SQLPTRepresentationTest"; class SQLPTRepresentationTest2 : public ::testing::Test { protected: @@ -378,7 +374,7 @@ class SQLPTRepresentationTest2 : public ::testing::Test { } SQLPTRepresentation* reps; - NiceMock<policy_handler_test::MockPolicySettings> policy_settings_; + NiceMock<MockPolicySettings> policy_settings_; const std::string kAppStorageFolder; const uint16_t kOpenAttemptTimeoutMs; const uint16_t kAttemptsToOpenPolicyDB; @@ -399,7 +395,7 @@ class SQLPTRepresentationTest3 : public ::testing::Test { } SQLPTRepresentation* reps; - NiceMock<policy_handler_test::MockPolicySettings> policy_settings_; + NiceMock<MockPolicySettings> policy_settings_; const std::string kAppStorageFolder; }; @@ -424,7 +420,7 @@ TEST_F(SQLPTRepresentationTest, ASSERT_EQ(0, dbms->FetchOneInt(query_select)); ASSERT_TRUE(reps->RefreshDB()); // Check PT structure destroyed and tables number is 0 - ASSERT_EQ(25, dbms->FetchOneInt(query_select)); + ASSERT_EQ(30, dbms->FetchOneInt(query_select)); const char* query_select_count_of_iap_buffer_full = "SELECT `count_of_iap_buffer_full` FROM `usage_and_error_count`"; const char* query_select_count_sync_out_of_memory = @@ -1102,7 +1098,7 @@ TEST_F(SQLPTRepresentationTest, GetInitialAppData_SetData_ExpectCorrectValuesReceived) { // Arrange const char* query_insert = - "INSERT INTO `nickname` (`application_id`, `name`)" + "INSERT INTO `nickname` (`application_id`, `name`) " "VALUES ('1111', 'first_app') , " "('2222', 'second_app'), ('3333', 'third_app')"; ASSERT_TRUE(dbms->Exec(query_insert)); diff --git a/src/components/remote_control/CMakeLists.txt b/src/components/remote_control/CMakeLists.txt new file mode 100644 index 0000000000..366a8be351 --- /dev/null +++ b/src/components/remote_control/CMakeLists.txt @@ -0,0 +1,86 @@ +set(target "RemoteControlModule") +set(install_destination ${CMAKE_BINARY_DIR}/bin/plugins) +if (ENABLE_GCOV) + set(GCOV_FLAGS "-ftest-coverage -fprofile-arcs") +else() + set(GCOV_FLAGS "") +endif() + +if (CMAKE_BUILD_TYPE) + if (${CMAKE_BUILD_TYPE} STREQUAL "Release") + set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG") + set(CMAKE_CXX_FLAGS_DEBUG "") + else () + set(CMAKE_CXX_FLAGS_RELEASE "") + set(CMAKE_CXX_FLAGS_DEBUG "-g3 -ggdb3 -DDEBUG") + endif() +endif() + +include_directories ( + ${COMPONENTS_DIR}/include/ + ${COMPONENTS_DIR}/application_manager/include + ${COMPONENTS_DIR}/remote_control/include/ + ${COMPONENTS_DIR}/connection_handler/include/ + ${COMPONENTS_DIR}/functional_module/include/ + ${COMPONENTS_DIR}/config_profile/include/ + + ${COMPONENTS_DIR}/hmi_message_handler/include/ + ${COMPONENTS_DIR}/formatters/include/ + ${POLICY_PATH}/include/ + ${POLICY_GLOBAL_INCLUDE_PATH}/ + ${COMPONENTS_DIR}/rpc_base/include/ + ${COMPONENTS_DIR}/application_manager/test/include/ + + ${COMPONENTS_DIR}/smart_objects/include/ + ${COMPONENTS_DIR}/utils/include/ + ${JSONCPP_INCLUDE_DIRECTORY} + ${LOG4CXX_INCLUDE_DIRECTORY} + ${CMAKE_BINARY_DIR}/src/components/ +) + +set (RC_SOURCE_DIR ${COMPONENTS_DIR}/remote_control/src) +set (RC_TEST_DIR ${COMPONENTS_DIR}/remote_control/test) +set (RC_COMMANDS_DIR ${RC_SOURCE_DIR}/commands) + +collect_sources(RC_SOURCES "${RC_SOURCE_DIR}") +collect_sources(RC_COMMANDS_SOURCES "${RC_COMMANDS_DIR}") + +set (SOURCES + ${RC_SOURCES} + ${RC_COMMANDS_SOURCES} +) + +set (LIBRARIES + jsoncpp + FunctionalModule + Utils + ConfigProfile +) + +add_library(${target} SHARED ${SOURCES}) +target_link_libraries(${target} ${LIBRARIES} ) + +if(ENABLE_LOG) + target_link_libraries(${target} log4cxx -L${LOG4CXX_LIBS_DIRECTORY}) +endif() + + +install(TARGETS ${target} + DESTINATION ${install_destination} + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE + GROUP_READ GROUP_EXECUTE + WORLD_READ WORLD_EXECUTE +) + +set(FILES_FOR_COPY +${CMAKE_CURRENT_SOURCE_DIR}/InteriorVehicleDataCapabilities.json +) + +install( + FILES ${FILES_FOR_COPY} + DESTINATION ${install_destination} +) + +if(BUILD_TESTS) + add_subdirectory(test) +endif() diff --git a/src/components/remote_control/InteriorVehicleDataCapabilities.json b/src/components/remote_control/InteriorVehicleDataCapabilities.json new file mode 100644 index 0000000000..7121425606 --- /dev/null +++ b/src/components/remote_control/InteriorVehicleDataCapabilities.json @@ -0,0 +1,6 @@ +{ + "interiorVehicleDataCapabilities": [ + {"moduleType": "CLIMATE"}, + {"moduleType": "RADIO"} + ] +} diff --git a/src/components/remote_control/include/remote_control/commands/base_command_notification.h b/src/components/remote_control/include/remote_control/commands/base_command_notification.h new file mode 100644 index 0000000000..7e695d68c7 --- /dev/null +++ b/src/components/remote_control/include/remote_control/commands/base_command_notification.h @@ -0,0 +1,112 @@ +/* + Copyright (c) 2013, 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_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_COMMANDS_BASE_COMMAND_NOTIFICATION_H_ +#define SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_COMMANDS_BASE_COMMAND_NOTIFICATION_H_ + +#include "remote_control/commands/command.h" +#include "application_manager/message.h" +#include "application_manager/service.h" +#include "remote_control/rc_app_extension.h" +#include "remote_control/remote_plugin_interface.h" +#include "utils/logger.h" + +namespace Json { +class Value; +} + +namespace remote_control { + +namespace commands { + +/** + * @brief Base command class for notifications + */ +class BaseCommandNotification : public Command { + public: + /** + * @brief BaseCommandNotification class constructor + * + * @param message Message from mobile + **/ + BaseCommandNotification(const application_manager::MessagePtr& message, + RemotePluginInterface& rc_module); + + /** + * @brief BaseCommandNotification class destructor + */ + virtual ~BaseCommandNotification(); + + /** + * \brief BaseCommandNotification on timeout reaction + */ + virtual void OnTimeout() {} + + // TODO(KKolodiy): need rename to Execute + void Run(); + + protected: + application_manager::MessagePtr message() { + return message_; + } + application_manager::ServicePtr service_; + + RCAppExtensionPtr GetAppExtension( + application_manager::ApplicationSharedPtr app) const; + + /** + * @brief executes specific logic of children classes + */ + // TODO(KKolodiy): need rename to Run + virtual void Execute() = 0; + + /** + * @brief Validates notification by xml schema + */ + virtual bool Validate(); + + virtual std::string ModuleType(const Json::Value& message); + virtual std::vector<std::string> ControlData(const Json::Value& message); + + void NotifyOneApplication(application_manager::MessagePtr message); + + private: + void NotifyApplications(); + bool CheckPolicy(application_manager::MessagePtr message); + application_manager::MessagePtr message_; +}; + +} // namespace commands + +} // namespace remote_control + +#endif // SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_COMMANDS_BASE_COMMAND_NOTIFICATION_H_ diff --git a/src/components/remote_control/include/remote_control/commands/base_command_request.h b/src/components/remote_control/include/remote_control/commands/base_command_request.h new file mode 100644 index 0000000000..fd58f50722 --- /dev/null +++ b/src/components/remote_control/include/remote_control/commands/base_command_request.h @@ -0,0 +1,281 @@ +/* + Copyright (c) 2013, 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_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_COMMANDS_BASE_COMMAND_REQUEST_H_ +#define SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_COMMANDS_BASE_COMMAND_REQUEST_H_ + +#include "remote_control/commands/command.h" +#include "remote_control/event_engine/event_observer.h" +#include "application_manager/message.h" +#include "application_manager/service.h" +#include "utils/logger.h" +#include "interfaces/HMI_API.h" +#include "remote_control/rc_app_extension.h" +#include "json/json.h" +#include "remote_control/remote_plugin_interface.h" + +namespace remote_control { + +namespace commands { + +// Forward declaration to make this struct friend to BaseCommandRequest +struct OnDriverAnswerCallback; + +/** + * @brief Base command class for requests + */ +class BaseCommandRequest + : public Command, + public rc_event_engine::EventObserver<application_manager::MessagePtr, + std::string> { + public: + /** + * @brief BaseCommandRequest class constructor + * + * @param message Message from mobile + **/ + BaseCommandRequest(const application_manager::MessagePtr& message, + RemotePluginInterface& rc_module); + + /** + * @brief BaseCommandRequest class destructor + */ + virtual ~BaseCommandRequest(); + + /** + * @brief BaseCommandRequest on timeout reaction + */ + virtual void OnTimeout(); + + // TODO(KKolodiy): need rename to Execute + void Run(); + void on_event(const rc_event_engine::Event<application_manager::MessagePtr, + std::string>& event); + + /** + * @brief Generates correct request to HMI + * @param function_id request ID + * @param msg_params json with message params + * @return generated request shared ptr + */ + application_manager::MessagePtr CreateHmiRequest( + const char* function_id, const Json::Value& message_params); + + /** + * @brief Prepares response for sending to mobile + * Adds necessary fields to message + * @param success true if successful; false, if failed + * @param result_code Mobile result code in string ("SUCCESS", "INVALID_DATA", + * e.t.c) + * @param info Provides additional human readable info regarding the + *result(may be empty) + */ + void PrepareResponse(const bool success, + const char* result_code, + const std::string& info); + + protected: + application_manager::MessagePtr message_; + Json::Value response_params_; + + /** + * @brief AcquireResource try to allocate resource for application + * In case if allocation of resource is not required, return ALLOWED by + * default. + * This method should be overrided in RPCs that requires resource allocation + * @return result of resource allocation, in case if allocation os not + * required, return ALLOWED + */ + virtual AcquireResult::eType AcquireResource(const Json::Value&) { + return AcquireResult::ALLOWED; + } + + /** + * @brief IsResourceFree check resource state + * This is default implementation which has to be redefined for RPCs which + * need to manage the resources + * @param module_type Resource name + * @return True if free, otherwise - false + */ + virtual bool IsResourceFree(const std::string& module_type) const { + UNUSED(module_type); + return true; + } + + /** + * @brief SetResourceState changes state of resource + * This is default implementation which has to be redefined for RPCs which + * need to manage the resources + * @param Message containing type of module to extract + * @param State to set for resource + */ + virtual void SetResourceState(const Json::Value&, + const ResourceState::eType) {} + + /** + * @brief Get extension for specified application. If extension doesn't exist, + * it will be created + * @param app pointer to application + * @return pointer to extension + */ + RCAppExtensionPtr GetAppExtension( + application_manager::ApplicationSharedPtr app) const; + + /** + * @brief Converts HMI result code to string with mobile result code + * + * @param hmi_code HMI result code + * @return String with mobile result code + */ + const char* GetMobileResultCode( + const hmi_apis::Common_Result::eType& hmi_code) const; + + /** + * @brief Sends Mobile response + * @param success true if successful; false, if failed + * @param result_code Mobile result code in string ("SUCCESS", "INVALID_DATA", + *e.t.c) + * @param info Provides additional human readable info regarding the + *result(may be empty) + */ + void SendResponse(const bool success, + const char* result_code, + const std::string& info); + + /** + * @brief Parse result code from response + * + * @param message Response from HMI or Can + * @param result_code Outgoing param with mobile result code in string + *("SUCCESS", "INVALID_DATA", e.t.c) + * @param info Outgoing param with additional human readable info regarding + *the result(may be empty) + * @return true if it is success response? otherwise false + */ + bool ParseResultCode(const Json::Value& value, + std::string& result_code, + std::string& info); + + /** + * @brief Sends request to HMI + * @param message_to_send to send + */ + void SendMessageToHMI(const application_manager::MessagePtr& message_to_send); + + /** + * @brief Sends request to CAN or HMI + * @param function_id request ID + * @param msg_params json with message params + */ + void SendRequest(const char* function_id, const Json::Value& message_params); + + application_manager::ApplicationSharedPtr app() { + DCHECK(app_); + return app_; + } + + /** + * @brief executes specific logic of children classes + */ + // TODO(KKolodiy): need rename to Run + void virtual Execute() = 0; + + /** + * @brief Validates request by xml schema + */ + bool Validate(); + + /* + * @brief Parses incoming string into Json + * @param parsed_mgs Resulting json object (must be valid pointer) + * @returns True if json string was valid false otherwise. + */ + virtual bool ParseJsonString(Json::Value* parsed_msg); + + /** + * @brief Interface method that is called whenever new event received + * @param event The received event + */ + void virtual OnEvent( + const rc_event_engine::Event<application_manager::MessagePtr, + std::string>& event) = 0; + + virtual std::string ModuleType(const Json::Value& message); + virtual std::vector<std::string> ControlData(const Json::Value& message); + virtual application_manager::TypeAccess CheckAccess( + const Json::Value& message); + + bool auto_allowed() const { + return auto_allowed_; + } + + void set_auto_allowed(bool value) { + auto_allowed_ = value; + } + + application_manager::ServicePtr service() { + return service_; + } + + void set_disallowed_info(const std::string& info) { + disallowed_info_ = info; + } + + private: + void CheckHMILevel(application_manager::TypeAccess access, + bool hmi_consented = false); + void UpdateHMILevel( + const rc_event_engine::Event<application_manager::MessagePtr, + std::string>& event); + bool CheckPolicyPermissions(); + bool CheckDriverConsent(); + inline bool IsAutoAllowed(application_manager::TypeAccess access) const; + inline bool IsNeededDriverConsent( + application_manager::TypeAccess access) const; + void SendDisallowed(application_manager::TypeAccess access); + void SendGetUserConsent(const Json::Value& value); + void ProcessAccessResponse( + const rc_event_engine::Event<application_manager::MessagePtr, + std::string>& event); + application_manager::ApplicationSharedPtr app_; + application_manager::ServicePtr service_; + bool auto_allowed_; + std::string disallowed_info_; + + friend struct OnDriverAnswerCallback; +}; + +} // namespace commands + +} // namespace remote_control + +#endif // SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_COMMANDS_BASE_COMMAND_REQUEST_H_ diff --git a/src/components/remote_control/include/remote_control/commands/button_press_request.h b/src/components/remote_control/include/remote_control/commands/button_press_request.h new file mode 100644 index 0000000000..6c5a60a9fe --- /dev/null +++ b/src/components/remote_control/include/remote_control/commands/button_press_request.h @@ -0,0 +1,104 @@ +/* + Copyright (c) 2013, 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_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_COMMANDS_BUTTON_PRESS_REQUEST_H_ +#define SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_COMMANDS_BUTTON_PRESS_REQUEST_H_ + +#include "remote_control/commands/base_command_request.h" +#include "remote_control/event_engine/event.h" +#include "utils/macro.h" + +namespace remote_control { + +namespace commands { + +/** + * @brief ButtonPressRequest command class + */ +class ButtonPressRequest : public BaseCommandRequest { + public: + /** + * @brief ButtonPressRequest class constructor + * + * @param message Message from mobile + **/ + ButtonPressRequest(const application_manager::MessagePtr& message, + RemotePluginInterface& rc_module); + /** + * @brief Execute command + */ + void Execute() FINAL; + + /** + * @brief AcquireResource Tries to acquire specific resource + * @param message Incoming message containg the resource name + * @return Acquire result + */ + AcquireResult::eType AcquireResource( + const Json::Value& message) OVERRIDE FINAL; + + /** + * @brief IsResourceFree check resource state + * @param module_type Resource name + * @return True if free, otherwise - false + */ + bool IsResourceFree(const std::string& module_type) const FINAL; + + /** + * @brief SetResourceState changes state of resource + * @param state State to set for resource + */ + void SetResourceState(const Json::Value& message, + const ResourceState::eType state) FINAL; + + /** + * @brief Interface method that is called whenever new event received + * + * @param event The received event + */ + void OnEvent(const rc_event_engine::Event<application_manager::MessagePtr, + std::string>& event); + + /** + * @brief ButtonPressRequest class destructor + */ + virtual ~ButtonPressRequest(); + + protected: + std::string ModuleType(const Json::Value& message) FINAL; +}; + +} // namespace commands + +} // namespace remote_control + +#endif // SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_COMMANDS_BUTTON_PRESS_REQUEST_H_ diff --git a/src/components/remote_control/include/remote_control/commands/command.h b/src/components/remote_control/include/remote_control/commands/command.h new file mode 100644 index 0000000000..ad471ba151 --- /dev/null +++ b/src/components/remote_control/include/remote_control/commands/command.h @@ -0,0 +1,84 @@ +/* + Copyright (c) 2013, 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_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_COMMANDS_COMMAND_H_ +#define SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_COMMANDS_COMMAND_H_ + +#include "utils/shared_ptr.h" +#include "remote_control/remote_plugin_interface.h" +#include "remote_control/event_engine/event.h" + +namespace remote_control { + +class RemotePluginInterface; + +namespace commands { + +/** + * @brief Command interface + **/ +class Command { + public: + /** + * @brief Execute command + */ + virtual void Run() = 0; + + /** + * \brief Command class destructor + */ + virtual ~Command() {} + + /** + * \brief Command on timeout reaction + */ + virtual void OnTimeout() = 0; + + /** + * @brief Interface method that is called whenever new event received + * @param event The received event + */ + virtual void on_event( + const rc_event_engine::Event<application_manager::MessagePtr, + std::string>& event) {} + + protected: + Command(RemotePluginInterface& rc_module) : rc_module_(rc_module) {} + + RemotePluginInterface& rc_module_; +}; + +} // namespace commands + +} // namespace remote_control + +#endif // SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_COMMANDS_COMMAND_H_ diff --git a/src/components/remote_control/include/remote_control/commands/get_interior_vehicle_data_request.h b/src/components/remote_control/include/remote_control/commands/get_interior_vehicle_data_request.h new file mode 100644 index 0000000000..d687221fbe --- /dev/null +++ b/src/components/remote_control/include/remote_control/commands/get_interior_vehicle_data_request.h @@ -0,0 +1,101 @@ +/* + Copyright (c) 2013, 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_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_COMMANDS_GET_INTERIOR_VEHICLE_DATA_REQUEST_H_ +#define SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_COMMANDS_GET_INTERIOR_VEHICLE_DATA_REQUEST_H_ + +#include "remote_control/commands/base_command_request.h" +#include "remote_control/event_engine/event.h" +#include "utils/macro.h" + +namespace remote_control { + +namespace commands { + +/** + * @brief GetInteriorVehicleDataRequest command class + */ +class GetInteriorVehicleDataRequest : public BaseCommandRequest { + public: + /** + * @brief GetInteriorVehicleDataRequest class constructor + * + * @param message Message from mobile + **/ + explicit GetInteriorVehicleDataRequest( + const application_manager::MessagePtr& message, + RemotePluginInterface& rc_module); + + /** + * @brief Execute command + */ + void Execute() FINAL; + + /** + * @brief Interface method that is called whenever new event received + * + * @param event The received event + */ + void OnEvent(const rc_event_engine::Event<application_manager::MessagePtr, + std::string>& event); + + /** + * @brief Check if app wants to proceed with already setup subscription + * @param request_params request parameters to check + * @return true if app already subscribed(unsubsribed) for module type but + * wants to subscribe(unsubscribe) for the same module again + * otherwise - false + */ + bool HasRequestExcessiveSubscription(const Json::Value& request_params); + + protected: + virtual std::string ModuleType(const Json::Value& message); + + private: + /** + * @brief Handle subscription to vehicle data + * @param hmi_response json message with response from HMI + */ + void ProccessSubscription(const Json::Value& hmi_response); + + /** + * @brief Cuts off subscribe parameter + * @param request_params request parameters to handle + */ + void RemoveExcessiveSubscription(Json::Value& request_params); +}; + +} // namespace commands + +} // namespace remote_control + +#endif // SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_COMMANDS_GET_INTERIOR_VEHICLE_DATA_REQUEST_H_ diff --git a/src/components/remote_control/include/remote_control/commands/on_interior_vehicle_data_notification.h b/src/components/remote_control/include/remote_control/commands/on_interior_vehicle_data_notification.h new file mode 100644 index 0000000000..bc9c9bee8e --- /dev/null +++ b/src/components/remote_control/include/remote_control/commands/on_interior_vehicle_data_notification.h @@ -0,0 +1,75 @@ +/* + Copyright (c) 2013, 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_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_COMMANDS_ON_INTERIOR_VEHICLE_DATA_NOTIFICATION_H_ +#define SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_COMMANDS_ON_INTERIOR_VEHICLE_DATA_NOTIFICATION_H_ + +#include "utils/macro.h" +#include "remote_control/commands/base_command_notification.h" + +namespace remote_control { + +namespace commands { + +/** + * @brief OnInteriorVehicleDataNotification command class + */ +class OnInteriorVehicleDataNotification : public BaseCommandNotification { + public: + /** + * @brief OnInteriorVehicleDataNotification class constructor + * + * @param message Message with notification + **/ + OnInteriorVehicleDataNotification( + const application_manager::MessagePtr& message, + RemotePluginInterface& rc_module); + + /** + * @brief Execute command + */ + void Execute() FINAL; + + /** + * @brief OnInteriorVehicleDataNotification class destructor + */ + virtual ~OnInteriorVehicleDataNotification(); + + protected: + std::string ModuleType(const Json::Value& message) FINAL; +}; + +} // namespace commands + +} // namespace remote_control + +#endif // SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_COMMANDS_ON_INTERIOR_VEHICLE_DATA_NOTIFICATION_H_ diff --git a/src/components/remote_control/include/remote_control/commands/on_remote_control_settings_notification.h b/src/components/remote_control/include/remote_control/commands/on_remote_control_settings_notification.h new file mode 100644 index 0000000000..ef248a2b38 --- /dev/null +++ b/src/components/remote_control/include/remote_control/commands/on_remote_control_settings_notification.h @@ -0,0 +1,79 @@ +/* + Copyright (c) 2017, 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_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_COMMANDS_ON_REMOTE_CONTROL_SETTINGS_NOTIFICATION_H_ +#define SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_COMMANDS_ON_REMOTE_CONTROL_SETTINGS_NOTIFICATION_H_ + +#include "utils/macro.h" +#include "remote_control/commands/base_command_notification.h" + +namespace remote_control { + +namespace commands { + +/** + * @brief OnRemoteControlSettingsNotification command class + */ +class OnRemoteControlSettingsNotification : public BaseCommandNotification { + public: + /** + * @brief OnRemoteControlSettingsNotification class constructor + * + * @param message Message with notification + * @param rc_module Module used for handling RC functionality + **/ + OnRemoteControlSettingsNotification( + const application_manager::MessagePtr& message, + RemotePluginInterface& rc_module); + + /** + * @brief Execute command + */ + void Execute() FINAL; + + private: + /** + * @brief Disalows RC functionality for all RC apps + * All registered apps with appHMIType REMOTE_CONTROL will be put to NONE hmi + * level + * OnHMIStatus (NONE) will be send to such apps + * All registered apps will be unsubsribed from OnInteriorVehicleData + * notifications + */ + void DisallowRCFunctionality(); +}; + +} // namespace commands + +} // namespace remote_control + +#endif // SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_COMMANDS_ON_REMOTE_CONTROL_SETTINGS_NOTIFICATION_H_ diff --git a/src/components/remote_control/include/remote_control/commands/set_interior_vehicle_data_request.h b/src/components/remote_control/include/remote_control/commands/set_interior_vehicle_data_request.h new file mode 100644 index 0000000000..92f449b034 --- /dev/null +++ b/src/components/remote_control/include/remote_control/commands/set_interior_vehicle_data_request.h @@ -0,0 +1,128 @@ +/* + Copyright (c) 2017, 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_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_COMMANDS_SET_INTERIOR_VEHICLE_DATA_REQUEST_H_ +#define SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_COMMANDS_SET_INTERIOR_VEHICLE_DATA_REQUEST_H_ + +#include "remote_control/commands/base_command_request.h" +#include "remote_control/event_engine/event.h" +#include "utils/macro.h" + +namespace remote_control { + +namespace commands { + +/** + * @brief SetInteriorVehicleDataRequest command class + */ +class SetInteriorVehicleDataRequest : public BaseCommandRequest { + public: + /** + * @brief SetInteriorVehicleDataRequest class constructor + * + * @param message Message from mobile + * @param rc_module Module used for handling RC functionality + **/ + SetInteriorVehicleDataRequest(const application_manager::MessagePtr& message, + RemotePluginInterface& rc_module); + + /** + * @brief Execute command + */ + void Execute() FINAL; + + /** + * @brief AcquireResource proxy AcquireResource to Resource allocation manager + * @param message message of requires contatin module types + * @return result of acauiring resources + */ + AcquireResult::eType AcquireResource( + const Json::Value& message) OVERRIDE FINAL; + + /** + * @brief IsResourceFree check resource state + * @param module_type Resource name + * @return True if free, otherwise - false + */ + bool IsResourceFree(const std::string& module_type) const FINAL; + + /** + * @brief SetResourceState changes state of resource + * @param state State to set for resource + */ + void SetResourceState(const Json::Value& message, + const ResourceState::eType state) FINAL; + + /** + * @brief Interface method that is called whenever new event received + * + * @param event The received event + */ + void OnEvent(const rc_event_engine::Event<application_manager::MessagePtr, + std::string>& event) OVERRIDE; + + /** + * @brief Method that check if READ_ONLY parameters present + * @param request_params params from received message + * @return true if present , false - otherwise + */ + bool AreReadOnlyParamsPresent(const Json::Value& request_params); + + /** + * @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 Json::Value& request_params); + + /** + * @brief Method that cuts-off READ_ONLY parameters + * @param request_params params to handle + */ + void CutOffReadOnlyParams(Json::Value& request_params); + + /** + * @brief SetInteriorVehicleDataRequest class destructor + */ + virtual ~SetInteriorVehicleDataRequest(); + + protected: + virtual std::string ModuleType(const Json::Value& message) FINAL; + virtual std::vector<std::string> ControlData( + const Json::Value& message) FINAL; +}; + +} // namespace commands + +} // namespace remote_control + +#endif // SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_COMMANDS_SET_INTERIOR_VEHICLE_DATA_REQUEST_H_ diff --git a/src/components/remote_control/include/remote_control/event_engine/event.h b/src/components/remote_control/include/remote_control/event_engine/event.h new file mode 100644 index 0000000000..531c35135b --- /dev/null +++ b/src/components/remote_control/include/remote_control/event_engine/event.h @@ -0,0 +1,127 @@ +/* + Copyright (c) 2013, 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_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_EVENT_ENGINE_EVENT_H_ +#define SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_EVENT_ENGINE_EVENT_H_ + +#include <string> +#include "remote_control/event_engine/event_dispatcher.h" +#include "utils/shared_ptr.h" +#include "application_manager/message.h" + +namespace rc_event_engine { + +template <typename EventMessage, typename EventID> +class EventDispatcher; + +template <typename EventMessage, typename EventID> +class Event { + public: + /* + * @brief Constructor with parameters + * + * @param id Event ID. + * @param message Message received in event + */ + Event(EventMessage& message, const EventID& id); + + /* + * @brief Destructor + */ + virtual ~Event() {} + + /* + * @brief Provides event ID + */ + inline const EventID& id() const; + + /* + * @brief Sets event message + * + * @param message The message received in event + */ + void set_event_message(EventMessage& message); + + /* + * @brief Retrieves event message + * + * @return The message received in event + */ + inline const EventMessage& event_message() const; + + /* + * @brief Retrieves event message request ID + */ + virtual int32_t event_message_function_id() const = 0; + + /* + * @brief Retrieves event message correlation ID + */ + virtual int32_t event_message_correlation_id() const = 0; + + /* + * @brief Retrieves event message response type + */ + virtual int32_t event_message_type() const = 0; + + void raise(EventDispatcher<EventMessage, EventID>& event_dispatcher); + + protected: + EventMessage event_message_; + + private: + EventID id_; +}; + +template <typename EventMessage, typename EventID> +const EventID& Event<EventMessage, EventID>::id() const { + return id_; +} + +template <typename EventMessage, typename EventID> +const EventMessage& Event<EventMessage, EventID>::event_message() const { + return event_message_; +} + +template <typename EventMessage, typename EventID> +Event<EventMessage, EventID>::Event(EventMessage& message, const EventID& id) + : event_message_(message), id_(id) {} + +template <typename EventMessage, typename EventID> +void Event<EventMessage, EventID>::raise( + EventDispatcher<EventMessage, EventID>& event_dispatcher) { + event_dispatcher.raise_event(*this); +} + +} // namespace event_engine + +#endif // SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_EVENT_ENGINE_EVENT_H_ diff --git a/src/components/remote_control/include/remote_control/event_engine/event_dispatcher.h b/src/components/remote_control/include/remote_control/event_engine/event_dispatcher.h new file mode 100644 index 0000000000..4776f355c4 --- /dev/null +++ b/src/components/remote_control/include/remote_control/event_engine/event_dispatcher.h @@ -0,0 +1,203 @@ +/* + Copyright (c) 2013, 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_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_EVENT_ENGINE_EVENT_DISPATCHER_H_ +#define SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_EVENT_ENGINE_EVENT_DISPATCHER_H_ + +#include <list> +#include <map> + +#include "utils/lock.h" + +#include "remote_control/event_engine/event.h" +#include "remote_control/event_engine/event_observer.h" + +#include "interfaces/HMI_API.h" + +namespace rc_event_engine { + +template <typename EventMessage, typename EventID> +class Event; + +template <typename EventMessage, typename EventID> +class EventObserver; + +template <typename EventMessage, typename EventID> +class EventDispatcher { + public: + /** + * @brief Default constructor + */ + EventDispatcher(); + + /** + * @brief Destructor + */ + virtual ~EventDispatcher(); + + /* + * @brief Delivers the event to all subscribers + * + * @param event Received event + */ + void raise_event(const Event<EventMessage, EventID>& event); + + /* + * @brief Subscribe the observer to event + * + * @param event_id The event ID to subscribe for + * @param hmi_correlation_id The event HMI correlation ID + * @param observer The observer to subscribe for event + */ + void add_observer(const EventID& event_id, + int32_t hmi_correlation_id, + EventObserver<EventMessage, EventID>* const observer); + + /* + * @brief Unsubscribes the observer from specific event + * + * @param event_id The event ID to unsubscribe from + * @param observer The observer to be unsubscribed + */ + void remove_observer( + const EventID& event_id, + const EventObserver<EventMessage, EventID>* const observer); + + /* + * @brief Unsubscribes the observer from all events + * + * @param observer The observer to be unsubscribed + */ + void remove_observer( + const EventObserver<EventMessage, EventID>* const observer); + + protected: + private: + DISALLOW_COPY_AND_ASSIGN(EventDispatcher); + + // Data types section + typedef std::list<EventObserver<EventMessage, EventID>*> ObserverList; + typedef std::map<int32_t, ObserverList> ObserversMap; + typedef std::map<EventID, ObserversMap> EventObserverMap; + + // Members section + sync_primitives::Lock state_lock_; + EventObserverMap observers_; +}; + +template <typename EventMessage, typename EventID> +EventDispatcher<EventMessage, EventID>::EventDispatcher() + : observers_() {} + +template <typename EventMessage, typename EventID> +EventDispatcher<EventMessage, EventID>::~EventDispatcher() {} + +template <typename EventMessage, typename EventID> +void EventDispatcher<EventMessage, EventID>::raise_event( + const Event<EventMessage, EventID>& event) { + // create local list + ObserverList list; + { + sync_primitives::AutoLock auto_lock(state_lock_); + // check if event is notification + if (hmi_apis::messageType::notification == event.event_message_type()) { + // ObserversMap iterator + typename ObserversMap::iterator it = observers_[event.id()].begin(); + for (; observers_[event.id()].end() != it; ++it) { + list = it->second; + } + } + + if ((hmi_apis::messageType::response == event.event_message_type()) || + (hmi_apis::messageType::error_response == event.event_message_type())) { + list = observers_[event.id()][event.event_message_correlation_id()]; + } + } + + // Call observers + typename ObserverList::iterator observers = list.begin(); + for (; list.end() != observers; ++observers) { + (*observers)->on_event(event); + } +} + +template <typename EventMessage, typename EventID> +void EventDispatcher<EventMessage, EventID>::add_observer( + const EventID& event_id, + int32_t hmi_correlation_id, + EventObserver<EventMessage, EventID>* const observer) { + sync_primitives::AutoLock auto_lock(state_lock_); + observers_[event_id][hmi_correlation_id].push_back(observer); +} + +template <typename EventMessage, typename EventID> +void EventDispatcher<EventMessage, EventID>::remove_observer( + const EventID& event_id, + const EventObserver<EventMessage, EventID>* const observer) { + sync_primitives::AutoLock auto_lock(state_lock_); + typename ObserversMap::iterator it = observers_[event_id].begin(); + for (; observers_[event_id].end() != it; ++it) { + // ObserverList iterator + typename ObserverList::iterator observer_it = it->second.begin(); + while (it->second.end() != observer_it) { + if (observer->id() == (*observer_it)->id()) { + observer_it = it->second.erase(observer_it); + } else { + ++observer_it; + } + } + } +} + +template <typename EventMessage, typename EventID> +void EventDispatcher<EventMessage, EventID>::remove_observer( + const EventObserver<EventMessage, EventID>* const observer) { + sync_primitives::AutoLock auto_lock(state_lock_); + typename EventObserverMap::iterator event_map = observers_.begin(); + for (; observers_.end() != event_map; ++event_map) { + typename ObserversMap::iterator it = event_map->second.begin(); + for (; event_map->second.end() != it; ++it) { + // ObserverList iterator + typename ObserverList::iterator observer_it = it->second.begin(); + while (it->second.end() != observer_it) { + if (observer->id() == (*observer_it)->id()) { + observer_it = it->second.erase(observer_it); + } else { + ++observer_it; + } + } + } + } +} +} + +#endif // SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_EVENT_ENGINE_EVENT_DISPATCHER_H_ diff --git a/src/components/remote_control/include/remote_control/event_engine/event_observer.h b/src/components/remote_control/include/remote_control/event_engine/event_observer.h new file mode 100644 index 0000000000..e2f3d8ea1e --- /dev/null +++ b/src/components/remote_control/include/remote_control/event_engine/event_observer.h @@ -0,0 +1,96 @@ +/* + Copyright (c) 2013, 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_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_EVENT_ENGINE_EVENT_OBSERVER_H_ +#define SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_EVENT_ENGINE_EVENT_OBSERVER_H_ + +#include <string> +#include "remote_control/event_engine/event.h" + +namespace rc_event_engine { + +template <typename EventMessage, typename EventID> +class Event; + +template <typename EventMessage, typename EventID> +class EventObserver { + public: + // Typedef for possible Observer ID's from mobile_apis functionID enum + typedef unsigned long ObserverID; + + /* + * @brief Constructor + * + */ + EventObserver(); + + /* + * @brief Destructor + */ + virtual ~EventObserver(); + + /** + * @brief Retrieves observer unique id + * + * @return Unique Observer id + */ + const ObserverID& id() const { + return id_; + } + + /** + * @brief Interface method that is called whenever new event received + * + * @param event The received event + */ + virtual void on_event(const Event<EventMessage, EventID>& event) = 0; + + private: + ObserverID id_; + + DISALLOW_COPY_AND_ASSIGN(EventObserver); +}; + +template <typename EventMessage, typename EventID> +EventObserver<EventMessage, EventID>::EventObserver() + : id_(0) { + // Get unique id based on this + id_ = reinterpret_cast<unsigned long>(this); +} + +template <typename EventMessage, typename EventID> +EventObserver<EventMessage, EventID>::~EventObserver() { + // unsubscribe_from_all_events(); +} +} + +#endif // SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_EVENT_ENGINE_EVENT_OBSERVER_H_ diff --git a/src/components/remote_control/include/remote_control/message_helper.h b/src/components/remote_control/include/remote_control/message_helper.h new file mode 100644 index 0000000000..f90e621e1e --- /dev/null +++ b/src/components/remote_control/include/remote_control/message_helper.h @@ -0,0 +1,135 @@ +/* + Copyright (c) 2013, 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_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_MESSAGE_HELPER_H_ +#define SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_MESSAGE_HELPER_H_ + +#include <stdint.h> +#include <string> +#include <map> + +#include "utils/macro.h" +#include "json/json.h" +#include "interfaces/HMI_API.h" +#include "functional_module/function_ids.h" +#include "remote_control/remote_plugin_interface.h" +#include "application_manager/message.h" + +namespace remote_control { + +/** + * @brief MessageHelper class + **/ +class MessageHelper { + public: + /** + * @brief Returns unique correlation ID for next CAN request + * + * @return Unique correlation ID + */ + static uint32_t GetNextRCCorrelationID(); + static const std::string GetMobileAPIName( + functional_modules::RCFunctionID func_id); + + /** + * @brief Convert Json::Value to std::string + * + * @param value Value with json + * + * @return string with json + */ + static std::string ValueToString(const Json::Value& value); + + /** + * @brief Convert std::string to Json::Value + * + * @param string string with json + * + * @return Value created from string with json + */ + static Json::Value StringToValue(const std::string& string); + + /** + * Validates structure DeviceInfo + * @param value json of DeviceInfo + * @return true if json is valid + */ + static bool ValidateDeviceInfo(const Json::Value& value); + + /** + * Validates structure InteriorZone + * @param value json of InteriorZone + * @return true if json is valid + */ + static bool ValidateInteriorZone(const Json::Value& value); + + /** + * Creates hmi request + * @param function_id - API function we create request for + * @param message_params - params in request + * @param rc_module - used module for requests handling + * @param hmi_app_id - app is used between SDL & HMI + * @return creted request - reqdy to be sent to hmi + */ + static application_manager::MessagePtr CreateHmiRequest( + const char* function_id, + const uint32_t hmi_app_id, + const Json::Value& message_params, + RemotePluginInterface& rc_module); + + /** @brief Converts string to hmi AccessMode enum value + * @param access_mode stringified value + * @return hmi AccessMode enum value if succedeed, otherwise - INVALID_ENUM + * value + */ + static hmi_apis::Common_RCAccessMode::eType AccessModeFromString( + const std::string& access_mode); + + private: + MessageHelper(); + + static uint32_t next_correlation_id_; + static const std::map<functional_modules::RCFunctionID, std::string> + kMobileAPINames; + DISALLOW_COPY_AND_ASSIGN(MessageHelper); +}; + +/** @brief Check for existence of specified key in Json::Value + * @param value Value with json + * @param key string with key name + * @return true if key exist + */ +bool IsMember(const Json::Value& value, const std::string& key); + +} // namespace remote_control + +#endif // SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_MESSAGE_HELPER_H_ diff --git a/src/components/remote_control/include/remote_control/module_helper.h b/src/components/remote_control/include/remote_control/module_helper.h new file mode 100644 index 0000000000..a964fe1422 --- /dev/null +++ b/src/components/remote_control/include/remote_control/module_helper.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013, 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_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_MODULE_HELPER_H_ +#define SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_MODULE_HELPER_H_ + +#include "functional_module/generic_module.h" +#include "json/json.h" +#include "interfaces/HMI_API.h" +#include "remote_control/remote_plugin_interface.h" + +namespace remote_control { + +/** + * @brief ModuleHelper class + **/ +class ModuleHelper { + public: + static void ProccessOnReverseAppsDisallowed(RemotePluginInterface& rc_module); + + private: + ModuleHelper(); + + static application_manager::MessagePtr ResponseToHMI( + unsigned int id, + hmi_apis::Common_Result::eType result_code, + const std::string& method_name); + DISALLOW_COPY_AND_ASSIGN(ModuleHelper); +}; + +} // namespace remote_control + +#endif // SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_MODULE_HELPER_H_ diff --git a/src/components/remote_control/include/remote_control/policy_helper.h b/src/components/remote_control/include/remote_control/policy_helper.h new file mode 100644 index 0000000000..92be79775a --- /dev/null +++ b/src/components/remote_control/include/remote_control/policy_helper.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013, 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_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_POLICY_HELPER_H_ +#define SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_POLICY_HELPER_H_ + +#include <string> +#include "application_manager/application.h" +#include "remote_control/remote_plugin_interface.h" + +namespace remote_control { + +class PolicyHelper { + public: + static void OnRSDLFunctionalityAllowing(bool allowed, + RemotePluginInterface& rc_module); + static void ChangeDeviceRank(const uint32_t device_handle, + const std::string& rank, + RemotePluginInterface& rc_module); + static void SetIsAppOnPrimaryDevice( + application_manager::ApplicationSharedPtr app, + RemotePluginInterface& rc_module); + + private: + static void MarkApplications(const uint32_t device_handle, + RemotePluginInterface& rc_module); + static void MarkAppOnPrimaryDevice( + application_manager::ApplicationSharedPtr app, + const uint32_t device_handle, + RemotePluginInterface& rc_module); +}; + +} // namespace remote_control + +#endif // SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_POLICY_HELPER_H_ diff --git a/src/components/remote_control/include/remote_control/rc_app_extension.h b/src/components/remote_control/include/remote_control/rc_app_extension.h new file mode 100644 index 0000000000..07a8eecb67 --- /dev/null +++ b/src/components/remote_control/include/remote_control/rc_app_extension.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013, 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_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_RC_APP_EXTENSION_H_ +#define SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_RC_APP_EXTENSION_H_ + +#include <string> +#include <set> +#include "application_manager/service.h" +#include "application_manager/app_extension.h" +#include "remote_control/remote_control_plugin.h" +#include "json/json.h" + +namespace remote_control { + +class RCAppExtension : public application_manager::AppExtension { + public: + explicit RCAppExtension(application_manager::AppExtensionUID uid); + ~RCAppExtension(); + + /** + * @brief Checks is application has access to a radio tune control + * @return true if control given + */ + bool IsControlGiven() const; + + /** + * @brief Give radio tune control to application + * @param is_control_given true - give control, false - cancel control + */ + void GiveControl(bool is_control_given); + + bool is_on_driver_device() const { + return is_on_driver_device_; + } + + void set_is_on_driver_device(bool is_driver_dev) { + is_on_driver_device_ = is_driver_dev; + } + + /** + * @brief Subscribe to OnInteriorVehicleDataNotification + * @param module interior data specification(zone, data type) + */ + void SubscribeToInteriorVehicleData(const Json::Value& module_type); + + /** + * @brief Unsubscribe from OnInteriorVehicleDataNotification + * @param module interior data specification(zone, data type) + */ + void UnsubscribeFromInteriorVehicleData(const Json::Value& module_type); + + /** + * @brief Check if application subscribed to OnInteriorVehicleDataNotification + * @param module interior data specification(zone, data type) + */ + bool IsSubscibedToInteriorVehicleData(const Json::Value& module_type); + + private: + bool is_control_given_; + bool is_on_driver_device_; + std::set<Json::Value> subscribed_interior_vehicle_data_; +}; + +typedef utils::SharedPtr<RCAppExtension> RCAppExtensionPtr; + +} // namespace remote_control + +#endif // SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_RC_APP_EXTENSION_H_ diff --git a/src/components/remote_control/include/remote_control/rc_command_factory.h b/src/components/remote_control/include/remote_control/rc_command_factory.h new file mode 100644 index 0000000000..06332995b2 --- /dev/null +++ b/src/components/remote_control/include/remote_control/rc_command_factory.h @@ -0,0 +1,66 @@ +/* + Copyright (c) 2013, 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_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_RC_COMMAND_FACTORY_H_ +#define SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_RC_COMMAND_FACTORY_H_ + +#include "utils/shared_ptr.h" +#include "remote_control/commands/command.h" +#include "remote_control/remote_control_plugin.h" +#include "application_manager/message.h" +#include "utils/macro.h" + +namespace remote_control { + +/** + * @brief Factory class for command creation + **/ +class RCCommandFactory { + public: + /** + * @brief Create command object and return pointer to it + * + * @param message Message shared pointer. + * @return Pointer to created command object. + **/ + static utils::SharedPtr<commands::Command> CreateCommand( + const application_manager::MessagePtr& msg, + RemotePluginInterface& rc_module); + + private: + RCCommandFactory(); + DISALLOW_COPY_AND_ASSIGN(RCCommandFactory); +}; + +} // namespace can_cooperaion + +#endif // SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_RC_COMMAND_FACTORY_H_ diff --git a/src/components/remote_control/include/remote_control/rc_module_constants.h b/src/components/remote_control/include/remote_control/rc_module_constants.h new file mode 100644 index 0000000000..503266f35c --- /dev/null +++ b/src/components/remote_control/include/remote_control/rc_module_constants.h @@ -0,0 +1,306 @@ +/* + Copyright (c) 2013, 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_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_RC_MODULE_CONSTANTS_H_ +#define SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_RC_MODULE_CONSTANTS_H_ + +namespace remote_control { + +namespace strings {} // strings + +namespace result_codes { +const char kSuccess[] = "SUCCESS"; +const char kUnsupportedRequest[] = "UNSUPPORTED_REQUEST"; +const char kUnsupportedResource[] = "UNSUPPORTED_RESOURCE"; +const char kDisallowed[] = "DISALLOWED"; +const char kRejected[] = "REJECTED"; +const char kAborted[] = "ABORTED"; +const char kIgnored[] = "IGNORED"; +const char kRetry[] = "RETRY"; +const char kInUse[] = "IN_USE"; +const char kVehicleDataNotAvailable[] = "VEHICLE_DATA_NOT_AVAILABLE"; +const char kTimedOut[] = "TIMED_OUT"; +const char kInvalidData[] = "INVALID_DATA"; +const char kCharLimitExceeded[] = "CHAR_LIMIT_EXCEEDED"; +const char kInvalidId[] = "INVALID_ID"; +const char kDuplicateName[] = "DUPLICATE_NAME"; +const char kApplicationNotRegistered[] = "APPLICATION_NOT_REGISTERED"; +const char kOutOfMemory[] = "OUT_OF_MEMORY"; +const char kTooManyPendingRequests[] = "TOO_MANY_PENDING_REQUESTS"; +const char kWarnings[] = "WARNINGS"; +const char kWrongLanguage[] = "WRONG_LANGUAGE"; +const char kGenericError[] = "GENERIC_ERROR"; +const char kUserDisallowed[] = "USER_DISALLOWED"; +const char kReadOnly[] = "READ_ONLY"; +} // result_codes + +namespace json_keys { +const char kParams[] = "params"; +const char kSuccess[] = "success"; +const char kResultCode[] = "resultCode"; +const char kResult[] = "result"; +const char kInfo[] = "info"; +const char kId[] = "id"; +const char kJsonrpc[] = "jsonrpc"; +const char kMethod[] = "method"; +const char kError[] = "error"; +const char kMessage[] = "message"; +const char kData[] = "data"; +const char kAppId[] = "appID"; +const char kCode[] = "code"; +} // json_keys + +namespace message_params { +/* +const char kCustomPresets[] = "customPresets"; +const char kRadioStation[] = "radioStation"; +const char kSongInfo[] = "songInfo"; +const char kEvent[] = "event"; +const char kAdvertisement[] = "advertisement"; +const char kActivity[] = "activity"; +const char kTriggerSource[] = "triggerSource"; + +// RadioStation struct +const char kFrequency[] = "frequency"; +const char kFraction[] = "fraction"; +const char kAvailableHDs[] = "availableHDs"; +const char kCurrentHD[] = "currentHD"; +// RadioStation struct + +// Time struct +const char kHours[] = "hours"; +const char kMinutes[] = "minutes"; +const char kSeconds[] = "seconds"; +const char kYear[] = "year"; +const char kMonth[] = "month"; +const char kDay[] = "day"; +const char kTZD[] = "TZD"; +// Time struct + +// Address struct +const char kState[] = "state"; +const char kZipCode[] = "zipcode"; +const char kCity[] = "city"; +const char kStreet[] = "street"; +// Address struct + +// Location struct +const char kGPSCoordinates[] = "gpsCoordinates"; +const char kAddress[] = "address"; +// Location struct + +// SongInfo struct +const char kArtist[] = "artist"; +const char kGenre[] = "genre"; +const char kAlbum[] = "album"; +const char kSongYear[] = "year"; +const char kDuration[] = "duration"; +// SongInfo struct + +// Advertisement struct +const char kProductName[] = "productName"; +const char kCompanyName[] = "companyName"; +const char kPhoneNumber[] = "phoneNumber"; +const char kLocation[] = "location"; +// Advertisement struct + +// EventDetails struct +const char kEventName[] = "eventName"; +// const char kPhoneNumber[] = "phoneNumber"; +const char kPrice[] = "price"; +const char kEventTime[] = "eventTime"; +// EventDetails struct + +// WebActivity struct +const char kURL[] = "url"; +const char kActionCode[] = "actionCode"; +// WebActivity struct +*/ + +// SetInteriorVehicleData request +const char kModuleData[] = "moduleData"; +// SetInteriorVehicleData request + +// SetInteriorVehicleData response +// const char kModuleData[] = "moduleData"; +// SetInteriorVehicleData response + +// GetInteriorVehicleData request +const char kSubscribe[] = "subscribe"; +// GetInteriorVehicleData request + +// GetInteriorVehicleData response +// const char kModuleData[] = "moduleData"; +const char kIsSubscribed[] = "isSubscribed"; +// GetInteriorVehicleData response + +// OnInteriorVehicleData notification +// const char kModuleData[] = "moduleData"; +// OnInteriorVehicleData notification + +// OnRemoteControlSettings notification +const char kAccessMode[] = "accessMode"; +const char kAllowed[] = "allowed"; +// OnRemoteControlSettings notification + +// RC.OnDriverRankChanged notification +const char kDevice[] = "device"; +const char kName[] = "name"; +const char kRank[] = "deviceRank"; +// RC.OnDriverRankChanged notification + +// ButtonPress request +const char kModuleType[] = "moduleType"; +const char kButtonName[] = "buttonName"; +const char kButtonPressMode[] = "buttonPressMode"; +// ButtonPress request + +// RdsData struct +const char kPS[] = "PS"; +const char kRT[] = "RT"; +const char kCT[] = "CT"; +const char kPI[] = "PI"; +const char kPTY[] = "PTY"; +const char kTA[] = "TA"; +const char kTP[] = "TP"; +const char kREG[] = "REG"; +// RdsData struct + +// RadioControlData struct +const char kFrequencyInteger[] = "frequencyInteger"; +const char kFrequencyFraction[] = "frequencyFraction"; +const char kBand[] = "band"; +const char kRdsData[] = "rdsData"; +const char kAvailableHDs[] = "availableHDs"; +const char kHdChannel[] = "hdChannel"; +const char kSignalStrength[] = "signalStrength"; +const char kSignalChangeThreshold[] = "signalChangeThreshold"; +const char kRadioEnable[] = "radioEnable"; +const char kState[] = "state"; +// RadioControlData struct + +// ClimateControlData struct +const char kFanSpeed[] = "fanSpeed"; +const char kCurrentTemperature[] = "currentTemperature"; +const char kDesiredTemperature[] = "desiredTemperature"; +const char kTemperatureUnit[] = "temperatureUnit"; +const char kACEnable[] = "acEnable"; +const char kCirculateAirEnable[] = "circulateAirEnable"; +const char kAutoModeEnable[] = "autoModeEnable"; +const char kDefrostZone[] = "defrostZone"; +const char kDualModeEnable[] = "dualModeEnable"; +const char kACMaxEnable[] = "acMaxEnable"; +const char kVentilationMode[] = "ventilationMode"; +// ClimateControlData struct + +// ModuleData struct +const char kRadioControlData[] = "radioControlData"; +const char kClimateControlData[] = "climateControlData"; +// ModuleData struct + +const char kHMIAppID[] = "appID"; +const char kHmiLevel[] = "hmiLevel"; +const char kSysContext[] = "systemContext"; +const char kAudioState[] = "audioStreamingState"; +} // namespace message_params + +namespace enums_value { +// TriggerSource enum +// const char kMenu[] = "MENU"; +// const char kVR[] = "VR"; +// TriggerSource enum + +// ModuleType enum +const char kClimate[] = "CLIMATE"; +const char kRadio[] = "RADIO"; +// ModuleType enum + +// RadioBand enum +const char kAM[] = "AM"; +const char kFM[] = "FM"; +const char kXM[] = "XM"; +// RadioBand enum + +// RadioState enum +const char kAcquiring[] = "ACQUIRING"; +const char kAcquired[] = "ACQUIRED"; +const char kMulticast[] = "MULTICAST"; +const char kNotFound[] = "NOT_FOUND"; +// RadioState enum + +// DefrostZone enum +const char kFront[] = "FRONT"; +const char kRear[] = "REAR"; +const char kAll[] = "ALL"; +// DefrostZone enum + +// TemperatureUnit enum +const char kFahrenheit[] = "FAHRENHEIT"; +const char kCelsius[] = "CELSIUS"; +// TemperatureUnit enum + +// ButtonName enum +const char kACMax[] = "AC_MAX"; +const char kAC[] = "AC"; +const char kRecirculate[] = "RECIRCULATE"; +const char kFanUp[] = "FAN_UP"; +const char kFanDown[] = "FAN_DOWN"; +const char kTempUp[] = "TEMP_UP"; +const char kTempDown[] = "TEMP_DOWN"; +const char kDefrostMax[] = "DEFROST_MAX"; +const char kDefrost[] = "DEFROST"; +const char kDefrostRear[] = "DEFROST_REAR"; +const char kUpperVent[] = "UPPER_VENT"; +const char kLowerVent[] = "LOWER_VENT"; +const char kVolumeUp[] = "VOLUME_UP"; +const char kVolumeDown[] = "VOLUME_DOWN"; +const char kEject[] = "EJECT"; +const char kSource[] = "SOURCE"; +const char kShuffle[] = "SHUFFLE"; +const char kRepeat[] = "REPEAT"; +// ButtonName enum + +// ButtonPressMode enum +const char kLong[] = "LONG"; +const char kShort[] = "SHORT"; +// ButtonPressMode enum + +// Access mode enum +const char kAutoAllow[] = "AUTO_ALLOW"; +const char kAutoDeny[] = "AUTO_DENY"; +const char kAskDriver[] = "ASK_DRIVER"; +// Access mode enum +} // namespace enums_value + +} // namespace remote_control + +#endif // SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_RC_MODULE_CONSTANTS_H_ diff --git a/src/components/remote_control/include/remote_control/rc_module_timer.h b/src/components/remote_control/include/remote_control/rc_module_timer.h new file mode 100644 index 0000000000..dbc072a62d --- /dev/null +++ b/src/components/remote_control/include/remote_control/rc_module_timer.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013, 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_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_RC_MODULE_TIMER_H_ +#define SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_RC_MODULE_TIMER_H_ + +#include "functional_module/timer/module_timer.h" + +namespace remote_control { + +class TrackableMessage : public functional_modules::Trackable { + public: + TrackableMessage(uint32_t app_id, uint32_t correlation_id) + : custom_interval_(0), app_id_(app_id), correlation_id_(correlation_id) {} + + functional_modules::TimeUnit custom_interval() const { + return custom_interval_; + } + + uint32_t app_id() const { + return app_id_; + } + + uint32_t correlation_id() const { + return correlation_id_; + } + + bool operator==(const TrackableMessage& other) const { + return (other.app_id_ == app_id_ && + other.correlation_id_ == correlation_id_); + } + + private: + functional_modules::TimeUnit custom_interval_; + uint32_t app_id_; + uint32_t correlation_id_; +}; + +} // namesapce remote_control + +#endif // SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_RC_MODULE_TIMER_H_ diff --git a/src/components/remote_control/include/remote_control/remote_control_event.h b/src/components/remote_control/include/remote_control/remote_control_event.h new file mode 100644 index 0000000000..4623310557 --- /dev/null +++ b/src/components/remote_control/include/remote_control/remote_control_event.h @@ -0,0 +1,82 @@ +/* + Copyright (c) 2013, 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_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_REMOTE_CONTROL_EVENT_H_ +#define SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_REMOTE_CONTROL_EVENT_H_ + +#include <string> + +#include "application_manager/message.h" + +#include "remote_control/event_engine/event.h" + +namespace remote_control { + +class RCPluginEvent + : public rc_event_engine::Event<application_manager::MessagePtr, + std::string> { + public: + /* + * @brief Constructor with parameters + * + * @param id Event ID. (HMI or CAN function name) + * @param message Message received in HMI or CAN response + */ + RCPluginEvent(application_manager::MessagePtr& message, + const std::string& id); + + /* + * @brief Destructor + */ + virtual ~RCPluginEvent(); + + /* + * @brief Retrieves event message request ID + */ + virtual int32_t event_message_function_id() const; + + /* + * @brief Retrieves event message correlation ID + */ + virtual int32_t event_message_correlation_id() const; + + /* + * @brief Retrieves event message response type + */ + virtual int32_t event_message_type() const; + + private: + DISALLOW_COPY_AND_ASSIGN(RCPluginEvent); +}; +} + +#endif // SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_REMOTE_CONTROL_EVENT_H_ diff --git a/src/components/remote_control/include/remote_control/remote_control_plugin.h b/src/components/remote_control/include/remote_control/remote_control_plugin.h new file mode 100644 index 0000000000..9875723f43 --- /dev/null +++ b/src/components/remote_control/include/remote_control/remote_control_plugin.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2013, 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_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_REMOTE_CONTROL_PLUGIN_H_ +#define SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_REMOTE_CONTROL_PLUGIN_H_ + +#include <queue> +#include <string> + +#include "remote_control/remote_plugin_interface.h" +#include "functional_module/generic_module.h" +#include "remote_control/request_controller.h" +#include "utils/threads/message_loop_thread.h" +#include "remote_control/event_engine/event_dispatcher.h" +#include "remote_control/resource_allocation_manager_impl.h" + +namespace remote_control { +typedef rc_event_engine::EventDispatcher<application_manager::MessagePtr, + std::string> RCEventDispatcher; + +class RemoteControlPlugin : public RemotePluginInterface { + public: + RemoteControlPlugin(); + ~RemoteControlPlugin(); + + functional_modules::PluginInfo GetPluginInfo() const; + virtual functional_modules::ProcessResult ProcessMessage( + application_manager::MessagePtr msg); + virtual functional_modules::ProcessResult ProcessHMIMessage( + application_manager::MessagePtr msg); + + /** + * @brief Sends response to mobile application + * @param msg response mesage + */ + void SendResponseToMobile(application_manager::MessagePtr msg); + + /** + * @brief Sends timeout response to mobile application + * @param msg response mesage + */ + void SendTimeoutResponseToMobile(application_manager::MessagePtr msg); + + /** + * @brief Remove extension created for specified application + * @param app_id application id + */ + virtual void RemoveAppExtension(uint32_t app_id); + + /** + * @brief Check registering app can be handled by plugin + * @param msg Registration message + * @param app Application basis already create by Core + */ + bool IsAppForPlugin(application_manager::ApplicationSharedPtr app); + + /** + * @brief Notify about change of HMILevel of plugin's app + * @param app App with new HMILevel + * @param old_level Old HMILevel of app + */ + void OnAppHMILevelChanged(application_manager::ApplicationSharedPtr app, + mobile_apis::HMILevel::eType old_level); + + /** + * @brief Checks if plugin hasn't put restrictions on app's HMI Level + * @param app App with old HMILevel + * @param new_level HMILevel which is about to be set to app + */ + virtual bool CanAppChangeHMILevel( + application_manager::ApplicationSharedPtr app, + mobile_apis::HMILevel::eType new_level); + + /** + * Handles removing (disconnecting) device + * @param device removed + */ + void OnDeviceRemoved(const connection_handler::DeviceHandle& device) OVERRIDE; + + /** + * @brief OnUnregisterApplication handles application unregistering event + * @param app_id application id which was unregistered + */ + void OnUnregisterApplication(const uint32_t app_id) OVERRIDE; + + void SendHmiStatusNotification( + application_manager::ApplicationSharedPtr app) OVERRIDE; + + RCEventDispatcher& event_dispatcher() OVERRIDE; + + ResourceAllocationManager& resource_allocation_manager() OVERRIDE; + + protected: + /** + * @brief Remove extension for all applications + */ + virtual void RemoveAppExtensions() OVERRIDE; + + private: + void SubscribeOnFunctions(); + void NotifyMobiles(application_manager::MessagePtr msg); + + functional_modules::ProcessResult HandleMessage( + application_manager::MessagePtr msg); + + functional_modules::PluginInfo plugin_info_; + bool is_scan_started_; + request_controller::RequestController request_controller_; + + RCEventDispatcher event_dispatcher_; + + ResourceAllocationManagerImpl resource_allocation_manager_; + DISALLOW_COPY_AND_ASSIGN(RemoteControlPlugin); +}; + +} // namespace remote_control + +#endif // SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_REMOTE_CONTROL_PLUGIN_H_ diff --git a/src/components/remote_control/include/remote_control/remote_plugin_interface.h b/src/components/remote_control/include/remote_control/remote_plugin_interface.h new file mode 100644 index 0000000000..31e894db99 --- /dev/null +++ b/src/components/remote_control/include/remote_control/remote_plugin_interface.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2013, 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_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_REMOTE_PLUGIN_INTERFACE_H_ +#define SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_REMOTE_PLUGIN_INTERFACE_H_ + +#include <queue> +#include <string> +#include "functional_module/generic_module.h" +#include "remote_control/request_controller.h" +#include "remote_control/event_engine/event_dispatcher.h" +#include "utils/threads/message_loop_thread.h" +#include "utils/shared_ptr.h" + +namespace remote_control { + +class RCAppExtension; +class ResourceAllocationManager; + +typedef utils::SharedPtr<RCAppExtension> RCAppExtensionPtr; + +class RemotePluginInterface : public functional_modules::GenericModule { + public: + RemotePluginInterface() : GenericModule(kCANModuleID) {} + virtual ~RemotePluginInterface() {} + virtual functional_modules::PluginInfo GetPluginInfo() const = 0; + virtual functional_modules::ProcessResult ProcessMessage( + application_manager::MessagePtr msg) = 0; + virtual functional_modules::ProcessResult ProcessHMIMessage( + application_manager::MessagePtr msg) = 0; + + /** + * @brief Sends response to mobile application + * @param msg response mesage + */ + virtual void SendResponseToMobile(application_manager::MessagePtr msg) = 0; + + /** + * @brief Sends timeout response to mobile application + * @param msg response mesage + */ + virtual void SendTimeoutResponseToMobile( + application_manager::MessagePtr msg) = 0; + + /** + * @brief Remove extension created for specified application + * @param app_id application id + */ + virtual void RemoveAppExtension(uint32_t app_id) = 0; + + /** + * @brief Check registering app can be handled by plugin + * @param msg Registration message + * @param app Application basis already create by Core + */ + virtual bool IsAppForPlugin( + application_manager::ApplicationSharedPtr app) = 0; + + /** + * @brief Notify about change of HMILevel of plugin's app + * @param app App with new HMILevel + * @param old_level Old HMILevel of app + */ + virtual void OnAppHMILevelChanged( + application_manager::ApplicationSharedPtr app, + mobile_apis::HMILevel::eType old_level) = 0; + + /** + * @brief Checks if plugin hasn't put restrictions on app's HMI Level + * @param app App with old HMILevel + * @param new_level HMILevel which is about to be set to app + */ + virtual bool CanAppChangeHMILevel( + application_manager::ApplicationSharedPtr app, + mobile_apis::HMILevel::eType new_level) = 0; + + /** + * Handles removing (disconnecting) device + * @param device removed + */ + virtual void OnDeviceRemoved( + const connection_handler::DeviceHandle& device) = 0; + + virtual void SendHmiStatusNotification( + application_manager::ApplicationSharedPtr app) = 0; + + typedef rc_event_engine::EventDispatcher<application_manager::MessagePtr, + std::string> RCPluginEventDispatcher; + + virtual RCPluginEventDispatcher& event_dispatcher() = 0; + + virtual ResourceAllocationManager& resource_allocation_manager() = 0; + + protected: + /** + * @brief Remove extension for all applications + */ + virtual void RemoveAppExtensions() = 0; + + // TODO(VS): must be uid + static const functional_modules::ModuleID kCANModuleID = 153; +}; + +} // namespace remote_control + +#endif // SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_REMOTE_PLUGIN_INTERFACE_H_ diff --git a/src/components/remote_control/include/remote_control/request_controller.h b/src/components/remote_control/include/remote_control/request_controller.h new file mode 100644 index 0000000000..c42d4b9c08 --- /dev/null +++ b/src/components/remote_control/include/remote_control/request_controller.h @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2014, 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_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_REQUEST_CONTROLLER_H_ +#define SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_REQUEST_CONTROLLER_H_ + +#include <map> + +#include "remote_control/commands/command.h" +#include "remote_control/rc_module_timer.h" +#include "functional_module/timer/timer_director.h" + +namespace remote_control { + +namespace commands { +class Command; +} + +namespace request_controller { + +typedef utils::SharedPtr<commands::Command> MobileRequestPtr; +typedef uint32_t correlation_id; + +/** + * @brief RequestController class is used to manage mobile requests lifetime. + */ +class RequestController + : public functional_modules::TimerObserver<TrackableMessage> { + public: + /** + * @brief Class constructor + * + */ + RequestController(); + + /** + * @brief Class destructor + * + */ + virtual ~RequestController(); + + /** + * @brief Adds pointer to request. + * @param mobile_correlation_id mobile request correlation id + * @param command pointer to request created in mobile factory + */ + void AddRequest(const uint32_t mobile_correlation_id, + MobileRequestPtr request); + + /** + * @brief Removes request + * @param mobile_corellation_id mobile request correlation id + */ + void DeleteRequest(const uint32_t& mobile_correlation_id); + + void OnTimeoutTriggered(const TrackableMessage& expired); + + private: + DISALLOW_COPY_AND_ASSIGN(RequestController); + + std::map<correlation_id, MobileRequestPtr> mobile_request_list_; + functional_modules::ModuleTimer<TrackableMessage> timer_; + functional_modules::TimerDirector time_director_; +}; + +} // namespace request_controller +} // namespace remote_control + +#endif // SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_REQUEST_CONTROLLER_H_ diff --git a/src/components/remote_control/include/remote_control/resource_allocation_manager.h b/src/components/remote_control/include/remote_control/resource_allocation_manager.h new file mode 100644 index 0000000000..0c1943eaf8 --- /dev/null +++ b/src/components/remote_control/include/remote_control/resource_allocation_manager.h @@ -0,0 +1,111 @@ +#ifndef SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_RESOURCE_ALLOCATION_H +#define SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_RESOURCE_ALLOCATION_H +#include <string> +#include "utils/macro.h" +#include "utils/shared_ptr.h" +#include "interfaces/HMI_API.h" +#include "remote_control/event_engine/event.h" + +namespace remote_control { + +/** + * Enum for list of results of allocation resources + */ +namespace AcquireResult { +enum eType { ALLOWED = 0, IN_USE, ASK_DRIVER, REJECTED }; +} + +/** + * Defines states of acquired resource + */ +namespace ResourceState { +enum eType { FREE = 0, BUSY }; +} + +/** + * @brief The AskDriverCallBack class callback for GetInteriourConsent response + */ +class AskDriverCallBack + : public rc_event_engine::EventObserver<application_manager::MessagePtr, + std::string> { + public: + virtual ~AskDriverCallBack() {} +}; + +typedef utils::SharedPtr<AskDriverCallBack> AskDriverCallBackPtr; + +class ResourceAllocationManager { + public: + /** + * @brief AcquireResource acquires resource by application + * @param module_type resource to acquire + * @param app_id application that acquire resource + * @return ALLOWED if resource acquired \ + * IN_USE if subscription is not allowed + * ASK_DRIVER if driver confirmation is required + */ + virtual AcquireResult::eType AcquireResource(const std::string& module_type, + 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 app_id Application aquired resource before + * @param state State to set for resource + */ + virtual void SetResourceState(const std::string& module_type, + const uint32_t app_id, + const ResourceState::eType state) = 0; + + /** + * @brief IsResourceFree check resource state + * @param module_type Resource name + * @return True if free, otherwise - false + */ + virtual bool IsResourceFree(const std::string& module_type) const = 0; + + /** + * @brief OnUnregisterApplication handles application unregistering event + * @param app_id application id which was unregistered + */ + virtual void OnUnregisterApplication(const uint32_t app_id) = 0; + + /** + * @brief AcquireResource forces acquiring resource by application + * @param module_type resource to acquire + * @param app_id application that acquire resource + */ + virtual void ForceAcquireResource(const std::string& module_type, + const uint32_t app_id) = 0; + + /** + * @brief OnDriverDisallowed callback for rejecting acquiring resource + * @param module_type resource type + * @param app_id application id + */ + virtual void OnDriverDisallowed(const std::string& module_type, + const uint32_t app_id) = 0; + /** + * @brief AskDriver send GetInteriorConsent request to HMI for acquiring + * resource + * @param module_type resource to acquire + * @param app_id application that acquire resource + * @param callback will be executed on OnInteriorConsent response + */ + virtual void AskDriver(const std::string& module_type, + const uint32_t app_id, + AskDriverCallBackPtr callback) = 0; + + /** + * @brief Set current access mode for acquiring resource + * @param access_mode + */ + virtual void SetAccessMode( + const hmi_apis::Common_RCAccessMode::eType access_mode) = 0; + + virtual ~ResourceAllocationManager() {} +}; + +} // namespace remote_control +#endif // SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_RESOURCE_ALLOCATION_H diff --git a/src/components/remote_control/include/remote_control/resource_allocation_manager_impl.h b/src/components/remote_control/include/remote_control/resource_allocation_manager_impl.h new file mode 100644 index 0000000000..5dbbc219a8 --- /dev/null +++ b/src/components/remote_control/include/remote_control/resource_allocation_manager_impl.h @@ -0,0 +1,80 @@ +#ifndef SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_RESOURCE_ALLOCATION_IMPL_H +#define SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_RESOURCE_ALLOCATION_IMPL_H +#include "remote_control/resource_allocation_manager.h" +#include "remote_control/remote_plugin_interface.h" +#include "utils/macro.h" +namespace remote_control { + +typedef rc_event_engine::EventDispatcher<application_manager::MessagePtr, + std::string> RCEventDispatcher; + +class ResourceAllocationManagerImpl : public ResourceAllocationManager { + public: + ResourceAllocationManagerImpl(RemotePluginInterface& rc_plugin); + + ~ResourceAllocationManagerImpl(); + + AcquireResult::eType AcquireResource(const std::string& module_type, + const uint32_t app_id) OVERRIDE FINAL; + + void SetResourceState(const std::string& module_type, + const uint32_t app_id, + const ResourceState::eType state) FINAL; + + bool IsResourceFree(const std::string& module_type) const FINAL; + + void AskDriver(const std::string& module_type, + const uint32_t hmi_app_id, + AskDriverCallBackPtr callback) OVERRIDE FINAL; + + void SetAccessMode( + const hmi_apis::Common_RCAccessMode::eType access_mode) FINAL; + + void ForceAcquireResource(const std::string& module_type, + const uint32_t app_id) OVERRIDE FINAL; + + void OnDriverDisallowed(const std::string& module_type, + const uint32_t app_id) OVERRIDE FINAL; + + void OnUnregisterApplication(const uint32_t app_id) FINAL; + + private: + /** + * @brief IsModuleTypeRejected check if current resource was rejected by + * driver for current application + * @param module_type resource to check + * @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 uint32_t app_id); + + /** + * @brief AllocatedResources contains link between resource and application + * owning that resource + */ + typedef std::map<std::string, uint32_t> AllocatedResources; + AllocatedResources allocated_resources_; + + /** + * @brief ResourcesState contains states of ALLOCATED resources + */ + typedef std::map<std::string, ResourceState::eType> ResourcesState; + ResourcesState resources_state_; + + /** + * @brief RejectedResources type for connecting list of resources rejected by + * driver for application + * application_id : [vector of rejected resources] + */ + typedef std::map<uint32_t, std::vector<std::string> > RejectedResources; + RejectedResources rejected_resources_for_application_; + + hmi_apis::Common_RCAccessMode::eType current_access_mode_; + AskDriverCallBackPtr active_call_back_; + RemotePluginInterface& rc_plugin_; +}; +} // remote_control + +#endif // SRC_COMPONENTS_REMOTE_CONTROL_INCLUDE_REMOTE_CONTROL_RESOURCE_ALLOCATION_IMPL_H diff --git a/src/components/remote_control/remote_sdl_pt.json b/src/components/remote_control/remote_sdl_pt.json new file mode 100644 index 0000000000..e013c70112 --- /dev/null +++ b/src/components/remote_control/remote_sdl_pt.json @@ -0,0 +1,2359 @@ +{ + "policy_table": { + "module_config": { + "equipment": { + }, + "preloaded_pt": true, + "country_consent_passengersRC": true, + "exchange_after_x_ignition_cycles": 100, + "exchange_after_x_kilometers": 1800, + "exchange_after_x_days": 30, + "timeout_after_x_seconds": 60, + "seconds_between_retries": [1, + 5, + 25, + 125, + 625], + "endpoints": { + "0x07": { + "default": ["http://policies.telematics.ford.com/api/policies"] + }, + "0x04": { + "default": ["http://ivsu.software.ford.com/api/getsoftwareupdates"] + }, + "queryAppsUrl": { + "default": ["http://sdl.shaid.server"] + } + }, + "notifications_per_minute_by_priority": { + "EMERGENCY": 60, + "NAVIGATION": 15, + "VOICECOM": 20, + "COMMUNICATION": 6, + "NORMAL": 4, + "NONE": 0 + } + }, + "functional_groupings": { + "Base-4": { + "rpcs": { + "AddCommand": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "AddSubMenu": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "Alert": { + "hmi_levels": ["FULL", + "LIMITED"] + }, + "ChangeRegistration": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "CreateInteractionChoiceSet": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "DeleteCommand": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "DeleteFile": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "DeleteInteractionChoiceSet": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "DeleteSubMenu": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "EncodedSyncPData": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "EndAudioPassThru": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "GenericResponse": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "ListFiles": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "OnAppInterfaceUnregistered": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "OnAudioPassThru": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "OnButtonEvent": { + "hmi_levels": ["FULL", + "LIMITED", + "BACKGROUND"] + }, + "OnButtonPress": { + "hmi_levels": ["FULL", + "LIMITED", + "BACKGROUND"] + }, + "OnCommand": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "OnDriverDistraction": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "OnEncodedSyncPData": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "OnHashChange": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "OnHMIStatus": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "OnLanguageChange": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "OnPermissionsChange": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "OnSystemRequest": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "PerformAudioPassThru": { + "hmi_levels": ["FULL", + "LIMITED"] + }, + "PerformInteraction": { + "hmi_levels": ["FULL", + "LIMITED"] + }, + "PutFile": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "RegisterAppInterface": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "ResetGlobalProperties": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "ScrollableMessage": { + "hmi_levels": ["FULL"] + }, + "SetAppIcon": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "SetDisplayLayout": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "SetGlobalProperties": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "SetMediaClockTimer": { + "hmi_levels": ["FULL", + "LIMITED", + "BACKGROUND"] + }, + "Show": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "Slider": { + "hmi_levels": ["FULL"] + }, + "Speak": { + "hmi_levels": ["FULL", + "LIMITED"] + }, + "SubscribeButton": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "SystemRequest": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "UnregisterAppInterface": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "UnsubscribeButton": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + } + } + }, + "Location-1": { + "user_consent_prompt": "Location", + "rpcs": { + "GetVehicleData": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"], + "parameters": ["gps", + "speed"] + }, + "OnVehicleData": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"], + "parameters": ["gps", + "speed"] + }, + "SubscribeVehicleData": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"], + "parameters": ["gps", + "speed"] + }, + "UnsubscribeVehicleData": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"], + "parameters": ["gps", + "speed"] + } + } + }, + "Notifications": { + "user_consent_prompt": "Notifications", + "rpcs": { + "Alert": { + "hmi_levels": ["BACKGROUND"] + } + } + }, + "Notifications-RC": { + "rpcs": { + "OnPermissionsChange": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "OnHMIStatus": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "OnSystemRequest": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + } + } + }, + "pre_BaseRC-1": { + "rpcs": { + "OnPermissionsChange": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "OnHMIStatus": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + } + } + }, + "DrivingCharacteristics-3": { + "user_consent_prompt": "DrivingCharacteristics", + "rpcs": { + "GetVehicleData": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"], + "parameters": ["accPedalPosition", + "beltStatus", + "driverBraking", + "myKey", + "prndl", + "rpm", + "steeringWheelAngle"] + }, + "OnVehicleData": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"], + "parameters": ["accPedalPosition", + "beltStatus", + "driverBraking", + "myKey", + "prndl", + "rpm", + "steeringWheelAngle"] + }, + "SubscribeVehicleData": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"], + "parameters": ["accPedalPosition", + "beltStatus", + "driverBraking", + "myKey", + "prndl", + "rpm", + "steeringWheelAngle"] + }, + "UnsubscribeVehicleData": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"], + "parameters": ["accPedalPosition", + "beltStatus", + "driverBraking", + "myKey", + "prndl", + "rpm", + "steeringWheelAngle"] + } + } + }, + "VehicleInfo-3": { + "user_consent_prompt": "VehicleInfo", + "rpcs": { + "GetVehicleData": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"], + "parameters": ["bodyInformation", + "deviceStatus", + "engineTorque", + "externalTemperature", + "fuelLevel", + "fuelLevel_State", + "headLampStatus", + "instantFuelConsumption", + "odometer", + "tirePressure", + "vin", + "wiperStatus"] + }, + "OnVehicleData": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"], + "parameters": ["bodyInformation", + "deviceStatus", + "engineTorque", + "externalTemperature", + "fuelLevel", + "fuelLevel_State", + "headLampStatus", + "instantFuelConsumption", + "odometer", + "tirePressure", + "vin", + "wiperStatus"] + }, + "SubscribeVehicleData": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"], + "parameters": ["bodyInformation", + "deviceStatus", + "engineTorque", + "externalTemperature", + "fuelLevel", + "fuelLevel_State", + "headLampStatus", + "instantFuelConsumption", + "odometer", + "tirePressure", + "wiperStatus"] + }, + "UnsubscribeVehicleData": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"], + "parameters": ["bodyInformation", + "deviceStatus", + "engineTorque", + "externalTemperature", + "fuelLevel", + "fuelLevel_State", + "headLampStatus", + "instantFuelConsumption", + "odometer", + "tirePressure", + "wiperStatus"] + } + } + }, + "PropriataryData-1": { + "rpcs": { + "DiagnosticMessage": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "GetDTCs": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "ReadDID": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + } + } + }, + "PropriataryData-2": { + "rpcs": { + "DiagnosticMessage": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "GetDTCs": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "ReadDID": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + } + } + }, + "ProprietaryData-3": { + "rpcs": { + "GetDTCs": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "ReadDID": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + } + } + }, + "Emergency-1": { + "rpcs": { + "GetVehicleData": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"], + "parameters": ["airbagStatus", + "clusterModeStatus", + "eCallInfo", + "emergencyEvent"] + }, + "OnVehicleData": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"], + "parameters": ["airbagStatus", + "clusterModeStatus", + "eCallInfo", + "emergencyEvent"] + }, + "SubscribeVehicleData": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"], + "parameters": ["airbagStatus", + "clusterModeStatus", + "eCallInfo", + "emergencyEvent"] + }, + "UnsubscribeVehicleData": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"], + "parameters": ["airbagStatus", + "clusterModeStatus", + "eCallInfo", + "emergencyEvent"] + } + } + }, + "Navigation-1": { + "rpcs": { + "AlertManeuver": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "ShowConstantTBT": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "UpdateTurnList": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + } + } + }, + "Base-6": { + "rpcs": { + "AddCommand": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "AddSubMenu": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "Alert": { + "hmi_levels": ["FULL", + "LIMITED"] + }, + "ChangeRegistration": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "CreateInteractionChoiceSet": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "DeleteCommand": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "DeleteFile": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "DeleteInteractionChoiceSet": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "DeleteSubMenu": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "EncodedSyncPData": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "EndAudioPassThru": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "GenericResponse": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "ListFiles": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "OnAppInterfaceUnregistered": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "OnAudioPassThru": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "OnButtonEvent": { + "hmi_levels": ["FULL", + "LIMITED"] + }, + "OnButtonPress": { + "hmi_levels": ["FULL", + "LIMITED"] + }, + "OnCommand": { + "hmi_levels": ["FULL", + "LIMITED"] + }, + "OnDriverDistraction": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "OnEncodedSyncPData": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "OnHMIStatus": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "OnLanguageChange": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "OnPermissionsChange": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "OnSyncPData": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "OnTBTClientState": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "PerformAudioPassThru": { + "hmi_levels": ["FULL", + "LIMITED"] + }, + "PerformInteraction": { + "hmi_levels": ["FULL", + "LIMITED"] + }, + "PutFile": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "RegisterAppInterface": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "ResetGlobalProperties": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "ScrollableMessage": { + "hmi_levels": ["FULL"] + }, + "SetAppIcon": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "SetDisplayLayout": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "SetGlobalProperties": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "SetMediaClockTimer": { + "hmi_levels": ["FULL"] + }, + "Show": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "Slider": { + "hmi_levels": ["FULL"] + }, + "Speak": { + "hmi_levels": ["FULL", + "LIMITED"] + }, + "SubscribeButton": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "SyncPData": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "UnregisterAppInterface": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "UnsubscribeButton": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + } + } + }, + "OnKeyboardInputOnlyGroup": { + "rpcs": { + "OnKeyboardInput": { + "hmi_levels": ["FULL"] + } + } + }, + "OnTouchEventOnlyGroup": { + "rpcs": { + "OnTouchEvent": { + "hmi_levels": ["FULL"] + } + } + }, + "DiagnosticMessageOnly": { + "rpcs": { + "DiagnosticMessage": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + } + } + }, + "DataConsent-2": { + "user_consent_prompt": "DataConsent", + "rpcs": null + }, + "BaseBeforeDataConsent": { + "rpcs": { + "ChangeRegistration": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "DeleteFile": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "EncodedSyncPData": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "ListFiles": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "OnAppInterfaceUnregistered": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "OnEncodedSyncPData": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "OnHashChange": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "OnHMIStatus": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "OnLanguageChange": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "OnPermissionsChange": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "OnSystemRequest": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "PutFile": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "RegisterAppInterface": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "ResetGlobalProperties": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "SetGlobalProperties": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "SetAppIcon": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "SetDisplayLayout": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "SystemRequest": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "UnregisterAppInterface": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + } + } + }, + "SendLocation": { + "rpcs": { + "SendLocation": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + } + } + }, + "BackgroundAPT": { + "rpcs": { + "EndAudioPassThru": { + "hmi_levels": ["BACKGROUND"] + }, + "OnAudioPassThru": { + "hmi_levels": ["BACKGROUND"] + }, + "PerformAudioPassThru": { + "hmi_levels": ["BACKGROUND"] + } + } + }, + "RemoteControl": { + "rpcs": { + "ButtonPress": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "GetInteriorVehicleDataCapabilities": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "GetInteriorVehicleData": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "SetInteriorVehicleData": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + }, + "OnInteriorVehicleData": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED"] + }, + "SystemRequest": { + "hmi_levels": ["BACKGROUND", + "FULL", + "LIMITED", + "NONE"] + } + } + } + }, + "consumer_friendly_messages": { + "version": "001.001.021", + "messages": { + "AppPermissions": { + "languages": { + "de-de": { + "tts": "%appName% benötigt die folgenden Fahrzeuginformationen und Zugriffsberechtigungen: %functionalGroupLabels%. Wenn Sie Ja drücken, erklären Sie sich damit einverstanden, dass %vehicleMake% nicht für Schäden oder Verletzungen der Privatsphäre haftet, die im Zusammenhang mit der Nutzung Ihrer Benutzerdaten durch %appName% entstehen. Mit Ja stimmen Sie zu; mit Nein lehnen Sie ab.", + "line1": "Zugriffsanfrage(n)", + "line2": "erlauben?" + }, + "en-au": { + "tts": "%appName% is requesting the use of the following vehicle information and permissions: %functionalGroupLabels%. If you press Yes, you agree that %vehicleMake% will not be liable for any damages or loss of privacy related to %appName%'s use of your data. Please press Yes to allow or No to deny.", + "line1": "Grant requested", + "line2": "permission(s)?" + }, + "en-gb": { + "tts": "%appName% is requesting the use of the following vehicle information and permissions: %functionalGroupLabels%. If you press Yes, you agree that %vehicleMake% will not be liable for any damages or loss of privacy related to %appName%`s use of your data. Please press Yes to allow or No to deny.", + "line1": "Grant requested", + "line2": "permission(s)?", + "textBody": "%appName% is requesting the use of the following vehicle information and permissions: %functionalGroupLabels%. If you press yes, you agree that %vehicleMake% will not be liable for any damages or loss of privacy related to %appName%`s use of your data. You can change these permissions and hear detailed descriptions in the mobile apps settings menu." + }, + "en-ie": { + "tts": "%appName% is requesting the use of the following vehicle information and permissions: %functionalGroupLabels%. If you press Yes, you agree that %vehicleMake% will not be liable for any damages or loss of privacy related to %appName%'s use of your data. Please press Yes to allow or No to deny.", + "line1": "Grant requested", + "line2": "permission(s)?" + }, + "en-us": { + "tts": "%appName% is requesting the use of the following vehicle information and permissions: %functionalGroupLabels%. If you press yes, you agree that %vehicleMake% will not be liable for any damages or loss of privacy related to %appName%’s use of your data. Please press yes to allow or no to deny.", + "line1": "Grant Requested", + "line2": "Permission(s)?", + "textBody": "%appName% is requesting the use of the following vehicle information and permissions: %functionalGroupLabels%. \n\nIf you press yes, you agree that %vehicleMake% will not be liable for any damages or loss of privacy related to %appName%’s use of your data. You can change these permissions and hear detailed descriptions in the mobile apps settings menu." + }, + "es-en": { + "tts": "%appName% solicita el uso de la siguiente información y permisos del vehículo: %functionalGroupLabels%. Si presiona Sí, acepta que %vehicleMake% no se hará responsable por los daños o pérdidas de privacidad relacionados con el uso que %appName% haga de sus datos. Presione Sí para permitir y No para denegar.", + "line1": "¿Otorgar permiso(s)", + "line2": "solicitado(s)?", + "textBody": "%appName% solicita el uso de la siguiente información y permisos del vehículo: %functionalGroupLabels%. Si presiona Sí, acepta que %vehicleMake% no se hará responsable por los daños o pérdidas de privacidad relacionados con el uso que %appName% haga de sus datos. Presione Sí para permitir y No para denegar. \n\n Puede cambiar estos permisos y consultar descripciones detalladas en el menú de configuración de las aplicaciones móviles." + }, + "es-es": { + "tts": "%appName% está solicitando el uso de los siguientes permisos e información del vehículo: %functionalGroupLabels%. Si pulsa sí, acepta que %vehicleMake% no será responsable de los daños o la pérdida de privacidad relacionados con el uso de sus datos por parte de %appName%. Pulse sí para permitir o no para denegar.", + "line1": "¿Conceder permisos", + "line2": "solicitados?" + }, + "es-mx": { + "tts": "%appName% solicita el uso de la siguiente información y permisos del vehículo: %functionalGroupLabels%. Si presiona Sí, acepta que %vehicleMake% no se hará responsable por los daños o pérdidas de privacidad relacionados con el uso que %appName% haga de sus datos. Presione Sí para permitir y No para denegar.", + "line1": "¿Otorgar permiso(s)", + "line2": "solicitado(s)?", + "textBody": "%appName% solicita el uso de la siguiente información y permisos del vehículo: %functionalGroupLabels%. \n\nSi presiona Sí, acepta que %vehicleMake% no se hará responsable por los daños o pérdidas de privacidad relacionados con el uso que %appName% haga de sus datos. Presione Sí para permitir y No para denegar. Puede cambiar estos permisos y consultar descripciones detalladas en el menú de configuración de las aplicaciones móviles." + }, + "fr-ca": { + "tts": "%appName% demande d’utiliser les informations du véhicule et les permissions suivantes : %functionalGroupLabels%. Si vous appuyez sur Oui, vous acceptez que %vehicleMake% ne sera pas responsable des dommages ou des pertes de confidentialité reliées à l’utilisation de vos données par %appName%. Veuillez appuyer sur Oui pour autoriser ou sur Non pour refuser.", + "line1": "Accorder permission(s)", + "line2": "demandée(s)", + "textBody": "%appName% demande d’utiliser les informations du véhicule et les permissions suivantes : %functionalGroupLabels%. Si vous appuyez sur Oui, vous acceptez que %vehicleMake% ne sera pas responsable des dommages ou des pertes de confidentialité reliées à l’utilisation de vos données par %appName%. Vous pouvez modifier ces permissions et entendre les descriptions détaillées dans le menu des réglages des applications mobiles." + }, + "fr-fr": { + "tts": "%appName% demande d’utiliser les informations du véhicule et les permissions suivantes : %functionalGroupLabels%. Si vous appuyez sur Oui, vous acceptez que %vehicleMake% ne sera pas responsable des dommages ou des pertes de confidentialité reliées à l’utilisation de vos données par %appName%. Veuillez appuyer sur Oui pour autoriser ou sur Non pour refuser.", + "line1": "Accorder permission(s)", + "line2": "demandée(s)" + }, + "it-it": { + "tts": "%appName% richiede l'uso delle seguenti informazioni e autorizzazioni sul veicolo: %functionalGroupLabels%. Se si preme Sì, si acconsente che %vehicleMake% non sarà responsabile per danni o perdita di privacy in relazione all'impiego dei dati da parte di %appName%. Premere Sì per consentire e No per negare.", + "line1": "Concedi autorizzaz.", + "line2": "richiesta(e)?" + }, + "nl-nl": { + "tts": "%appName% vraagt gebruikmaking van de volgende voertuiginformatie en toestemmingen aan: %functionalGroupLabels%. Als u op Ja drukt, gaat u ermee akkoord dat %vehicleMake% in geen geval aansprakelijk gesteld kan worden voor schade of verlies van privacy als gevolg van het feit dat %appName% gebruik maakt van uw gegevens. Druk op Ja om dit toe te staan of Nee om te weigeren.", + "line1": "Aangevraagde", + "line2": "permissie(s) verlenen?" + }, + "pl-pl": { + "tts": "%appName% wymaga następujących informacji o pojeździe oraz pozwoleń: %functionalGroupLabels%. Naciśnięcie TAK oznacza zgodę na fakt, iż %vehicleMake% nie będzie ponosić odpowiedzialności za szkody ani utratę prywatności w związku z wykorzystaniem przez %appName% danych, należących do użytkownika. Naciśnij TAK w celu udzielenia zgody lub NIE w celu odrzucenia żądania.", + "line1": "Udzielić żądanych", + "line2": "pozwoleń?" + }, + "pt-br": { + "tts": "%appName% está solicitando o uso das seguintes informações e permissões do veículo: %functionalGroupLabels%. Se pressionar sim, você concorda que a %vehicleMake% não será responsável por danos ou perdas de privacidade relacionados ao uso dos seus dados por %appName%. Pressione sim para permitir ou não para negar.", + "line1": "Conceder permissão", + "line2": "solicitada?" + }, + "pt-pt": { + "tts": "%appName% está a solicitar a utilização das seguintes informações e permissões do veículo: %functionalGroupLabels%. Se premir “Sim”, concorda que %vehicleMake% não será responsável por quaisquer danos ou perda de privacidade relacionada com a utilização dos seus dados por parte de %appName%. Prima “Sim” para permitir ou “Não” para recusar.", + "line1": "Conceder permiss.", + "line2": "solicitada(s)?" + }, + "ru-ru": { + "tts": "%appName% запрашивает следующую информацию об автомобиле и разрешения: %functionalGroupLabels%. Нажатием \"\"да\"\", Вы соглашаетесь, что %vehicleMake% не будет нести ответственность за какие-либо убытки или потерю прайвеси, связанные с использованием Ваших данных компанией %appName%. Нажмите \"\"Да\"\", если Вы согласны, или \"\"Нет\"\" - если не согласны.", + "line1": "Предост. заправш.", + "line2": "разрешения?" + }, + "sv-se": { + "tts": "%appName% begär att få tillgång till följande fordonsinformation och tillstånd: %functionalGroupLabels%. Om du trycker Ja godkänner du att %vehicleMake% ska hållas skadeslös för alla skador som kan uppstå eller eventuella integritetsintrång som uppstår när %appName% använder dina data. Tryck Ja för att godkänna eller Nej för att neka.", + "line1": "Vill du ge", + "line2": "tillstånd?" + }, + "tr-tr": { + "tts": "%appName%, şu araç bilgilerini ve izinleri kullanma isteğinde bulunuyor: %functionalGroupLabels%. Evet'e basarsanız, %appName%'in verilerinizi kullanması sonucunda oluşabilecek hasarlardan veya gizlilik kaybından %vehicleMake%'in sorumlu olmayacağını kabul etmiş olacaksınız. Lütfen kabul etmek için Evet'e veya reddetmek için Hayır'a basın.", + "line1": "İstenen izinler", + "line2": "verilsin mi?" + }, + "zh-cn": { + "tts": "%appName% 正在请求使用下列车辆信息和权限: %functionalGroupLabels%。如果您按“是”,则表示您同意。 %vehicleMake% 将不会对因 %appName% 使用您的数据而引起的任何损毁或隐私损失负责。 请按“是”允许或按“否”拒绝。", + "line1": "是否允许请求的", + "line2": "权限?" + }, + "zh-tw": { + "tts": "%appName% 正請求使用 %functionalGroupLabels% 的車輛資訊和許可。按「是」,表示您同意,如因 %appName% 使用您的資料導致任何損害或損失,%vehicleMake% 將不負賠償責任。同意請按「是」,拒絕請按「否」。", + "line1": "允許", + "line2": "授權請求?" + } + } + }, + "AppPermissionsHelp": { + "languages": { + "de-de": { + "tts": "%appName% fordert folgende Fahrzeuginformationen und Zugriffsberechtigungen: %functionalGroupLabels%. Im Einstellungsmenü der mobilen Apps können Sie diese Berechtigungen ändern und sich detaillierte Beschreibungen anhören. Mit Ja stimmen Sie zu; mit Nein lehnen Sie ab." + }, + "en-au": { + "tts": "%appName% is requesting the following vehicle information and permissions: %functionalGroupLabels%. You can change these permissions and hear detailed descriptions in the mobile apps settings menu. Please press Yes to grant permissions or No to deny." + }, + "en-gb": { + "tts": "%appName% is requesting the following vehicle information and permissions: %functionalGroupLabels%. You can change these permissions and hear detailed descriptions in the mobile apps settings menu. Please press Yes to grant permissions or No to deny." + }, + "en-ie": { + "tts": "%appName% is requesting the following vehicle information and permissions: %functionalGroupLabels%. You can change these permissions and hear detailed descriptions in the mobile apps settings menu. Please press Yes to grant permissions or No to deny." + }, + "en-us": { + "tts": "%appName% is requesting the following vehicle information and permissions: %functionalGroupLabels%. You can change these permissions and hear detailed descriptions in the mobile apps settings menu. Please press yes to grant permissions or no to deny." + }, + "es-en": { + "tts": "%appName% solicita la siguiente información y permisos del vehículo: %functionalGroupLabels%. Puede cambiar estos permisos y consultar descripciones detalladas en el menú de configuración de las aplicaciones móviles. Presione Sí para otorgar permisos y No para denegar." + }, + "es-es": { + "tts": "%appName% está solicitando los siguientes permisos e información del vehículo: %functionalGroupLabels%. Puede cambiar estos permisos y escuchar descripciones detalladas en el menú de configuración de la aplicación móvil. Pulse sí para conceder el permiso o no para denegarlo." + }, + "es-mx": { + "tts": "%appName% solicita la siguiente información y permisos del vehículo: %functionalGroupLabels%. Puede cambiar estos permisos y consultar descripciones detalladas en el menú de configuración de las aplicaciones móviles. Presione Sí para otorgar permisos y No para denegar." + }, + "fr-ca": { + "tts": "%appName% demande d’utiliser les informations du véhicule et les permissions suivantes : %functionalGroupLabels%. Vous pouvez modifier ces permissions et entendre les descriptions détaillées dans le menu des réglages des applications mobiles. Veuillez appuyer sur Oui pour accorder les permissions ou sur Non pour refuser." + }, + "fr-fr": { + "tts": "%appName% demande d’utiliser les informations du véhicule et les permissions suivantes : %functionalGroupLabels%. Vous pouvez modifier ces permissions et entendre les descriptions détaillées dans le menu des réglages des applications mobiles. Veuillez appuyer sur Oui pour accorder les permissions ou sur Non pour refuser." + }, + "it-it": { + "tts": "%appName% richiede le seguenti informazioni e autorizzazioni riguardo il veicolo: %functionalGroupLabels%. È possibile modificare tali autorizzazioni e ascoltare descrizioni dettagliate nel menu impostazioni delle app mobili. Premere Sì per concedere le autorizzazioni e No per negarle." + }, + "nl-nl": { + "tts": "%appName% vraagt gebruikmaking van de volgende voertuiginformatie en toestemmingen aan: %functionalGroupLabels%. U kunt deze toestemmingen wijzigen en gedetailleerde beschrijvingen beluisteren in het instellingenmenu voor mobiele apps. Druk op Ja om permissies te verlenen of op Nee om te weigeren." + }, + "pl-pl": { + "tts": "%appName% wymaga następujących informacji o pojeździe oraz zezwoleń: %functionalGroupLabels%. W menu ustawień aplikacji mobilnych można zmienić owe zezwolenia i usłyszeć ich szczegółowy opis. Naciśnij TAK, aby wyrazić zgodę lub NIE w celu odrzucenia żądania." + }, + "pt-br": { + "tts": "%appName% está solicitando as seguintes informações e permissões do veículo: %functionalGroupLabels%. Você pode alterar estas permissões e ouvir descrições detalhadas no menu de configurações de aplicativos móveis. Pressione sim para conceder as permissões ou não para negar." + }, + "pt-pt": { + "tts": "%appName% está a solicitar as seguintes informações e permissões do veículo: %functionalGroupLabels%. Pode alterar estas permissões e ouvir descrições detalhadas no menu de definições das aplicações móveis. Prima \"\"Sim\"\" para permitir ou \"\"Não\"\" para recusar." + }, + "ru-ru": { + "tts": "%appName% запрашивает следующую информацию об автомобиле и разрешения: %functionalGroupLabels%. Вы можете изменить эти разрешения и прослушать подробные их описания в меню настроек мобильного приложения. Нажмите \"\"да\"\", чтобы предоставить разрешения, или \"\"нет\"\", чтобы не предоставлять." + }, + "sv-se": { + "tts": "%appName% begär tillgång till följande fordonsinformation och tillstånd: %functionalGroupLabels%. Du kan ändra tillstånden och höra detaljerade beskrivningar i menyn för mobilappsinställningar. Tryck Ja för att ge tillstånd eller Nej för att neka." + }, + "tr-tr": { + "tts": "%appName%, şu araç bilgilerini ve izinleri istiyor: %functionalGroupLabels%. Bu izinleri değiştirebilir ve mobil uygulamalar ayarlar menüsünden ayrıntılı açıklamaları dinleyebilirsiniz. Lütfen izin vermek için Evet'e veya reddetmek için Hayır'a basın." + }, + "zh-cn": { + "tts": "%appName% 正在请求下列车辆信息和权限: %functionalGroupLabels%。您可在移动应用程序设置菜单中更改这些权限,并听取详细说明。请按“是”允许权限或按“否”拒绝。" + }, + "zh-tw": { + "tts": "%appName% 正請求使用 %functionalGroupLabels% 的車輛資訊和許可。您可在行動應用程式設定清單中更改這些許可,並聆聽詳細說明。給予許可請按「是」,拒絕請按「否」。" + } + } + }, + "AppPermissionsRevoked": { + "languages": { + "de-de": { + "tts": "Die Autorisierungsdaten der App wurden geändert. %appName% hat keinen Zugriff auf %functionalGroupLabels% mehr. Installieren Sie die neueste Version der App auf Ihrem Gerät.." + }, + "en-au": { + "tts": "App authorizations have changed. %appName% can no longer access %functionalGroupLabels%. Please ensure you have the most recent app version installed on your mobile device." + }, + "en-gb": { + "tts": "App authorizations have changed. %appName% can no longer access %functionalGroupLabels%. Please ensure you have the most recent app version installed on your mobile device." + }, + "en-ie": { + "tts": "App authorizations have changed. %appName% can no longer access %functionalGroupLabels%. Please ensure you have the most recent app version installed on your mobile device." + }, + "en-us": { + "tts": "App authorizations have changed. %appName% can no longer access %functionalGroupLabels%. Please ensure you have the most recent app version installed on your mobile device." + }, + "es-en": { + "tts": "Las autorizaciones de la aplicación han cambiado. %appName% ya no puede acceder a %functionalGroupLabels%. Asegúrese de haber instalado la versión más reciente de la aplicación en su dispositivo móvil." + }, + "es-es": { + "tts": "Las autorizaciones de la aplicación han cambiado. %appName% ya no puede acceder a %functionalGroupLabels%. Asegúrese de que tiene la versión más reciente de la aplicación instalada en su dispositivo móvil." + }, + "es-mx": { + "tts": "Las autorizaciones de la aplicación han cambiado. %appName% ya no puede acceder a %functionalGroupLabels%. Asegúrese de haber instalado la versión más reciente de la aplicación en su dispositivo móvil." + }, + "fr-ca": { + "tts": "Les autorisations pour app ont changé. %appName% ne peut plus accéder à %functionalGroupLabels%. Veuillez vous assurer que la plus récente version de l’application est installée sur votre appareil mobile." + }, + "fr-fr": { + "tts": "Les autorisations pour app ont changé. %appName% ne peut plus accéder à %functionalGroupLabels%. Veuillez vous assurer que la plus récente version de l’application est installée sur votre appareil mobile." + }, + "it-it": { + "tts": "Le autorizzazioni dell'app sono cambiate. %appName% non è più in grado di accedere a %functionalGroupLabels%. Assicurarsi di avere la versione più recente dell'app installata sul dispositivo mobile." + }, + "nl-nl": { + "tts": "De app-autorisaties zijn gewijzigd. %appName% heeft geen toegang meer tot %functionalGroupLabels%. Zorg ervoor dat u de meest recente app-versie op uw mobiele apparaat geïnstalleerd hebt." + }, + "pl-pl": { + "tts": "Dane dostępu aplikacji zostały zmienione. %appName% nie ma już dostępu do %functionalGroupLabels%. Sprawdź, czy na telefonie komórkowym zainstalowano najnowszą wersję aplikacji." + }, + "pt-br": { + "tts": "As autorizações dos aplicativos foram alteradas. %appName% não pode mais acessar %functionalGroupLabels%. Certifique-se de que a versão mais recente do aplicativo está instalada no seu dispositivo móvel." + }, + "pt-pt": { + "tts": "As autorizações das aplicações mudaram. %appName% já não consegue aceder a %functionalGroupLabels%. Certifique-se de que tem a última versão da aplicação no seu dispositivo móvel." + }, + "ru-ru": { + "tts": "Авторизации приложения изменены. %appName% больше не имеет доступа к %functionalGroupLabels%. Убедитесь, что на вашем мобильном устройстве установлена самая новая версия приложения." + }, + "sv-se": { + "tts": "Appens behörigheter har ändrats. %appName% har inte längre åtkomst till %functionalGroupLabels%. Kontrollera att du har installerat den senaste versionen av appen på mobilenheten." + }, + "tr-tr": { + "tts": "Uygulama yetkileri değişti. %appName% artık %functionalGroupLabels%'e erişemeyecek. Lütfen mobil aygıtınızda en son uygulama sürümünün yüklü olduğundan emin olun." + }, + "zh-cn": { + "tts": "应用程序授权已变更。 %appName% 将不能再访问 %functionalGroupLabels%。 请确认您的移动设备上安装的应用程序是最新版本。" + }, + "zh-tw": { + "tts": "應用程式授權已改變。%appName% 已無法進入 %functionalGroupLabels%。請確認您的行動裝置上安裝了最新版應用程式。" + } + } + }, + "AppUnauthorized": { + "languages": { + "de-de": { + "tts": "Diese Version von %appName% ist nicht autorisiert und wird nicht mit SYNC funktionieren.", + "line1": "nicht autorisiert" + }, + "en-au": { + "tts": "This version of %appName% is not authorized and will not work with SYNC.", + "line1": "not authorized" + }, + "en-gb": { + "tts": "This version of %appName% is not authorized and will not work with SYNC.", + "line1": "not authorized", + "textBody": "This version of %appName% is not authorized and will not work with SYNC." + }, + "en-ie": { + "tts": "This version of %appName% is not authorized and will not work with SYNC.", + "line1": "not authorized" + }, + "en-us": { + "tts": "This version of %appName% is not authorized and will not work with SYNC.", + "line1": "Not Authorized", + "textBody": "This version of %appName% is no longer authorized to work with AppLink. Please update to the latest version of %appName%." + }, + "es-en": { + "tts": "Esta versión de %appName% no tiene autorización y no funcionará con SYNC.", + "line1": "no autorizada", + "textBody": "Esta versión de %appName% no tiene autorización y no funcionará con SYNC." + }, + "es-es": { + "tts": "Esta versión de %appName% no está autorizada y no funcionará con SYNC.", + "line1": "No autorizada" + }, + "es-mx": { + "tts": "Esta versión de %appName% no tiene autorización y no funcionará con SYNC.", + "line1": "no autorizada", + "textBody": "Esta versión de %appName% no tiene autorización y no funcionará con SYNC." + }, + "fr-ca": { + "tts": "Cette version de %appName% n’est pas autorisée et ne fonctionnera pas avec SYNC.", + "line1": "non autorisée", + "textBody": "Cette version de %appName% n’est pas autorisée et ne fonctionnera pas avec SYNC." + }, + "fr-fr": { + "tts": "Cette version de %appName% n’est pas autorisée et ne fonctionnera pas avec SYNC.", + "line1": "non autorisée" + }, + "it-it": { + "tts": "Questa versione di %appName% non è autorizzata e non funziona con il SYNC.", + "line1": "non autorizzata" + }, + "nl-nl": { + "tts": "Deze versie van %appName% is niet geautoriseerd en werkt niet met SYNC.", + "line1": "niet geautoriseerd" + }, + "pl-pl": { + "tts": "Niniejsza wersja %appName% nie posiada autoryzacji i nie będzie działać z SYNC.", + "line1": "brak autoryzacji" + }, + "pt-br": { + "tts": "Esta versão do %appName% não tem autorização e não funcionará com o SYNC.", + "line1": "não autorizado" + }, + "pt-pt": { + "tts": "Esta versão de %appName% não está autorizada e não funcionará com o SYNC.", + "line1": "não autorizada" + }, + "ru-ru": { + "tts": "Эта версия %appName% не авторизирована и не будет работать с SYNC.", + "line1": "не авторизировано" + }, + "sv-se": { + "tts": "Den här versionen av %appName% är inte godkänd och fungerar inte med SYNC.", + "line1": "är ej godkänd" + }, + "tr-tr": { + "tts": "Bu %appName% sürümüne izin verilmediğinden SYNC ile çalışamaz.", + "line1": "için izin yok" + }, + "zh-cn": { + "tts": "此版本的%appName% 未得到授权,无法在SYNC上使用。", + "line1": "未得到授权" + }, + "zh-tw": { + "tts": "%appName% 的版本未獲得授權,將無法透過 SYNC 使用。", + "line1": "無授權" + } + } + }, + "AppUnsupported": { + "languages": { + "de-de": { + "tts": "Diese Version von %appName% wird von SYNC nicht unterstützt.", + "line1": "nicht unterstützt" + }, + "en-au": { + "tts": "This version of %appName% is not supported by SYNC.", + "line1": "not supported" + }, + "en-gb": { + "tts": "This version of %appName% is not supported by SYNC.", + "line1": "not supported", + "textBody": "This version of %appName% is not supported by SYNC." + }, + "en-ie": { + "tts": "This version of %appName% is not supported by SYNC.", + "line1": "not supported" + }, + "en-us": { + "tts": "This version of %appName% is not supported by SYNC.", + "line1": "Not Supported", + "textBody": "Your version of %appName% is not supported by SYNC." + }, + "es-en": { + "tts": "Esta versión de %appName% no es compatible con SYNC.", + "line1": "no compatible", + "textBody": "Esta versión de %appName% no es compatible con SYNC." + }, + "es-es": { + "tts": "Esta versión de %appName% no es compatible con SYNC.", + "line1": "No compatible" + }, + "es-mx": { + "tts": "Esta versión de %appName% no es compatible con SYNC.", + "line1": "no compatible", + "textBody": "Esta versión de %appName% no es compatible con SYNC." + }, + "fr-ca": { + "tts": "Cette version de %appName% n’est pas prise en charge par SYNC.", + "line1": "incompatible", + "textBody": "Cette version de %appName% n’est pas prise en charge par SYNC." + }, + "fr-fr": { + "tts": "Cette version de %appName% n’est pas prise en charge par SYNC.", + "line1": "incompatible" + }, + "it-it": { + "tts": "Questa versione di %appName% non è supportata dal SYNC.", + "line1": "non supportata" + }, + "nl-nl": { + "tts": "Deze versie van %appName% wordt niet ondersteund door SYNC.", + "line1": "niet ondersteund" + }, + "pl-pl": { + "tts": "Niniejsza wersja %appName% nie jest obsługiwana przez system SYNC.", + "line1": "aplikacja nie obsług." + }, + "pt-br": { + "tts": "Esta versão do %appName% não é suportada pelo SYNC.", + "line1": "não suportado" + }, + "pt-pt": { + "tts": "Esta versão de %appName% não é suportado pelo SYNC.", + "line1": "não suportada" + }, + "ru-ru": { + "tts": "Эта версия %appName% не поддерживается SYNC.", + "line1": "не поддерживается" + }, + "sv-se": { + "tts": "SYNC har inte stöd för den här versionen av %appName%.", + "line1": "stöds ej" + }, + "tr-tr": { + "tts": "Bu %appName% sürümü SYNC tarafından desteklenmiyor.", + "line1": "desteklenmiyor" + }, + "zh-cn": { + "tts": "SYNC不支持此版本的%appName%。", + "line1": "不受支持" + }, + "zh-tw": { + "tts": "SYNC 不支援此版本的%appName% 。", + "line1": "不支援" + } + } + }, + "DataConsent": { + "languages": { + "en-gb": { + "textBody": "Would you like to enable Mobile Apps on SYNC? To use Mobile Apps with SYNC, SYNC will communicate with Ford at least once per month using your mobile device’s data plan. Standard rates may apply. SYNC will send your VIN and SYNC module number to Ford U.S. \r\n\r\nUpdates are about the size of an email, and the occurrence of updates depends on your vehicle usage and when a new app is found on your device. To turn on or off, visit the SYNC Settings menu. See your Owner Guide for more information." + }, + "en-us": { + "line1": "Enable Mobile Apps", + "line2": "on SYNC? (Uses Data)", + "textBody": "Would you like to enable Mobile Apps on SYNC?\r\n\r\nTo use Mobile Apps with SYNC, SYNC will communicate with Ford at least once per month using your mobile device’s data plan. Standard rates may apply. SYNC will send your VIN and SYNC module number to Ford U.S.\r\n\r\nUpdates are about the size of an email, and the occurrence of updates depends on your vehicle usage and when a new app is found on your device. To turn on or off, visit the SYNC Settings menu. See your Owner Guide for more information." + }, + "es-mx": { + "textBody": "Para usar aplicaciones móviles con SYNC, este debe comunicarse con Ford al menos una vez al mes a través del plan de datos de su dispositivo móvil. Pueden aplicar tarifas normales. SYNC enviará su VIN y el número de módulo de SYNC a Ford de Estados Unidos de América. \n\nLas actualizaciones tienen el tamaño aproximado de un mensaje de correo electrónico, y la frecuencia de las actualizaciones depende del uso de su vehículo y de si se encuentran nuevas aplicaciones en su dispositivo. Para obtener más información, consulte la Guía del propietario. \n\nPresione Sí para permitir y No para denegar." + }, + "fr-ca": { + "textBody": "Pour utiliser AppLink, SYNC devra communiquer avec Ford au moins une fois par mois en utilisant le forfait de données de votre appareil mobile. Les tarifs réguliers peuvent s’appliquer. SYNC enverra votre NIV et le numéro de votre module SYNC à Ford États-Unis. Les mises à jour ont la taille d’un courriel et la fréquence des mises à jour dépend de l’utilisation de votre véhicule et si une nouvelle application se trouve sur votre appareil. Consultez le Guide de l’utilisateur pour obtenir d’autres renseignements.\r\n\r\nVeuillez appuyer sur Oui pour autoriser ou sur Non pour refuser." + } + } + }, + "DataConsentHelp": { + "languages": { + "en-us": { + "textBody": "By enabling mobile apps, you consent to allowing SYNC to communicate with Ford at least once per month using your mobile device’s data plan. Disabling will stop all data usage, but you will not be able to use mobile apps on SYNC. See your Owner Guide for more information." + }, + "es-mx": { + "textBody": "Las actualizaciones tienen el tamaño aproximado de un mensaje de correo electrónico, y la frecuencia de las actualizaciones depende del uso de su vehículo y de si se encuentran nuevas aplicaciones en su dispositivo. Para obtener más información, consulte la Guía del propietario." + }, + "fr-ca": { + "textBody": "Les mises à jour ont la taille d’un courriel et la fréquence des mises à jour dépend de l’utilisation de votre véhicule et si une nouvelle application se trouve sur votre appareil. Consultez le Guide de l’utilisateur pour obtenir d’autres renseignements." + } + } + }, + "DisableApps": { + "languages": { + "de-de": { + "tts": "Ausschalten der automatischen Updates führt zum Ausschalten von SYNC mobile Apps. Sie können Ihre mobilen Apps dann nicht mehr mit SYNC nutzen. Bitte drücken Sie Ja zur Bestätigung oder Nein, um abzubrechen.", + "line1": "Auto-Update", + "line2": "und Mobile Apps deaktivieren" + }, + "en-au": { + "tts": "Disabling automatic updates will also disable SYNC mobile apps. You will not be able to use any mobile apps with SYNC. Please press Yes to confirm or No to cancel.", + "line1": "Disable auto-updates", + "line2": "and Mobile Apps?" + }, + "en-gb": { + "tts": "Disabling automatic updates will also disable SYNC mobile apps. You will not be able to use any mobile apps with SYNC. Please press Yes to confirm or No to cancel.", + "line1": "Disable auto-updates", + "line2": "and Mobile Apps?", + "textBody": "Disabling automatic updates will also disable SYNC mobile apps. You will not be able to use any mobile apps with SYNC. Please press Yes to confirm or No to cancel." + }, + "en-ie": { + "tts": "Disabling automatic updates will also disable SYNC mobile apps. You will not be able to use any mobile apps with SYNC. Please press Yes to confirm or No to cancel.", + "line1": "Disable auto-updates", + "line2": "and Mobile Apps?" + }, + "en-us": { + "tts": "Disabling automatic updates will also disable sync mobile apps. You will not be able to use any mobile apps with SYNC. Please press yes to confirm or no to cancel.", + "line1": "Disable Auto-Updates", + "line2": "and Mobile Apps?", + "textBody": "If you disable, you will not be able to use any mobile apps with SYNC and your vehicle will stop receiving mobile app permission updates via your device`s data plan. Please press yes to disable mobile apps or no to cancel." + }, + "es-en": { + "tts": "Si se desactivan las actualizaciones automáticas, también se desactivarán las aplicaciones móviles de SYNC. No podrá usar ninguna aplicación móvil con SYNC. Presione Sí para confirmar o No para cancelar.", + "line1": "¿Deshab. actualiz.", + "line2": "autom. y aplic. móv.?", + "textBody": "Si se desactivan las actualizaciones automáticas, también se desactivarán las aplicaciones móviles de SYNC. No podrá usar ninguna aplicación móvil con SYNC. Presione Sí para confirmar o No para cancelar." + }, + "es-es": { + "tts": "Si desactiva las actualizaciones automáticas, también se desactivará la sincronización de las aplicaciones móviles. No podrá utilizar ninguna aplicación móvil con SYNC. Pulse sí para confirmar o no para cancelar.", + "line1": "¿Desact. actual. auto", + "line2": "y apl. móviles?" + }, + "es-mx": { + "tts": "Si se desactivan las actualizaciones automáticas, también se desactivarán las aplicaciones móviles de SYNC. No podrá usar ninguna aplicación móvil con SYNC. Presione Sí para confirmar o No para cancelar.", + "line1": "¿Deshab. actualiz.", + "line2": "autom. y aplic. móv.?", + "textBody": "Si se desactivan las actualizaciones automáticas, también se desactivarán las aplicaciones móviles de SYNC. No podrá usar ninguna aplicación móvil con SYNC. Presione Sí para confirmar o No para cancelar." + }, + "fr-ca": { + "tts": "La désactivation des mises à jour automatiques désactivera aussi les applications mobiles SYNC. Vous ne pourrez pas utiliser d’application mobile avec SYNC. Veuillez appuyer sur Oui pour confirmer ou sur Non pour annuler.", + "line1": "Désactiver màj autom.", + "line2": "et app. mobiles?", + "textBody": "La désactivation des mises à jour automatiques désactivera aussi les applications mobiles SYNC. Vous ne pourrez pas utiliser d’application mobile avec SYNC. Veuillez appuyer sur Oui pour confirmer ou sur Non pour annuler." + }, + "fr-fr": { + "tts": "La désactivation des mises à jour automatiques désactivera aussi les applications mobiles SYNC. Vous ne pourrez pas utiliser d’application mobile avec SYNC. Veuillez appuyer sur Oui pour confirmer ou sur Non pour annuler.", + "line1": "Désactiver màj autom.", + "line2": "et app. mobiles?" + }, + "it-it": { + "tts": "Disabilitando gli aggiornamenti automatici si disattiva anche la sincronizzazione delle app mobili. Non sarà possibile usare app mobili con il SYNC. Premere Sì per confermare e No per cancellare.", + "line1": "Disabilitare agg. aut.", + "line2": "e app mobili?" + }, + "nl-nl": { + "tts": "Door automatische updates uit te schakelen, schakelt u ook SYNC-mobiele apps uit. U kunt dan geen mobiele apps meer gebruiken met SYNC. Druk op Ja om te bevestigen of op Nee om te annuleren.", + "line1": "Auto-updates en mob.", + "line2": "apps uitschakelen?" + }, + "pl-pl": { + "tts": "Wyłączenie automatycznych aktualizacji spowoduje także wyłączenie aplikacji mobilnych SYNC. Korzystanie z mobilnych aplikacji za pomocą SYNC będzie niemożliwe. Naciśnij TAK, by potwierdzić lub NIE, by anulować.", + "line1": "Wył. automat. aktual.", + "line2": "i aplikacje mobilne?" + }, + "pt-br": { + "tts": "Se as atualizações automáticas forem desativadas, os aplicativos também serão desativados. Você não poderá usar nenhum aplicativo com o SYNC. Pressione sim para confirmar ou não para cancelar.", + "line1": "Desativar atualizações", + "line2": "autom. e aplicativos?" + }, + "pt-pt": { + "tts": "A desactivação das actualizações automáticas desactiva igualmente as aplicações móveis do SYNC. Não poderá utilizar quaisquer aplicações móveis com o SYNC. Prima \"\"Sim\"\" para confirmar ou \"\"Não\"\" para cancelar.", + "line1": "Desact. actual. autom.", + "line2": "e aplicações móveis?" + }, + "ru-ru": { + "tts": "При отключении автоматических обновлений также будут отключены мобильные приложения sync. Вы не сможете использовать какие-либо мобильные приложения с SYNC. Нажмите \"\"Да\"\" для подтверждения или \"\"Нет\"\" для отмены.", + "line1": "Откл. автообновления", + "line2": "и мобил. прилож.?" + }, + "sv-se": { + "tts": "Om du avaktiverar automatisk uppdatering avaktiverar du även synkning av mobilappar. Du kommer inte längre att kunna använda dina mobilappar med SYNC. Tryck Ja för att bekräfta eller Nej för att avbryta.", + "line1": "Avaktiverar autouppdat.", + "line2": "och mobilappar?" + }, + "tr-tr": { + "tts": "Otomatik güncellemeleri devre dışı bırakırsanız sync mobil uygulamalar da devre dışı kalır. SYNC ile mobil uygulama kullanmanız mümkün olmaz. Lütfen onaylamak için Evet'e veya iptal etmek için Hayır'a basın.", + "line1": "Oto. güncelleme ve", + "line2": "mobil uygul. kapat?" + }, + "zh-cn": { + "tts": "禁用自动更新同时也会禁用SYNC移动应用程序。您将无法在 SYNC 中使用任何移动应用程序。请按“是”确认或按“否”取消。", + "line1": "是否禁用自动更新和", + "line2": "移动应用程序?" + }, + "zh-tw": { + "tts": "停用自動更新也將停用 sync 行動應用程式。您將無法透過 SYNC 使用任何行動應用程式。確認請按「是」,取消請按「否」。", + "line1": "停用自動更新", + "line2": "和行動應用程式?" + } + } + }, + "DrivingCharacteristics": { + "languages": { + "de-de": { + "tts": "Eine App hat Zugriff auf die folgenden Fahreigenschaften: Kraftstoffverbrauch, MyKey, Sicherheitsgurtstatus.", + "label": "Fahreigenschaften" + }, + "en-au": { + "tts": "An app can access the following driving characteristics: Fuel consumption, MyKey, Seat belt status.", + "label": "Driving characteristics" + }, + "en-gb": { + "tts": "An app can access the following driving characteristics: Fuel consumption, MyKey, Seat belt status.", + "label": "Driving characteristics", + "textBody": "An app can access the following driving characteristics: Fuel consumption, MyKey, Seat belt status." + }, + "en-ie": { + "tts": "An app can access the following driving characteristics: Fuel consumption, MyKey, Seat belt status.", + "label": "Driving characteristics" + }, + "en-us": { + "tts": "An app can access the following driving characteristics: Fuel Consumption, MyKey, Seat Belt Status.", + "label": "Driving Characteristics", + "textBody": "An app can access the following driving characteristics: Fuel Consumption, MyKey, Seat Belt Status." + }, + "es-en": { + "tts": "Las aplicaciones pueden acceder a las siguientes características del manejo: Consumo de combustible, MyKey, Estado del cinturón de seguridad.", + "label": "Características del manejo", + "textBody": "Las aplicaciones pueden acceder a las siguientes características del manejo: Consumo de combustible, MyKey, Estado del cinturón de seguridad." + }, + "es-es": { + "tts": "Una aplicación puede acceder a las siguientes características de conducción: Consumo de combustible, MyKey, Estado cinturones de seguridad.", + "label": "Características de conducción" + }, + "es-mx": { + "tts": "Las aplicaciones pueden acceder a las siguientes características del manejo: Consumo de combustible, MyKey, Estado del cinturón de seguridad.", + "label": "Características del manejo", + "textBody": "Las aplicaciones pueden acceder a las siguientes características del manejo: Consumo de combustible, MyKey, Estado del cinturón de seguridad." + }, + "fr-ca": { + "tts": "Une application peut accéder aux caractéristiques de conduite suivantes: Consommation de carburant, MyKey, État des ceintures de sécurité.", + "label": "Caractéristiques de conduite", + "textBody": "Une application peut accéder aux caractéristiques de conduite suivantes: Consommation de carburant, MyKey, État des ceintures de sécurité." + }, + "fr-fr": { + "tts": "Une application peut accéder aux caractéristiques de conduite suivantes: Consommation de carburant, MyKey, État des ceintures de sécurité.", + "label": "Caractéristiques de conduite" + }, + "it-it": { + "tts": "Un'app può avere accesso alle seguenti caratteristiche di guida: Consumo carburante, MyKey, Stato cinture di sicurezza.", + "label": "Caratteristiche di guida" + }, + "nl-nl": { + "tts": "Een app heeft toegang tot de volgende rijkenmerken: Brandstofverbruik, MyKey, Veiligheidsgordelstatus.", + "label": "Rijkenmerken" + }, + "pl-pl": { + "tts": "Aplikacja może uzyskać dostęp do następujących informacji dotyczących jazdy: Zużycie paliwa, MyKey, Stan pasów bezpieczeństwa.", + "label": "Informacje dotyczące stylu jazdy" + }, + "pt-br": { + "tts": "Um aplicativo pode acessar as seguintes características de condução: Consumo de combustível, MyKey, Estado do cinto de segurança.", + "label": "Características de condução" + }, + "pt-pt": { + "tts": "Uma aplicação consegue aceder às seguintes informações de condução: Consumo de combustível, MyKey, Estado dos cintos de segurança.", + "label": "Características de condução" + }, + "ru-ru": { + "tts": "Приложение имеет доступ к следующим характеристикам движения: Расход топлива, MyKey, Состояние ремней безопасности.", + "label": "Характеристики движения" + }, + "sv-se": { + "tts": "Appen kan komma åt följande köregenskaper: Bränsleförbrukning, MyKey, Bältesstatus.", + "label": "Köregenskaper" + }, + "tr-tr": { + "tts": "Bir uygulama şu sürüş karakteristiklerine erişebilir: Yakıt tüketimi, MyKey, Emniyet kemeri durumu.", + "label": "Sürüş karakteristikleri" + }, + "zh-cn": { + "tts": "移动应用程序可访问下列行驶特性: 油耗, MyKey, 安全带状态", + "label": "行驶特性" + }, + "zh-tw": { + "tts": "應用程式可存取以下駕駛特性: 油耗, MyKey, 安全帶狀態", + "label": "駕駛特性" + } + } + }, + "Location": { + "languages": { + "de-de": { + "tts": "Eine App hat Zugriff auf die GPS-Daten und die Geschwindigkeit des Fahrzeugs.", + "label": "GPS und Geschwindigkeit" + }, + "en-au": { + "tts": "An app can access vehicle GPS and speed.", + "label": "GPS and speed" + }, + "en-gb": { + "tts": "An app can access vehicle GPS and speed.", + "label": "GPS and speed", + "textBody": "An app can access vehicle GPS and speed." + }, + "en-ie": { + "tts": "An app can access vehicle GPS and speed.", + "label": "GPS and speed" + }, + "en-us": { + "tts": "An app can access vehicle GPS and speed.", + "label": "GPS and speed", + "textBody": "An app can access vehicle GPS and speed." + }, + "es-en": { + "tts": "Las aplicaciones pueden acceder al GPS y a la velocidad del vehículo.", + "label": "GPS y velocidad", + "textBody": "Las aplicaciones pueden acceder al GPS y a la velocidad del vehículo." + }, + "es-es": { + "tts": "Una aplicación puede acceder al GPS y la velocidad del vehículo.", + "label": "GPS y velocidad" + }, + "es-mx": { + "tts": "Las aplicaciones pueden acceder al GPS y a la velocidad del vehículo.", + "label": "GPS y velocidad", + "textBody": "Las aplicaciones pueden acceder al GPS y a la velocidad del vehículo." + }, + "fr-ca": { + "tts": "Une application peut accéder au GPS et à la vitesse du véhicule.", + "label": "GPS et vitesse", + "textBody": "Une application peut accéder au GPS et à la vitesse du véhicule." + }, + "fr-fr": { + "tts": "Une application peut accéder au GPS et à la vitesse du véhicule.", + "label": "GPS et vitesse" + }, + "it-it": { + "tts": "Un'app può avere accesso a GPS e velocità del veicolo.", + "label": "GPS e velocità" + }, + "nl-nl": { + "tts": "Een app heeft toegang tot gps en de snelheid van het voertuig.", + "label": "Gps en snelheid" + }, + "pl-pl": { + "tts": "Aplikacja może uzyskać dostęp do modułu GPS i prędkości pojazdu.", + "label": "GPS i prędkość" + }, + "pt-br": { + "tts": "Um aplicativo pode acessar o GPS e a velocidade do veículo.", + "label": "GPS e velocidade" + }, + "pt-pt": { + "tts": "Uma aplicação consegue aceder ao GPS e à velocidade do veículo.", + "label": "GPS e velocidade" + }, + "ru-ru": { + "tts": "Приложение имеет доступ к GPS и скорости автомобиля.", + "label": "GPS и скорость" + }, + "sv-se": { + "tts": "Appen kan komma åt fordonets GPS och hastighetsmätare.", + "label": "GPS och hastighet" + }, + "tr-tr": { + "tts": "Bu uygulama aracın GPS ve hız bilgilerine erişebilir.", + "label": "GPS ve hız" + }, + "zh-cn": { + "tts": "移动应用程序可以访问车辆 GPS 和车速信息。", + "label": "GPS 和车速" + }, + "zh-tw": { + "tts": "應用程式可存取車輛的GPS和速度。", + "label": "GPS和車速" + } + } + }, + "Notifications": { + "languages": { + "de-de": { + "tts": "Läuft die App im Hintergrund, kann Sie Benachrichtigungen senden.", + "label": "Push-Benachrichtigungen" + }, + "en-au": { + "tts": "An app can send notifications when running in the background.", + "label": "Push notifications" + }, + "en-gb": { + "tts": "An app can send notifications when running in the background.", + "label": "Push notifications", + "textBody": "An app can send notifications when running in the background." + }, + "en-ie": { + "tts": "An app can send notifications when running in the background.", + "label": "Push notifications" + }, + "en-us": { + "tts": "An app can send notifications when running in the background.", + "label": "Push notifications", + "textBody": "An app can send notifications when running in the background." + }, + "es-en": { + "tts": "Las aplicaciones pueden enviar notificaciones cuando se ejecutan en segundo plano.", + "label": "Notificaciones tipo Push", + "textBody": "Las aplicaciones pueden enviar notificaciones cuando se ejecutan en segundo plano." + }, + "es-es": { + "tts": "Una aplicación puede enviar notificaciones cuando se está ejecutando en segundo plano.", + "label": "Notificaciones push" + }, + "es-mx": { + "tts": "Las aplicaciones pueden enviar notificaciones cuando se ejecutan en segundo plano.", + "label": "Notificaciones tipo Push", + "textBody": "Las aplicaciones pueden enviar notificaciones cuando se ejecutan en segundo plano." + }, + "fr-ca": { + "tts": "Une application peut envoyer des avis lorsqu’elle fonctionne en arrière-plan.", + "label": "Notifications instantanées", + "textBody": "Une application peut envoyer des avis lorsqu’elle fonctionne en arrière-plan." + }, + "fr-fr": { + "tts": "Une application peut envoyer des avis lorsqu’elle fonctionne en arrière-plan.", + "label": "Notifications push" + }, + "it-it": { + "tts": "Un'app può inviare notifiche se eseguita in background.", + "label": "Notifiche push" + }, + "nl-nl": { + "tts": "Een app kan meldingen versturen als deze op de achtergrond actief is.", + "label": "Push-meldingen" + }, + "pl-pl": { + "tts": "Aplikacja może wysyłać powiadomienia, działając w tle.", + "label": "Powiadomienia Push" + }, + "pt-br": { + "tts": "Um aplicativo pode enviar notificações quando estiver sendo executado em segundo plano.", + "label": "Notificações Push" + }, + "pt-pt": { + "tts": "Uma aplicação consegue enviar notificações quando está activa em segundo plano.", + "label": "Notificações push" + }, + "ru-ru": { + "tts": "Если приложение работает в фоновом режиме, оно может отправлять оповещения.", + "label": "Оповещения о пересылке" + }, + "sv-se": { + "tts": "Appen kan skicka meddelanden när den körs i bakgrunden.", + "label": "Push-notiser" + }, + "tr-tr": { + "tts": "Bir uygulama arka planda çalışırken bildirim gönderebilir.", + "label": "Anlık bildirimleri" + }, + "zh-cn": { + "tts": "移动应用程序在后台运行时可推送通知。", + "label": "推送通知" + }, + "zh-tw": { + "tts": "車輛行進時,應用程式可在背景中傳送通知。", + "label": "傳送通知" + } + } + }, + "SettingDisableUpdates": { + "languages": { + "de-de": { + "line1": "Updates deakt." + }, + "en-au": { + "line1": "Disable updates" + }, + "en-gb": { + "line1": "Disable updates" + }, + "en-ie": { + "line1": "Disable updates" + }, + "en-us": { + "line1": "Disable Updates", + "textBody": "Disable Updates" + }, + "es-en": { + "line1": "Deshab. actual.", + "textBody": "Deshab. actual." + }, + "es-es": { + "line1": "Desact. actual." + }, + "es-mx": { + "line1": "Deshab. actual.", + "textBody": "Deshab. actual." + }, + "fr-ca": { + "line1": "Désactiver MAJ", + "textBody": "Désactiver MAJ" + }, + "fr-fr": { + "line1": "Désactiver màj" + }, + "it-it": { + "line1": "Disabilita agg." + }, + "nl-nl": { + "line1": "Upd. uitschak." + }, + "pl-pl": { + "line1": "Wyłącz aktual." + }, + "pt-br": { + "line1": "Desat. atualiz." + }, + "pt-pt": { + "line1": "Desact. actualiz." + }, + "ru-ru": { + "line1": "Откл. обновл." + }, + "sv-se": { + "line1": "Inaktivera uppd." + }, + "tr-tr": { + "line1": "Güncell. Kapat" + }, + "zh-cn": { + "line1": "禁用更新" + }, + "zh-tw": { + "line1": "停用更新" + } + } + }, + "SettingEnableUpdates": { + "languages": { + "de-de": { + "line1": "Apps aktivieren" + }, + "en-au": { + "line1": "Enable Apps" + }, + "en-gb": { + "line1": "Enable Apps" + }, + "en-ie": { + "line1": "Enable Apps" + }, + "en-us": { + "line1": "Enable Apps" + }, + "es-en": { + "line1": "Hab. aplic." + }, + "es-es": { + "line1": "Activar apl." + }, + "es-mx": { + "line1": "Hab. aplic." + }, + "fr-ca": { + "line1": "Activer app.", + "textBody": "Activer app." + }, + "fr-fr": { + "line1": "Activer app." + }, + "it-it": { + "line1": "Abilita app" + }, + "nl-nl": { + "line1": "Apps inschak." + }, + "pl-pl": { + "line1": "Włącz aplikacje" + }, + "pt-br": { + "line1": "Ativar aplic." + }, + "pt-pt": { + "line1": "Activar actualiz." + }, + "ru-ru": { + "line1": "Вкл. прилож." + }, + "sv-se": { + "line1": "Aktivera appar" + }, + "tr-tr": { + "line1": "Uygulamaları aç" + }, + "zh-cn": { + "line1": "启用应用程序" + }, + "zh-tw": { + "line1": "啟用應用程式" + } + } + }, + "SettingUpdateAuto": { + "languages": { + "de-de": { + "line1": "Update anford." + }, + "en-au": { + "line1": "Request update" + }, + "en-gb": { + "line1": "Request update" + }, + "en-ie": { + "line1": "Request update" + }, + "en-us": { + "line1": "Request Update", + "textBody": "Select `Update now` to receive app permissions for your SYNC-enabled mobile apps. This may enable additional functionality depending on the app and your settings. If your phone has a working data connection, an update should complete in less than 1 minute." + }, + "es-en": { + "line1": "Solicit. actualiz.", + "textBody": "Solicit. actualiz." + }, + "es-es": { + "line1": "Solicitar actual." + }, + "es-mx": { + "line1": "Solicit. actualiz.", + "textBody": "Solicit. actualiz." + }, + "fr-ca": { + "line1": "Demander MAJ", + "textBody": "Demander MAJ" + }, + "fr-fr": { + "line1": "Demander màj" + }, + "it-it": { + "line1": "Rich. aggiorn." + }, + "nl-nl": { + "line1": "Upd. aanvragen" + }, + "pl-pl": { + "line1": "Zażądaj aktual." + }, + "pt-br": { + "line1": "Solicitar atualiz." + }, + "pt-pt": { + "line1": "Solicit. actualiz." + }, + "ru-ru": { + "line1": "Запрос на обн." + }, + "sv-se": { + "line1": "Begär uppdat." + }, + "tr-tr": { + "line1": "Güncelleme iste" + }, + "zh-cn": { + "line1": "请求更新" + }, + "zh-tw": { + "line1": "請求更新" + } + } + }, + "StatusNeeded": { + "languages": { + "de-de": { + "line1": "Update benötigt" + }, + "en-au": { + "line1": "Update needed" + }, + "en-gb": { + "line1": "Update needed", + "textBody": "Update needed" + }, + "en-ie": { + "line1": "Update needed" + }, + "en-us": { + "line1": "Update Needed", + "textBody": "Update Needed" + }, + "es-en": { + "line1": "Actualiz. neces.", + "textBody": "Actualiz. neces." + }, + "es-es": { + "line1": "Actu. necesaria" + }, + "es-mx": { + "line1": "Actualiz. neces.", + "textBody": "Actualiz. neces." + }, + "fr-ca": { + "line1": "Màj requise", + "textBody": "Màj requise" + }, + "fr-fr": { + "line1": "Mise à jour requise" + }, + "it-it": { + "line1": "Necess. aggiorn." + }, + "nl-nl": { + "line1": "Update nodig" + }, + "pl-pl": { + "line1": "Potrzeba aktual." + }, + "pt-br": { + "line1": "Atualiz. necess." + }, + "pt-pt": { + "line1": "Actual. necess." + }, + "ru-ru": { + "line1": "Необх. обновл." + }, + "sv-se": { + "line1": "Uppdat. krävs" + }, + "tr-tr": { + "line1": "Güncellenmeli" + }, + "zh-cn": { + "line1": "需要进行更新" + }, + "zh-tw": { + "line1": "需更新" + } + } + }, + "StatusPending": { + "languages": { + "de-de": { + "line1": "Aktualisieren..." + }, + "en-au": { + "line1": "Updating..." + }, + "en-gb": { + "line1": "Updating...", + "textBody": "Updating..." + }, + "en-ie": { + "line1": "Updating..." + }, + "en-us": { + "line1": "Updating...", + "textBody": "Updating..." + }, + "es-en": { + "line1": "Actualizando...", + "textBody": "Actualizando..." + }, + "es-es": { + "line1": "Actualizando..." + }, + "es-mx": { + "line1": "Actualizando...", + "textBody": "Actualizando..." + }, + "fr-ca": { + "line1": "MAJ en cours...", + "textBody": "MAJ en cours..." + }, + "fr-fr": { + "line1": "Màj en cours..." + }, + "it-it": { + "line1": "Aggiornamento" + }, + "nl-nl": { + "line1": "Updaten..." + }, + "pl-pl": { + "line1": "Aktualizowanie" + }, + "pt-br": { + "line1": "Atualizando..." + }, + "pt-pt": { + "line1": "A actualizar..." + }, + "ru-ru": { + "line1": "Обновление..." + }, + "sv-se": { + "line1": "Uppdaterar..." + }, + "tr-tr": { + "line1": "Güncelleniyor..." + }, + "zh-cn": { + "line1": "正在更新......" + }, + "zh-tw": { + "line1": "更新中..." + } + } + }, + "StatusUpToDate": { + "languages": { + "de-de": { + "line1": "Aktuelle Version" + }, + "en-au": { + "line1": "Up-to-date" + }, + "en-gb": { + "line1": "Up-to-date", + "textBody": "Up-to-date" + }, + "en-ie": { + "line1": "Up-to-date" + }, + "en-us": { + "line1": "Up-To-Date", + "textBody": "Up-To-Date" + }, + "es-en": { + "line1": "Actualizado", + "textBody": "Actualizado" + }, + "es-es": { + "line1": "Actualizada" + }, + "es-mx": { + "line1": "Actualizado", + "textBody": "Actualizado" + }, + "fr-ca": { + "line1": "Déjà à jour", + "textBody": "Déjà à jour" + }, + "fr-fr": { + "line1": "Déjà à jour" + }, + "it-it": { + "line1": "più recente" + }, + "nl-nl": { + "line1": "Up-to-date" + }, + "pl-pl": { + "line1": "Aktualne" + }, + "pt-br": { + "line1": "Atualizado" + }, + "pt-pt": { + "line1": "Actualizado" + }, + "ru-ru": { + "line1": "Обновлено" + }, + "sv-se": { + "line1": "Uppdat. krävs ej" + }, + "tr-tr": { + "line1": "Güncel" + }, + "zh-cn": { + "line1": "最新更新" + }, + "zh-tw": { + "line1": "更新最新" + } + } + }, + "VehicleInfo": { + "languages": { + "de-de": { + "tts": "Eine App hat Zugriff auf die folgenden Fahrzeuginformationen: Kraftstoff-Füllstand, Kraftstoffverbrauch, Motordrehzahl, Kilometerzähler, FIN, Außentemperatur, Gangstellung, Reifenluftdruck.", + "label": "Fahrzeuginformationen" + }, + "en-au": { + "tts": "An app can access the following vehicle information: Fuel level, Fuel economy, Engine RPMs, Odometer, VIN, Outside air temperature, Gear position, Tyre pressure.", + "label": "Vehicle information" + }, + "en-gb": { + "tts": "An app can access the following vehicle information: Fuel level, Fuel economy, Engine RPMs, Odometer, VIN, Outside air temperature, Gear position, Tire pressure.", + "label": "Vehicle information", + "textBody": "An app can access the following vehicle information: Fuel level, Fuel economy, Engine RPMs, Odometer, VIN, Outside air temperature, Gear position, Tire pressure." + }, + "en-ie": { + "tts": "An app can access the following vehicle information: Fuel level, Fuel economy, Engine RPMs, Odometer, VIN, Outside air temperature, Gear position, Tyre pressure.", + "label": "Vehicle information" + }, + "en-us": { + "tts": "An app can access the following vehicle information: Fuel Level, Fuel Economy, Engine RPMs, Odometer, VIN, External Temperature, Gear Position, Tire Pressure.", + "label": "Vehicle information", + "textBody": "An app can access the following vehicle information: Fuel Level, Fuel Economy, Engine RPMs, Odometer, VIN, External Temperature, Gear Position, Tire Pressure." + }, + "es-en": { + "tts": "Las aplicaciones pueden acceder a la siguiente información del vehículo: Nivel de combustible, Economía de combustible, RPM del motor, Cuentakilómetros, Número de identificación del vehículo, Temperatura externa, Posición del cambio, Presión de los neumáticos.", + "label": "Información del vehículo", + "textBody": "Las aplicaciones pueden acceder a la siguiente información del vehículo: Nivel de combustible, Economía de combustible, RPM del motor, Cuentakilómetros, Número de identificación del vehículo, Temperatura externa, Posición del cambio, Presión de los neumáticos." + }, + "es-es": { + "tts": "Una aplicación puede acceder a la siguiente información del vehículo: Nivel de combustible, Ahorro de combustible, RPM del motor, Cuentakilómetros, VIN, Temperatura aire exterior, Marcha engranada, Presión de neumáticos.", + "label": "Información del vehículo" + }, + "es-mx": { + "tts": "Las aplicaciones pueden acceder a la siguiente información del vehículo: Nivel de combustible, Economía de combustible, RPM del motor, Cuentakilómetros, Número de identificación del vehículo, Temperatura externa, Posición del cambio, Presión de los neumáticos.", + "label": "Información del vehículo", + "textBody": "Las aplicaciones pueden acceder a la siguiente información del vehículo: Nivel de combustible, Economía de combustible, RPM del motor, Cuentakilómetros, Número de identificación del vehículo, Temperatura externa, Posición del cambio, Presión de los neumáticos." + }, + "fr-ca": { + "tts": "Une application peut accéder aux informations suivantes du véhicule: Niveau de carburant, Économie de carburant, Au régime du moteur, Odomètre, NIV, Température extérieure, Position d’embrayage, Pression des pneus.", + "label": "Renseignements du véhicule", + "textBody": "Une application peut accéder aux informations suivantes du véhicule: Niveau de carburant, Économie de carburant, Au régime du moteur, Odomètre, NIV, Température extérieure, Position d’embrayage, Pression des pneus." + }, + "fr-fr": { + "tts": "Une application peut accéder aux informations suivantes du véhicule: Niveau de carburant, Économie de carburant, Vitesse de moteur, Compteur kilométrique, NIV, Température extérieure, Position de vitesse, Pression des pneus.", + "label": "Renseignements du véhicule" + }, + "it-it": { + "tts": "Un'app può avere accesso alle seguenti informazioni del veicolo: Livello carburante, Consumi carburante, Numero giri motore, Contachilometri, VIN, Temperatura esterna, Posizione marcia, Pressione pneumatici.", + "label": "Informazioni sul veicolo" + }, + "nl-nl": { + "tts": "Een app heeft toegang tot de volgende voertuiginformatie: Brandstofpeil, Brandstofverbruik, Motortoerental, Kilometerteller, VIN, Buitentemperatuur, Versnellingsstand, Bandenspanning.", + "label": "Voertuiginformatie" + }, + "pl-pl": { + "tts": "Aplikacja może uzyskać dostęp do następujących informacji o pojeździe: Poziom paliwa, Zużycie paliwa, Obroty silnika, Licznik przebiegu, Numer VIN, Temperatura zewnętrzna, Aktualny bieg, Ciśnienie opon.", + "label": "Informacje o pojeździe" + }, + "pt-br": { + "tts": "Um aplicativo pode acessar as seguintes informações sobre o veículo: Nível de combustível, Economia de combustível, RPM do motor, Hodômetro, VIN, Temperatura externa, Posição das marchas, Pressão dos pneus.", + "label": "Informações sobre o veículo" + }, + "pt-pt": { + "tts": "Uma aplicação consegue aceder às seguintes informações do veículo: Nível de combustível, Poupança de combustível, RPM do motor, Conta-quilómetros, VIN, Temperatura exterior, Posição da mudança de velocidade, Pressão dos pneus.", + "label": "Informações do veículo" + }, + "ru-ru": { + "tts": "Приложение имеет доступ к следующим данным автомобиля: Уровень топлива, Економия топлива, Число оборотов двигателя, Одометр, Номер VIN, Температура за бортом, Положение передачи, Давление шин.", + "label": "Информация об автомобиле" + }, + "sv-se": { + "tts": "Appen kan komma åt följande fordonsinformation: Bränslenivå, Bränsleekonomi, Motorns varvtal, Vägmätare, VIN, Utetemperatur, Växelläge, Däcktryck.", + "label": "Fordonsinformation" + }, + "tr-tr": { + "tts": "Bir uygulama şu araç bilgilerine erişebilir: Yakıt seviyesi, Yakıt ekonomisi, Motor devirleri, Kilometre sayacı, VIN, Dış sıcaklık, Vites konumu, Lastik basıncı.", + "label": "Araç bilgisi" + }, + "zh-cn": { + "tts": "移动应用程序可访问下列车辆信息 : 燃油量, 燃油经济性, 发动机转速(RPM), 里程表, VIN, 车外温度, 档位, 胎压.", + "label": "车辆信息" + }, + "zh-tw": { + "tts": "一個應用程式可存取以下車輛資訊 : 燃油存量, 燃油經濟性, 引擎轉速, 里程表, 車輛識別號碼, 車外溫度, 檔位, 胎壓.", + "label": "車輛資訊" + } + } + } + } + }, + "app_policies": { + "default": { + "keep_context": false, + "steal_focus": false, + "priority": "NONE", + "default_hmi": "NONE", + "moduleType": ["RADIO", "CLIMATE"], + "groups": ["Base-4"], + "groups_primaryRC": ["Base-4", "RemoteControl"], + "groups_nonPrimaryRC": ["Notifications-RC", "RemoteControl"] + }, + "pre_consent_passengersRC": { + "keep_context": false, + "steal_focus": false, + "priority": "NONE", + "default_hmi":"NONE", + "groups": ["pre_BaseRC-1"] + }, + "device": { + "keep_context": false, + "steal_focus": false, + "priority": "NONE", + "default_hmi": "NONE", + "groups": ["DataConsent-2"] + }, + "pre_DataConsent": { + "keep_context": false, + "steal_focus": false, + "priority": "NONE", + "default_hmi": "NONE", + "groups": ["BaseBeforeDataConsent"] + } + } + } +} diff --git a/src/components/remote_control/src/commands/base_command_notification.cc b/src/components/remote_control/src/commands/base_command_notification.cc new file mode 100644 index 0000000000..c79e800a88 --- /dev/null +++ b/src/components/remote_control/src/commands/base_command_notification.cc @@ -0,0 +1,154 @@ +/* + Copyright (c) 2013, 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 "remote_control/commands/base_command_notification.h" +#include "json/json.h" +#include "remote_control/remote_control_plugin.h" +#include "remote_control/rc_module_constants.h" +#include "application_manager/application_manager.h" + +namespace remote_control { + +namespace commands { + +CREATE_LOGGERPTR_GLOBAL(logger_, "RemoteControlModule") + +BaseCommandNotification::BaseCommandNotification( + const application_manager::MessagePtr& message, + RemotePluginInterface& rc_module) + : Command(rc_module), service_(rc_module_.service()), message_(message) { + Json::Value value; + Json::Reader reader; + reader.parse(message_->json_message(), value); + if (value.isMember(json_keys::kParams)) { + Json::FastWriter writer; + message_->set_json_message(writer.write(value[json_keys::kParams])); + } else { + message_->set_json_message(""); + } +} + +BaseCommandNotification::~BaseCommandNotification() {} + +RCAppExtensionPtr BaseCommandNotification::GetAppExtension( + application_manager::ApplicationSharedPtr app) const { + if (!app) { + return NULL; + } + + functional_modules::ModuleID id = rc_module_.GetModuleID(); + + RCAppExtensionPtr rc_app_extension; + application_manager::AppExtensionPtr app_extension = app->QueryInterface(id); + if (!app_extension) { + return NULL; + } + + rc_app_extension = + application_manager::AppExtensionPtr::static_pointer_cast<RCAppExtension>( + app_extension); + + return rc_app_extension; +} + +void BaseCommandNotification::Run() { + LOG4CXX_AUTO_TRACE(logger_); + Execute(); +} + +void BaseCommandNotification::NotifyApplications() { + LOG4CXX_AUTO_TRACE(logger_); + typedef std::vector<application_manager::ApplicationSharedPtr> AppList; + AppList applications = service_->GetApplications(rc_module_.GetModuleID()); + for (AppList::iterator i = applications.begin(); i != applications.end(); + ++i) { + application_manager::MessagePtr message( + new application_manager::Message(*message_)); + message->set_connection_key((*i)->app_id()); + NotifyOneApplication(message); + } +} + +void BaseCommandNotification::NotifyOneApplication( + application_manager::MessagePtr message) { + LOG4CXX_AUTO_TRACE(logger_); + if (CheckPolicy(message)) { + service_->SendMessageToMobile(message); + } else { + LOG4CXX_WARN(logger_, + "Function \"" << message->function_name() << "\" (#" + << message->function_id() + << ") not allowed by policy"); + } +} + +bool BaseCommandNotification::CheckPolicy( + application_manager::MessagePtr message) { + LOG4CXX_AUTO_TRACE(logger_); + application_manager::ApplicationSharedPtr app = + service_->GetApplication(message->connection_key()); + + if (!app) { + LOG4CXX_WARN(logger_, + "Application " << message->connection_key() + << "isn't registered"); + return false; + } + + mobile_apis::Result::eType permission = + service_->CheckPolicyPermissions(message); + + Json::Value value; + Json::Reader reader; + LOG4CXX_DEBUG(logger_, "Notification: " << message->json_message()); + reader.parse(message->json_message(), value); + + return permission == mobile_apis::Result::eType::SUCCESS && + service_->CheckModule(app->app_id(), ModuleType(value)); +} + +std::string BaseCommandNotification::ModuleType(const Json::Value& message) { + return ""; +} + +bool BaseCommandNotification::Validate() { + return true; +} + +std::vector<std::string> BaseCommandNotification::ControlData( + const Json::Value& message) { + return std::vector<std::string>(); +} + +} // namespace commands + +} // namespace remote_control diff --git a/src/components/remote_control/src/commands/base_command_request.cc b/src/components/remote_control/src/commands/base_command_request.cc new file mode 100644 index 0000000000..900d94a190 --- /dev/null +++ b/src/components/remote_control/src/commands/base_command_request.cc @@ -0,0 +1,647 @@ +/* + Copyright (c) 2013, 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 "remote_control/commands/base_command_request.h" +#include <cstring> +#include "utils/make_shared.h" +#include "remote_control/event_engine/event_dispatcher.h" +#include "remote_control/message_helper.h" +#include "remote_control/remote_control_plugin.h" +#include "remote_control/rc_module_constants.h" +#include "application_manager/application_manager_impl.h" + +namespace remote_control { + +namespace commands { + +using rc_event_engine::EventDispatcher; + +using namespace json_keys; + +CREATE_LOGGERPTR_GLOBAL(logger_, "RemoteControlModule") + +BaseCommandRequest::BaseCommandRequest( + const application_manager::MessagePtr& message, + RemotePluginInterface& rc_module) + : Command(rc_module), message_(message), auto_allowed_(false) { + service_ = rc_module_.service(); + app_ = service_->GetApplication(message_->connection_key()); +} + +BaseCommandRequest::~BaseCommandRequest() { + rc_module_.event_dispatcher().remove_observer(this); +} + +void BaseCommandRequest::OnTimeout() { + LOG4CXX_AUTO_TRACE(logger_); + PrepareResponse( + false, result_codes::kGenericError, "Request timeout expired."); + rc_module_.SendTimeoutResponseToMobile(message_); +} + +void BaseCommandRequest::PrepareResponse(const bool success, + const char* result_code, + const std::string& info) { + message_->set_message_type(application_manager::MessageType::kResponse); + Json::Value msg_params; + + if (!response_params_.isNull()) { + msg_params = response_params_; + } + + msg_params[kSuccess] = success; + msg_params[kResultCode] = result_code; + if (!info.empty()) { + msg_params[kInfo] = info; + } + + Json::FastWriter writer; + std::string params = writer.write(msg_params); + message_->set_json_message(params); +} + +void BaseCommandRequest::SendResponse(const bool success, + const char* result_code, + const std::string& info) { + LOG4CXX_AUTO_TRACE(logger_); + PrepareResponse(success, result_code, info); + rc_module_.SendResponseToMobile(message_); +} + +struct OnDriverAnswerCallback : AskDriverCallBack { + public: + OnDriverAnswerCallback(application_manager::MessagePtr hmi_message_to_send, + ResourceAllocationManager& resource_manager, + BaseCommandRequest& request, + application_manager::Service& service, + const std::string& module_type, + uint32_t app_id) + : hmi_message_to_send_(hmi_message_to_send) + , resource_manager_(resource_manager) + , request_(request) + , service_(service) + , module_type_(module_type) + , app_id_(app_id) {} + + void on_event(const rc_event_engine::Event<application_manager::MessagePtr, + std::string>& event) FINAL { + LOG4CXX_AUTO_TRACE(logger_); + application_manager::Message& hmi_response = *(event.event_message()); + const application_manager::MessageValidationResult validate_result = + service_.ValidateMessageBySchema(hmi_response); + LOG4CXX_DEBUG(logger_, + "HMI response validation result is " << validate_result); + if (validate_result != + application_manager::MessageValidationResult::SUCCESS) { + request_.SendResponse(false, + result_codes::kGenericError, + "HMI has sent invalid parameters"); + return; + } + + const Json::Value value = + MessageHelper::StringToValue(hmi_response.json_message()); + + std::string result_code; + std::string info; + const bool is_response_successful = + request_.ParseResultCode(value, result_code, info); + + if (result_codes::kTimedOut == result_code) { + info = "The resource is in use and the driver did not respond in time"; + } + + if (!is_response_successful) { + request_.SendResponse(false, result_code.c_str(), info); + return; + } + + const bool allowed = + value[json_keys::kResult][message_params::kAllowed].asBool(); + + if (allowed) { + request_.rc_module_.event_dispatcher().add_observer( + hmi_message_to_send_->function_name(), + hmi_message_to_send_->correlation_id(), + &request_); + LOG4CXX_DEBUG(logger_, + "HMI Request:\n " << hmi_message_to_send_->json_message()); + + resource_manager_.ForceAcquireResource(module_type_, app_id_); + request_.SetResourceState( + MessageHelper::StringToValue(request_.message_->json_message()), + ResourceState::BUSY); + + service_.SendMessageToHMI(hmi_message_to_send_); + } else { + request_.SendResponse(false, + result_codes::kRejected, + "The resource is in use and the driver disallows " + "this remote control RPC"); + resource_manager_.OnDriverDisallowed(module_type_, app_id_); + } + } + + application_manager::MessagePtr hmi_message_to_send_; + ResourceAllocationManager& resource_manager_; + BaseCommandRequest& request_; + application_manager::Service& service_; + const std::string module_type_; + const uint32_t app_id_; +}; + +void BaseCommandRequest::SendMessageToHMI( + const application_manager::MessagePtr& message_to_send) { + LOG4CXX_AUTO_TRACE(logger_); + const Json::Value message_params = + MessageHelper::StringToValue(message_->json_message()); + + if (!IsResourceFree(ModuleType(message_params))) { + LOG4CXX_WARN(logger_, "Resource is busy."); + SendResponse(false, result_codes::kInUse, ""); + return; + } + + AcquireResult::eType acquire_result = AcquireResource(message_params); + switch (acquire_result) { + case AcquireResult::ALLOWED: { + SetResourceState(MessageHelper::StringToValue(message_->json_message()), + ResourceState::BUSY); + + rc_module_.event_dispatcher().add_observer( + message_to_send->function_name(), + message_to_send->correlation_id(), + this); + LOG4CXX_DEBUG(logger_, + "HMI Request:\n " << message_to_send->json_message()); + service_->SendMessageToHMI(message_to_send); + break; + } + case AcquireResult::IN_USE: { + SendResponse(false, result_codes::kInUse, ""); + break; + } + case AcquireResult::ASK_DRIVER: { + ResourceAllocationManager& resource_manager = + rc_module_.resource_allocation_manager(); + AskDriverCallBackPtr callback( + new OnDriverAnswerCallback(message_to_send, + resource_manager, + *this, + *service(), + ModuleType(message_params), + app()->app_id())); + resource_manager.AskDriver( + ModuleType(message_params), app()->hmi_app_id(), callback); + break; + } + case AcquireResult::REJECTED: { + SendResponse(false, result_codes::kRejected, ""); + break; + } + } +} + +void BaseCommandRequest::SendRequest(const char* function_id, + const Json::Value& message_params) { + LOG4CXX_AUTO_TRACE(logger_); + application_manager::MessagePtr message_to_send = + CreateHmiRequest(function_id, message_params); + SendMessageToHMI(message_to_send); +} + +application_manager::MessagePtr BaseCommandRequest::CreateHmiRequest( + const char* function_id, const Json::Value& message_params) { + LOG4CXX_AUTO_TRACE(logger_); + const uint32_t hmi_app_id = app_->hmi_app_id(); + return MessageHelper::CreateHmiRequest( + function_id, hmi_app_id, message_params, rc_module_); +} + +bool BaseCommandRequest::Validate() { + return application_manager::MessageValidationResult::SUCCESS == + service_->ValidateMessageBySchema(*message_); +} + +bool BaseCommandRequest::ParseJsonString(Json::Value* parsed_msg) { + LOG4CXX_AUTO_TRACE(logger_); + DCHECK(parsed_msg); + if (!parsed_msg) + return false; + + (*parsed_msg) = MessageHelper::StringToValue(message_->json_message()); + if (Json::ValueType::nullValue == parsed_msg->type()) { + LOG4CXX_ERROR(logger_, + "Invalid JSON received in " << message_->json_message()); + SendResponse( + false, result_codes::kInvalidData, "Mobile request validation failed!"); + return false; + } + return true; +} + +const char* BaseCommandRequest::GetMobileResultCode( + const hmi_apis::Common_Result::eType& hmi_code) const { + LOG4CXX_AUTO_TRACE(logger_); + switch (hmi_code) { + case hmi_apis::Common_Result::SUCCESS: { + return result_codes::kSuccess; + } + case hmi_apis::Common_Result::UNSUPPORTED_REQUEST: { + return result_codes::kUnsupportedRequest; + } + case hmi_apis::Common_Result::UNSUPPORTED_RESOURCE: { + return result_codes::kUnsupportedResource; + } + case hmi_apis::Common_Result::DISALLOWED: { + return result_codes::kDisallowed; + } + case hmi_apis::Common_Result::REJECTED: { + return result_codes::kRejected; + } + case hmi_apis::Common_Result::ABORTED: { + return result_codes::kAborted; + } + case hmi_apis::Common_Result::IGNORED: { + return result_codes::kIgnored; + } + case hmi_apis::Common_Result::RETRY: { + return result_codes::kRetry; + } + case hmi_apis::Common_Result::IN_USE: { + return result_codes::kInUse; + } + case hmi_apis::Common_Result::DATA_NOT_AVAILABLE: { + return result_codes::kVehicleDataNotAvailable; + } + case hmi_apis::Common_Result::TIMED_OUT: { + return result_codes::kTimedOut; + } + case hmi_apis::Common_Result::INVALID_DATA: { + return result_codes::kInvalidData; + } + case hmi_apis::Common_Result::CHAR_LIMIT_EXCEEDED: { + return result_codes::kCharLimitExceeded; + } + case hmi_apis::Common_Result::INVALID_ID: { + return result_codes::kInvalidId; + } + case hmi_apis::Common_Result::DUPLICATE_NAME: { + return result_codes::kDuplicateName; + } + case hmi_apis::Common_Result::APPLICATION_NOT_REGISTERED: { + return result_codes::kApplicationNotRegistered; + } + case hmi_apis::Common_Result::WRONG_LANGUAGE: { + return result_codes::kWrongLanguage; + } + case hmi_apis::Common_Result::OUT_OF_MEMORY: { + return result_codes::kOutOfMemory; + } + case hmi_apis::Common_Result::TOO_MANY_PENDING_REQUESTS: { + return result_codes::kTooManyPendingRequests; + } + case hmi_apis::Common_Result::NO_APPS_REGISTERED: { + return result_codes::kApplicationNotRegistered; + } + case hmi_apis::Common_Result::NO_DEVICES_CONNECTED: { + return result_codes::kApplicationNotRegistered; + } + case hmi_apis::Common_Result::WARNINGS: { + return result_codes::kWarnings; + } + case hmi_apis::Common_Result::GENERIC_ERROR: { + return result_codes::kGenericError; + } + case hmi_apis::Common_Result::USER_DISALLOWED: { + return result_codes::kUserDisallowed; + } + case hmi_apis::Common_Result::READ_ONLY: { + return result_codes::kReadOnly; + } + default: { + LOG4CXX_ERROR(logger_, "Unknown HMI result code " << hmi_code); + return result_codes::kGenericError; + } + } +} + +RCAppExtensionPtr BaseCommandRequest::GetAppExtension( + application_manager::ApplicationSharedPtr app) const { + LOG4CXX_AUTO_TRACE(logger_); + if (!app) { + return NULL; + } + + functional_modules::ModuleID id = rc_module_.GetModuleID(); + + RCAppExtensionPtr rc_app_extension; + application_manager::AppExtensionPtr app_extension = app->QueryInterface(id); + if (!app_extension) { + LOG4CXX_DEBUG(logger_, "New app extension will be created"); + app_extension = new RCAppExtension(id); + app->AddExtension(app_extension); + } + + rc_app_extension = + application_manager::AppExtensionPtr::static_pointer_cast<RCAppExtension>( + app_extension); + + return rc_app_extension; +} + +bool BaseCommandRequest::ParseResultCode(const Json::Value& value, + std::string& result_code, + std::string& info) { + LOG4CXX_AUTO_TRACE(logger_); + result_code = result_codes::kInvalidData; + info = ""; + + if (IsMember(value, kResult) && IsMember(value[kResult], kCode)) { + result_code = + GetMobileResultCode(static_cast<hmi_apis::Common_Result::eType>( + value[kResult][kCode].asInt())); + } else if (IsMember(value, kError) && IsMember(value[kError], kCode)) { + result_code = + GetMobileResultCode(static_cast<hmi_apis::Common_Result::eType>( + value[kError][kCode].asInt())); + + if (IsMember(value[kError], kMessage)) { + info = value[kError][kMessage].asCString(); + } + } + + if ((result_codes::kSuccess == result_code) || + (result_codes::kWarnings == result_code)) { + return true; + } + + return false; +} + +void BaseCommandRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + if (Validate()) { + LOG4CXX_INFO(logger_, "Request message validated successfully!"); + if (CheckPolicyPermissions() && CheckDriverConsent()) { + Execute(); // run child's logic + } + } else { + SendResponse(false, result_codes::kInvalidData, ""); + } +} + +bool BaseCommandRequest::CheckPolicyPermissions() { + LOG4CXX_AUTO_TRACE(logger_); + if (!app_) { + LOG4CXX_ERROR(logger_, "Application doesn't registered!"); + SendResponse(false, result_codes::kApplicationNotRegistered, ""); + return false; + } + + mobile_apis::Result::eType ret = service_->CheckPolicyPermissions(message_); + if (ret != mobile_apis::Result::eType::SUCCESS) { + SendResponse(false, result_codes::kDisallowed, ""); + LOG4CXX_WARN(logger_, + "Function \"" << message_->function_name() << "\" (#" + << message_->function_id() + << ") not allowed by policy"); + return false; + } + + return true; +} + +application_manager::TypeAccess BaseCommandRequest::CheckAccess( + const Json::Value& message) { + const std::string& module = ModuleType(message); + return service_->CheckAccess( + app_->app_id(), module, message_->function_name(), ControlData(message)); +} + +bool BaseCommandRequest::CheckDriverConsent() { + LOG4CXX_AUTO_TRACE(logger_); + RCAppExtensionPtr extension = GetAppExtension(app_); + if (!extension) { + return false; + } + Json::Value value; + Json::Reader reader; + LOG4CXX_DEBUG(logger_, "Request: " << message_->json_message()); + reader.parse(message_->json_message(), value); + + application_manager::TypeAccess access = CheckAccess(value); + + if (IsAutoAllowed(access)) { + set_auto_allowed(true); + return true; + } + if (IsNeededDriverConsent(access)) { + SendGetUserConsent(value); + } else { + SendDisallowed(access); + } + return false; +} + +bool BaseCommandRequest::IsNeededDriverConsent( + application_manager::TypeAccess access) const { + return access == application_manager::kManual; +} + +bool BaseCommandRequest::IsAutoAllowed( + application_manager::TypeAccess access) const { + return access == application_manager::kAllowed; +} + +void BaseCommandRequest::SendDisallowed( + application_manager::TypeAccess access) { + LOG4CXX_AUTO_TRACE(logger_); + std::string info; + switch (access) { + case application_manager::kAllowed: + case application_manager::kManual: + return; + case application_manager::kDisallowed: + info = disallowed_info_.empty() + ? "The RPC is disallowed by vehicle settings" + : disallowed_info_; + break; + case application_manager::kNone: + info = "Internal issue"; + break; + default: + info = "Unknown issue"; + } + LOG4CXX_ERROR(logger_, info); + SendResponse(false, result_codes::kDisallowed, info); +} + +void BaseCommandRequest::SendGetUserConsent(const Json::Value& value) { + LOG4CXX_AUTO_TRACE(logger_); + DCHECK(app_); + Json::Value params; + params[json_keys::kAppId] = app_->hmi_app_id(); + params[message_params::kModuleType] = ModuleType(value); + SendRequest(functional_modules::hmi_api::get_user_consent, params); +} + +std::string BaseCommandRequest::ModuleType(const Json::Value& message) { + return ""; +} + +std::vector<std::string> BaseCommandRequest::ControlData( + const Json::Value& message) { + return std::vector<std::string>(); +} + +void BaseCommandRequest::on_event( + const rc_event_engine::Event<application_manager::MessagePtr, std::string>& + event) { + LOG4CXX_AUTO_TRACE(logger_); + if (event.id() == functional_modules::hmi_api::get_user_consent) { + ProcessAccessResponse(event); + } else { + if (auto_allowed()) { + UpdateHMILevel(event); + } + SetResourceState(MessageHelper::StringToValue(message_->json_message()), + ResourceState::FREE); + OnEvent(event); // run child's logic + } +} + +void BaseCommandRequest::UpdateHMILevel( + const rc_event_engine::Event<application_manager::MessagePtr, std::string>& + event) { + LOG4CXX_AUTO_TRACE(logger_); + RCAppExtensionPtr extension = GetAppExtension(app_); + if (!extension) { + return; + } + if (!extension->is_on_driver_device()) { + Json::Value value = + MessageHelper::StringToValue(event.event_message()->json_message()); + std::string result_code; + std::string info; + bool success = ParseResultCode(value, result_code, info); + CheckHMILevel(application_manager::kAllowed, success); + } +} + +void BaseCommandRequest::ProcessAccessResponse( + const rc_event_engine::Event<application_manager::MessagePtr, std::string>& + event) { + LOG4CXX_AUTO_TRACE(logger_); + if (!app_) { + LOG4CXX_ERROR(logger_, "Application doesn't registered!"); + SendResponse(false, result_codes::kApplicationNotRegistered, ""); + return; + } + Json::Value value; + Json::Reader reader; + reader.parse(event.event_message()->json_message(), value); + + std::string result_code; + std::string info; + bool allowed = ParseResultCode(value, result_code, info); + // Check if valid successfull message has arrived + if (allowed) { + if (IsMember(value[kResult], message_params::kAllowed) && + value[kResult][message_params::kAllowed].isBool()) { + allowed = value[kResult][message_params::kAllowed].asBool(); + } else { + allowed = false; + } + } + + // Check the actual User's answer. + if (allowed) { + Json::Value request; + reader.parse(message_->json_message(), request); + std::string module = ModuleType(request); + LOG4CXX_DEBUG(logger_, + "Setting allowed access for " << app_->app_id() << " for " + << module); + service_->SetAccess(app_->app_id(), module, allowed); + CheckHMILevel(application_manager::kManual, allowed); + Execute(); // run child's logic + } else { + SendResponse(false, + result_codes::kRejected, + "The resource is in use and the driver disallows this remote " + "control RPC"); + } +} + +void BaseCommandRequest::CheckHMILevel(application_manager::TypeAccess access, + bool user_consented) { + LOG4CXX_AUTO_TRACE(logger_); + switch (access) { + case application_manager::kAllowed: + if (user_consented) { + if (app_->hmi_level() == mobile_apis::HMILevel::eType::HMI_NONE) { + LOG4CXX_DEBUG(logger_, + "RSDL functionality for " + << app_->name().c_str() + << " is auto allowed; setting BACKGROUND level."); + service_->ChangeNotifyHMILevel( + app_, mobile_apis::HMILevel::eType::HMI_BACKGROUND); + } + } + break; + case application_manager::kManual: { + if (user_consented) { + if (app_->hmi_level() == mobile_apis::HMILevel::eType::HMI_NONE || + app_->hmi_level() == mobile_apis::HMILevel::eType::HMI_BACKGROUND) { + LOG4CXX_DEBUG(logger_, + "User consented RSDL functionality for " + << app_->name().c_str() + << "; setting LIMITED level."); + service_->ChangeNotifyHMILevel( + app_, mobile_apis::HMILevel::eType::HMI_LIMITED); + } + } + break; + } + case application_manager::kDisallowed: + case application_manager::kNone: + default: + LOG4CXX_DEBUG(logger_, + "No access information or disallowed: " + << "do nothing about hmi levels"); + break; + } +} + +} // namespace commands +} // namespace remote_control diff --git a/src/components/remote_control/src/commands/button_press_request.cc b/src/components/remote_control/src/commands/button_press_request.cc new file mode 100644 index 0000000000..5423504ad2 --- /dev/null +++ b/src/components/remote_control/src/commands/button_press_request.cc @@ -0,0 +1,156 @@ +/* + Copyright (c) 2017, 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 "remote_control/commands/button_press_request.h" +#include "remote_control/message_helper.h" +#include "remote_control/rc_module_constants.h" +#include "functional_module/function_ids.h" +#include "json/json.h" + +namespace remote_control { + +namespace commands { + +using namespace json_keys; +using namespace message_params; + +CREATE_LOGGERPTR_GLOBAL(logger_, "ButtonPressRequest") + +ButtonPressRequest::ButtonPressRequest( + const application_manager::MessagePtr& message, + RemotePluginInterface& rc_module) + : BaseCommandRequest(message, rc_module) {} + +ButtonPressRequest::~ButtonPressRequest() {} + +const bool CheckButtonName(const std::string& module_type, + const std::string& button_name) { + if (enums_value::kRadio == module_type) { + return (button_name == enums_value::kVolumeUp) || + (button_name == enums_value::kVolumeDown) || + (button_name == enums_value::kEject) || + (button_name == enums_value::kSource) || + (button_name == enums_value::kShuffle) || + (button_name == enums_value::kRepeat); + } + + if (enums_value::kClimate == module_type) { + return (button_name == enums_value::kACMax) || + (button_name == enums_value::kAC) || + (button_name == enums_value::kRecirculate) || + (button_name == enums_value::kFanUp) || + (button_name == enums_value::kFanDown) || + (button_name == enums_value::kTempUp) || + (button_name == enums_value::kTempDown) || + (button_name == enums_value::kDefrostMax) || + (button_name == enums_value::kDefrost) || + (button_name == enums_value::kDefrostRear) || + (button_name == enums_value::kUpperVent) || + (button_name == enums_value::kLowerVent); + } + return false; +} + +void ButtonPressRequest::Execute() { + LOG4CXX_AUTO_TRACE(logger_); + + const Json::Value request_params = + MessageHelper::StringToValue(message_->json_message()); + + const std::string button_name = request_params[kButtonName].asString(); + const std::string module_type = request_params[kModuleType].asString(); + const bool button_name_matches_module_type = + CheckButtonName(module_type, button_name); + + if (button_name_matches_module_type) { + SendRequest(functional_modules::hmi_api::button_press, request_params); + } else { + LOG4CXX_WARN(logger_, "Request module type and button name mismatch!"); + SendResponse(false, + result_codes::kInvalidData, + "Request module type and button name mismatch!"); + } +} + +AcquireResult::eType ButtonPressRequest::AcquireResource( + const Json::Value& message) { + ResourceAllocationManager& allocation_manager = + rc_module_.resource_allocation_manager(); + const std::string& module_type = ModuleType(message); + const uint32_t app_id = app()->app_id(); + return allocation_manager.AcquireResource(module_type, app_id); +} + +bool ButtonPressRequest::IsResourceFree(const std::string& module_type) const { + return rc_module_.resource_allocation_manager().IsResourceFree(module_type); +} + +void ButtonPressRequest::SetResourceState(const Json::Value& message, + const ResourceState::eType state) { + const std::string& module_type = ModuleType(message); + const uint32_t app_id = app()->app_id(); + + ResourceAllocationManager& allocation_manager = + rc_module_.resource_allocation_manager(); + allocation_manager.SetResourceState(module_type, app_id, state); +} + +void ButtonPressRequest::OnEvent( + const rc_event_engine::Event<application_manager::MessagePtr, std::string>& + event) { + LOG4CXX_AUTO_TRACE(logger_); + DCHECK_OR_RETURN_VOID( + (functional_modules::hmi_api::button_press == event.id())); + + application_manager::Message& hmi_response = *(event.event_message()); + const Json::Value value = + MessageHelper::StringToValue(hmi_response.json_message()); + + std::string result_code; + std::string info; + + bool is_response_successful = ParseResultCode(value, result_code, info); + + if (remote_control::result_codes::kReadOnly == result_code) { + is_response_successful = false; + result_code = result_codes::kGenericError; + } + SendResponse(is_response_successful, result_code.c_str(), info); +} + +std::string ButtonPressRequest::ModuleType(const Json::Value& message) { + return message.get(message_params::kModuleType, Json::Value("")).asString(); +} + +} // namespace commands + +} // namespace remote_control diff --git a/src/components/remote_control/src/commands/get_interior_vehicle_data_request.cc b/src/components/remote_control/src/commands/get_interior_vehicle_data_request.cc new file mode 100644 index 0000000000..cfd08b47f6 --- /dev/null +++ b/src/components/remote_control/src/commands/get_interior_vehicle_data_request.cc @@ -0,0 +1,191 @@ +/* + Copyright (c) 2013, 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 <map> + +#include "remote_control/commands/get_interior_vehicle_data_request.h" +#include "remote_control/rc_module_constants.h" +#include "remote_control/message_helper.h" +#include "remote_control/remote_control_plugin.h" +#include "functional_module/function_ids.h" +#include "json/json.h" + +namespace remote_control { + +namespace commands { + +using namespace enums_value; +using namespace json_keys; +using namespace message_params; + +CREATE_LOGGERPTR_GLOBAL(logger_, "GetInteriorVehicleDataRequest") + +GetInteriorVehicleDataRequest::GetInteriorVehicleDataRequest( + const application_manager::MessagePtr& message, + RemotePluginInterface& rc_module) + : BaseCommandRequest(message, rc_module) {} + +void GetInteriorVehicleDataRequest::Execute() { + LOG4CXX_AUTO_TRACE(logger_); + Json::Value request_params = + MessageHelper::StringToValue(message_->json_message()); + + if (HasRequestExcessiveSubscription(request_params)) { + RemoveExcessiveSubscription(request_params); + } + + SendRequest(functional_modules::hmi_api::get_interior_vehicle_data, + request_params); +} + +void GetInteriorVehicleDataRequest::OnEvent( + const rc_event_engine::Event<application_manager::MessagePtr, std::string>& + event) { + LOG4CXX_AUTO_TRACE(logger_); + DCHECK_OR_RETURN_VOID( + (functional_modules::hmi_api::get_interior_vehicle_data == event.id())); + + application_manager::Message& hmi_response = *(event.event_message()); + const bool validate_result = + application_manager::MessageValidationResult::SUCCESS == + service()->ValidateMessageBySchema(hmi_response); + LOG4CXX_DEBUG(logger_, + "HMI response validation result is " << validate_result); + const Json::Value value = + MessageHelper::StringToValue(hmi_response.json_message()); + std::string result_code; + std::string info; + bool success = validate_result && ParseResultCode(value, result_code, info); + + if (!validate_result || + remote_control::result_codes::kReadOnly == result_code) { + success = false; + result_code = result_codes::kGenericError; + } + + if (success) { + ProccessSubscription(value); + response_params_[kModuleData] = value[kResult][kModuleData]; + } + SendResponse(success, result_code.c_str(), info); +} + +void GetInteriorVehicleDataRequest::ProccessSubscription( + const Json::Value& hmi_response) { + LOG4CXX_AUTO_TRACE(logger_); + Json::Value request_params; + Json::Reader reader; + reader.parse(message_->json_message(), request_params); + + const bool is_subscribe_present_in_request = + IsMember(request_params, kSubscribe); + const bool isSubscribed_present_in_response = + IsMember(hmi_response[kResult], kIsSubscribed); + + if (!is_subscribe_present_in_request && !isSubscribed_present_in_response) { + return; + } + + RCAppExtensionPtr extension = GetAppExtension(app()); + if (is_subscribe_present_in_request && !isSubscribed_present_in_response) { + LOG4CXX_WARN(logger_, + "conditional mandatory parameter " + << kIsSubscribed << " missed in hmi response"); + response_params_[kIsSubscribed] = + extension->IsSubscibedToInteriorVehicleData( + request_params[kModuleType]); + return; + } + + if (!is_subscribe_present_in_request && isSubscribed_present_in_response) { + LOG4CXX_WARN(logger_, + "Parameter " << kIsSubscribed << " is ignored due to absence '" + << kSubscribe << "' parameter in request"); + return; + } + + const bool request_subscribe = request_params[kSubscribe].asBool(); + const bool response_subscribe = hmi_response[kResult][kIsSubscribed].asBool(); + response_params_[kIsSubscribed] = response_subscribe; + LOG4CXX_TRACE(logger_, "request_subscribe = " << request_subscribe); + LOG4CXX_TRACE(logger_, "response_subscribe = " << response_subscribe); + if (request_subscribe == response_subscribe) { + if (response_subscribe) { + LOG4CXX_DEBUG(logger_, + "SubscribeToInteriorVehicleData " + << app()->app_id() << " " + << request_params[kModuleType].asString()); + extension->SubscribeToInteriorVehicleData(request_params[kModuleType]); + } else { + LOG4CXX_DEBUG(logger_, + "UnsubscribeFromInteriorVehicleData " + << app()->app_id() << " " + << request_params[kModuleType].asString()); + extension->UnsubscribeFromInteriorVehicleData( + request_params[kModuleType]); + } + } +} + +bool GetInteriorVehicleDataRequest::HasRequestExcessiveSubscription( + const Json::Value& request_params) { + LOG4CXX_AUTO_TRACE(logger_); + const bool is_subscribe_present_in_request = + IsMember(request_params, kSubscribe); + if (is_subscribe_present_in_request) { + RCAppExtensionPtr extension = GetAppExtension(app()); + const bool is_app_already_subscribed = + extension->IsSubscibedToInteriorVehicleData( + request_params[kModuleType]); + const bool app_wants_to_subscribe = request_params[kSubscribe].asBool(); + if (!app_wants_to_subscribe && !is_app_already_subscribed) { + return true; + } + return app_wants_to_subscribe && is_app_already_subscribed; + } + return false; +} + +void GetInteriorVehicleDataRequest::RemoveExcessiveSubscription( + Json::Value& request_params) { + LOG4CXX_AUTO_TRACE(logger_); + request_params.removeMember(kSubscribe); +} + +std::string GetInteriorVehicleDataRequest::ModuleType( + const Json::Value& message) { + return message.get(message_params::kModuleType, "").asString(); +} + +} // namespace commands + +} // namespace remote_control diff --git a/src/components/remote_control/src/commands/on_interior_vehicle_data_notification.cc b/src/components/remote_control/src/commands/on_interior_vehicle_data_notification.cc new file mode 100644 index 0000000000..79e8491a30 --- /dev/null +++ b/src/components/remote_control/src/commands/on_interior_vehicle_data_notification.cc @@ -0,0 +1,103 @@ +/* + Copyright (c) 2017, 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 "remote_control/commands/on_interior_vehicle_data_notification.h" +#include <algorithm> +#include <vector> +#include "json/json.h" +#include "utils/make_shared.h" +#include "remote_control/rc_module_constants.h" +#include "remote_control/message_helper.h" +#include "remote_control/remote_control_plugin.h" +#include "remote_control/rc_app_extension.h" + +namespace remote_control { + +namespace commands { + +CREATE_LOGGERPTR_GLOBAL(logger_, "OnInteriorVehicleDataNotification") + +OnInteriorVehicleDataNotification::OnInteriorVehicleDataNotification( + const application_manager::MessagePtr& message, + RemotePluginInterface& rc_module) + : BaseCommandNotification(message, rc_module) {} + +OnInteriorVehicleDataNotification::~OnInteriorVehicleDataNotification() {} + +void OnInteriorVehicleDataNotification::Execute() { + LOG4CXX_AUTO_TRACE(logger_); + + Json::Value json; + + application_manager::MessagePtr msg = message(); + + json = MessageHelper::StringToValue(msg->json_message()); + + Json::Value module_type = ModuleType(json); + + typedef std::vector<application_manager::ApplicationSharedPtr> AppPtrs; + AppPtrs apps = service_->GetApplications(rc_module_.GetModuleID()); + + for (AppPtrs::iterator it = apps.begin(); it != apps.end(); ++it) { + DCHECK(*it); + application_manager::Application& app = **it; + + RCAppExtensionPtr extension = + application_manager::AppExtensionPtr::static_pointer_cast< + RCAppExtension>(app.QueryInterface(rc_module_.GetModuleID())); + DCHECK(extension); + LOG4CXX_TRACE(logger_, "Check subscription for " << app.app_id()); + if (extension->IsSubscibedToInteriorVehicleData(module_type)) { + application_manager::MessagePtr message = + utils::MakeShared<application_manager::Message>(*msg); + message->set_message_type( + application_manager::MessageType::kNotification); + message->set_protocol_version(application_manager::kV3); + message->set_function_id(functional_modules::ON_INTERIOR_VEHICLE_DATA); + message->set_function_name(MessageHelper::GetMobileAPIName( + functional_modules::ON_INTERIOR_VEHICLE_DATA)); + message->set_connection_key(app.app_id()); + NotifyOneApplication(message); + } + } +} + +std::string OnInteriorVehicleDataNotification::ModuleType( + const Json::Value& message) { + const Json::Value& module_data = + message.get(message_params::kModuleData, Json::Value(Json::objectValue)); + return module_data.get(message_params::kModuleType, "").asString(); +} + +} // namespace commands + +} // namespace remote_control diff --git a/src/components/remote_control/src/commands/on_remote_control_settings_notification.cc b/src/components/remote_control/src/commands/on_remote_control_settings_notification.cc new file mode 100644 index 0000000000..6f70d4e0f8 --- /dev/null +++ b/src/components/remote_control/src/commands/on_remote_control_settings_notification.cc @@ -0,0 +1,113 @@ +/* + Copyright (c) 2017, 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 "remote_control/commands/on_remote_control_settings_notification.h" +#include <algorithm> +#include <vector> +#include "json/json.h" +#include "remote_control/rc_module_constants.h" +#include "remote_control/message_helper.h" +#include "remote_control/remote_control_plugin.h" +#include "remote_control/rc_app_extension.h" +#include "functional_module/function_ids.h" + +namespace remote_control { + +namespace commands { + +CREATE_LOGGERPTR_GLOBAL(logger_, "OnRemoteControlSettingsNotification"); + +OnRemoteControlSettingsNotification::OnRemoteControlSettingsNotification( + const application_manager::MessagePtr& message, + RemotePluginInterface& rc_module) + : BaseCommandNotification(message, rc_module) {} + +void UnsubscribeFromInteriorVehicleDataForAllModules( + RCAppExtensionPtr extension) { + LOG4CXX_AUTO_TRACE(logger_); + const Json::Value climate(enums_value::kClimate); + extension->UnsubscribeFromInteriorVehicleData(climate); + const Json::Value radio(enums_value::kRadio); + extension->UnsubscribeFromInteriorVehicleData(radio); +} + +void OnRemoteControlSettingsNotification::DisallowRCFunctionality() { + LOG4CXX_AUTO_TRACE(logger_); + typedef std::vector<application_manager::ApplicationSharedPtr> Apps; + Apps apps = service_->GetApplications(rc_module_.GetModuleID()); + for (Apps::iterator it = apps.begin(); it != apps.end(); ++it) { + application_manager::ApplicationSharedPtr app = *it; + DCHECK(app); + service_->ChangeNotifyHMILevel(app, mobile_apis::HMILevel::eType::HMI_NONE); + + const RCAppExtensionPtr extension = + application_manager::AppExtensionPtr::static_pointer_cast< + RCAppExtension>(app->QueryInterface(rc_module_.GetModuleID())); + if (extension) { + UnsubscribeFromInteriorVehicleDataForAllModules(extension); + } + } +} + +void OnRemoteControlSettingsNotification::Execute() { + LOG4CXX_AUTO_TRACE(logger_); + const Json::Value value = + MessageHelper::StringToValue(message()->json_message()); + + if (!value.isMember(message_params::kAllowed)) { + LOG4CXX_DEBUG(logger_, + "Notification is ignored due to \"allow\" parameter absense"); + LOG4CXX_DEBUG(logger_, "RC Functionality remains unchanged"); + return; + } + const bool is_allowed = value[message_params::kAllowed].asBool(); + if (is_allowed) { + LOG4CXX_DEBUG(logger_, "Allowing RC Functionality"); + const std::string access_mode = + value.get(message_params::kAccessMode, enums_value::kAutoAllow) + .asString(); + + const hmi_apis::Common_RCAccessMode::eType access_mode_ = + MessageHelper::AccessModeFromString(access_mode); + ResourceAllocationManager& allocation_manager = + rc_module_.resource_allocation_manager(); + LOG4CXX_DEBUG(logger_, "Setting up access mode : " << access_mode); + allocation_manager.SetAccessMode(access_mode_); + } else { + LOG4CXX_DEBUG(logger_, "Disallowing RC Functionality"); + DisallowRCFunctionality(); + } +} + +} // namespace commands + +} // namespace remote_control diff --git a/src/components/remote_control/src/commands/set_interior_vehicle_data_request.cc b/src/components/remote_control/src/commands/set_interior_vehicle_data_request.cc new file mode 100644 index 0000000000..e2d25e719e --- /dev/null +++ b/src/components/remote_control/src/commands/set_interior_vehicle_data_request.cc @@ -0,0 +1,248 @@ +/* + Copyright (c) 2017, 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 "remote_control/commands/set_interior_vehicle_data_request.h" +#include <algorithm> +#include "remote_control/rc_module_constants.h" +#include "remote_control/message_helper.h" +#include "functional_module/function_ids.h" +#include "json/json.h" +#include "utils/helpers.h" + +namespace remote_control { + +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(kSignalStrength); + module_ro_params.push_back(kSignalChangeThreshold); + module_ro_params.push_back(kState); + } + return module_ro_params; +} + +} // namespace + +CREATE_LOGGERPTR_GLOBAL(logger_, "SetInteriorVehicleDataRequest") + +SetInteriorVehicleDataRequest::SetInteriorVehicleDataRequest( + const application_manager::MessagePtr& message, + RemotePluginInterface& rc_module) + : BaseCommandRequest(message, rc_module) {} + +SetInteriorVehicleDataRequest::~SetInteriorVehicleDataRequest() {} + +void SetInteriorVehicleDataRequest::Execute() { + LOG4CXX_AUTO_TRACE(logger_); + + Json::Value request_params = + MessageHelper::StringToValue(message_->json_message()); + const Json::Value module_data = request_params[kModuleData]; + const std::string module_type = module_data[kModuleType].asString(); + bool module_type_and_data_match = true; + + if (enums_value::kRadio == module_type) { + module_type_and_data_match = !IsMember(module_data, kClimateControlData); + } + + if (enums_value::kClimate == module_type) { + module_type_and_data_match = !IsMember(module_data, kRadioControlData); + } + + if (module_type_and_data_match) { + if (AreAllParamsReadOnly(request_params)) { + LOG4CXX_WARN(logger_, "All request params in module type are READ ONLY!"); + SendResponse(false, + result_codes::kReadOnly, + "All request params in module type are READ ONLY!"); + return; + } + if (AreReadOnlyParamsPresent(request_params)) { + LOG4CXX_DEBUG(logger_, "Request module type has READ ONLY parameters"); + LOG4CXX_DEBUG(logger_, "Cutting-off READ ONLY parameters... "); + CutOffReadOnlyParams(request_params); + } + application_manager::MessagePtr hmi_request = CreateHmiRequest( + functional_modules::hmi_api::set_interior_vehicle_data, request_params); + service()->RemoveHMIFakeParameters(hmi_request); + SendMessageToHMI(hmi_request); + } else { + LOG4CXX_WARN(logger_, "Request module type & data mismatch!"); + SendResponse(false, + result_codes::kInvalidData, + "Request module type & data mismatch!"); + } +} + +AcquireResult::eType SetInteriorVehicleDataRequest::AcquireResource( + const Json::Value& message) { + return rc_module_.resource_allocation_manager().AcquireResource( + ModuleType(message), app()->app_id()); +} + +bool SetInteriorVehicleDataRequest::IsResourceFree( + const std::string& module_type) const { + return rc_module_.resource_allocation_manager().IsResourceFree(module_type); +} + +void SetInteriorVehicleDataRequest::SetResourceState( + const Json::Value& message, const ResourceState::eType state) { + const std::string& module_type = ModuleType(message); + const uint32_t app_id = app()->app_id(); + + ResourceAllocationManager& allocation_manager = + rc_module_.resource_allocation_manager(); + + allocation_manager.SetResourceState(module_type, app_id, state); +} + +bool SetInteriorVehicleDataRequest::AreReadOnlyParamsPresent( + const Json::Value& request_params) { + LOG4CXX_AUTO_TRACE(logger_); + std::vector<std::string> module_type_params = ControlData(request_params); + std::vector<std::string>::iterator it = module_type_params.begin(); + std::vector<std::string> ro_params = + GetModuleReadOnlyParams(ModuleType(request_params)); + for (; it != module_type_params.end(); ++it) { + if (helpers::in_range(ro_params, *it)) { + return true; + } + } + return false; +} + +void SetInteriorVehicleDataRequest::CutOffReadOnlyParams( + Json::Value& request_params) { + LOG4CXX_AUTO_TRACE(logger_); + std::vector<std::string> module_type_params = ControlData(request_params); + std::vector<std::string>::iterator it = module_type_params.begin(); + const std::string module_type = ModuleType(request_params); + std::vector<std::string> ro_params = GetModuleReadOnlyParams(module_type); + for (; it != module_type_params.end(); ++it) { + if (helpers::in_range(ro_params, *it)) { + if (enums_value::kClimate == module_type) { + request_params[message_params::kModuleData] + [message_params::kClimateControlData].removeMember(*it); + LOG4CXX_DEBUG(logger_, "Cutting-off READ ONLY parameter: " << *it); + } else if (enums_value::kRadio == module_type) { + request_params[message_params::kModuleData] + [message_params::kRadioControlData].removeMember(*it); + LOG4CXX_DEBUG(logger_, "Cutting-off READ ONLY parameter: " << *it); + } + } + } +} + +bool SetInteriorVehicleDataRequest::AreAllParamsReadOnly( + const Json::Value& request_params) { + LOG4CXX_AUTO_TRACE(logger_); + std::vector<std::string> module_type_params = ControlData(request_params); + std::vector<std::string>::iterator it = module_type_params.begin(); + std::vector<std::string> ro_params = + GetModuleReadOnlyParams(ModuleType(request_params)); + for (; it != module_type_params.end(); ++it) { + if (!helpers::in_range(ro_params, *it)) { + return false; + } + } + return true; +} + +void SetInteriorVehicleDataRequest::OnEvent( + const rc_event_engine::Event<application_manager::MessagePtr, std::string>& + event) { + LOG4CXX_AUTO_TRACE(logger_); + DCHECK_OR_RETURN_VOID( + (functional_modules::hmi_api::set_interior_vehicle_data == event.id())); + + application_manager::Message& hmi_response = *(event.event_message()); + const bool validate_result = + application_manager::MessageValidationResult::SUCCESS == + service()->ValidateMessageBySchema(hmi_response); + LOG4CXX_DEBUG(logger_, + "HMI response validation result is " << validate_result); + const Json::Value value = + MessageHelper::StringToValue(hmi_response.json_message()); + + std::string result_code; + std::string info; + + const bool success = + validate_result && ParseResultCode(value, result_code, info); + + if (success) { + response_params_[kModuleData] = value[kResult][kModuleData]; + } else if (!validate_result) { + result_code = result_codes::kGenericError; + } + + SendResponse(success, result_code.c_str(), info); +} + +std::string SetInteriorVehicleDataRequest::ModuleType( + const Json::Value& message) { + const Json::Value& module_data = + message.get(message_params::kModuleData, Json::Value(Json::objectValue)); + return module_data.get(message_params::kModuleType, "").asString(); +} + +std::vector<std::string> SetInteriorVehicleDataRequest::ControlData( + const Json::Value& message) { + Json::Value data = + message.get(message_params::kModuleData, Json::Value(Json::objectValue)); + const char* name_control_data; + std::string module = ModuleType(message); + if (module == enums_value::kRadio) { + name_control_data = message_params::kRadioControlData; + } + if (module == enums_value::kClimate) { + name_control_data = message_params::kClimateControlData; + } + Json::Value params = + data.get(name_control_data, Json::Value(Json::objectValue)); + return params.getMemberNames(); +} + +} // namespace commands + +} // namespace remote_control diff --git a/src/components/remote_control/src/message_helper.cc b/src/components/remote_control/src/message_helper.cc new file mode 100644 index 0000000000..5bd786a0eb --- /dev/null +++ b/src/components/remote_control/src/message_helper.cc @@ -0,0 +1,157 @@ +/* + Copyright (c) 2013, 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 "remote_control/message_helper.h" +#include "remote_control/rc_module_constants.h" +#include "utils/make_shared.h" + +namespace remote_control { +using functional_modules::RCFunctionID; +namespace { +std::map<RCFunctionID, std::string> GenerateAPINames() { + std::map<RCFunctionID, std::string> result; + result.insert(std::make_pair<RCFunctionID, std::string>( + RCFunctionID::BUTTON_PRESS, "ButtonPress")); + result.insert(std::make_pair<RCFunctionID, std::string>( + RCFunctionID::GET_INTERIOR_VEHICLE_DATA, "GetInteriorVehicleData")); + result.insert(std::make_pair<RCFunctionID, std::string>( + RCFunctionID::SET_INTERIOR_VEHICLE_DATA, "SetInteriorVehicleData")); + result.insert(std::make_pair<RCFunctionID, std::string>( + RCFunctionID::ON_INTERIOR_VEHICLE_DATA, "OnInteriorVehicleData")); + result.insert(std::make_pair<RCFunctionID, std::string>( + RCFunctionID::ON_REMOTE_CONTROL_SETTINGS, "OnRemoteControlSettingd")); + return result; +} +} + +uint32_t MessageHelper::next_correlation_id_ = 1; +const std::map<RCFunctionID, std::string> MessageHelper::kMobileAPINames = + GenerateAPINames(); + +uint32_t MessageHelper::GetNextRCCorrelationID() { + return next_correlation_id_++; +} + +const std::string MessageHelper::GetMobileAPIName(RCFunctionID func_id) { + std::map<RCFunctionID, std::string>::const_iterator it = + kMobileAPINames.find(func_id); + if (kMobileAPINames.end() != it) { + return it->second; + } else { + return ""; + } +} + +std::string MessageHelper::ValueToString(const Json::Value& value) { + Json::FastWriter writer; + + return writer.write(value); +} + +Json::Value MessageHelper::StringToValue(const std::string& string) { + Json::Reader reader; + + Json::Value json; + + if (reader.parse(string, json)) { + return json; + } + + return Json::Value(Json::ValueType::nullValue); +} + +bool IsMember(const Json::Value& value, const std::string& key) { + if (!value.isObject()) { + return false; + } + + return value.isMember(key); +} + +// TODO(KKolodiy): after creating commands for notification from HMI +// this validate methods may move to commands +bool MessageHelper::ValidateDeviceInfo(const Json::Value& value) { + return value.isObject() && value.isMember(json_keys::kId) && + value.isMember(message_params::kName) && + value[message_params::kName].isString(); +} + +application_manager::MessagePtr MessageHelper::CreateHmiRequest( + const char* function_id, + const uint32_t hmi_app_id, + const Json::Value& message_params, + RemotePluginInterface& rc_module) { + using namespace json_keys; + Json::Value msg; + + msg[json_keys::kId] = rc_module.service()->GetNextCorrelationID(); + + msg[kJsonrpc] = "2.0"; + msg[kMethod] = function_id; + if (!message_params.isNull()) { + msg[kParams] = message_params; + } + + msg[kParams][json_keys::kAppId] = hmi_app_id; + + Json::FastWriter writer; + application_manager::MessagePtr message_to_send = + utils::MakeShared<application_manager::Message>( + application_manager::Message( + protocol_handler::MessagePriority::kDefault)); + message_to_send->set_protocol_version( + application_manager::ProtocolVersion::kHMI); + message_to_send->set_correlation_id(msg[json_keys::kId].asInt()); + message_to_send->set_function_name(msg[kMethod].asString()); + std::string json_msg = writer.write(msg); + message_to_send->set_json_message(json_msg); + message_to_send->set_message_type(application_manager::MessageType::kRequest); + + return message_to_send; +} + +hmi_apis::Common_RCAccessMode::eType MessageHelper::AccessModeFromString( + const std::string& access_mode) { + if (enums_value::kAutoAllow == access_mode) { + return hmi_apis::Common_RCAccessMode::AUTO_ALLOW; + } + if (enums_value::kAutoDeny == access_mode) { + return hmi_apis::Common_RCAccessMode::AUTO_DENY; + } + if (enums_value::kAskDriver == access_mode) { + return hmi_apis::Common_RCAccessMode::ASK_DRIVER; + } + return hmi_apis::Common_RCAccessMode::INVALID_ENUM; +} + +} // namespace remote_control diff --git a/src/components/remote_control/src/module_helper.cc b/src/components/remote_control/src/module_helper.cc new file mode 100644 index 0000000000..8a7f565691 --- /dev/null +++ b/src/components/remote_control/src/module_helper.cc @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2013, 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 "remote_control/module_helper.h" +#include "remote_control/remote_control_plugin.h" +#include "remote_control/rc_module_constants.h" +#include "remote_control/rc_app_extension.h" +#include "application_manager/message.h" +#include "remote_control/message_helper.h" + +namespace remote_control { + +using functional_modules::ProcessResult; +using application_manager::AppExtensionPtr; + +application_manager::MessagePtr ModuleHelper::ResponseToHMI( + unsigned int id, + hmi_apis::Common_Result::eType result_code, + const std::string& method_name) { + Json::Value msg; + msg[json_keys::kId] = id; + msg[json_keys::kJsonrpc] = "2.0"; + + if (hmi_apis::Common_Result::eType::SUCCESS == result_code) { + msg[json_keys::kResult] = Json::Value(Json::ValueType::objectValue); + msg[json_keys::kResult][json_keys::kCode] = result_code; + msg[json_keys::kResult][json_keys::kMethod] = method_name; + } else { + msg[json_keys::kError] = Json::Value(Json::ValueType::objectValue); + msg[json_keys::kError][json_keys::kCode] = result_code; + msg[json_keys::kError][json_keys::kData] = + Json::Value(Json::ValueType::objectValue); + msg[json_keys::kError][json_keys::kData][json_keys::kMethod] = method_name; + } + + application_manager::MessagePtr message(new application_manager::Message( + protocol_handler::MessagePriority::kDefault)); + message->set_protocol_version(application_manager::ProtocolVersion::kHMI); + message->set_correlation_id(msg[json_keys::kId].asInt()); + Json::FastWriter writer; + std::string json_msg = writer.write(msg); + message->set_json_message(json_msg); + message->set_message_type(application_manager::MessageType::kResponse); + return message; +} + +// (TODO)VS: Replace this functions for separate OnReverseAppsDisallowed +// notiifcation +void ModuleHelper::ProccessOnReverseAppsDisallowed( + RemotePluginInterface& rc_module) { + std::vector<application_manager::ApplicationSharedPtr> applications = + rc_module.service()->GetApplications(rc_module.GetModuleID()); + + for (uint32_t i = 0; i < applications.size(); ++i) { + application_manager::AppExtensionPtr app_extension = + applications[i]->QueryInterface(rc_module.GetModuleID()); + if (app_extension) { + RCAppExtensionPtr rc_app_extension = + application_manager::AppExtensionPtr::static_pointer_cast< + RCAppExtension>(app_extension); + if (!rc_app_extension->is_on_driver_device()) { + } + } + } +} + +} // namespace remote_control diff --git a/src/components/remote_control/src/policy_helper.cc b/src/components/remote_control/src/policy_helper.cc new file mode 100644 index 0000000000..5ef0b780fb --- /dev/null +++ b/src/components/remote_control/src/policy_helper.cc @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2013, 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 "remote_control/policy_helper.h" +#include "remote_control/remote_control_plugin.h" +#include "remote_control/rc_app_extension.h" +#include "utils/logger.h" + +CREATE_LOGGERPTR_GLOBAL(logger_, "RemoteControl") + +namespace remote_control { + +void PolicyHelper::OnRSDLFunctionalityAllowing( + bool allowed, RemotePluginInterface& rc_module) { + rc_module.service()->SetRemoteControl(allowed); +} + +void PolicyHelper::ChangeDeviceRank(const uint32_t device_handle, + const std::string& rank, + RemotePluginInterface& rc_module) { + if (rank == "DRIVER") { + rc_module.service()->SetPrimaryDevice(device_handle); + // MarkApplications(device_handle); + } else if (rank == "PASSENGER") { + if (rc_module.service()->PrimaryDevice() == device_handle) { + rc_module.service()->ResetPrimaryDevice(); + // MarkApplications(0); + } + } else { + LOG4CXX_WARN(logger_, "Unknown device rank"); + } +} + +void PolicyHelper::SetIsAppOnPrimaryDevice( + application_manager::ApplicationSharedPtr app, + RemotePluginInterface& rc_module) { + MarkAppOnPrimaryDevice(app, rc_module.service()->PrimaryDevice(), rc_module); +} + +void PolicyHelper::MarkAppOnPrimaryDevice( + application_manager::ApplicationSharedPtr app, + const uint32_t device_handle, + RemotePluginInterface& rc_module) { + application_manager::AppExtensionUID module_id = rc_module.GetModuleID(); + RCAppExtensionPtr extension = + application_manager::AppExtensionPtr::static_pointer_cast<RCAppExtension>( + app->QueryInterface(module_id)); + DCHECK(extension); + bool is_driver = (app->device() == device_handle); + extension->set_is_on_driver_device(is_driver); +} + +void PolicyHelper::MarkApplications(const uint32_t device_handle, + RemotePluginInterface& rc_module) { + application_manager::AppExtensionUID module_id = rc_module.GetModuleID(); + std::vector<application_manager::ApplicationSharedPtr> applications = + rc_module.service()->GetApplications(module_id); + + for (size_t i = 0; i < applications.size(); ++i) { + MarkAppOnPrimaryDevice(applications[i], device_handle, rc_module); + } +} + +} // namespace remote_control diff --git a/src/components/remote_control/src/rc_app_extension.cc b/src/components/remote_control/src/rc_app_extension.cc new file mode 100644 index 0000000000..ded3a15775 --- /dev/null +++ b/src/components/remote_control/src/rc_app_extension.cc @@ -0,0 +1,68 @@ +/* + Copyright (c) 2013, 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 "remote_control/rc_app_extension.h" + +namespace remote_control { +RCAppExtension::RCAppExtension(application_manager::AppExtensionUID uid) + : AppExtension(uid) + , is_control_given_(false) + , is_on_driver_device_(false) {} + +bool RCAppExtension::IsControlGiven() const { + return is_control_given_; +} + +void RCAppExtension::GiveControl(bool is_control_given) { + is_control_given_ = is_control_given; +} + +void RCAppExtension::SubscribeToInteriorVehicleData( + const Json::Value& module_type) { + subscribed_interior_vehicle_data_.insert(module_type); +} + +void RCAppExtension::UnsubscribeFromInteriorVehicleData( + const Json::Value& module_type) { + subscribed_interior_vehicle_data_.erase(module_type); +} + +bool RCAppExtension::IsSubscibedToInteriorVehicleData( + const Json::Value& module_type) { + std::set<Json::Value>::iterator it = + subscribed_interior_vehicle_data_.find(module_type); + + return (it != subscribed_interior_vehicle_data_.end()); +} + +RCAppExtension::~RCAppExtension() {} +} // namespace remote_control diff --git a/src/components/remote_control/src/rc_command_factory.cc b/src/components/remote_control/src/rc_command_factory.cc new file mode 100644 index 0000000000..410b7eadfa --- /dev/null +++ b/src/components/remote_control/src/rc_command_factory.cc @@ -0,0 +1,86 @@ +/* + Copyright (c) 2013, 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 "utils/shared_ptr.h" +#include "utils/make_shared.h" +#include "remote_control/rc_command_factory.h" +#include "functional_module/function_ids.h" +#include "remote_control/commands/get_interior_vehicle_data_request.h" +#include "remote_control/commands/set_interior_vehicle_data_request.h" +#include "remote_control/commands/button_press_request.h" +#include "remote_control/commands/on_interior_vehicle_data_notification.h" +#include "remote_control/commands/on_remote_control_settings_notification.h" + +namespace remote_control { + +CREATE_LOGGERPTR_GLOBAL(logger_, "RemoteControl") + +using functional_modules::RCFunctionID; + +utils::SharedPtr<commands::Command> RCCommandFactory::CreateCommand( + const application_manager::MessagePtr& msg, + RemotePluginInterface& rc_module) { + switch (msg->function_id()) { + case RCFunctionID::GET_INTERIOR_VEHICLE_DATA: { + return utils::MakeShared<commands::GetInteriorVehicleDataRequest>( + msg, rc_module); + break; + } + case RCFunctionID::SET_INTERIOR_VEHICLE_DATA: { + return utils::MakeShared<commands::SetInteriorVehicleDataRequest>( + msg, rc_module); + break; + } + case RCFunctionID::BUTTON_PRESS: { + return utils::MakeShared<commands::ButtonPressRequest>(msg, rc_module); + break; + } + case RCFunctionID::ON_INTERIOR_VEHICLE_DATA: { + return utils::MakeShared<commands::OnInteriorVehicleDataNotification>( + msg, rc_module); + break; + } + case RCFunctionID::ON_REMOTE_CONTROL_SETTINGS: { + return utils::MakeShared<commands::OnRemoteControlSettingsNotification>( + msg, rc_module); + break; + } + default: { + utils::SharedPtr<commands::Command> invalid_command; + LOG4CXX_DEBUG(logger_, + "RSDL unable to proces function " << msg->function_id()); + return invalid_command; + } + } +} + +} // namespace remote_control diff --git a/src/components/remote_control/src/remote_control_event.cc b/src/components/remote_control/src/remote_control_event.cc new file mode 100644 index 0000000000..ef8a2c4e6f --- /dev/null +++ b/src/components/remote_control/src/remote_control_event.cc @@ -0,0 +1,56 @@ +/* + Copyright (c) 2013, 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 "remote_control/remote_control_event.h" + +namespace remote_control { + +RCPluginEvent::RCPluginEvent(application_manager::MessagePtr& message, + const std::string& id) + : rc_event_engine::Event<application_manager::MessagePtr, std::string>( + message, id) {} + +RCPluginEvent::~RCPluginEvent() {} + +int32_t RCPluginEvent::event_message_function_id() const { + return event_message_->function_id(); +} + +int32_t RCPluginEvent::event_message_correlation_id() const { + return event_message_->correlation_id(); +} + +int32_t RCPluginEvent::event_message_type() const { + return event_message_->type(); +} + +} // namespace remote_control diff --git a/src/components/remote_control/src/remote_control_plugin.cc b/src/components/remote_control/src/remote_control_plugin.cc new file mode 100644 index 0000000000..6d265d579b --- /dev/null +++ b/src/components/remote_control/src/remote_control_plugin.cc @@ -0,0 +1,369 @@ +/* + Copyright (c) 2013, 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 "remote_control/remote_control_plugin.h" +#include "remote_control/rc_command_factory.h" +#include "remote_control/remote_control_event.h" +#include "remote_control/rc_module_constants.h" +#include "remote_control/rc_app_extension.h" +#include "remote_control/message_helper.h" +#include "remote_control/policy_helper.h" +#include "remote_control/module_helper.h" +#include "utils/logger.h" +#include "interfaces/MOBILE_API.h" +#include "utils/macro.h" +#include "utils/make_shared.h" +#include "application_manager/smart_object_keys.h" + +namespace remote_control { + +using functional_modules::ProcessResult; +using functional_modules::GenericModule; +using functional_modules::PluginInfo; +using functional_modules::RCFunctionID; +namespace hmi_api = functional_modules::hmi_api; + +using namespace json_keys; + +CREATE_LOGGERPTR_GLOBAL(logger_, "RemoteControl"); + +EXPORT_FUNCTION_IMPL(remote_control::RemoteControlPlugin); + +RemoteControlPlugin::RemoteControlPlugin() + : is_scan_started_(false), resource_allocation_manager_(*this) { + plugin_info_.name = "RemoteControlPlugin"; + plugin_info_.version = 1; + SubscribeOnFunctions(); +} + +void RemoteControlPlugin::SubscribeOnFunctions() { + plugin_info_.rc_function_list.push_back(RCFunctionID::BUTTON_PRESS); + plugin_info_.rc_function_list.push_back( + RCFunctionID::GET_INTERIOR_VEHICLE_DATA); + plugin_info_.rc_function_list.push_back( + RCFunctionID::SET_INTERIOR_VEHICLE_DATA); + plugin_info_.rc_function_list.push_back( + RCFunctionID::ON_INTERIOR_VEHICLE_DATA); + + plugin_info_.hmi_function_list.push_back(hmi_api::get_interior_vehicle_data); + plugin_info_.hmi_function_list.push_back(hmi_api::set_interior_vehicle_data); + plugin_info_.hmi_function_list.push_back(hmi_api::on_interior_vehicle_data); + plugin_info_.hmi_function_list.push_back(hmi_api::button_press); + plugin_info_.hmi_function_list.push_back(hmi_api::get_user_consent); + plugin_info_.hmi_function_list.push_back(hmi_api::on_remote_control_settings); +} + +RemoteControlPlugin::~RemoteControlPlugin() { + RemoveAppExtensions(); +} + +functional_modules::PluginInfo RemoteControlPlugin::GetPluginInfo() const { + return plugin_info_; +} + +const std::string ExtractFunctionAndAddMetadata( + const Json::Value& value, application_manager::Message& out_msg) { + if (value.isMember(json_keys::kMethod)) { + const std::string& function_name = + value.get(json_keys::kMethod, "").asCString(); + + // Existence of method name must be guaranteed by plugin manager + DCHECK_OR_RETURN(!function_name.empty(), ""); + + if (value.isMember(json_keys::kId)) { + out_msg.set_correlation_id(value.get(json_keys::kId, "").asInt()); + out_msg.set_message_type(application_manager::MessageType::kRequest); + } else { + out_msg.set_message_type(application_manager::MessageType::kNotification); + } + return function_name; + } + + if (value.isMember(json_keys::kResult)) { + const Json::Value& result = value.get(json_keys::kResult, Json::Value()); + const std::string& function_name = + result.get(json_keys::kMethod, "").asCString(); + out_msg.set_correlation_id(value.get(json_keys::kId, "").asInt()); + + // Existence of method name must be guaranteed by plugin manager + DCHECK_OR_RETURN(!function_name.empty(), ""); + + out_msg.set_message_type(application_manager::MessageType::kResponse); + return function_name; + } + + if (value.isMember(json_keys::kError)) { + const Json::Value& error = value.get(json_keys::kError, Json::Value()); + const Json::Value& data = error.get(json_keys::kData, Json::Value()); + const std::string& function_name = + data.get(json_keys::kMethod, "").asCString(); + + // Existence of method name must be guaranteed by plugin manager + DCHECK_OR_RETURN(!function_name.empty(), ""); + + out_msg.set_message_type(application_manager::MessageType::kErrorResponse); + out_msg.set_correlation_id(value.get(json_keys::kId, "").asInt()); + return function_name; + } + return std::string(); +} + +ProcessResult RemoteControlPlugin::ProcessMessage( + application_manager::MessagePtr msg) { + DCHECK_OR_RETURN(msg, ProcessResult::FAILED); + + const std::string& function_name = MessageHelper::GetMobileAPIName( + static_cast<functional_modules::RCFunctionID>(msg->function_id())); + + LOG4CXX_DEBUG(logger_, "Function name to set : " << function_name); + msg->set_function_name(function_name); + + LOG4CXX_DEBUG(logger_, "Mobile message: " << msg->json_message()); + + request_controller::MobileRequestPtr command( + RCCommandFactory::CreateCommand(msg, *this)); + if (command) { + request_controller_.AddRequest(msg->correlation_id(), command); + command->Run(); + } else { + return ProcessResult::CANNOT_PROCESS; + } + + return ProcessResult::PROCESSED; +} + +ProcessResult RemoteControlPlugin::ProcessHMIMessage( + application_manager::MessagePtr msg) { + LOG4CXX_AUTO_TRACE(logger_); + + Json::Value value; + Json::Reader reader; + reader.parse(msg->json_message(), value); + LOG4CXX_TRACE(logger_, "Process " << msg->json_message()); + const std::string& function_name = ExtractFunctionAndAddMetadata(value, *msg); + + // Existence of method name must be guaranteed by plugin manager + DCHECK_OR_RETURN(!function_name.empty(), ProcessResult::FAILED); + + LOG4CXX_DEBUG(logger_, "Process " << function_name); + + switch (msg->type()) { + case application_manager::MessageType::kResponse: + case application_manager::MessageType::kErrorResponse: { + RCPluginEvent event(msg, function_name); + LOG4CXX_DEBUG(logger_, "Response received"); + event_dispatcher_.raise_event(event); + return ProcessResult::PROCESSED; + } + case application_manager::MessageType::kRequest: + case application_manager::MessageType::kNotification: { + if (hmi_api::on_interior_vehicle_data == function_name) { + msg->set_function_id(functional_modules::ON_INTERIOR_VEHICLE_DATA); + } + if (hmi_api::on_remote_control_settings == function_name) { + msg->set_function_id(functional_modules::ON_REMOTE_CONTROL_SETTINGS); + } + const application_manager::MessageValidationResult validation_result = + service()->ValidateMessageBySchema(*msg); + utils::SharedPtr<commands::Command> command = + RCCommandFactory::CreateCommand(msg, *this); + if ((validation_result == + application_manager::MessageValidationResult::SUCCESS) && + command) { + command->Run(); + return ProcessResult::PROCESSED; + } + LOG4CXX_DEBUG(logger_, "Message validation failed"); + break; + } + default: { LOG4CXX_DEBUG(logger_, "Unknown message type"); } + } + return ProcessResult::CANNOT_PROCESS; +} + +void RemoteControlPlugin::SendHmiStatusNotification( + application_manager::ApplicationSharedPtr app) { + LOG4CXX_AUTO_TRACE(logger_); + application_manager::MessagePtr msg = new application_manager::Message( + protocol_handler::MessagePriority::kDefault); + Json::Value msg_params; + + msg->set_function_id(mobile_apis::FunctionID::OnHMIStatusID); + msg->set_message_type(application_manager::MessageType::kNotification); + + msg->set_connection_key(app->app_id()); + msg->set_protocol_version(application_manager::kV3); + + msg_params["hmiLevel"] = static_cast<uint32_t>(app->hmi_level()); + + msg_params["audioStreamingState"] = + static_cast<uint32_t>(app->audio_streaming_state()); + + msg_params["systemContext"] = static_cast<uint32_t>(app->system_context()); + + application_manager::AppExtensionPtr app_extension = + app->QueryInterface(GetModuleID()); + RCAppExtensionPtr rc_app_extension = + application_manager::AppExtensionPtr::static_pointer_cast<RCAppExtension>( + app_extension); + + if (rc_app_extension->is_on_driver_device()) { + msg_params[message_params::kRank] = "DRIVER"; + } else { + msg_params[message_params::kRank] = "PASSENGER"; + } + + msg->set_json_message(MessageHelper::ValueToString(msg_params)); + + service()->SendMessageToMobile(msg); +} + +void RemoteControlPlugin::NotifyMobiles( + application_manager::MessagePtr message) { + LOG4CXX_AUTO_TRACE(logger_); + request_controller::MobileRequestPtr command = + RCCommandFactory::CreateCommand(message, *this); + if (command) { + command->Run(); + } +} + +void RemoteControlPlugin::SendResponseToMobile( + application_manager::MessagePtr msg) { + LOG4CXX_DEBUG(logger_, "Response to mobile: " << msg->json_message()); + service()->SendMessageToMobile(msg); + request_controller_.DeleteRequest(msg->correlation_id()); +} + +void RemoteControlPlugin::SendTimeoutResponseToMobile( + application_manager::MessagePtr msg) { + LOG4CXX_DEBUG( + logger_, + "Timeout is expired. Response to mobile: " << msg->json_message()); + service()->SendMessageToMobile(msg); +} + +void RemoteControlPlugin::RemoveAppExtensions() { + std::vector<application_manager::ApplicationSharedPtr> applications = + service()->GetApplications(GetModuleID()); + + std::vector<application_manager::ApplicationSharedPtr>::iterator it = + applications.begin(); + + for (; it != applications.end(); ++it) { + application_manager::ApplicationSharedPtr app = *it; + if (app) { + app->RemoveExtension(GetModuleID()); + } + } +} + +void RemoteControlPlugin::RemoveAppExtension(uint32_t app_id) { + application_manager::ApplicationSharedPtr app = + service()->GetApplication(app_id); + + if (app) { + app->RemoveExtension(GetModuleID()); + } +} + +bool RemoteControlPlugin::IsAppForPlugin( + application_manager::ApplicationSharedPtr app) { + LOG4CXX_AUTO_TRACE(logger_); + application_manager::AppExtensionPtr app_extension = + app->QueryInterface(GetModuleID()); + if (app_extension) { + return true; + } + + if (service()->IsRemoteControlApplication(app)) { + RCAppExtensionPtr rc_app_extension = new RCAppExtension(GetModuleID()); + app->AddExtension(rc_app_extension); + service()->NotifyHMIAboutHMILevel(app, app->hmi_level()); + service()->SetPrimaryDevice(app->device()); + PolicyHelper::SetIsAppOnPrimaryDevice(app, *this); + return true; + } + return false; +} + +void RemoteControlPlugin::OnAppHMILevelChanged( + application_manager::ApplicationSharedPtr app, + mobile_apis::HMILevel::eType) { + LOG4CXX_DEBUG(logger_, + "RSDL application " << app->name().AsMBString() + << " has changed hmi level to " + << app->hmi_level()); + service()->NotifyHMIAboutHMILevel(app, app->hmi_level()); +} + +bool RemoteControlPlugin::CanAppChangeHMILevel( + application_manager::ApplicationSharedPtr app, + mobile_apis::HMILevel::eType new_level) { + application_manager::AppExtensionPtr app_extension = + app->QueryInterface(GetModuleID()); + if (!app_extension) { + return true; + } + RCAppExtensionPtr rc_app_extension = + application_manager::AppExtensionPtr::static_pointer_cast<RCAppExtension>( + app_extension); + if (new_level == mobile_apis::HMILevel::eType::HMI_FULL || + new_level == mobile_apis::HMILevel::eType::HMI_LIMITED) { + return rc_app_extension->is_on_driver_device(); + } + return true; +} + +void RemoteControlPlugin::OnDeviceRemoved( + const connection_handler::DeviceHandle& device) { + LOG4CXX_AUTO_TRACE(logger_); + bool is_driver = service()->PrimaryDevice() == device; + if (is_driver) { + service()->ResetPrimaryDevice(); + } +} + +void RemoteControlPlugin::OnUnregisterApplication(const uint32_t app_id) { + LOG4CXX_AUTO_TRACE(logger_); + resource_allocation_manager_.OnUnregisterApplication(app_id); +} + +RCEventDispatcher& RemoteControlPlugin::event_dispatcher() { + return event_dispatcher_; +} + +ResourceAllocationManager& RemoteControlPlugin::resource_allocation_manager() { + return resource_allocation_manager_; +} + +} // namespace remote_control diff --git a/src/components/remote_control/src/request_controller.cc b/src/components/remote_control/src/request_controller.cc new file mode 100644 index 0000000000..c457e94586 --- /dev/null +++ b/src/components/remote_control/src/request_controller.cc @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2014, 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 "remote_control/request_controller.h" +#include "json/json.h" +#include "utils/logger.h" +#include "functional_module/settings.h" + +namespace remote_control { +namespace request_controller { + +CREATE_LOGGERPTR_GLOBAL(logger_, "RCRequestController") + +RequestController::RequestController() { + functional_modules::TimeUnit timeout_seconds = 100; + functional_modules::Settings settings; + settings.ReadParameter( + "Remote Control", "timeout_period_seconds", &timeout_seconds); + timer_.set_period(timeout_seconds); + LOG4CXX_DEBUG(logger_, "Timeout is set to " << timeout_seconds); + timer_.AddObserver(this); + time_director_.RegisterTimer(timer_); +} + +RequestController::~RequestController() { + time_director_.UnregisterTimer(timer_); + timer_.RemoveObserver(this); +} + +void RequestController::AddRequest(const uint32_t mobile_correlation_id, + MobileRequestPtr request) { + // TODO(VS) Research and fix be problem with overlap correlation ids from two + // different apllications(on two different mobile devices) + LOG4CXX_DEBUG(logger_, + "Add request with correlation_id: " << mobile_correlation_id); + mobile_request_list_[mobile_correlation_id] = request; + // TODO(VS): add app id + timer_.AddTrackable(TrackableMessage(0, mobile_correlation_id)); + time_director_.ResetTimer(timer_); +} + +void RequestController::DeleteRequest(const uint32_t& mobile_correlation_id) { + LOG4CXX_DEBUG( + logger_, "Delete request with correlation_id: " << mobile_correlation_id); + mobile_request_list_.erase(mobile_correlation_id); + // TODO(VS): add app id + timer_.RemoveTrackable(TrackableMessage(0, mobile_correlation_id)); +} + +void RequestController::OnTimeoutTriggered(const TrackableMessage& expired) { + LOG4CXX_DEBUG(logger_, + "Timeout is expired for request with correlation_id: " + << expired.correlation_id()); + std::map<correlation_id, MobileRequestPtr>::iterator it = + mobile_request_list_.find(expired.correlation_id()); + if (mobile_request_list_.end() == it) { + // no corresponding request found, error. + return; + } + it->second->OnTimeout(); + mobile_request_list_.erase(it); +} + +} // namespace request_controller +} // namespace remote_control diff --git a/src/components/remote_control/src/resource_allocation_manager_impl.cc b/src/components/remote_control/src/resource_allocation_manager_impl.cc new file mode 100644 index 0000000000..f2c3b63600 --- /dev/null +++ b/src/components/remote_control/src/resource_allocation_manager_impl.cc @@ -0,0 +1,229 @@ +#include "remote_control/resource_allocation_manager_impl.h" +#include "application_manager/application.h" +#include "application_manager/message_helper.h" +#include "remote_control/rc_module_constants.h" +#include "json/json.h" +#include "utils/helpers.h" +#include "utils/make_shared.h" +#include "remote_control/message_helper.h" + +namespace remote_control { + +CREATE_LOGGERPTR_GLOBAL(logger_, "RemoteControlModule") + +ResourceAllocationManagerImpl::ResourceAllocationManagerImpl( + RemotePluginInterface& rc_plugin) + : current_access_mode_(hmi_apis::Common_RCAccessMode::AUTO_ALLOW) + , active_call_back_() + , rc_plugin_(rc_plugin) {} + +ResourceAllocationManagerImpl::~ResourceAllocationManagerImpl() {} + +AcquireResult::eType ResourceAllocationManagerImpl::AcquireResource( + const std::string& module_type, const uint32_t app_id) { + LOG4CXX_AUTO_TRACE(logger_); + const application_manager::ApplicationSharedPtr acquiring_app = + rc_plugin_.service()->GetApplication(app_id); + if (!acquiring_app) { + LOG4CXX_WARN(logger_, "App with app_id: " << app_id << "does not exist!"); + return AcquireResult::IN_USE; + } + + const AllocatedResources::const_iterator allocated_it = + allocated_resources_.find(module_type); + if (allocated_resources_.end() == allocated_it) { + allocated_resources_[module_type] = app_id; + LOG4CXX_DEBUG(logger_, + "Resource is not acquired yet. " + << "App: " << app_id << " is allowed to acquire " + << module_type); + return AcquireResult::ALLOWED; + } + + if (app_id == allocated_resources_[module_type]) { + LOG4CXX_DEBUG(logger_, + "App: " << app_id << " is already acquired resource " + << module_type); + return AcquireResult::ALLOWED; + } + + if (IsModuleTypeRejected(module_type, app_id)) { + LOG4CXX_DEBUG(logger_, + "Driver disallowed app: " << app_id << " to acquire " + << module_type); + return AcquireResult::REJECTED; + } + + const mobile_apis::HMILevel::eType acquiring_app_hmi_level = + acquiring_app->hmi_level(); + + if (mobile_apis::HMILevel::HMI_FULL != acquiring_app_hmi_level) { + LOG4CXX_DEBUG( + logger_, + "Aquiring resources is not allowed in HMI level: " + << application_manager::MessageHelper::StringifiedHMILevel( + acquiring_app_hmi_level) << ". App: " << app_id + << " is disallowed to acquire " << module_type); + return AcquireResult::REJECTED; + } + + switch (current_access_mode_) { + case hmi_apis::Common_RCAccessMode::AUTO_DENY: { + LOG4CXX_DEBUG(logger_, + "Current access_mode is AUTO_DENY. " + << "App: " << app_id << " is disallowed to acquire " + << module_type); + 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); + 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); + + allocated_resources_[module_type] = app_id; + return AcquireResult::ALLOWED; + } + default: { DCHECK_OR_RETURN(false, AcquireResult::IN_USE); } + } +} + +void ResourceAllocationManagerImpl::SetResourceState( + const std::string& module_type, + 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); + const AllocatedResources::const_iterator allocated_it = + allocated_resources_.find(module_type); + + DCHECK_OR_RETURN_VOID(allocated_resources_.end() != allocated_it) + LOG4CXX_DEBUG(logger_, + "Resource " << module_type << " is acquired." + << " Owner application id is " + << allocated_it->second + << " Changing application id is " << app_id); + DCHECK_OR_RETURN_VOID(app_id == allocated_it->second); + + resources_state_[module_type] = state; + LOG4CXX_DEBUG(logger_, "Resource" << module_type << " got state " << state); +} + +bool ResourceAllocationManagerImpl::IsResourceFree( + const std::string& module_type) const { + LOG4CXX_AUTO_TRACE(logger_); + const ResourcesState::const_iterator resource = + resources_state_.find(module_type); + + if (resources_state_.end() == resource) { + LOG4CXX_DEBUG(logger_, "Resource " << module_type << " is free."); + return true; + } + + LOG4CXX_DEBUG(logger_, + "Resource " << module_type << " state is " << resource->second); + + return ResourceState::FREE == resource->second; +} + +void ResourceAllocationManagerImpl::SetAccessMode( + const hmi_apis::Common_RCAccessMode::eType access_mode) { + if (hmi_apis::Common_RCAccessMode::ASK_DRIVER != access_mode) { + rejected_resources_for_application_.clear(); + } + current_access_mode_ = access_mode; +} + +void ResourceAllocationManagerImpl::AskDriver(const std::string& module_type, + const uint32_t hmi_app_id, + AskDriverCallBackPtr callback) { + LOG4CXX_AUTO_TRACE(logger_); + DCHECK(callback); + // Create GetInteriorConsent request to HMI + Json::Value params; + params[message_params::kModuleType] = module_type; + application_manager::MessagePtr message_to_send = + remote_control::MessageHelper::CreateHmiRequest( + functional_modules::hmi_api::get_user_consent, + hmi_app_id, + params, + rc_plugin_); + + LOG4CXX_DEBUG(logger_, + "Request to HMI: \n" << message_to_send->json_message()); + // Send GetInteriorConsent request to HMI + rc_plugin_.service()->SendMessageToHMI(message_to_send); + + // Execute callback on response + rc_plugin_.event_dispatcher().add_observer(message_to_send->function_name(), + message_to_send->correlation_id(), + callback.get()); + active_call_back_ = callback; +} + +void ResourceAllocationManagerImpl::ForceAcquireResource( + const std::string& module_type, const uint32_t app_id) { + LOG4CXX_DEBUG(logger_, "Force " << app_id << " acquiring " << module_type); + allocated_resources_[module_type] = app_id; +} + +bool ResourceAllocationManagerImpl::IsModuleTypeRejected( + const std::string& module_type, const uint32_t app_id) { + LOG4CXX_AUTO_TRACE(logger_); + RejectedResources::iterator it = + rejected_resources_for_application_.find(app_id); + + if (rejected_resources_for_application_.end() == it) { + return false; + } + + const std::vector<std::string>& list_of_rejected_resources = + rejected_resources_for_application_[app_id]; + + return helpers::in_range(list_of_rejected_resources, module_type); +} + +void ResourceAllocationManagerImpl::OnDriverDisallowed( + const std::string& module_type, const uint32_t app_id) { + LOG4CXX_AUTO_TRACE(logger_); + RejectedResources::iterator 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>(); + } + std::vector<std::string>& list_of_rejected_resources = + rejected_resources_for_application_[app_id]; + list_of_rejected_resources.push_back(module_type); +} + +void ResourceAllocationManagerImpl::OnUnregisterApplication( + const uint32_t app_id) { + LOG4CXX_AUTO_TRACE(logger_); + + rejected_resources_for_application_.erase(app_id); + for (AllocatedResources::const_iterator it = allocated_resources_.begin(); + it != allocated_resources_.end();) { + if (app_id == it->second) { + LOG4CXX_INFO(logger_, + "Application " << app_id + << " is unregistered. Releasing resource " + << it->first); + resources_state_.erase(it->first); + it = allocated_resources_.erase(it); + } else { + ++it; + } + } +} + +} // namespace remote_control diff --git a/src/components/remote_control/test/CMakeLists.txt b/src/components/remote_control/test/CMakeLists.txt new file mode 100644 index 0000000000..75d2e15fa9 --- /dev/null +++ b/src/components/remote_control/test/CMakeLists.txt @@ -0,0 +1,73 @@ +include_directories ( + ${LOG4CXX_INCLUDE_DIRECTORY} + ${GMOCK_INCLUDE_DIRECTORY} + ${CMAKE_SOURCE_DIR}/src/components/functional_module/include/ + ${CMAKE_SOURCE_DIR}/src/components/functional_module/test/ + ${CMAKE_SOURCE_DIR}/src/components/remote_control/include/ + ${CMAKE_SOURCE_DIR}/src/components/remote_control/test/include/ + ${CMAKE_SOURCE_DIR}/src/components/include/ + ${CMAKE_SOURCE_DIR}/src/components/application_manager/test/include/ + ${CMAKE_SOURCE_DIR}/src/components/connection_handler/include/ + ${CMAKE_SOURCE_DIR}/src/components/smart_objects/include/ + ${CMAKE_SOURCE_DIR}/src/components/policy/src/policy/usage_statistics/include/ + ${JSONCPP_INCLUDE_DIRECTORY} + ${CMAKE_BINARY_DIR}/src/components/ + include/ +) + +set (SOURCES + src/rc_module_test.cc + src/rc_app_extension_test.cc + src/resource_allocation_manager_impl_test.cc + ${CMAKE_SOURCE_DIR}/src/components/application_manager/test/mock_message_helper.cc +) + +set (LIBRARIES + gtest + gmock + gmock_main + RemoteControlModule + SmartObjects + gcov + Policy +) + +if (ENABLE_TEST_COV_COUNT) + set(GCOV_FLAGS "-ftest-coverage -fprofile-arcs") +else() + set(GCOV_FLAGS "") +endif() + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCOV_FLAGS}") + +configure_file(lc.awk lc.awk COPYONLY) +configure_file(run_calc_comments.sh run_calc_comments.sh COPYONLY) +configure_file(run_mem_check.sh run_mem_check.sh COPYONLY) +configure_file(smartDeviceLink.ini smartDeviceLink.ini COPYONLY) +configure_file(../InteriorVehicleDataCapabilities.json InteriorVehicleDataCapabilities.json COPYONLY) + +# use, i.e. don't skip the full RPATH for the build tree +#SET(CMAKE_SKIP_BUILD_RPATH FALSE) + +# when building, don't use the install RPATH already +# (but later on when installing) +#SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) + +#SET(RPATH_DIRECTORIES +# ${CMAKE_BINARY_DIR}/src/components/remote_control/ +# /usr/local/lib +# /usr/local +# ${CMAKE_BINARY_DIR}/src/components/utils +#) + +#SET(CMAKE_INSTALL_RPATH "${RPATH_DIRECTORIES}") + +add_custom_command( +OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/libPolicy.so + COMMAND ${CMAKE_COMMAND} -E + copy ${COMPONENTS_DIR}/policy/libPolicy.so ${CMAKE_CURRENT_BINARY_DIR}) + set(CMAKE_EXE_LINKER_FLAGS + "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath=${CMAKE_CURRENT_BINARY_DIR}") + +create_test("remote_control_test" "${SOURCES}" "${LIBRARIES}") +add_subdirectory(commands) diff --git a/src/components/remote_control/test/commands/CMakeLists.txt b/src/components/remote_control/test/commands/CMakeLists.txt new file mode 100644 index 0000000000..1ac186ebf8 --- /dev/null +++ b/src/components/remote_control/test/commands/CMakeLists.txt @@ -0,0 +1,62 @@ +# Copyright (c) 2016, 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(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) + +include_directories( + ${GMOCK_INCLUDE_DIRECTORY} + ${COMPONENTS_DIR}/remote_control/include/ + ${COMPONENTS_DIR}/remote_control/include/remote_control/ + ${COMPONENTS_DIR}/remote_control/include/remote_control/commands/ + ${COMPONENTS_DIR}/remote_control/test/include +) + +set(RC_COMMANDS_TEST_DIR ${RC_TEST_DIR}/commands) + +file(GLOB SOURCES + ${COMPONENTS_DIR}/application_manager/test/mock_message_helper.cc + ${RC_COMMANDS_TEST_DIR}/* +) + +set(LIBRARIES + gmock + RemoteControlModule + Utils + SmartObjects + jsoncpp + HMI_API + MOBILE_API + ApplicationManager + AMHMICommandsLibrary + AMMobileCommandsLibrary + connectionHandler +) + +create_test("rc_commands_test" "${SOURCES}" "${LIBRARIES}" ) diff --git a/src/components/remote_control/test/commands/button_press_request_test.cc b/src/components/remote_control/test/commands/button_press_request_test.cc new file mode 100644 index 0000000000..e4de8902fd --- /dev/null +++ b/src/components/remote_control/test/commands/button_press_request_test.cc @@ -0,0 +1,295 @@ +/* + * Copyright (c) 2017, 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 "remote_control/commands/button_press_request.h" +#include "gtest/gtest.h" +#include "mock_remote_control_plugin.h" +#include "mock_application.h" +#include "mock_resource_allocation_manager.h" +#include "remote_control/rc_app_extension.h" +#include "remote_control/remote_control_event.h" +#include "remote_control/rc_module_constants.h" +#include "remote_control/message_helper.h" +#include "remote_control/rc_command_factory.h" +#include "remote_control/event_engine/event_dispatcher.h" +#include "functional_module/function_ids.h" +#include "include/mock_service.h" +#include "utils/shared_ptr.h" +#include "utils/make_shared.h" + +using functional_modules::RCFunctionID; +using application_manager::ServicePtr; + +using application_manager::MockService; +using test::components::remote_control_test::MockApplication; + +using ::testing::_; +using ::testing::Mock; +using ::testing::NiceMock; +using ::testing::Return; +using ::testing::ReturnRef; +using ::testing::SaveArg; +using ::application_manager::Message; +using ::application_manager::MessageType; +using ::protocol_handler::MessagePriority; +using remote_control::RemotePluginInterface; +using remote_control::MessageHelper; + +namespace { +const int kModuleId = 153; + +const std::string kCorrectMobileRequest = + "{\"moduleType\":\"CLIMATE\",\"buttonName\":\"AC\",\"buttonPressMode\":" + "\"SHORT\"}"; +const std::string kWrongMobileRequest = + "{\"moduleType\":\"RADIO\",\"buttonName\":\"AC\",\"buttonPressMode\":" + "\"SHORT\"}"; +const std::string kValidHmiResponse = + "{\"result\":{\"code\":0,\"method\":\"Buttons.ButtonPress\"},\"id\":31," + "\"jsonrpc\":\"2.0\"} "; +const std::string KReadOnlyHmiResponse = + "{\"jsonrpc\":\"2.0\",\"error\":{\"code\":26,\"data\":{\"method\":" + "\"Buttons.ButtonPress\"},\"message\":\"Read only parameters " + "received\"},\"id\":31}"; +const uint32_t kAppId = 11u; +} + +namespace test { +namespace components { +namespace remote_control_test { +namespace button_press_request_test { + +class ButtonPressRequestTest : public ::testing::Test { + public: + ButtonPressRequestTest() + : mock_service_(utils::MakeShared<NiceMock<MockService> >()) + , mock_app_(utils::MakeShared<NiceMock<MockApplication> >()) + , rc_app_extention_( + utils::MakeShared<remote_control::RCAppExtension>(kModuleId)) { + ON_CALL(mock_module_, service()).WillByDefault(Return(mock_service_)); + ON_CALL(mock_module_, resource_allocation_manager()) + .WillByDefault(ReturnRef(mock_allocation_manager_)); + ON_CALL(*mock_service_, GetApplication(kAppId)) + .WillByDefault(Return(mock_app_)); + EXPECT_CALL(mock_module_, event_dispatcher()) + .WillRepeatedly(ReturnRef(event_dispatcher_)); + ServicePtr exp_service(mock_service_); + mock_module_.set_service(exp_service); + } + + remote_control::request_controller::MobileRequestPtr CreateCommand( + application_manager::MessagePtr msg) { + return remote_control::RCCommandFactory::CreateCommand(msg, mock_module_); + } + + application_manager::MessagePtr CreateBasicMessage() { + application_manager::MessagePtr message = utils::MakeShared<Message>( + MessagePriority::FromServiceType(protocol_handler::ServiceType::kRpc)); + message->set_function_id(RCFunctionID::BUTTON_PRESS); + message->set_function_name( + MessageHelper::GetMobileAPIName(functional_modules::BUTTON_PRESS)); + message->set_connection_key(kAppId); + return message; + } + + protected: + utils::SharedPtr<NiceMock<application_manager::MockService> > mock_service_; + utils::SharedPtr<NiceMock<MockApplication> > mock_app_; + utils::SharedPtr<remote_control::RCAppExtension> rc_app_extention_; + testing::NiceMock<remote_control_test::MockRemotePluginInterface> + mock_module_; + testing::NiceMock<remote_control_test::MockResourceAllocationManager> + mock_allocation_manager_; + RemotePluginInterface::RCPluginEventDispatcher event_dispatcher_; +}; + +TEST_F(ButtonPressRequestTest, + Execute_ButtonNameMatchesModuleType_ExpectCorrectMessageSentToHMI) { + namespace json_keys = remote_control::json_keys; + // Arrange + application_manager::MessagePtr mobile_message = CreateBasicMessage(); + mobile_message->set_json_message(kCorrectMobileRequest); + // Expectations + ON_CALL(*mock_app_, app_id()) + .WillByDefault(Return(mobile_message->connection_key())); + EXPECT_CALL(*mock_service_, GetApplication(mobile_message->connection_key())) + .WillOnce(Return(mock_app_)); + EXPECT_CALL(*mock_service_, ValidateMessageBySchema(*mobile_message)) + .WillOnce(Return(application_manager::MessageValidationResult::SUCCESS)); + EXPECT_CALL(*mock_service_, CheckPolicyPermissions(mobile_message)) + .WillOnce(Return(mobile_apis::Result::eType::SUCCESS)); + application_manager::AppExtensionPtr invalid_ext; + EXPECT_CALL(*mock_app_, QueryInterface(kModuleId)) + .WillOnce(Return(invalid_ext)) + .WillRepeatedly(Return(rc_app_extention_)); + application_manager::AppExtensionPtr app_extension; + EXPECT_CALL(*mock_app_, AddExtension(_)) + .WillOnce(DoAll(SaveArg<0>(&app_extension), Return(true))); + EXPECT_CALL(*mock_service_, CheckAccess(_, _, _, _)) + .WillOnce(Return(application_manager::TypeAccess::kAllowed)); + EXPECT_CALL(*mock_service_, GetNextCorrelationID()).WillOnce(Return(1)); + + const std::string resource = "CLIMATE"; + + EXPECT_CALL(mock_allocation_manager_, IsResourceFree(resource)) + .WillOnce(Return(true)); + EXPECT_CALL(mock_allocation_manager_, AcquireResource(resource, kAppId)) + .WillOnce(Return(remote_control::AcquireResult::ALLOWED)); + EXPECT_CALL( + mock_allocation_manager_, + SetResourceState(resource, kAppId, remote_control::ResourceState::BUSY)); + + application_manager::MessagePtr result_msg; + EXPECT_CALL(*mock_service_, SendMessageToHMI(_)) + .WillOnce(SaveArg<0>(&result_msg)); + + // Act + remote_control::request_controller::MobileRequestPtr command = + CreateCommand(mobile_message); + command->Run(); + // Assertions + EXPECT_EQ(kModuleId, app_extension->uid()); + EXPECT_EQ(application_manager::ProtocolVersion::kHMI, + result_msg->protocol_version()); + EXPECT_EQ(1, result_msg->correlation_id()); + EXPECT_EQ(application_manager::MessageType::kRequest, result_msg->type()); + const Json::Value& hmi_request_params = + MessageHelper::StringToValue(result_msg->json_message()); + EXPECT_EQ(functional_modules::hmi_api::button_press, + hmi_request_params[json_keys::kMethod].asString()); +} + +TEST_F( + ButtonPressRequestTest, + Execute_ButtonNameDoesNotMatchModuleType_ExpectMessageNotSentToHMI_AndFalseSentToMobile) { + namespace json_keys = remote_control::json_keys; + namespace result_codes = remote_control::result_codes; + // Arrange + application_manager::MessagePtr mobile_message = CreateBasicMessage(); + mobile_message->set_json_message(kWrongMobileRequest); + // Expectations + EXPECT_CALL(*mock_service_, GetApplication(mobile_message->connection_key())) + .WillOnce(Return(mock_app_)); + EXPECT_CALL(*mock_service_, ValidateMessageBySchema(*mobile_message)) + .WillOnce(Return(application_manager::MessageValidationResult::SUCCESS)); + EXPECT_CALL(*mock_service_, CheckPolicyPermissions(mobile_message)) + .WillOnce(Return(mobile_apis::Result::eType::SUCCESS)); + application_manager::AppExtensionPtr invalid_ext; + EXPECT_CALL(*mock_app_, QueryInterface(kModuleId)) + .WillOnce(Return(invalid_ext)) + .WillRepeatedly(Return(rc_app_extention_)); + application_manager::AppExtensionPtr app_extension; + EXPECT_CALL(*mock_app_, AddExtension(_)) + .WillOnce(DoAll(SaveArg<0>(&app_extension), Return(true))); + EXPECT_CALL(*mock_service_, CheckAccess(_, _, _, _)) + .WillOnce(Return(application_manager::TypeAccess::kAllowed)); + EXPECT_CALL(*mock_service_, SendMessageToHMI(_)).Times(0); + application_manager::MessagePtr result_msg; + EXPECT_CALL(mock_module_, SendResponseToMobile(_)) + .WillOnce(SaveArg<0>(&result_msg)); + // Act + remote_control::request_controller::MobileRequestPtr command = + CreateCommand(mobile_message); + command->Run(); + // Assertions + const Json::Value& response_params = + MessageHelper::StringToValue(result_msg->json_message()); + EXPECT_FALSE(response_params[result_codes::kSuccess].asBool()); + EXPECT_EQ(result_codes::kInvalidData, + response_params[json_keys::kResultCode].asString()); +} + +TEST_F(ButtonPressRequestTest, OnEvent_ExpectSuccessfullResponseSentToMobile) { + namespace json_keys = remote_control::json_keys; + namespace result_codes = remote_control::result_codes; + // Arrange + application_manager::MessagePtr mobile_message = CreateBasicMessage(); + mobile_message->set_json_message(kCorrectMobileRequest); + + application_manager::MessagePtr hmi_message = CreateBasicMessage(); + hmi_message->set_json_message(kValidHmiResponse); + hmi_message->set_message_type(application_manager::MessageType::kResponse); + // Expectations + EXPECT_CALL(*mock_service_, GetApplication(mobile_message->connection_key())) + .WillOnce(Return(mock_app_)); + application_manager::MessagePtr result_msg; + EXPECT_CALL(mock_module_, SendResponseToMobile(_)) + .WillOnce(SaveArg<0>(&result_msg)); + // Act + remote_control::RCPluginEvent event( + hmi_message, functional_modules::hmi_api::button_press); + remote_control::request_controller::MobileRequestPtr command = + CreateCommand(mobile_message); + command->on_event(event); + // Assertions + const Json::Value& response_params = + MessageHelper::StringToValue(result_msg->json_message()); + EXPECT_TRUE(response_params[json_keys::kSuccess].asBool()); + EXPECT_EQ(result_codes::kSuccess, + response_params[json_keys::kResultCode].asString()); +} + +TEST_F(ButtonPressRequestTest, + OnEvent_ReadOnlyParamFromHMI_ExpectFalseSentToMobile) { + namespace json_keys = remote_control::json_keys; + namespace result_codes = remote_control::result_codes; + // Arrange + application_manager::MessagePtr mobile_message = CreateBasicMessage(); + mobile_message->set_json_message(kCorrectMobileRequest); + + application_manager::MessagePtr hmi_message = CreateBasicMessage(); + hmi_message->set_json_message(KReadOnlyHmiResponse); + hmi_message->set_message_type(application_manager::MessageType::kResponse); + // Expectations + EXPECT_CALL(*mock_service_, GetApplication(mobile_message->connection_key())) + .WillOnce(Return(mock_app_)); + application_manager::MessagePtr result_msg; + EXPECT_CALL(mock_module_, SendResponseToMobile(_)) + .WillOnce(SaveArg<0>(&result_msg)); + // Act + remote_control::RCPluginEvent event( + hmi_message, functional_modules::hmi_api::button_press); + remote_control::request_controller::MobileRequestPtr command = + CreateCommand(mobile_message); + command->on_event(event); + // Assertions + const Json::Value& response_params = + MessageHelper::StringToValue(result_msg->json_message()); + EXPECT_FALSE(response_params[json_keys::kSuccess].asBool()); + EXPECT_EQ(result_codes::kGenericError, + response_params[json_keys::kResultCode].asString()); +} + +} // namespace button_press_request_test +} // namespace remote_control_test +} // namespace components +} // namespace test diff --git a/src/components/remote_control/test/commands/get_interior_vehicle_data_request_test.cc b/src/components/remote_control/test/commands/get_interior_vehicle_data_request_test.cc new file mode 100644 index 0000000000..b8a6c0f675 --- /dev/null +++ b/src/components/remote_control/test/commands/get_interior_vehicle_data_request_test.cc @@ -0,0 +1,288 @@ +/* + * Copyright (c) 2017, 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 "remote_control/commands/get_interior_vehicle_data_request.h" +#include "gtest/gtest.h" +#include "mock_remote_control_plugin.h" +#include "mock_application.h" +#include "remote_control/rc_app_extension.h" +#include "remote_control/remote_control_event.h" +#include "remote_control/rc_module_constants.h" +#include "remote_control/message_helper.h" +#include "remote_control/rc_command_factory.h" +#include "remote_control/event_engine/event_dispatcher.h" +#include "functional_module/function_ids.h" +#include "include/mock_service.h" +#include "utils/shared_ptr.h" +#include "utils/make_shared.h" + +using functional_modules::RCFunctionID; +using application_manager::ServicePtr; + +using application_manager::MockService; +using test::components::remote_control_test::MockApplication; + +using ::testing::_; +using ::testing::Mock; +using ::testing::NiceMock; +using ::testing::StrictMock; +using ::testing::Return; +using ::testing::ReturnRef; +using ::testing::SaveArg; +using ::application_manager::Message; +using ::application_manager::MessageType; +using ::application_manager::ApplicationSharedPtr; +using ::protocol_handler::MessagePriority; +using remote_control::RemotePluginInterface; +using remote_control::MessageHelper; +using namespace remote_control; + +namespace { +const int32_t kConnectionKey = 5; +const int kModuleId = 153; +const std::string kInvalidMobileRequest = "{{\"moduleTip\":\"LUXOFT\"}}"; +const std::string kValidMobileRequest = + "{\"subscribe\":true,\"moduleDescription\":{\"moduleType\":\"CLIMATE\"}}"; +const std::string kValidHmiResponse = + "{\"jsonrpc\":\"2.0\",\"id\":51,\"result\":{\"code\":0,\"method\":\"RC." + "GetInteriorVehicleData\",\"moduleData\":{\"moduleType\":\"CLIMATE\"," + "\"climateControlData\":{\"fanSpeed\":0,\"currentTemperature\":{\"unit\":" + "\"CELSIUS\",\"value\":20},\"desiredTemperature\":{\"unit\":\"CELSIUS\"," + "\"value\":25},\"acEnable\":true,\"circulateAirEnable\":true," + "\"autoModeEnable\":true,\"defrostZone\":\"ALL\",\"dualModeEnable\":true," + "\"acMaxEnable\":true,\"ventilationMode\":\"BOTH\"}},\"isSubscribed\":" + "true}}"; +const std::string kInvalidHmiResponse = + "{\"jsonrpc\":\"2.0\",\"id\":51,\"result\":{\"code\":21,\"method\":\"RC." + "GetInteriorVehicleData\",\"moduleData\":{\"moduleType\":\"CLIMATE\"," + "\"ControlData\":{\"Speed\":0,\"outsideTemperature\":{\"unit\":" + "\"CELSIUS\",\"value\":\"high\"},\"desiredTemperature\":{\"unit\":" + "\"CELSIUS\"," + "\"value\":25},\"acEnable\":true,\"circulateAirEnable\":true," + "\"autoModeEnable\":true,\"defrostZone\":\"ALL\",\"dualModeEnable\":true," + "\"acMaxEnable\":true,\"ventilationMode\":\"BOTH\"}},\"isSubscribed\":" + "false}}"; +} + +namespace test { +namespace components { +namespace remote_control_test { +namespace get_interior_vehicle_data_request_test { + +class GetInteriorVehicleDataRequestTest : public ::testing::Test { + public: + typedef utils::SharedPtr<remote_control::commands::BaseCommandRequest> + GIVDRequestPtr; + typedef rc_event_engine::Event<application_manager::MessagePtr, std::string> + GIVD_HMI_Response; + GetInteriorVehicleDataRequestTest() + : mock_service_(utils::MakeShared<NiceMock<MockService> >()) + , mock_app_(utils::MakeShared<NiceMock<MockApplication> >()) + , rc_app_extention_( + utils::MakeShared<remote_control::RCAppExtension>(kModuleId)) { + ON_CALL(*mock_app_, app_id()).WillByDefault(Return(app_id_)); + ON_CALL(mock_module_, service()).WillByDefault(Return(mock_service_)); + ON_CALL(*mock_service_, GetApplication(app_id_)) + .WillByDefault(Return(mock_app_)); + EXPECT_CALL(mock_module_, event_dispatcher()) + .WillRepeatedly(ReturnRef(event_dispatcher_)); + ServicePtr exp_service(mock_service_); + mock_module_.set_service(exp_service); + } + + remote_control::request_controller::MobileRequestPtr CreateCommand( + application_manager::MessagePtr msg) { + return remote_control::RCCommandFactory::CreateCommand(msg, mock_module_); + } + + application_manager::MessagePtr CreateBasicMessage() { + application_manager::MessagePtr message = utils::MakeShared<Message>( + MessagePriority::FromServiceType(protocol_handler::ServiceType::kRpc)); + message->set_connection_key(kConnectionKey); + message->set_function_id(RCFunctionID::GET_INTERIOR_VEHICLE_DATA); + message->set_function_name("GetInteriorVehicleData"); + return message; + } + + protected: + utils::SharedPtr<NiceMock<application_manager::MockService> > mock_service_; + utils::SharedPtr<NiceMock<MockApplication> > mock_app_; + utils::SharedPtr<remote_control::RCAppExtension> rc_app_extention_; + remote_control_test::MockRemotePluginInterface mock_module_; + RemotePluginInterface::RCPluginEventDispatcher event_dispatcher_; + const uint32_t app_id_ = 11u; +}; + +TEST_F(GetInteriorVehicleDataRequestTest, + Execute_MessageValidationOk_ExpectCorrectMessageSentToHMI) { + // Arrange + application_manager::MessagePtr mobile_message = CreateBasicMessage(); + mobile_message->set_json_message(kValidMobileRequest); + // Expectations + EXPECT_CALL(mock_module_, service()).Times(2).WillOnce(Return(mock_service_)); + EXPECT_CALL(*mock_service_, GetApplication(mobile_message->connection_key())) + .WillOnce(Return(mock_app_)); + EXPECT_CALL(*mock_service_, ValidateMessageBySchema(*mobile_message)) + .WillOnce(Return(application_manager::MessageValidationResult::SUCCESS)); + EXPECT_CALL(*mock_service_, CheckPolicyPermissions(mobile_message)) + .WillOnce(Return(mobile_apis::Result::eType::SUCCESS)); + application_manager::AppExtensionPtr invalid_ext; + EXPECT_CALL(*mock_app_, QueryInterface(kModuleId)) + .WillOnce(Return(invalid_ext)) + .WillRepeatedly(Return(rc_app_extention_)); + application_manager::AppExtensionPtr app_extension; + EXPECT_CALL(*mock_app_, AddExtension(_)) + .WillOnce(DoAll(SaveArg<0>(&app_extension), Return(true))); + EXPECT_CALL(*mock_service_, CheckAccess(_, _, _, _)) + .WillOnce(Return(application_manager::TypeAccess::kAllowed)); + EXPECT_CALL(*mock_service_, GetNextCorrelationID()).WillOnce(Return(1)); + application_manager::MessagePtr result_msg; + EXPECT_CALL(*mock_service_, SendMessageToHMI(_)) + .WillOnce(SaveArg<0>(&result_msg)); + // Act + remote_control::request_controller::MobileRequestPtr command = + CreateCommand(mobile_message); + command->Run(); + // Assertions + EXPECT_EQ(kModuleId, app_extension->uid()); + EXPECT_EQ(application_manager::ProtocolVersion::kHMI, + result_msg->protocol_version()); + EXPECT_EQ(1, result_msg->correlation_id()); + EXPECT_EQ(application_manager::MessageType::kRequest, result_msg->type()); + const Json::Value hmi_request_params = + MessageHelper::StringToValue(result_msg->json_message()); + EXPECT_EQ(functional_modules::hmi_api::get_interior_vehicle_data, + hmi_request_params[json_keys::kMethod].asString()); +} + +TEST_F( + GetInteriorVehicleDataRequestTest, + Execute_MessageValidationFailed_ExpectMessageNotSentToHMI_AndFalseSentToMobile) { + // Arrange + application_manager::MessagePtr mobile_message = CreateBasicMessage(); + mobile_message->set_json_message(kInvalidMobileRequest); + // Expectations + EXPECT_CALL(mock_module_, service()).WillOnce(Return(mock_service_)); + EXPECT_CALL(*mock_service_, GetApplication(mobile_message->connection_key())) + .WillOnce(Return(mock_app_)); + EXPECT_CALL(*mock_service_, ValidateMessageBySchema(*mobile_message)) + .WillOnce( + Return(application_manager::MessageValidationResult::INVALID_JSON)); + EXPECT_CALL(*mock_service_, SendMessageToHMI(_)).Times(0); + application_manager::MessagePtr result_msg; + EXPECT_CALL(mock_module_, SendResponseToMobile(_)) + .WillOnce(SaveArg<0>(&result_msg)); + // Act + remote_control::request_controller::MobileRequestPtr command = + CreateCommand(mobile_message); + command->Run(); + // Assertions + const Json::Value response_params = + MessageHelper::StringToValue(result_msg->json_message()); + EXPECT_FALSE(response_params[result_codes::kSuccess].asBool()); + EXPECT_EQ(result_codes::kInvalidData, + response_params[json_keys::kResultCode].asString()); +} + +TEST_F(GetInteriorVehicleDataRequestTest, + OnEvent_ValidHmiResponse_ExpectSuccessfullResponseSentToMobile) { + // Arrange + application_manager::MessagePtr mobile_message = CreateBasicMessage(); + mobile_message->set_json_message(kValidMobileRequest); + + application_manager::MessagePtr hmi_message = CreateBasicMessage(); + hmi_message->set_json_message(kValidHmiResponse); + hmi_message->set_message_type(application_manager::MessageType::kResponse); + // Expectations + EXPECT_CALL(mock_module_, service()).WillOnce(Return(mock_service_)); + EXPECT_CALL(*mock_service_, GetApplication(mobile_message->connection_key())) + .WillOnce(Return(mock_app_)); + EXPECT_CALL(*mock_service_, ValidateMessageBySchema(*hmi_message)) + .WillOnce(Return(application_manager::MessageValidationResult::SUCCESS)); + EXPECT_CALL(*mock_app_, QueryInterface(kModuleId)) + .WillOnce(Return(rc_app_extention_)); + application_manager::MessagePtr result_msg; + EXPECT_CALL(mock_module_, SendResponseToMobile(_)) + .WillOnce(SaveArg<0>(&result_msg)); + // Act + remote_control::RCPluginEvent event( + hmi_message, functional_modules::hmi_api::get_interior_vehicle_data); + remote_control::request_controller::MobileRequestPtr command = + CreateCommand(mobile_message); + command->on_event(event); + // Assertions + const Json::Value response_params = + MessageHelper::StringToValue(result_msg->json_message()); + EXPECT_TRUE(response_params[json_keys::kSuccess].asBool()); + EXPECT_EQ(result_codes::kSuccess, + response_params[json_keys::kResultCode].asString()); +} + +TEST_F(GetInteriorVehicleDataRequestTest, + OnEvent_InvalidHmiResponse_ExpectGenericErrorResponseSentToMobile) { + // Arrange + application_manager::MessagePtr mobile_message = CreateBasicMessage(); + mobile_message->set_json_message(kValidMobileRequest); + application_manager::MessagePtr hmi_message = CreateBasicMessage(); + hmi_message->set_json_message(kInvalidHmiResponse); + hmi_message->set_message_type(application_manager::MessageType::kResponse); + // Expectations + EXPECT_CALL(mock_module_, service()).WillOnce(Return(mock_service_)); + EXPECT_CALL(*mock_service_, GetApplication(mobile_message->connection_key())) + .WillOnce(Return(mock_app_)); + EXPECT_CALL(*mock_service_, ValidateMessageBySchema(*hmi_message)) + .WillOnce( + Return(application_manager::MessageValidationResult::INVALID_JSON)); + application_manager::MessagePtr result_msg; + EXPECT_CALL(mock_module_, SendResponseToMobile(_)) + .WillOnce(SaveArg<0>(&result_msg)); + // Act + remote_control::request_controller::MobileRequestPtr command = + CreateCommand(mobile_message); + remote_control::RCPluginEvent event( + hmi_message, functional_modules::hmi_api::get_interior_vehicle_data); + command->on_event(event); + const Json::Value response_params = + MessageHelper::StringToValue(result_msg->json_message()); + EXPECT_FALSE(response_params[json_keys::kSuccess].asBool()); + EXPECT_EQ(result_codes::kGenericError, + response_params[json_keys::kResultCode].asString()); + const Json::Value hmi_response = + MessageHelper::StringToValue(hmi_message->json_message()); + EXPECT_EQ(hmi_response[json_keys::kInfo].asString(), + response_params[json_keys::kInfo].asString()); +} + +} // namespace get_interior_vehicle_data_request_test +} // namespace remote_control_test +} // namespace components +} // namespace test diff --git a/src/components/remote_control/test/commands/on_interior_vehicle_data_notification_test.cc b/src/components/remote_control/test/commands/on_interior_vehicle_data_notification_test.cc new file mode 100644 index 0000000000..2bf7771199 --- /dev/null +++ b/src/components/remote_control/test/commands/on_interior_vehicle_data_notification_test.cc @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2017, 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 "remote_control/commands/on_interior_vehicle_data_notification.h" +#include "gtest/gtest.h" +#include "mock_remote_control_plugin.h" +#include "mock_application.h" +#include "remote_control/rc_app_extension.h" +#include "remote_control/remote_control_event.h" +#include "remote_control/rc_module_constants.h" +#include "remote_control/message_helper.h" +#include "remote_control/rc_command_factory.h" +#include "remote_control/event_engine/event_dispatcher.h" +#include "functional_module/function_ids.h" +#include "include/mock_service.h" +#include "utils/shared_ptr.h" +#include "utils/make_shared.h" + +using functional_modules::RCFunctionID; +using application_manager::ServicePtr; + +using application_manager::MockService; +using test::components::remote_control_test::MockApplication; + +using ::testing::_; +using ::testing::Mock; +using ::testing::NiceMock; +using ::testing::Return; +using ::testing::SaveArg; +using ::application_manager::Message; +using ::application_manager::MessageType; +using ::application_manager::ApplicationSharedPtr; +using ::protocol_handler::MessagePriority; +using remote_control::RemotePluginInterface; +using remote_control::MessageHelper; +using namespace remote_control; + +namespace { +const int kModuleId = 153; +const std::string kJson = + "{ \"jsonrpc\": \"2.0\",\"method\": \"RC.OnInteriorVehicleData\",\ + \"params\":{\"moduleData\":{\ + \"moduleType\": \"CLIMATE\",\"climateControlData\": {\"fanSpeed\": 100}}}}"; +const uint32_t kAppId_ = 11u; +} + +namespace test { +namespace components { +namespace remote_control_test { +namespace on_interior_vehicle_data_notification_test { + +class OnInteriorVehicleDataNotificationTest : public ::testing::Test { + public: + OnInteriorVehicleDataNotificationTest() + : mock_service_(utils::MakeShared<NiceMock<MockService> >()) + , mock_app_(utils::MakeShared<NiceMock<MockApplication> >()) + , rc_app_extention_( + utils::MakeShared<remote_control::RCAppExtension>(kModuleId)) { + ON_CALL(mock_module_, service()).WillByDefault(Return(mock_service_)); + ServicePtr exp_service(mock_service_); + mock_module_.set_service(exp_service); + } + + remote_control::request_controller::MobileRequestPtr CreateCommand( + application_manager::MessagePtr msg) { + return remote_control::RCCommandFactory::CreateCommand(msg, mock_module_); + } + + application_manager::MessagePtr CreateBasicMessage() { + application_manager::MessagePtr message = utils::MakeShared<Message>( + MessagePriority::FromServiceType(protocol_handler::ServiceType::kRpc)); + message->set_function_id(RCFunctionID::ON_INTERIOR_VEHICLE_DATA); + message->set_function_name("OnInteriorVehicleData"); + message->set_json_message(kJson); + return message; + } + + protected: + utils::SharedPtr<NiceMock<application_manager::MockService> > mock_service_; + utils::SharedPtr<NiceMock<MockApplication> > mock_app_; + utils::SharedPtr<remote_control::RCAppExtension> rc_app_extention_; + remote_control_test::MockRemotePluginInterface mock_module_; + std::vector<ApplicationSharedPtr> apps_; +}; + +TEST_F(OnInteriorVehicleDataNotificationTest, + Execute_SendMessageToMobile_IfAppIsSubscribed) { + // Arrange + application_manager::MessagePtr message = CreateBasicMessage(); + Json::Value json_value = MessageHelper::StringToValue(kJson); + Json::Value module_type = + json_value[json_keys::kParams][message_params::kModuleData] + [message_params::kModuleType]; + rc_app_extention_->SubscribeToInteriorVehicleData(module_type); + apps_.push_back(mock_app_); + // Expectations + EXPECT_CALL(mock_module_, service()).WillOnce(Return(mock_service_)); + EXPECT_CALL(*mock_service_, GetApplications(kModuleId)) + .WillOnce(Return(apps_)); + EXPECT_CALL(*mock_app_, QueryInterface(kModuleId)) + .WillOnce(Return(rc_app_extention_)); + ON_CALL(*mock_app_, app_id()).WillByDefault(Return(kAppId_)); + EXPECT_CALL(*mock_service_, GetApplication(kAppId_)) + .WillOnce(Return(mock_app_)); + EXPECT_CALL(*mock_service_, CheckPolicyPermissions(_)) + .WillOnce(Return(mobile_apis::Result::eType::SUCCESS)); + EXPECT_CALL(*mock_service_, CheckModule(kAppId_, enums_value::kClimate)) + .WillOnce(Return(true)); + application_manager::MessagePtr result_msg; + EXPECT_CALL(*mock_service_, SendMessageToMobile(_)) + .WillOnce(SaveArg<0>(&result_msg)); + // Act + remote_control::request_controller::MobileRequestPtr command = + CreateCommand(message); + command->Run(); + // Assertions + EXPECT_EQ(application_manager::ProtocolVersion::kV3, + result_msg->protocol_version()); + EXPECT_EQ(application_manager::MessageType::kNotification, + result_msg->type()); + EXPECT_EQ(functional_modules::ON_INTERIOR_VEHICLE_DATA, + result_msg->function_id()); + EXPECT_EQ(MessageHelper::GetMobileAPIName( + functional_modules::ON_INTERIOR_VEHICLE_DATA), + result_msg->function_name()); +} + +TEST_F(OnInteriorVehicleDataNotificationTest, + Execute_NotSendMessageToMobile_IfAppUnsubscribed) { + // Arrange + application_manager::MessagePtr message = CreateBasicMessage(); + apps_.push_back(mock_app_); + // Expectations + EXPECT_CALL(mock_module_, service()).WillOnce(Return(mock_service_)); + EXPECT_CALL(*mock_service_, GetApplications(kModuleId)) + .WillOnce(Return(apps_)); + EXPECT_CALL(*mock_app_, QueryInterface(kModuleId)) + .WillOnce(Return(rc_app_extention_)); + EXPECT_CALL(*mock_service_, SendMessageToMobile(_)).Times(0); + // Act + remote_control::request_controller::MobileRequestPtr command = + CreateCommand(message); + command->Run(); +} + +} // namespace on_interior_vehicle_data_notification_test +} // namespace remote_control_test +} // namespace components +} // namespace test diff --git a/src/components/remote_control/test/commands/on_remote_control_settings_test.cc b/src/components/remote_control/test/commands/on_remote_control_settings_test.cc new file mode 100644 index 0000000000..879e9e1de0 --- /dev/null +++ b/src/components/remote_control/test/commands/on_remote_control_settings_test.cc @@ -0,0 +1,322 @@ +/* + * Copyright (c) 2017, 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 "remote_control/commands/on_remote_control_settings_notification.h" +#include "gtest/gtest.h" +#include "mock_remote_control_plugin.h" +#include "mock_application.h" +#include "mock_resource_allocation_manager.h" +#include "remote_control/rc_app_extension.h" +#include "remote_control/remote_control_event.h" +#include "remote_control/rc_module_constants.h" +#include "remote_control/message_helper.h" +#include "remote_control/rc_command_factory.h" +#include "remote_control/event_engine/event_dispatcher.h" +#include "functional_module/function_ids.h" +#include "include/mock_service.h" +#include "utils/shared_ptr.h" +#include "utils/make_shared.h" + +using functional_modules::RCFunctionID; +using application_manager::ServicePtr; + +using application_manager::MockService; +using test::components::remote_control_test::MockApplication; + +using ::testing::_; +using ::testing::Mock; +using ::testing::NiceMock; +using ::testing::Return; +using ::testing::ReturnRef; +using ::testing::SaveArg; +using ::application_manager::Message; +using ::application_manager::MessageType; +using ::application_manager::ApplicationSharedPtr; +using ::protocol_handler::MessagePriority; +using remote_control::RemotePluginInterface; +using remote_control::MessageHelper; +using namespace remote_control; + +namespace { +const int kModuleId = 153; +const std::string kAllowedTrueAUTO_ALLOWJson = + "{ \"jsonrpc\": \"2.0\",\"method\": \"RC.OnRemoteControlSettings\",\ + \"params\":{\"accessMode\": \"AUTO_ALLOW\", \"allowed\":true}}"; +const std::string kAllowedTrueASK_DRIVERJson = + "{ \"jsonrpc\": \"2.0\",\"method\": \"RC.OnRemoteControlSettings\",\ + \"params\":{\"accessMode\": \"ASK_DRIVER\", \"allowed\":true}}"; +const std::string kAllowedTrueAUTO_DENYJson = + "{ \"jsonrpc\": \"2.0\",\"method\": \"RC.OnRemoteControlSettings\",\ + \"params\":{\"accessMode\": \"AUTO_DENY\", \"allowed\":true}}"; +const std::string kAllowedFalseAUTO_ALLOWJson = + "{ \"jsonrpc\": \"2.0\",\"method\": \"RC.OnRemoteControlSettings\",\ + \"params\":{\"accessMode\": \"AUTO_ALLOW\", \"allowed\":false}}"; +const std::string kAllowedFalseASK_DRIVERJson = + "{ \"jsonrpc\": \"2.0\",\"method\": \"RC.OnRemoteControlSettings\",\ + \"params\":{\"accessMode\": \"ASK_DRIVER\", \"allowed\":false}}"; +const std::string kAllowedFalseAUTO_DENYJson = + "{ \"jsonrpc\": \"2.0\",\"method\": \"RC.OnRemoteControlSettings\",\ + \"params\":{\"accessMode\": \"AUTO_DENY\", \"allowed\":false}}"; +const std::string kWithoutParamsJson = + "{ \"jsonrpc\": \"2.0\",\"method\": \"RC.OnRemoteControlSettings\"}"; +} + +namespace test { +namespace components { +namespace remote_control_test { +namespace on_remote_control_settings_notification_test { + +class OnRemoteControlSettingsNotificationTest : public ::testing::Test { + public: + OnRemoteControlSettingsNotificationTest() + : mock_service_(utils::MakeShared<NiceMock<MockService> >()) + , mock_app_(utils::MakeShared<NiceMock<MockApplication> >()) + , rc_app_extention_( + utils::MakeShared<remote_control::RCAppExtension>(kModuleId)) { + ON_CALL(mock_module_, resource_allocation_manager()) + .WillByDefault(ReturnRef(mock_allocation_manager_)); + apps_.push_back(mock_app_); + } + + remote_control::request_controller::MobileRequestPtr CreateCommand( + application_manager::MessagePtr msg) { + return remote_control::RCCommandFactory::CreateCommand(msg, mock_module_); + } + + application_manager::MessagePtr CreateBasicMessage( + const std::string& json_message) { + application_manager::MessagePtr message = utils::MakeShared<Message>( + MessagePriority::FromServiceType(protocol_handler::ServiceType::kRpc)); + message->set_function_id(RCFunctionID::ON_REMOTE_CONTROL_SETTINGS); + message->set_function_name( + MessageHelper::GetMobileAPIName(functional_modules::BUTTON_PRESS)); + message->set_json_message(json_message); + return message; + } + + protected: + utils::SharedPtr<NiceMock<application_manager::MockService> > mock_service_; + utils::SharedPtr<NiceMock<MockApplication> > mock_app_; + utils::SharedPtr<remote_control::RCAppExtension> rc_app_extention_; + remote_control_test::MockRemotePluginInterface mock_module_; + std::vector<ApplicationSharedPtr> apps_; + testing::NiceMock<remote_control_test::MockResourceAllocationManager> + mock_allocation_manager_; +}; + +TEST_F(OnRemoteControlSettingsNotificationTest, + Execute_SetAccessModeAUTO_ALLOW_IfAllowedTrue) { + // Arrange + const Json::Value value = + MessageHelper::StringToValue(kAllowedTrueAUTO_ALLOWJson); + const std::string access_mode = + value[json_keys::kParams][message_params::kAccessMode].asString(); + const hmi_apis::Common_RCAccessMode::eType access_mode_ = + MessageHelper::AccessModeFromString(access_mode); + // Expectations + EXPECT_CALL(mock_module_, service()).WillOnce(Return(mock_service_)); + EXPECT_CALL(mock_allocation_manager_, SetAccessMode(access_mode_)); + + application_manager::MessagePtr message = + CreateBasicMessage(kAllowedTrueAUTO_ALLOWJson); + // Act + remote_control::request_controller::MobileRequestPtr command = + CreateCommand(message); + command->Run(); +} + +TEST_F(OnRemoteControlSettingsNotificationTest, + Execute_SetAccessModeAUTO_DENY_IfAllowedTrue) { + // Arrange + const Json::Value value = + MessageHelper::StringToValue(kAllowedTrueAUTO_DENYJson); + const std::string access_mode = + value[json_keys::kParams][message_params::kAccessMode].asString(); + const hmi_apis::Common_RCAccessMode::eType access_mode_ = + MessageHelper::AccessModeFromString(access_mode); + // Expectations + EXPECT_CALL(mock_module_, service()).WillOnce(Return(mock_service_)); + EXPECT_CALL(mock_allocation_manager_, SetAccessMode(access_mode_)); + + application_manager::MessagePtr message = + CreateBasicMessage(kAllowedTrueAUTO_DENYJson); + // Act + remote_control::request_controller::MobileRequestPtr command = + CreateCommand(message); + command->Run(); +} + +TEST_F(OnRemoteControlSettingsNotificationTest, + Execute_SetAccessModeASK_DRIVER_IfAllowedTrue) { + // Arrange + const Json::Value value = + MessageHelper::StringToValue(kAllowedTrueASK_DRIVERJson); + const std::string access_mode = + value[json_keys::kParams][message_params::kAccessMode].asString(); + const hmi_apis::Common_RCAccessMode::eType access_mode_ = + MessageHelper::AccessModeFromString(access_mode); + // Expectations + EXPECT_CALL(mock_module_, service()).WillOnce(Return(mock_service_)); + EXPECT_CALL(mock_allocation_manager_, SetAccessMode(access_mode_)); + application_manager::MessagePtr message = + CreateBasicMessage(kAllowedTrueASK_DRIVERJson); + // Act + remote_control::request_controller::MobileRequestPtr command = + CreateCommand(message); + command->Run(); +} + +TEST_F(OnRemoteControlSettingsNotificationTest, + Execute_DisallowRCFunctionality_IfAllowedFalseAccessModeAUTO_ALLOW) { + // Arrange + const Json::Value module_type(enums_value::kClimate); + rc_app_extention_->SubscribeToInteriorVehicleData(module_type); + const Json::Value value = + MessageHelper::StringToValue(kAllowedFalseAUTO_ALLOWJson); + const std::string access_mode = + value[json_keys::kParams][message_params::kAccessMode].asString(); + const hmi_apis::Common_RCAccessMode::eType access_mode_ = + MessageHelper::AccessModeFromString(access_mode); + // Expectations + EXPECT_CALL(mock_module_, service()).WillOnce(Return(mock_service_)); + EXPECT_CALL(mock_allocation_manager_, SetAccessMode(access_mode_)).Times(0); + EXPECT_CALL(*mock_service_, GetApplications(kModuleId)) + .WillOnce(Return(apps_)); + EXPECT_CALL( + *mock_service_, + ChangeNotifyHMILevel(apps_[0], mobile_apis::HMILevel::eType::HMI_NONE)); + EXPECT_CALL(*mock_app_, QueryInterface(kModuleId)) + .WillOnce(Return(rc_app_extention_)); + EXPECT_EQ(rc_app_extention_->IsSubscibedToInteriorVehicleData(module_type), + true); + application_manager::MessagePtr message = + CreateBasicMessage(kAllowedFalseAUTO_ALLOWJson); + // Act + remote_control::request_controller::MobileRequestPtr command = + CreateCommand(message); + command->Run(); + // Assertions + EXPECT_EQ(rc_app_extention_->IsSubscibedToInteriorVehicleData(module_type), + false); +} + +TEST_F(OnRemoteControlSettingsNotificationTest, + Execute_DisallowRCFunctionality_IfAllowedFalseAccessModeASK_DRIVER) { + // Arrange + const Json::Value module_type(enums_value::kRadio); + rc_app_extention_->SubscribeToInteriorVehicleData(module_type); + const Json::Value value = + MessageHelper::StringToValue(kAllowedFalseASK_DRIVERJson); + const std::string access_mode = + value[json_keys::kParams][message_params::kAccessMode].asString(); + const hmi_apis::Common_RCAccessMode::eType access_mode_ = + MessageHelper::AccessModeFromString(access_mode); + // Expectations + EXPECT_CALL(mock_module_, service()).WillOnce(Return(mock_service_)); + EXPECT_CALL(mock_allocation_manager_, SetAccessMode(access_mode_)).Times(0); + EXPECT_CALL(*mock_service_, GetApplications(kModuleId)) + .WillOnce(Return(apps_)); + EXPECT_CALL( + *mock_service_, + ChangeNotifyHMILevel(apps_[0], mobile_apis::HMILevel::eType::HMI_NONE)); + EXPECT_CALL(*mock_app_, QueryInterface(kModuleId)) + .WillOnce(Return(rc_app_extention_)); + EXPECT_EQ(rc_app_extention_->IsSubscibedToInteriorVehicleData(module_type), + true); + application_manager::MessagePtr message = + CreateBasicMessage(kAllowedFalseASK_DRIVERJson); + // Act + remote_control::request_controller::MobileRequestPtr command = + CreateCommand(message); + command->Run(); + // Assertions + EXPECT_EQ(rc_app_extention_->IsSubscibedToInteriorVehicleData(module_type), + false); +} + +TEST_F(OnRemoteControlSettingsNotificationTest, + Execute_DisallowRCFunctionality_IfAllowedFalseAccessModeAUTO_DENY) { + // Arrange + const Json::Value module_type(enums_value::kClimate); + rc_app_extention_->SubscribeToInteriorVehicleData(module_type); + const Json::Value value = + MessageHelper::StringToValue(kAllowedFalseAUTO_DENYJson); + const std::string access_mode = + value[json_keys::kParams][message_params::kAccessMode].asString(); + const hmi_apis::Common_RCAccessMode::eType access_mode_ = + MessageHelper::AccessModeFromString(access_mode); + // Expectations + EXPECT_CALL(mock_module_, service()).WillOnce(Return(mock_service_)); + EXPECT_CALL(mock_allocation_manager_, SetAccessMode(access_mode_)).Times(0); + EXPECT_CALL(*mock_service_, GetApplications(kModuleId)) + .WillOnce(Return(apps_)); + EXPECT_CALL( + *mock_service_, + ChangeNotifyHMILevel(apps_[0], mobile_apis::HMILevel::eType::HMI_NONE)); + EXPECT_CALL(*mock_app_, QueryInterface(kModuleId)) + .WillOnce(Return(rc_app_extention_)); + EXPECT_EQ(rc_app_extention_->IsSubscibedToInteriorVehicleData(module_type), + true); + application_manager::MessagePtr message = + CreateBasicMessage(kAllowedFalseAUTO_DENYJson); + // Act + remote_control::request_controller::MobileRequestPtr command = + CreateCommand(message); + command->Run(); + // Assertions + EXPECT_EQ(rc_app_extention_->IsSubscibedToInteriorVehicleData(module_type), + false); +} + +TEST_F(OnRemoteControlSettingsNotificationTest, + Execute_NothingHappens_IfParamsOmitted) { + // Expectations + EXPECT_CALL(mock_module_, service()).WillOnce(Return(mock_service_)); + EXPECT_CALL(mock_allocation_manager_, SetAccessMode(_)).Times(0); + EXPECT_CALL(*mock_service_, GetApplications(kModuleId)).Times(0); + EXPECT_CALL(*mock_app_, QueryInterface(kModuleId)).Times(0); + EXPECT_CALL(*mock_service_, + ChangeNotifyHMILevel( + apps_[0], mobile_apis::HMILevel::eType::HMI_NONE)).Times(0); + + application_manager::MessagePtr message = + CreateBasicMessage(kWithoutParamsJson); + // Act + remote_control::request_controller::MobileRequestPtr command = + CreateCommand(message); + command->Run(); +} + +} // namespace on_remote_control_settings_notification_test +} // namespace remote_control_test +} // namespace components +} // namespace test diff --git a/src/components/remote_control/test/commands/set_interior_vehicle_data_request_test.cc b/src/components/remote_control/test/commands/set_interior_vehicle_data_request_test.cc new file mode 100644 index 0000000000..44dd422468 --- /dev/null +++ b/src/components/remote_control/test/commands/set_interior_vehicle_data_request_test.cc @@ -0,0 +1,429 @@ +/* + * Copyright (c) 2017, 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 "remote_control/commands/set_interior_vehicle_data_request.h" +#include "gtest/gtest.h" +#include "mock_remote_control_plugin.h" +#include "mock_application.h" +#include "mock_resource_allocation_manager.h" +#include "remote_control/rc_app_extension.h" +#include "remote_control/remote_control_event.h" +#include "remote_control/rc_module_constants.h" +#include "remote_control/message_helper.h" +#include "remote_control/rc_command_factory.h" +#include "remote_control/event_engine/event_dispatcher.h" +#include "functional_module/function_ids.h" +#include "include/mock_service.h" +#include "utils/shared_ptr.h" +#include "utils/make_shared.h" + +using functional_modules::RCFunctionID; +using application_manager::ServicePtr; + +using application_manager::MockService; +using test::components::remote_control_test::MockApplication; + +using ::testing::_; +using ::testing::Mock; +using ::testing::NiceMock; +using ::testing::StrictMock; +using ::testing::Return; +using ::testing::ReturnRef; +using ::testing::SaveArg; +using ::application_manager::Message; +using ::application_manager::MessageType; +using ::application_manager::ApplicationSharedPtr; +using ::protocol_handler::MessagePriority; +using remote_control::RemotePluginInterface; +using remote_control::MessageHelper; +using namespace remote_control; + +namespace { +const uint32_t kAppId = 11u; +const int32_t kConnectionKey = 5; +const int kModuleId = 153; +const uint32_t kCorrelationId = 1u; +const std::string kValidMobileRequestWithOnlySettableParams = + "{\"moduleData\":{\"moduleType\":\"CLIMATE\", " + "\"climateControlData\":{\"defrostZone\":" + "\"FRONT\", \"fanSpeed\":10}}}"; +const std::string kValidMobileRequestWithSettableAndReadOnlyParams = + "{\"moduleData\":{\"moduleType\":\"CLIMATE\", " + "\"climateControlData\":{\"defrostZone\":" + "\"FRONT\", \"fanSpeed\":10, \"currentTemperature\":{\"unit\":\"CELSIUS\", " + "\"value\":17.5}}}}"; +const std::string kValidMobileRequestWithoutSettableAndWithReadOnlyParams = + "{\"moduleData\":{\"moduleType\":\"CLIMATE\", \"climateControlData\":" + "{\"currentTemperature\":{\"unit\":\"CELSIUS\", \"value\":17.5}}}}"; +const std::string kInvalidMobileRequest = "{{\"moduleTip\":\"LUXOFT\"}}"; +const std::string kValidHmiResponse = + "{\"jsonrpc\":\"2.0\",\"id\":51,\"result\":{\"code\":0,\"method\":\"RC." + "SetInteriorVehicleData\",\"moduleData\":{\"moduleType\":\"CLIMATE\"," + "\"climateControlData\":{\"fanSpeed\":0,\"desiredTemperature\":{\"unit\":" + "\"CELSIUS\"," + "\"value\":25},\"acEnable\":true,\"circulateAirEnable\":true," + "\"autoModeEnable\":true,\"defrostZone\":\"ALL\",\"dualModeEnable\":true," + "\"acMaxEnable\":true,\"ventilationMode\":\"BOTH\"}}}}"; +const std::string kInvalidHmiResponse = + "{\"jsonrpc\":\"2.0\",\"id\":51,\"result\":{\"code\":21,\"method\":\"RC." + "SetInteriorVehicleData\",\"moduleData\":{\"moduleType\":\"CLIMATE\"," + "\"ControlData\":{\"Speed\":0,\"outsideTemperature\":{\"unit\":" + "\"CELSIUS\",\"value\":\"high\"},\"desiredTemperature\":{\"unit\":" + "\"CELSIUS\"," + "\"value\":25},\"acEnable\":true,\"circulateAirEnable\":true," + "\"autoModeEnable\":true,\"defrostZone\":\"ALL\",\"dualModeEnable\":true," + "\"acMaxEnable\":true,\"ventilationMode\":\"BOTH\"}},\"isSubscribed\":" + "false}}"; +} + +namespace test { +namespace components { +namespace remote_control_test { +namespace set_interior_vehicle_data_request_test { + +class SetInteriorVehicleDataRequestTest : public ::testing::Test { + public: + SetInteriorVehicleDataRequestTest() + : mock_service_(utils::MakeShared<NiceMock<MockService> >()) + , mock_app_(utils::MakeShared<NiceMock<MockApplication> >()) + , rc_app_extention_( + utils::MakeShared<remote_control::RCAppExtension>(kModuleId)) { + ON_CALL(*mock_app_, app_id()).WillByDefault(Return(kAppId)); + ON_CALL(mock_module_, resource_allocation_manager()) + .WillByDefault(ReturnRef(mock_allocation_manager_)); + ON_CALL(mock_module_, service()).WillByDefault(Return(mock_service_)); + ON_CALL(*mock_service_, GetApplication(_)).WillByDefault(Return(mock_app_)); + ON_CALL(mock_module_, event_dispatcher()) + .WillByDefault(ReturnRef(event_dispatcher_)); + ServicePtr exp_service(mock_service_); + } + + remote_control::request_controller::MobileRequestPtr CreateCommand( + application_manager::MessagePtr msg) { + return remote_control::RCCommandFactory::CreateCommand(msg, mock_module_); + } + + application_manager::MessagePtr CreateBasicMessage() { + application_manager::MessagePtr message = utils::MakeShared<Message>( + MessagePriority::FromServiceType(protocol_handler::ServiceType::kRpc)); + message->set_connection_key(kConnectionKey); + message->set_function_id(RCFunctionID::SET_INTERIOR_VEHICLE_DATA); + message->set_function_name(MessageHelper::GetMobileAPIName( + functional_modules::SET_INTERIOR_VEHICLE_DATA)); + return message; + } + + protected: + utils::SharedPtr<NiceMock<application_manager::MockService> > mock_service_; + utils::SharedPtr<NiceMock<MockApplication> > mock_app_; + utils::SharedPtr<remote_control::RCAppExtension> rc_app_extention_; + testing::NiceMock<remote_control_test::MockRemotePluginInterface> + mock_module_; + testing::NiceMock<remote_control_test::MockResourceAllocationManager> + mock_allocation_manager_; + RemotePluginInterface::RCPluginEventDispatcher event_dispatcher_; +}; + +TEST_F(SetInteriorVehicleDataRequestTest, + Execute_ValidWithoutReadOnlyParams_ExpectResendToHMI) { + // Arrange + application_manager::MessagePtr mobile_message = CreateBasicMessage(); + mobile_message->set_json_message(kValidMobileRequestWithOnlySettableParams); + + // Expectations + EXPECT_CALL(*mock_service_, ValidateMessageBySchema(*mobile_message)) + .WillOnce(Return(application_manager::MessageValidationResult::SUCCESS)); + EXPECT_CALL(*mock_service_, CheckPolicyPermissions(mobile_message)) + .WillOnce(Return(mobile_apis::Result::eType::SUCCESS)); + application_manager::AppExtensionPtr invalid_ext; + EXPECT_CALL(*mock_app_, QueryInterface(kModuleId)) + .WillOnce(Return(invalid_ext)) + .WillRepeatedly(Return(rc_app_extention_)); + + application_manager::AppExtensionPtr app_extension; + EXPECT_CALL(*mock_app_, AddExtension(_)) + .WillOnce(DoAll(SaveArg<0>(&app_extension), Return(true))); + EXPECT_CALL(*mock_service_, CheckAccess(_, _, _, _)) + .WillOnce(Return(application_manager::TypeAccess::kAllowed)); + EXPECT_CALL(*mock_service_, GetNextCorrelationID()) + .WillOnce(Return(kCorrelationId)); + + const std::string resource = "CLIMATE"; + + EXPECT_CALL(mock_allocation_manager_, IsResourceFree(resource)) + .WillOnce(Return(true)); + EXPECT_CALL(mock_allocation_manager_, AcquireResource(resource, kAppId)) + .WillOnce(Return(remote_control::AcquireResult::ALLOWED)); + EXPECT_CALL( + mock_allocation_manager_, + SetResourceState(resource, kAppId, remote_control::ResourceState::BUSY)); + + application_manager::MessagePtr result_msg; + EXPECT_CALL(*mock_service_, SendMessageToHMI(_)) + .WillOnce(SaveArg<0>(&result_msg)); + + // Act + remote_control::request_controller::MobileRequestPtr command = + CreateCommand(mobile_message); + command->Run(); + + // Assertions + EXPECT_EQ(kModuleId, app_extension->uid()); + EXPECT_EQ(application_manager::ProtocolVersion::kHMI, + result_msg->protocol_version()); + EXPECT_EQ(1, result_msg->correlation_id()); + EXPECT_EQ(application_manager::MessageType::kRequest, result_msg->type()); + const Json::Value hmi_request_params = + MessageHelper::StringToValue(result_msg->json_message()); + EXPECT_EQ(functional_modules::hmi_api::set_interior_vehicle_data, + hmi_request_params[json_keys::kMethod].asString()); + const Json::Value hmi_request_climate_control_data = + hmi_request_params[json_keys::kParams][message_params::kModuleData] + [message_params::kClimateControlData]; + EXPECT_EQ(2u, hmi_request_climate_control_data.size()); + const Json::Value hmi_request_module_data_fan_speed = + hmi_request_climate_control_data[message_params::kFanSpeed]; + const Json::Value hmi_request_module_data_defrost_zone = + hmi_request_climate_control_data[message_params::kDefrostZone]; + EXPECT_EQ("FRONT", hmi_request_module_data_defrost_zone.asString()); + EXPECT_EQ(10, hmi_request_module_data_fan_speed.asInt()); +} + +TEST_F( + SetInteriorVehicleDataRequestTest, + Execute_ValidWithSettableAndReadOnlyParams_ExpectCutReadOnlyAndResendToHMI) { + // Arrange + application_manager::MessagePtr mobile_message = CreateBasicMessage(); + mobile_message->set_json_message( + kValidMobileRequestWithSettableAndReadOnlyParams); + + // Expectations + EXPECT_CALL(*mock_service_, ValidateMessageBySchema(*mobile_message)) + .WillOnce(Return(application_manager::MessageValidationResult::SUCCESS)); + EXPECT_CALL(*mock_service_, CheckPolicyPermissions(mobile_message)) + .WillOnce(Return(mobile_apis::Result::eType::SUCCESS)); + + application_manager::AppExtensionPtr invalid_ext; + EXPECT_CALL(*mock_app_, QueryInterface(kModuleId)) + .WillOnce(Return(invalid_ext)) + .WillRepeatedly(Return(rc_app_extention_)); + + application_manager::AppExtensionPtr app_extension; + EXPECT_CALL(*mock_app_, AddExtension(_)) + .WillOnce(DoAll(SaveArg<0>(&app_extension), Return(true))); + EXPECT_CALL(*mock_service_, CheckAccess(_, _, _, _)) + .WillOnce(Return(application_manager::TypeAccess::kAllowed)); + EXPECT_CALL(*mock_service_, GetNextCorrelationID()) + .WillOnce(Return(kCorrelationId)); + + const std::string resource = "CLIMATE"; + + EXPECT_CALL(mock_allocation_manager_, IsResourceFree(resource)) + .WillOnce(Return(true)); + EXPECT_CALL(mock_allocation_manager_, AcquireResource(resource, kAppId)) + .WillOnce(Return(remote_control::AcquireResult::ALLOWED)); + EXPECT_CALL( + mock_allocation_manager_, + SetResourceState(resource, kAppId, remote_control::ResourceState::BUSY)); + + application_manager::MessagePtr result_msg; + EXPECT_CALL(*mock_service_, SendMessageToHMI(_)) + .WillOnce(SaveArg<0>(&result_msg)); + + // Act + remote_control::request_controller::MobileRequestPtr command = + CreateCommand(mobile_message); + command->Run(); + + // Assertions + EXPECT_EQ(kModuleId, app_extension->uid()); + EXPECT_EQ(application_manager::ProtocolVersion::kHMI, + result_msg->protocol_version()); + EXPECT_EQ(1, result_msg->correlation_id()); + EXPECT_EQ(application_manager::MessageType::kRequest, result_msg->type()); + const Json::Value hmi_request_params = + MessageHelper::StringToValue(result_msg->json_message()); + EXPECT_EQ(functional_modules::hmi_api::set_interior_vehicle_data, + hmi_request_params[json_keys::kMethod].asString()); + const Json::Value hmi_request_climate_control_data = + hmi_request_params[json_keys::kParams][message_params::kModuleData] + [message_params::kClimateControlData]; + EXPECT_EQ(2u, hmi_request_climate_control_data.size()); + const Json::Value hmi_request_module_data_fan_speed = + hmi_request_climate_control_data[message_params::kFanSpeed]; + const Json::Value hmi_request_module_data_defrost_zone = + hmi_request_climate_control_data[message_params::kDefrostZone]; + EXPECT_EQ("FRONT", hmi_request_module_data_defrost_zone.asString()); + EXPECT_EQ(10, hmi_request_module_data_fan_speed.asInt()); +} + +TEST_F(SetInteriorVehicleDataRequestTest, + Execute_ValidWithOnlyParamsReadOnly_ExpectResponseReadOnly) { + // Arrange + application_manager::MessagePtr mobile_message = CreateBasicMessage(); + mobile_message->set_json_message( + kValidMobileRequestWithoutSettableAndWithReadOnlyParams); + + // Expectations + EXPECT_CALL(*mock_service_, ValidateMessageBySchema(*mobile_message)) + .WillOnce(Return(application_manager::MessageValidationResult::SUCCESS)); + EXPECT_CALL(*mock_service_, CheckPolicyPermissions(mobile_message)) + .WillOnce(Return(mobile_apis::Result::eType::SUCCESS)); + + application_manager::AppExtensionPtr invalid_ext; + EXPECT_CALL(*mock_app_, QueryInterface(kModuleId)) + .WillOnce(Return(invalid_ext)) + .WillRepeatedly(Return(rc_app_extention_)); + + application_manager::AppExtensionPtr app_extension; + EXPECT_CALL(*mock_app_, AddExtension(_)) + .WillOnce(DoAll(SaveArg<0>(&app_extension), Return(true))); + EXPECT_CALL(*mock_service_, CheckAccess(_, _, _, _)) + .WillOnce(Return(application_manager::TypeAccess::kAllowed)); + EXPECT_CALL(*mock_service_, SendMessageToHMI(_)).Times(0); + + application_manager::MessagePtr result_msg; + EXPECT_CALL(mock_module_, SendResponseToMobile(_)) + .WillOnce(SaveArg<0>(&result_msg)); + + // Act + remote_control::request_controller::MobileRequestPtr command = + CreateCommand(mobile_message); + command->Run(); + + // Assertions + const Json::Value response_params = + MessageHelper::StringToValue(result_msg->json_message()); + EXPECT_FALSE(response_params[result_codes::kSuccess].asBool()); + EXPECT_EQ(result_codes::kReadOnly, + response_params[json_keys::kResultCode].asString()); +} + +TEST_F( + SetInteriorVehicleDataRequestTest, + Execute_MessageValidationFailed_ExpectMessageNotSentToHMI_AndFalseSentToMobile) { + // Arrange + application_manager::MessagePtr mobile_message = CreateBasicMessage(); + mobile_message->set_json_message(kInvalidMobileRequest); + + // Expectations + EXPECT_CALL(*mock_service_, ValidateMessageBySchema(*mobile_message)) + .WillOnce( + Return(application_manager::MessageValidationResult::INVALID_JSON)); + EXPECT_CALL(*mock_service_, SendMessageToHMI(_)).Times(0); + application_manager::MessagePtr result_msg; + EXPECT_CALL(mock_module_, SendResponseToMobile(_)) + .WillOnce(SaveArg<0>(&result_msg)); + + // Act + remote_control::request_controller::MobileRequestPtr command = + CreateCommand(mobile_message); + command->Run(); + + // Assertions + const Json::Value response_params = + MessageHelper::StringToValue(result_msg->json_message()); + EXPECT_FALSE(response_params[result_codes::kSuccess].asBool()); + EXPECT_EQ(result_codes::kInvalidData, + response_params[json_keys::kResultCode].asString()); +} + +TEST_F(SetInteriorVehicleDataRequestTest, + OnEvent_ValidHmiResponse_ExpectSuccessfulResponseSentToMobile) { + // Arrange + application_manager::MessagePtr mobile_message = CreateBasicMessage(); + mobile_message->set_json_message(kValidMobileRequestWithOnlySettableParams); + + application_manager::MessagePtr hmi_message = CreateBasicMessage(); + hmi_message->set_json_message(kValidHmiResponse); + hmi_message->set_message_type(application_manager::MessageType::kResponse); + + // Expectations + EXPECT_CALL(*mock_service_, ValidateMessageBySchema(*hmi_message)) + .WillOnce(Return(application_manager::MessageValidationResult::SUCCESS)); + application_manager::MessagePtr result_msg; + EXPECT_CALL(mock_module_, SendResponseToMobile(_)) + .WillOnce(SaveArg<0>(&result_msg)); + + // Act + remote_control::RCPluginEvent event( + hmi_message, functional_modules::hmi_api::set_interior_vehicle_data); + remote_control::request_controller::MobileRequestPtr command = + CreateCommand(mobile_message); + command->on_event(event); + + // Assertions + const Json::Value response_params = + MessageHelper::StringToValue(result_msg->json_message()); + EXPECT_TRUE(response_params[json_keys::kSuccess].asBool()); + EXPECT_EQ(result_codes::kSuccess, + response_params[json_keys::kResultCode].asString()); +} + +TEST_F(SetInteriorVehicleDataRequestTest, + OnEvent_InvalidHmiResponse_ExpectGenericErrorResponseSentToMobile) { + // Arrange + application_manager::MessagePtr mobile_message = CreateBasicMessage(); + mobile_message->set_json_message(kValidMobileRequestWithOnlySettableParams); + application_manager::MessagePtr hmi_message = CreateBasicMessage(); + hmi_message->set_json_message(kInvalidHmiResponse); + hmi_message->set_message_type(application_manager::MessageType::kResponse); + + // Expectations + EXPECT_CALL(*mock_service_, ValidateMessageBySchema(*hmi_message)) + .WillOnce( + Return(application_manager::MessageValidationResult::INVALID_JSON)); + application_manager::MessagePtr result_msg; + EXPECT_CALL(mock_module_, SendResponseToMobile(_)) + .WillOnce(SaveArg<0>(&result_msg)); + + // Act + remote_control::request_controller::MobileRequestPtr command = + CreateCommand(mobile_message); + remote_control::RCPluginEvent event( + hmi_message, functional_modules::hmi_api::set_interior_vehicle_data); + command->on_event(event); + const Json::Value response_params = + MessageHelper::StringToValue(result_msg->json_message()); + EXPECT_FALSE(response_params[json_keys::kSuccess].asBool()); + EXPECT_EQ(result_codes::kGenericError, + response_params[json_keys::kResultCode].asString()); + const Json::Value hmi_response = + MessageHelper::StringToValue(hmi_message->json_message()); + EXPECT_EQ(hmi_response[json_keys::kInfo].asString(), + response_params[json_keys::kInfo].asString()); +} + +} // namespace set_interior_vehicle_data_request_test +} // namespace remote_control_test +} // namespace components +} // namespace test diff --git a/src/components/remote_control/test/include/mock_application.h b/src/components/remote_control/test/include/mock_application.h new file mode 100644 index 0000000000..d466ba9ca5 --- /dev/null +++ b/src/components/remote_control/test/include/mock_application.h @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2017, 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_REMOTE_CONTROL_TEST_INCLUDE_MOCK_APPLICATION_H_ +#define SRC_COMPONENTS_REMOTE_CONTROL_TEST_INCLUDE_MOCK_APPLICATION_H_ + +#include <string> + +#include <string> +#include "gmock/gmock.h" +#include "application_manager/application.h" +#include "interfaces/MOBILE_API.h" +#include "application_manager/app_extension.h" +#include "smart_objects/smart_object.h" +#include "utils/custom_string.h" +#include "application_manager/usage_statistics.h" + +namespace test { +namespace components { +namespace remote_control_test { + +namespace am = application_manager; +namespace mobile_api = mobile_apis; +namespace custom_str = utils::custom_string; + +namespace custom_str = utils::custom_string; +class MockApplication : public ::application_manager::Application { + public: + MockApplication() {} + MOCK_CONST_METHOD0(active_message, const smart_objects::SmartObject*()); + MOCK_CONST_METHOD0(curHash, const std::string&()); + MOCK_METHOD0(UpdateHash, void()); + MOCK_CONST_METHOD0(flag_sending_hash_change_after_awake, bool()); + MOCK_METHOD1(set_flag_sending_hash_change_after_awake, void(bool flag)); + MOCK_CONST_METHOD0(is_application_data_changed, bool()); + MOCK_METHOD1(set_is_application_data_changed, + void(bool state_application_data)); + MOCK_METHOD0(CloseActiveMessage, void()); + MOCK_CONST_METHOD0(IsFullscreen, bool()); + MOCK_METHOD0(ChangeSupportingAppHMIType, void()); + MOCK_CONST_METHOD0(is_navi, bool()); + MOCK_METHOD1(set_is_navi, void(bool allow)); + MOCK_CONST_METHOD0(video_streaming_approved, bool()); + MOCK_METHOD1(set_video_streaming_approved, void(bool state)); + MOCK_CONST_METHOD0(audio_streaming_approved, bool()); + MOCK_METHOD1(set_audio_streaming_approved, void(bool state)); + MOCK_CONST_METHOD0(video_streaming_allowed, bool()); + MOCK_METHOD1(set_video_streaming_allowed, void(bool state)); + MOCK_CONST_METHOD0(audio_streaming_allowed, bool()); + MOCK_METHOD1(set_audio_streaming_allowed, void(bool state)); + MOCK_CONST_METHOD0(is_audio, bool()); + MOCK_METHOD1(StartStreaming, + void(protocol_handler::ServiceType service_type)); + MOCK_METHOD1(StopStreaming, void(protocol_handler::ServiceType service_type)); + MOCK_METHOD1(StopStreamingForce, + void(protocol_handler::ServiceType service_type)); + MOCK_METHOD1(SuspendStreaming, + void(protocol_handler::ServiceType service_type)); + MOCK_METHOD1(WakeUpStreaming, + void(protocol_handler::ServiceType service_type)); + MOCK_CONST_METHOD0(is_voice_communication_supported, bool()); + MOCK_METHOD1(set_voice_communication_supported, + void(bool is_voice_communication_supported)); + MOCK_CONST_METHOD0(app_allowed, bool()); + MOCK_CONST_METHOD0(has_been_activated, bool()); + MOCK_METHOD1(set_activated, bool(bool is_active)); + MOCK_CONST_METHOD0(version, const ::application_manager::Version&()); + MOCK_METHOD1(set_hmi_application_id, void(uint32_t hmi_app_id)); + MOCK_CONST_METHOD0(hmi_app_id, uint32_t()); + MOCK_CONST_METHOD0(name, const custom_str::CustomString&()); + MOCK_METHOD1(set_folder_name, void(const std::string& folder_name)); + MOCK_CONST_METHOD0(folder_name, const std::string()); + MOCK_CONST_METHOD0(is_media_application, bool()); + MOCK_CONST_METHOD0(hmi_level, const mobile_apis::HMILevel::eType()); + MOCK_CONST_METHOD0(put_file_in_none_count, const uint32_t()); + MOCK_CONST_METHOD0(delete_file_in_none_count, const uint32_t()); + MOCK_CONST_METHOD0(list_files_in_none_count, const uint32_t()); + MOCK_CONST_METHOD0(system_context, const mobile_apis::SystemContext::eType()); + MOCK_CONST_METHOD0(audio_streaming_state, + const mobile_apis::AudioStreamingState::eType()); + MOCK_CONST_METHOD0(app_icon_path, const std::string&()); + MOCK_CONST_METHOD0(device, connection_handler::DeviceHandle()); + MOCK_CONST_METHOD0(CurrentHmiState, const application_manager::HmiStatePtr()); + MOCK_CONST_METHOD0(RegularHmiState, const application_manager::HmiStatePtr()); + MOCK_CONST_METHOD0(PostponedHmiState, + const application_manager::HmiStatePtr()); + MOCK_METHOD1(set_tts_properties_in_none, void(bool active)); + MOCK_METHOD0(tts_properties_in_none, bool()); + MOCK_METHOD1(set_tts_properties_in_full, void(bool active)); + MOCK_METHOD0(tts_properties_in_full, bool()); + MOCK_METHOD1(set_version, + void(const ::application_manager::Version& version)); + MOCK_METHOD1(set_name, void(const custom_str::CustomString& name)); + MOCK_METHOD1(set_is_media_application, void(bool is_media)); + MOCK_METHOD0(increment_put_file_in_none_count, void()); + MOCK_METHOD0(increment_delete_file_in_none_count, void()); + MOCK_METHOD0(increment_list_files_in_none_count, void()); + MOCK_METHOD1(set_app_icon_path, bool(const std::string& file_name)); + MOCK_METHOD1(set_app_allowed, void(const bool allowed)); + MOCK_METHOD1(set_device, void(connection_handler::DeviceHandle device)); + MOCK_CONST_METHOD0(get_grammar_id, uint32_t()); + MOCK_METHOD1(set_grammar_id, void(uint32_t value)); + MOCK_METHOD1( + set_protocol_version, + void(const ::application_manager::ProtocolVersion& protocol_version)); + MOCK_CONST_METHOD0(protocol_version, + ::application_manager::ProtocolVersion()); + MOCK_METHOD1(set_is_resuming, void(bool)); + MOCK_CONST_METHOD0(is_resuming, bool()); + MOCK_METHOD1(AddFile, bool(const ::application_manager::AppFile& file)); + MOCK_CONST_METHOD0(getAppFiles, const ::application_manager::AppFilesMap&()); + MOCK_METHOD1(UpdateFile, bool(const ::application_manager::AppFile& file)); + MOCK_METHOD1(DeleteFile, bool(const std::string& file_name)); + MOCK_METHOD1( + GetFile, + const ::application_manager::AppFile*(const std::string& file_name)); + MOCK_METHOD1(SubscribeToButton, + bool(mobile_apis::ButtonName::eType btn_name)); + MOCK_METHOD1(IsSubscribedToButton, + bool(mobile_apis::ButtonName::eType btn_name)); + MOCK_METHOD1(UnsubscribeFromButton, + bool(mobile_apis::ButtonName::eType btn_name)); + MOCK_METHOD1(SubscribeToIVI, bool(uint32_t vehicle_info_type)); + MOCK_CONST_METHOD1(IsSubscribedToIVI, bool(uint32_t vehicle_info_type)); + MOCK_METHOD1(UnsubscribeFromIVI, bool(uint32_t vehicle_info_type)); + MOCK_METHOD0(ResetDataInNone, void()); + MOCK_METHOD2(AreCommandLimitsExceeded, + bool(mobile_apis::FunctionID::eType cmd_id, + ::application_manager::TLimitSource source)); + MOCK_METHOD0(usage_report, ::application_manager::UsageStatistics&()); + MOCK_METHOD1(SetRegularState, void(::application_manager::HmiStatePtr state)); + MOCK_METHOD1(SetPostponedState, + void(::application_manager::HmiStatePtr state)); + MOCK_METHOD0(RemovePostponedState, void()); + MOCK_METHOD1(AddHMIState, void(::application_manager::HmiStatePtr state)); + MOCK_METHOD1(RemoveHMIState, + void(::application_manager::HmiState::StateID state_id)); + MOCK_METHOD2(SubscribeToSoftButtons, + void(int32_t cmd_id, + const ::application_manager::SoftButtonID& softbuttons_id)); + MOCK_METHOD1(IsSubscribedToSoftButton, bool(const uint32_t softbutton_id)); + MOCK_METHOD1(UnsubscribeFromSoftButtons, void(int32_t cmd_id)); + MOCK_CONST_METHOD0(IsAudioApplication, bool()); + MOCK_METHOD0(LoadPersistentFiles, void()); + // InitialApplicationData methods + MOCK_CONST_METHOD0(app_types, const smart_objects::SmartObject*()); + MOCK_CONST_METHOD0(vr_synonyms, const smart_objects::SmartObject*()); + MOCK_CONST_METHOD0(policy_app_id, std::string()); + MOCK_CONST_METHOD0(tts_name, const smart_objects::SmartObject*()); + MOCK_CONST_METHOD0(ngn_media_screen_name, + const smart_objects::SmartObject*()); + MOCK_CONST_METHOD0(language, const mobile_apis::Language::eType&()); + MOCK_CONST_METHOD0(ui_language, const mobile_apis::Language::eType&()); + MOCK_METHOD1(set_app_types, + void(const smart_objects::SmartObject& app_types)); + MOCK_METHOD1(set_vr_synonyms, + void(const smart_objects::SmartObject& vr_synonyms)); + MOCK_METHOD1(set_policy_app_id, void(const std::string& policy_app_id)); + MOCK_METHOD1(set_tts_name, void(const smart_objects::SmartObject& tts_name)); + MOCK_METHOD1(set_ngn_media_screen_name, + void(const smart_objects::SmartObject& ngn_name)); + MOCK_METHOD1(set_language, + void(const mobile_apis::Language::eType& language)); + MOCK_METHOD1(set_ui_language, + void(const mobile_apis::Language::eType& ui_language)); + // DynamicApplicationData methods + MOCK_CONST_METHOD0(help_prompt, const smart_objects::SmartObject*()); + MOCK_CONST_METHOD0(timeout_prompt, const smart_objects::SmartObject*()); + MOCK_CONST_METHOD0(vr_help_title, const smart_objects::SmartObject*()); + MOCK_CONST_METHOD0(vr_help, const smart_objects::SmartObject*()); + MOCK_CONST_METHOD0(tbt_state, const mobile_apis::TBTState::eType&()); + MOCK_CONST_METHOD0(show_command, const smart_objects::SmartObject*()); + MOCK_CONST_METHOD0(tbt_show_command, const smart_objects::SmartObject*()); + MOCK_CONST_METHOD0( + SubscribedButtons, + DataAccessor< ::application_manager::ButtonSubscriptions>()); + MOCK_CONST_METHOD0( + SubscribedIVI, + DataAccessor< ::application_manager::VehicleInfoSubscriptions>()); + MOCK_CONST_METHOD0(keyboard_props, const smart_objects::SmartObject*()); + MOCK_CONST_METHOD0(menu_title, const smart_objects::SmartObject*()); + MOCK_CONST_METHOD0(menu_icon, const smart_objects::SmartObject*()); + MOCK_METHOD1(load_global_properties, + void(const smart_objects::SmartObject& so)); + MOCK_METHOD1(set_help_prompt, + void(const smart_objects::SmartObject& help_prompt)); + MOCK_METHOD1(set_timeout_prompt, + void(const smart_objects::SmartObject& timeout_prompt)); + MOCK_METHOD1(set_vr_help_title, + void(const smart_objects::SmartObject& vr_help_title)); + MOCK_METHOD0(reset_vr_help_title, void()); + MOCK_METHOD1(set_vr_help, void(const smart_objects::SmartObject& vr_help)); + MOCK_METHOD0(reset_vr_help, void()); + MOCK_METHOD1(set_tbt_state, + void(const mobile_apis::TBTState::eType& tbt_state)); + MOCK_METHOD1(set_show_command, + void(const smart_objects::SmartObject& show_command)); + MOCK_METHOD1(set_tbt_show_command, + void(const smart_objects::SmartObject& tbt_show)); + MOCK_METHOD1(set_keyboard_props, + void(const smart_objects::SmartObject& keyboard_props)); + MOCK_METHOD1(set_menu_title, + void(const smart_objects::SmartObject& menu_title)); + MOCK_METHOD1(set_menu_icon, + void(const smart_objects::SmartObject& menu_icon)); + MOCK_CONST_METHOD0(audio_stream_retry_number, uint32_t()); + MOCK_METHOD1(set_audio_stream_retry_number, + void(const uint32_t& audio_stream_retry_number)); + MOCK_CONST_METHOD0(video_stream_retry_number, uint32_t()); + MOCK_METHOD1(set_video_stream_retry_number, + void(const uint32_t& video_stream_retry_number)); + MOCK_METHOD2(AddCommand, + void(uint32_t cmd_id, + const smart_objects::SmartObject& command)); + MOCK_METHOD1(RemoveCommand, void(uint32_t cmd_id)); + MOCK_METHOD1(FindCommand, smart_objects::SmartObject*(uint32_t cmd_id)); + MOCK_METHOD2(AddSubMenu, + void(uint32_t menu_id, const smart_objects::SmartObject& menu)); + MOCK_METHOD1(RemoveSubMenu, void(uint32_t menu_id)); + MOCK_CONST_METHOD1(FindSubMenu, + smart_objects::SmartObject*(uint32_t menu_id)); + MOCK_METHOD1(IsSubMenuNameAlreadyExist, bool(const std::string& name)); + MOCK_METHOD2(AddChoiceSet, + void(uint32_t choice_set_id, + const smart_objects::SmartObject& choice_set)); + MOCK_METHOD1(RemoveChoiceSet, void(uint32_t choice_set_id)); + MOCK_METHOD1(FindChoiceSet, + smart_objects::SmartObject*(uint32_t choice_set_id)); + MOCK_METHOD3(AddPerformInteractionChoiceSet, + void(uint32_t correlation_id, + uint32_t choice_set_id, + const smart_objects::SmartObject& choice_set)); + MOCK_METHOD1(DeletePerformInteractionChoiceSet, + void(uint32_t correlation_id)); + MOCK_CONST_METHOD0( + performinteraction_choice_set_map, + DataAccessor< ::application_manager::PerformChoiceSetMap>()); + MOCK_CONST_METHOD0(commands_map, + DataAccessor< ::application_manager::CommandsMap>()); + MOCK_CONST_METHOD0(sub_menu_map, + DataAccessor< ::application_manager::SubMenuMap>()); + MOCK_CONST_METHOD0(choice_set_map, + DataAccessor< ::application_manager::ChoiceSetMap>()); + MOCK_METHOD1(set_perform_interaction_active, void(uint32_t active)); + MOCK_CONST_METHOD0(is_perform_interaction_active, uint32_t()); + MOCK_METHOD1(set_perform_interaction_mode, void(int32_t mode)); + MOCK_CONST_METHOD0(perform_interaction_mode, int32_t()); + MOCK_METHOD1(set_perform_interaction_layout, + void(mobile_apis::LayoutMode::eType mode)); + MOCK_CONST_METHOD0(perform_interaction_layout, + mobile_apis::LayoutMode::eType()); + MOCK_METHOD1(set_reset_global_properties_active, void(bool active)); + MOCK_CONST_METHOD0(is_reset_global_properties_active, bool()); + MOCK_CONST_METHOD0(app_id, uint32_t()); + MOCK_CONST_METHOD0(mac_address, const std::string&()); + MOCK_CONST_METHOD0(bundle_id, const std::string&()); + MOCK_METHOD1(set_bundle_id, void(const std::string& bundle_id)); + MOCK_METHOD0(GetAvailableDiskSpace, uint32_t()); + + MOCK_METHOD1(set_mobile_app_id, void(const std::string& policy_app_id)); + MOCK_CONST_METHOD0(is_foreground, bool()); + MOCK_METHOD1(set_foreground, void(bool is_foreground)); + MOCK_CONST_METHOD0(IsRegistered, bool()); + MOCK_CONST_METHOD0(SchemaUrl, std::string()); + MOCK_CONST_METHOD0(PackageName, std::string()); + +#ifdef SDL_REMOTE_CONTROL + MOCK_METHOD1( + set_system_context, + void(const application_manager::mobile_api::SystemContext::eType&)); + MOCK_METHOD1( + set_audio_streaming_state, + void(const application_manager::mobile_api::AudioStreamingState::eType& + state)); + MOCK_METHOD1(IsSubscribedToInteriorVehicleData, + bool(smart_objects::SmartObject module)); + MOCK_METHOD1(SubscribeToInteriorVehicleData, + bool(smart_objects::SmartObject module)); + MOCK_METHOD1(UnsubscribeFromInteriorVehicleData, + bool(smart_objects::SmartObject module)); + MOCK_METHOD1( + set_hmi_level, + void(const application_manager::mobile_api::HMILevel::eType& hmi_level)); + MOCK_METHOD1(QueryInterface, + application_manager::AppExtensionPtr( + application_manager::AppExtensionUID uid)); + MOCK_METHOD1(AddExtension, + bool(application_manager::AppExtensionPtr extention)); + MOCK_METHOD1(RemoveExtension, bool(application_manager::AppExtensionUID uid)); + MOCK_METHOD0(RemoveExtensions, void()); + MOCK_CONST_METHOD0(SubscribesIVI, const std::set<uint32_t>&()); + +#endif // SDL_REMOTE_CONTROL +}; + +} // namespace remote_control_test +} // namespace components +} // namespace test + +#endif // SRC_COMPONENTS_REMOTE_CONTROL_TEST_INCLUDE_MOCK_APPLICATION_H_ diff --git a/src/components/remote_control/test/include/mock_remote_control_plugin.h b/src/components/remote_control/test/include/mock_remote_control_plugin.h new file mode 100644 index 0000000000..fccaac2828 --- /dev/null +++ b/src/components/remote_control/test/include/mock_remote_control_plugin.h @@ -0,0 +1,55 @@ +#ifndef SRC_COMPONENTS_REMOTE_CONTROL_TEST_INCLUDE_MOCK_REMOTE_CONTROL_PLUGIN_H_ +#define SRC_COMPONENTS_REMOTE_CONTROL_TEST_INCLUDE_MOCK_REMOTE_CONTROL_PLUGIN_H_ + +#include <stdint.h> +#include "remote_control/remote_plugin_interface.h" +#include "remote_control/resource_allocation_manager.h" +#include "application_manager/message.h" +#include "mock_application.h" + +namespace test { +namespace components { +namespace remote_control_test { + +class RCAppExtension; +typedef utils::SharedPtr<RCAppExtension> RCAppExtensionPtr; + +class MockRemotePluginInterface : public remote_control::RemotePluginInterface { + public: + MOCK_CONST_METHOD0(GetPluginInfo, functional_modules::PluginInfo()); + MOCK_METHOD1( + ProcessMessage, + functional_modules::ProcessResult(application_manager::MessagePtr msg)); + MOCK_METHOD1( + ProcessHMIMessage, + functional_modules::ProcessResult(application_manager::MessagePtr msg)); + MOCK_METHOD1(SendResponseToMobile, void(application_manager::MessagePtr msg)); + MOCK_METHOD1(SendTimeoutResponseToMobile, + void(application_manager::MessagePtr msg)); + MOCK_METHOD1(RemoveAppExtension, void(uint32_t app_id)); + MOCK_METHOD1(IsAppForPlugin, + bool(application_manager::ApplicationSharedPtr app)); + MOCK_METHOD2(OnAppHMILevelChanged, + void(application_manager::ApplicationSharedPtr app, + mobile_apis::HMILevel::eType old_level)); + MOCK_METHOD2(CanAppChangeHMILevel, + bool(application_manager::ApplicationSharedPtr app, + mobile_apis::HMILevel::eType new_level)); + MOCK_METHOD1(OnDeviceRemoved, + void(const connection_handler::DeviceHandle& device)); + MOCK_METHOD1(OnUnregisterApplication, void(const uint32_t app_id)); + MOCK_METHOD1(SendHmiStatusNotification, + void(application_manager::ApplicationSharedPtr app)); + MOCK_METHOD0(event_dispatcher, RCPluginEventDispatcher&()); + MOCK_METHOD0(RemoveAppExtensions, void()); + MOCK_METHOD0(service, application_manager::ServicePtr()); + MOCK_CONST_METHOD0(GetModuleID, functional_modules::ModuleID()); + MOCK_METHOD0(resource_allocation_manager, + remote_control::ResourceAllocationManager&()); +}; + +} // namespace remote_control_test +} // namespace components +} // namespace test + +#endif // SRC_COMPONENTS_REMOTE_CONTROL_TEST_INCLUDE_MOCK_REMOTE_CONTROL_PLUGIN_H_ diff --git a/src/components/remote_control/test/include/mock_resource_allocation_manager.h b/src/components/remote_control/test/include/mock_resource_allocation_manager.h new file mode 100644 index 0000000000..5a83410932 --- /dev/null +++ b/src/components/remote_control/test/include/mock_resource_allocation_manager.h @@ -0,0 +1,47 @@ +#ifndef SRC_COMPONENTS_REMOTE_CONTROL_TEST_INCLUDE_MOCK_RESOURCE_ALLOCATION_MANAGER_H_ +#define SRC_COMPONENTS_REMOTE_CONTROL_TEST_INCLUDE_MOCK_RESOURCE_ALLOCATION_MANAGER_H_ + +#include "gmock/gmock.h" +#include "remote_control/resource_allocation_manager.h" + +namespace test { +namespace components { +namespace remote_control_test { + +class MockAskDriverCallBack : public remote_control::AskDriverCallBack { + public: + MOCK_METHOD1( + on_event, + void(const rc_event_engine::Event<application_manager::MessagePtr, + std::string>& event)); +}; + +class MockResourceAllocationManager + : public remote_control::ResourceAllocationManager { + public: + MOCK_METHOD2(AcquireResource, + remote_control::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(AskDriver, + void(const std::string& module_type, + const uint32_t app_id, + remote_control::AskDriverCallBackPtr callback)); + MOCK_METHOD1(SetAccessMode, + void(const hmi_apis::Common_RCAccessMode::eType access_mode)); + MOCK_METHOD3(SetResourceState, + void(const std::string& module_type, + const uint32_t app_id, + const remote_control::ResourceState::eType state)); + MOCK_METHOD1(OnUnregisterApplication, void(const uint32_t app_id)); + MOCK_CONST_METHOD1(IsResourceFree, bool(const std::string& module_type)); +}; + +} // namespace remote_control_test +} // namespace components +} // namespace test + +#endif // SRC_COMPONENTS_REMOTE_CONTROL_TEST_INCLUDE_MOCK_RESOURCE_ALLOCATION_MANAGER_H_ diff --git a/src/components/remote_control/test/lc.awk b/src/components/remote_control/test/lc.awk new file mode 100755 index 0000000000..6bc2331c5d --- /dev/null +++ b/src/components/remote_control/test/lc.awk @@ -0,0 +1,170 @@ +#!/usr/bin/awk +#---------------------------------------------------------------------------- +# +# Awk program to count lines of code in C source files. +# Has logic to keep track of comments as well. +# +# Assumptions/limitations: +# - Does *not* undestand inline asm - counted as source lines! +# - Does not include blank lines in the average +# - Assumes no code on a line after a "*/" - poss change this? +# - Counts *any* non-comment line as code eg { or } by themselves, etc +# - depends on hash order of awk - this is risky! (See END code) +# - Presently, the output redirects quite badly - command line option? +# - Overflow if any number >32768 - mawk limitation. +# +# Paul Hubbard phubbard@computer.org written 5/1993 +# Apache 2.0 license - enjoy! + +#---------------------------------------------------------------------------- + +BEGIN { # Init vars at startup + print "" +} + +#---------------------------------------------------------------------------- +# Main loop + +# Print filename on read of first record +FNR == 1 { + printf("\r ") + printf("\rReading file: %s", FILENAME) + comments[FILENAME] = 0 + lines[FILENAME] = 0 + fname[FILENAME] = FILENAME + raw_linecount[FILENAME] = 0 + in_comment = 0 +} + +# Increment line count as first thing done +raw_linecount[FILENAME]++{} + +# Test for "//" in the first record +($1 ~ /\/\//) { # single line comment - skip to next rec + comments[FILENAME]++ + next +} + +# Test for "//" in rest of the record (comment after code - counts as both) +/\/\// { + in_comment = 0 + comments[FILENAME]++ # lines count will be incremented below +} + +# This wierd "/\/\*/" junk is awk-ish for the string "/*" - aka comment begin +/\/\*/ { # Begin multi-line comment + if($1 ~ /\/\*/) { # Comment is first record - no code here! + in_comment = 1 + } + else { # "/*" type comment AFTER code - is both + in_comment = 0 + comments[FILENAME]++ # Lines array inc below + } +} + +# And this is "*/" aka comment end +/\*\// { # End of multi-line comment + if(in_comment = 1){ # Multi line comment - can increment + comments[FILENAME]++ + in_comment = 0 # Reset Boolean + next # Assumes no code after "*/" !! + } +} + +# Test for empty lines and skip +(length($0) == 0) {next} + +(in_comment > 0) {comments[FILENAME]++} +(in_comment == 0) {lines[FILENAME]++} + +#---------------------------------------------------------------------------- +# Termination code +END { + + # Kluge clear EOL + printf("\r \n") + + CCT = LCT = 0 # init totals + idx = 0 # init pseudo-index + maxlen = 0 + name_len = 0 + + # Walk thru file names array to get maxlen + for(i in fname) { + if((length(fname[i])) > maxlen) {maxlen = length(fname[i])} + } + + maxlen++ + name_len = maxlen # save maxlen for formatting header + if(name_len < 4) {name_len = 4} + + # Build formatting string for sprintf; eg "%15s " to beautify output + spf_str = "%" + maxlen = maxlen "s " # Convert number to string and add trailer + spf_str = spf_str maxlen# Add pieces together to build format str + + # Walk thru file names array + for(i in fname) { + output[idx] = sprintf(spf_str, fname[i]) + idx++ + } + + idx = 0 + + # Walk thru lines array + for(i in lines) { + tempstr = sprintf("%5d", lines[i]) + output[idx] = output[idx] tempstr + LCT += lines[i] + idx++ + } + + idx = 0 + + # Walk thru comments array + for(i in comments) { + tempstr = sprintf("%11d", comments[i]) + output[idx] = output[idx] tempstr + CCT += comments[i] + idx++ + } + + idx = 0 + raw_lc = 0 + + # Walk thru array of raw line counts (includes empty lines) + for(i in raw_linecount) { + tempstr = sprintf("%12d", raw_linecount[i]) + output[idx] = output[idx] tempstr + idx++ + raw_lc += raw_linecount[i] + } + + # Print header + for(i = 0; i < (name_len - 4); i++) {printf"-"} + str = "File---Code---Comments---Raw Lines" + printf(str) + + j = length(str) + (name_len - 4) + + # Finish off the header line + printf("\n") + for(i = j; i < 80; i++) {printf("-")} + + # Dump constructed lines of data + for(i = 0; i < idx; i++) {print output[i]} + + # Print trailer line + for(i = 0; i < 80; i++) {printf("-")} + + #Dump totals + printf("\n Total code: %d", LCT) + printf("\n Total comments: %d", CCT) + printf("\n Total raw lines: %d\n", raw_lc) + + if((LCT + CCT) > 0) { + printf("Comment percentage: %f", (CCT / (LCT + CCT)) * 100) + } + + print "" +}
\ No newline at end of file diff --git a/src/components/remote_control/test/run_calc_comments.sh b/src/components/remote_control/test/run_calc_comments.sh new file mode 100755 index 0000000000..bd295a6ce4 --- /dev/null +++ b/src/components/remote_control/test/run_calc_comments.sh @@ -0,0 +1,38 @@ +#!/bin/sh +# Script to call awk line-counting script + +show_help() { + echo " + Usage: ./run_calc_comments.sh [OPTION]... + Counts comment percentage in source files.\n + Arguments: + -h displays help message and exits + -d PATH_TO_DIRECTORY specifies path to directory with source files.\ + Script applies counting to all files in directory recursively. \ + Default is current directory. + -f FILE_FORMAT specifies file extension or other format of file names. \ + Script applies counting to all files with specified file name recursively in directory. \ + Default is *.h.\n + Example: + ./run_calc_comments.sh -f *.h -d ../../../src/components/can_cooperation/\n" +} + + +OPTIND=1 +input_directory="." +file_type="*.h" + +while getopts "hd:f:" opt; do + case "$opt" in + h) + show_help + exit 0 + ;; + d) input_directory=$OPTARG + ;; + f) file_type=$OPTARG + ;; + esac +done + +find $input_directory -name "$file_type" -printf "%p " | xargs awk -f ./lc.awk
\ No newline at end of file diff --git a/src/components/remote_control/test/run_mem_check.sh b/src/components/remote_control/test/run_mem_check.sh new file mode 100755 index 0000000000..ce6f128263 --- /dev/null +++ b/src/components/remote_control/test/run_mem_check.sh @@ -0,0 +1,94 @@ +#!/bin/bash +# Srcipt to call valgring check + +OPTIND=1 +only_install=0 +install_quietly=0 +command_name="valgrind" + +show_help() { + echo " + Usage: ./run_mem_check.sh [OPTION]... + Runs valgring against binary. + Arguments: + -h displays help message and exits + -b specifies binary to be tested. Default is can_cooperation_test. + -q install missing software without prompting. Default is false. + -i only install missing software and exit. No prompts will be issued. + -x <file> save XML output to file. Only for memcheck tool. + -t <name> module tool name for analyse (memcheck - default, callgrind, massif and etc.) + -f <filter> to run selected tests (see examples below) + + GUI tools which you can use to analyse: + Valkyrie - memcheck + KCachegrind- callgrind + Massif-Visualizer - massif + + Example: + ./run_mem_check.sh -b ./test_can_module + ./run_mem_check.sh -t callgrind + ./run_mem_check.sh -x output.xml + ./run_mem_check.sh -f CanTcpConnectionTest* + ./run_mem_check.sh -f *WriteData +" +} + +installation_prompt() { + read -n 1 -p "Would you like to install $command_name? [Y/n] " is_ok + echo + if [ "$is_ok" == "y" -o "$is_ok" == "Y" ] + then + sudo apt-get install $command_name + else + echo "$command_name will no be installed. Quiting." + exit 0 + fi +} + +install_if_not() { + if command -v $command_name >/dev/null 2>&1; then + echo "Run $command_name" + else + echo "Installation of $command_name is required." + if [ $install_quietly -eq 1 ]; then + sudo apt-get install $command_name + else + installation_prompt + fi + fi +} + +binary_test="./can_cooperation_test" + +tool_name=memcheck +while getopts "t:x:hqib:f:" opt; do + case "$opt" in + h) + show_help + exit 0 + ;; + q) install_quietly=1 + ;; + i) only_install=1 + install_quietly=1 + install_if_not + exit 0 + ;; + b) binary_test=$OPTARG + ;; + x) xml_report="--xml=yes --xml-file=$OPTARG" + ;; + t) tool_name=$OPTARG + ;; + f) gtest_filter="--gtest_filter=$OPTARG" + ;; + esac +done + +install_if_not + +if [ "$tool_name" == "memcheck" ]; then + params="--leak-check=full --leak-check-heuristics=all --show-leak-kinds=all" +fi + +$command_name --tool=$tool_name $params $xml_report $binary_test $gtest_filter diff --git a/src/components/remote_control/test/setup_rsdl.sh b/src/components/remote_control/test/setup_rsdl.sh new file mode 100755 index 0000000000..b1d9082bcd --- /dev/null +++ b/src/components/remote_control/test/setup_rsdl.sh @@ -0,0 +1,160 @@ +#!/bin/bash + +show_help() { + echo " + Usage: ./setup_rsdl.sh [OPTION]... + Runs installers to setup environment. + Arguments: + -h displays help message and exits + -b Install basic packages: cmake; subversion; git; g++; sqlite. + -B Install BlueTooth related packages: libbluetooth3 libbluetooth-dev and bluez + -W Install WiFi additional packages: avahi + -U Install USB additional packages: libudev; sets USB permissions (recommended) + -A Install additional packages: chromium browser for HTML HMI; SSL for security feature. + -L Install lua packages: lua5.2 + -a Install all packages + -i Do not specify packages; prompt on each packages need to be installed + + Example: + ./setup_rsdl.sh -b + ./setup_rsdl.sh -a + ./setup_rsdl.sh -bBWUA +" +} + +install_base=false; +bt_install=false; +wifi_additional=false; +usb_install=false; +additional_install=false; +interact_mode=false; +lua_install=false; + +while getopts "hbBWUALai" opt; do + case "$opt" in + h) + show_help + exit 0 + ;; + b) install_base=true + ;; + B) bt_install=true + ;; + W) wifi_additional=true + ;; + U) usb_install=true + ;; + A) additional_install=true + ;; + L) lua_install=true + ;; + a) install_base=true + bt_install=true + wifi_additional=true + usb_install=true + additional_install=true + lua_install=true + ;; + i) interact_mode=true + install_base=true + bt_install=true + wifi_additional=true + usb_install=true + additional_install=true + lua_install=true + ;; + esac +done + +#apt-get install wrapper function +function apt-install() { + if [ -z "$1" ]; then + return 1; + fi + if ${interact_mode}; then + APT_ARGS="" + else + APT_ARGS="--yes --force-yes" + fi + set -x #Show install command to user" + apt-get install ${APT_ARGS} $* + set +x +} + +if ${install_base}; then + CMAKE_BUILD_SYSTEM="cmake" + SUBVERSION="subversion" + GIT="git" + GNU_CPP_COMPILER="g++" + LIB_SQLITE="libsqlite3-dev" +else + CMAKE_BUILD_SYSTEM="" + SUBVERSION="" + GIT="" + GNU_CPP_COMPILER="" + LIB_SQLITE="" +fi + +if ${bt_install}; then + BLUEZ_PROTOCOL_STACK="libbluetooth3 libbluetooth-dev" + BLUEZ_TOOLS="bluez-tools" +else + BLUEZ_PROTOCOL_STACK="" + BLUEZ_TOOLS="" +fi + +if ${wifi_additional}; then + AVAHI_CLIENT_LIBRARY="libavahi-client-dev" +else + AVAHI_CLIENT_LIBRARY="" +fi + +if ${usb_install}; then + LIB_UDEV="libudev-dev" + USB_PERMISSIONS="SUBSYSTEM==\"usb\", GROUP=\"users\", MODE=\"0666\"" +else + LIB_UDEV="" + USB_PERMISSIONS="" +fi + +if ${lua_install}; then + LUA_PACKAGE="lua5.2" +else + LUA_PACKAGE="" +fi + +if ${additional_install}; then + CHROMIUM_BROWSER="chromium-browser" + LIB_SSL="libssl-dev" +else + CHROMIUM_BROWSER="" + LIB_SSL="" +fi + +#apt-get update +apt-install ${CMAKE_BUILD_SYSTEM} +apt-install ${SUBVERSION} +apt-install ${GIT} +apt-install ${GNU_CPP_COMPILER} +apt-install ${LIB_SQLITE} +apt-install ${BLUEZ_PROTOCOL_STACK} +apt-install ${BLUEZ_TOOLS} +apt-install ${AVAHI_CLIENT_LIBRARY} +apt-install ${CHROMIUM_BROWSER} +apt-install ${LIB_SSL} +apt-install ${LUA_PACKAGE} + +apt-install ${LIB_UDEV} +if ${usb_install}; then + echo "Setting up USB permissions..." + if [ ! -f "/etc/udev/rules.d/90-usbpermission.rules" ]; then + echo "Create permission file" + touch /etc/udev/rules.d/90-usbpermission.rules + echo -e "\n" | tee /etc/udev/rules.d/90-usbpermission.rules + fi + + if ! grep --quiet "$USB_PERMISSIONS" /etc/udev/rules.d/90-usbpermission.rules; then + echo "Adding permissions..." + sed -i "\$i$USB_PERMISSIONS" /etc/udev/rules.d/90-usbpermission.rules + fi +fi diff --git a/src/components/remote_control/test/smartDeviceLink.ini b/src/components/remote_control/test/smartDeviceLink.ini new file mode 100644 index 0000000000..e9c07f3698 --- /dev/null +++ b/src/components/remote_control/test/smartDeviceLink.ini @@ -0,0 +1,5 @@ +[Remote Control] +InteriorVDCapabilitiesFile = ./InteriorVehicleDataCapabilities.json +address = 127.0.0.1 +port = 8092 +timeout_period_seconds = 10 diff --git a/src/components/remote_control/test/src/rc_app_extension_test.cc b/src/components/remote_control/test/src/rc_app_extension_test.cc new file mode 100644 index 0000000000..5022853e30 --- /dev/null +++ b/src/components/remote_control/test/src/rc_app_extension_test.cc @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2015, 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 "remote_control/rc_app_extension.h" + +namespace remote_control { + +TEST(CanAppExtensionTest, Create) { + RCAppExtension extension(7); + ASSERT_TRUE(extension.uid() == 7); +} + +TEST(CanAppExtensionTest, Control) { + RCAppExtension extension(3); + ASSERT_EQ(3, extension.uid()); + ASSERT_FALSE(extension.IsControlGiven()); + extension.GiveControl(true); + ASSERT_TRUE(extension.IsControlGiven()); +} + +TEST(CanAppExtensionTest, DriverDevice) { + RCAppExtension extension(5); + ASSERT_EQ(5, extension.uid()); + ASSERT_FALSE(extension.is_on_driver_device()); + extension.set_is_on_driver_device(true); + ASSERT_TRUE(extension.is_on_driver_device()); +} + +} // namespace remote_control diff --git a/src/components/remote_control/test/src/rc_library_test.cc b/src/components/remote_control/test/src/rc_library_test.cc new file mode 100644 index 0000000000..77a57c4c3f --- /dev/null +++ b/src/components/remote_control/test/src/rc_library_test.cc @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2015, 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 <dlfcn.h> +#include "gtest/gtest.h" +#include "remote_control/remote_control_plugin.h" +#include "mock_service.h" + +using functional_modules::PluginInfo; +using application_manager::MockService; + +using ::testing::Return; + +namespace remote_control { + +::testing::AssertionResult IsError(void* error) { + if (error) { + return ::testing::AssertionSuccess() << static_cast<const char*>(error); + } else { + return ::testing::AssertionFailure() << error; + } +} + +TEST(CanLibraryTest, Load) { + const std::string kLibraryPath = "libRemoteControlModule.so"; + + void* handle = dlopen(kLibraryPath.c_str(), RTLD_LAZY); + EXPECT_FALSE(IsError(dlerror())); + ASSERT_TRUE(handle != NULL); + + const std::string kSymbol = "Create"; + void* symbol = dlsym(handle, kSymbol.c_str()); + EXPECT_FALSE(IsError(dlerror())); + ASSERT_TRUE(symbol != NULL); + + typedef CANModule* (*Create)(); + Create create_manager = reinterpret_cast<Create>(symbol); + CANModule* module = create_manager(); + ASSERT_TRUE(module != NULL); + + PluginInfo plugin = module->GetPluginInfo(); + EXPECT_EQ(plugin.name, "RemoteControlPlugin"); + EXPECT_EQ(plugin.version, 1); + + MockService* service = new MockService(); + module->set_service(service); + std::vector<application_manager::ApplicationSharedPtr> apps; + EXPECT_CALL(*service, GetApplications(module->GetModuleID())) + .Times(1) + .WillOnce(Return(apps)); + + // in order for all sub-threads to start before shutting them down + // The logic conditions must be chosen to insure that the "signal" is + // executed if the "wait" is ever processed. + // (see http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html) + sleep(3); + // CANModule::destroy(); + int ret = dlclose(handle); + EXPECT_FALSE(ret); + EXPECT_FALSE(IsError(dlerror())); +} + +} // namespace remote_control diff --git a/src/components/remote_control/test/src/rc_module_test.cc b/src/components/remote_control/test/src/rc_module_test.cc new file mode 100644 index 0000000000..4d4e1ac52d --- /dev/null +++ b/src/components/remote_control/test/src/rc_module_test.cc @@ -0,0 +1,484 @@ +/* + * Copyright (c) 2015, 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 "remote_control/remote_control_plugin.h" +#include "remote_control/rc_app_extension.h" +#include "remote_control/rc_module_constants.h" +#include "remote_control/message_helper.h" +#include "functional_module/module_observer.h" +#include "application_manager/mock_application.h" +#include "include/mock_service.h" +#include "utils/shared_ptr.h" +#include "utils/make_shared.h" +#include "application_manager/mock_message_helper.h" + +using functional_modules::PluginInfo; +using functional_modules::ProcessResult; +using functional_modules::RCFunctionID; +using application_manager::ServicePtr; + +using application_manager::MockService; +using application_manager::MockMessageHelper; +using test::components::application_manager_test::MockApplication; + +using ::testing::_; +using ::testing::Mock; +using ::testing::NiceMock; +using ::testing::StrictMock; +using ::testing::Return; +using ::testing::ReturnRef; +using ::testing::Eq; +using ::application_manager::Message; +using ::application_manager::MessageType; +using ::application_manager::ApplicationSharedPtr; +using ::protocol_handler::MessagePriority; + +namespace { +const bool kDeviceHandle = 1u; +const std::string kDeviceId = "1"; +const std::string kDeviceName = "1"; +} + +namespace remote_control { + +class RCModuleTest : public ::testing::Test { + public: + RCModuleTest() + : mock_service_(utils::MakeShared<NiceMock<MockService> >()) + , mock_message_helper_(*MockMessageHelper::message_helper_mock()) + , app0_(utils::MakeShared<NiceMock<MockApplication> >()) + , app1_(utils::MakeShared<NiceMock<MockApplication> >()) + , message_(utils::MakeShared<Message>(MessagePriority::FromServiceType( + protocol_handler::ServiceType::kRpc))) + , rc_app_extention_( + utils::MakeShared<RCAppExtension>(module_.GetModuleID())) {} + + void HandleMessage() { + module_.ProcessHMIMessage(message_); + } + + protected: + RemoteControlPlugin module_; + utils::SharedPtr<NiceMock<MockService> > mock_service_; + MockMessageHelper& mock_message_helper_; + std::vector<ApplicationSharedPtr> apps_; + utils::SharedPtr<NiceMock<MockApplication> > app0_; + utils::SharedPtr<NiceMock<MockApplication> > app1_; + application_manager::MessagePtr message_; + utils::SharedPtr<RCAppExtension> rc_app_extention_; + + void SetUp() OVERRIDE { + Mock::VerifyAndClearExpectations(&mock_message_helper_); + ServicePtr exp_service(mock_service_); + module_.set_service(exp_service); + ServicePtr out_service = module_.service(); + EXPECT_EQ(exp_service.get(), out_service.get()); + } + + void TearDown() OVERRIDE { + Mock::VerifyAndClearExpectations(&mock_message_helper_); + EXPECT_CALL(*mock_service_, GetApplications(module_.GetModuleID())) + .WillOnce(Return(apps_)); + } +}; + +TEST_F(RCModuleTest, Create) { + EXPECT_EQ(153, module_.GetModuleID()); + PluginInfo plugin = module_.GetPluginInfo(); + EXPECT_EQ(plugin.name, "RemoteControlPlugin"); + EXPECT_EQ(plugin.version, 1); +} + +TEST_F(RCModuleTest, ProcessMessageWrongMessage) { + message_->set_function_id(-1); + EXPECT_CALL(*mock_service_, SendMessageToMobile(_)).Times(0); + EXPECT_EQ(ProcessResult::CANNOT_PROCESS, module_.ProcessMessage(message_)); +} + +TEST_F(RCModuleTest, ProcessMessageEmptyapps_List) { + message_->set_function_id(RCFunctionID::ON_INTERIOR_VEHICLE_DATA); + message_->set_function_name("OnInteriorVehicleData"); + + std::string json = + "{\"jsonrpc\": \"2.0\", \"method\": \"RC.OnInteriorVehicleData\",\ + \"params\": {\"moduleData\": {\"moduleType\": \"CLIMATE\",\ + \"climateControlData\": {\"fanSpeed\": 100} }}}"; + message_->set_json_message(json); + + EXPECT_CALL(*mock_service_, ValidateMessageBySchema(_)) + .WillOnce(Return( + application_manager::MessageValidationResult::SCHEMA_MISMATCH)); + EXPECT_CALL(*mock_service_, SendMessageToMobile(_)).Times(0); + + // EXPECT_EQ(ProcessResult::PROCESSED, module_.ProcessMessage(message_)); + EXPECT_EQ(ProcessResult::CANNOT_PROCESS, module_.ProcessHMIMessage(message_)); +} + +TEST_F(RCModuleTest, ProcessMessagePass) { + message_->set_function_id(RCFunctionID::ON_INTERIOR_VEHICLE_DATA); + + std::string json = + "{ \"jsonrpc\": \"2.0\",\"method\": \"RC.OnInteriorVehicleData\",\ + \"params\":{\"moduleData\":{\ + \"moduleType\": \"CLIMATE\",\"climateControlData\": {\"fanSpeed\": 100}}}}"; + + message_->set_json_message(json); + + application_manager::BinaryData buf; + application_manager::BinaryData* data = &buf; + data->push_back(1); + + message_->set_binary_data(data); + + Json::Value json_value = MessageHelper::StringToValue(json); + Json::Value module_type = + json_value[json_keys::kParams][message_params::kModuleData] + [message_params::kModuleType]; + apps_.push_back(app0_); + rc_app_extention_->SubscribeToInteriorVehicleData(module_type); + EXPECT_CALL(*mock_service_, ValidateMessageBySchema(_)) + .WillOnce(Return(application_manager::MessageValidationResult::SUCCESS)); + EXPECT_CALL(*app0_, QueryInterface(module_.GetModuleID())) + .WillOnce(Return(rc_app_extention_)); + EXPECT_CALL(*app0_, app_id()).WillRepeatedly(Return(1)); + EXPECT_CALL(*mock_service_, GetApplications(module_.GetModuleID())) + .WillOnce(Return(apps_)); + EXPECT_CALL(*mock_service_, GetApplication(1)).WillOnce(Return(app0_)); + EXPECT_CALL(*mock_service_, CheckPolicyPermissions(_)) + .WillOnce(Return(mobile_apis::Result::eType::SUCCESS)); + EXPECT_CALL(*mock_service_, CheckModule(1, "CLIMATE")).WillOnce(Return(true)); + EXPECT_CALL(*mock_service_, SendMessageToMobile(_)); + + EXPECT_EQ(ProcessResult::PROCESSED, module_.ProcessHMIMessage(message_)); +} + +TEST_F(RCModuleTest, RemoveAppExtensionPassWay) { + EXPECT_CALL(*mock_service_, GetApplication(1)).WillOnce(Return(app0_)); + EXPECT_CALL(*app0_, RemoveExtension(module_.GetModuleID())); + + module_.RemoveAppExtension(1); +} + +TEST_F(RCModuleTest, RemoveAppExtensionIfAppNoExist) { + ApplicationSharedPtr invalid_app; + + EXPECT_CALL(*mock_service_, GetApplication(_)).WillOnce(Return(invalid_app)); + + module_.RemoveAppExtension(1); +} + +TEST_F(RCModuleTest, SendResponseToMobile) { + EXPECT_CALL(*mock_service_, SendMessageToMobile(message_)); + + module_.SendResponseToMobile(message_); +} + +TEST_F(RCModuleTest, IsAppForPluginSuccess) { + application_manager::AppExtensionPtr invalid_ext; + EXPECT_CALL(*app0_, QueryInterface(module_.GetModuleID())) + .WillOnce(Return(invalid_ext)) + .WillRepeatedly(Return(rc_app_extention_)); + EXPECT_CALL(*app0_, AddExtension(_)).WillOnce(Return(true)); + mobile_apis::HMILevel::eType hmi = mobile_apis::HMILevel::eType::HMI_FULL; + EXPECT_CALL(*app0_, hmi_level()).WillRepeatedly(Return(hmi)); + ON_CALL(*app0_, device()).WillByDefault(Return(1)); + EXPECT_CALL(*mock_service_, NotifyHMIAboutHMILevel(Eq(app0_), _)); + EXPECT_CALL(*mock_service_, PrimaryDevice()); + EXPECT_CALL(*mock_service_, IsRemoteControlApplication(Eq(app0_))) + .WillOnce(Return(true)); + ASSERT_TRUE(module_.IsAppForPlugin(app0_)); +} + +TEST_F(RCModuleTest, IsAppForPluginNotNew) { + EXPECT_CALL(*app0_, QueryInterface(module_.GetModuleID())) + .WillOnce(Return(rc_app_extention_)); + EXPECT_CALL(*mock_service_, NotifyHMIAboutHMILevel(Eq(app0_), _)).Times(0); + ASSERT_TRUE(module_.IsAppForPlugin(app0_)); +} + +TEST_F(RCModuleTest, IsAppForPluginFail) { + application_manager::AppExtensionPtr invalid_ext; + EXPECT_CALL(*app0_, QueryInterface(module_.GetModuleID())) + .WillOnce(Return(invalid_ext)); + EXPECT_CALL(*mock_service_, IsRemoteControlApplication(Eq(app0_))) + .Times(1) + .WillOnce(Return(false)); + ASSERT_FALSE(module_.IsAppForPlugin(app0_)); +} + +TEST_F(RCModuleTest, OnAppHMILevelChanged) { + const application_manager::custom_str::CustomString name("name"); + ON_CALL(*app0_, name()).WillByDefault(ReturnRef(name)); + mobile_apis::HMILevel::eType hmi = mobile_apis::HMILevel::eType::HMI_NONE; + EXPECT_CALL(*app0_, hmi_level()).WillRepeatedly(Return(hmi)); + EXPECT_CALL(*mock_service_, + NotifyHMIAboutHMILevel(Eq(app0_), + mobile_apis::HMILevel::eType::HMI_NONE)); + module_.OnAppHMILevelChanged(app0_, mobile_apis::HMILevel::eType::HMI_FULL); +} + +TEST_F(RCModuleTest, SetDriverDeviceOnRegister) { + application_manager::AppExtensionPtr invalid_ext; + EXPECT_CALL(*app0_, QueryInterface(module_.GetModuleID())) + .Times(2) + .WillOnce(Return(invalid_ext)) + .WillRepeatedly(Return(rc_app_extention_)); + EXPECT_CALL(*app0_, AddExtension(_)).WillOnce(Return(true)); + ON_CALL(*app0_, device()).WillByDefault(Return(12)); + mobile_apis::HMILevel::eType hmi = mobile_apis::HMILevel::eType::HMI_NONE; + EXPECT_CALL(*app0_, hmi_level()).Times(1).WillRepeatedly(Return(hmi)); + EXPECT_CALL(*mock_service_, NotifyHMIAboutHMILevel(Eq(app0_), _)).Times(1); + EXPECT_CALL(*mock_service_, PrimaryDevice()).Times(1).WillOnce(Return(12)); + EXPECT_CALL(*mock_service_, IsRemoteControlApplication(Eq(app0_))) + .Times(1) + .WillOnce(Return(true)); + + ASSERT_TRUE(module_.IsAppForPlugin(app0_)); + ASSERT_TRUE(rc_app_extention_->is_on_driver_device()); +} + +TEST_F(RCModuleTest, SetDriverDeviceOnRegisterFail) { + application_manager::AppExtensionPtr invalid_ext; + EXPECT_CALL(*app0_, QueryInterface(module_.GetModuleID())) + .Times(2) + .WillOnce(Return(invalid_ext)) + .WillRepeatedly(Return(rc_app_extention_)); + EXPECT_CALL(*app0_, AddExtension(_)).WillOnce(Return(true)); + mobile_apis::HMILevel::eType hmi = mobile_apis::HMILevel::eType::HMI_FULL; + EXPECT_CALL(*app0_, hmi_level()).WillRepeatedly(Return(hmi)); + ON_CALL(*app0_, device()).WillByDefault(Return(12)); + EXPECT_CALL(*mock_service_, NotifyHMIAboutHMILevel(Eq(app0_), _)).Times(1); + EXPECT_CALL(*mock_service_, PrimaryDevice()).Times(1).WillOnce(Return(3)); + EXPECT_CALL(*mock_service_, IsRemoteControlApplication(Eq(app0_))) + .Times(1) + .WillOnce(Return(true)); + + ASSERT_TRUE(module_.IsAppForPlugin(app0_)); + ASSERT_FALSE(rc_app_extention_->is_on_driver_device()); +} + +// TODO(ILytvynenko): Uncomment after CANModule::HandleMessage implementtion +// TEST_F(RCModuleTest, ChangeDriverDevice) { +// Json::Value value(Json::ValueType::objectValue); +// value[json_keys::kMethod] = +// functional_modules::hmi_api::on_device_rank_changed; +// value[json_keys::kParams] = Json::Value(Json::ValueType::objectValue); +// value[json_keys::kParams][message_params::kDevice] = +// Json::Value(Json::ValueType::objectValue); +// value[json_keys::kParams][message_params::kDevice][json_keys::kId] = +// kDeviceId; +// value[json_keys::kParams][message_params::kDevice][message_params::kName] = +// kDeviceName; +// value[json_keys::kParams][message_params::kRank] = "DRIVER"; +// Json::FastWriter writer; +// std::string json_str = writer.write(value); + +// message_->set_function_name( +// functional_modules::hmi_api::on_device_rank_changed); +// message_->set_json_message(json_str); + +// apps_.push_back(app0_); + +// mobile_apis::HMILevel::eType hmi = mobile_apis::HMILevel::eType::HMI_FULL; +// EXPECT_CALL(*app0_, hmi_level()).WillRepeatedly(Return(hmi)); +// EXPECT_CALL(*app0_, device()).WillRepeatedly(Return(1)); +// EXPECT_CALL(*app0_, QueryInterface(module_.GetModuleID())) +// .WillRepeatedly(Return(rc_app_extention_)); +// EXPECT_CALL(*mock_service_, GetApplications(module_.GetModuleID())) +// .WillOnce(Return(apps_)); +// EXPECT_CALL(*mock_service_, GetDeviceHandlerById(kDeviceId)) +// .WillRepeatedly(Return(kDeviceHandle)); +// EXPECT_CALL(*mock_service_, SetPrimaryDevice(kDeviceHandle)).Times(1); +// EXPECT_CALL(*mock_service_, ResetPrimaryDevice()).Times(0); + +// RCModuleTest::HandleMessage(); +// ASSERT_TRUE(rc_app_extention_->is_on_driver_device()); +//} + +// TEST_F(RCModuleTest, ChangeDriverDeviceOnOther) { +// Json::Value value(Json::ValueType::objectValue); +// value[json_keys::kMethod] = +// functional_modules::hmi_api::on_device_rank_changed; +// value[json_keys::kParams] = Json::Value(Json::ValueType::objectValue); +// value[json_keys::kParams][message_params::kDevice] = +// Json::Value(Json::ValueType::objectValue); +// value[json_keys::kParams][message_params::kDevice][json_keys::kId] = +// kDeviceId; +// value[json_keys::kParams][message_params::kDevice][message_params::kName] = +// kDeviceName; +// value[json_keys::kParams][message_params::kRank] = "DRIVER"; +// Json::FastWriter writer; +// std::string json_str = writer.write(value); + +// message_->set_function_name( +// functional_modules::hmi_api::on_device_rank_changed); +// message_->set_message_type(MessageType::kNotification); +// message_->set_json_message(json_str); + +// apps_.push_back(app0_); +// apps_.push_back(app1_); + +// rc_app_extention_->set_is_on_driver_device(true); +// EXPECT_TRUE(rc_app_extention_->is_on_driver_device()); +// utils::SharedPtr<RCAppExtension> ext = +// utils::MakeShared<RCAppExtension>(module_.GetModuleID()); +// EXPECT_FALSE(ext->is_on_driver_device()); + +// EXPECT_CALL(*app0_, device()).WillOnce(Return(1)); +// EXPECT_CALL(*app1_, device()).WillOnce(Return(2)); +// EXPECT_CALL(*app0_, QueryInterface(module_.GetModuleID())) +// .WillOnce(Return(rc_app_extention_)); +// EXPECT_CALL(*mock_service_, GetApplications(module_.GetModuleID())) +// .WillRepeatedly(Return(apps_)); +// EXPECT_CALL(*mock_service_, GetDeviceHandlerById(kDeviceId)) +// .WillRepeatedly(Return(kDeviceHandle)); +// EXPECT_CALL(*mock_service_, SetPrimaryDevice(kDeviceHandle)).Times(1); +// EXPECT_CALL(*mock_service_, ResetPrimaryDevice()).Times(0); + +// RCModuleTest::HandleMessage(); +// ASSERT_TRUE(rc_app_extention_->is_on_driver_device()); +// ASSERT_FALSE(ext->is_on_driver_device()); +//} + +// TEST_F(RCModuleTest, ChangeDriverDeviceToPassenger) { +// Json::Value value(Json::ValueType::objectValue); +// value[json_keys::kMethod] = +// functional_modules::hmi_api::on_device_rank_changed; +// value[json_keys::kParams] = Json::Value(Json::ValueType::objectValue); +// value[json_keys::kParams][message_params::kDevice] = +// Json::Value(Json::ValueType::objectValue); +// value[json_keys::kParams][message_params::kDevice][json_keys::kId] = +// kDeviceId; +// value[json_keys::kParams][message_params::kDevice][message_params::kName] = +// kDeviceName; +// value[json_keys::kParams][message_params::kRank] = "PASSENGER"; +// Json::FastWriter writer; +// std::string json_str = writer.write(value); + +// message_->set_function_name( +// functional_modules::hmi_api::on_device_rank_changed); +// message_->set_message_type(MessageType::kNotification); +// message_->set_json_message(json_str); + +// apps_.push_back(app0_); +// rc_app_extention_->set_is_on_driver_device(true); +// EXPECT_TRUE(rc_app_extention_->is_on_driver_device()); + +// mobile_apis::HMILevel::eType hmi = mobile_apis::HMILevel::eType::HMI_FULL; +// EXPECT_CALL(*app0_, hmi_level()).WillRepeatedly(Return(hmi)); +// EXPECT_CALL(*app0_, device()).WillOnce(Return(1)); +// EXPECT_CALL(*app0_, QueryInterface(module_.GetModuleID())) +// .WillRepeatedly(Return(rc_app_extention_)); +// EXPECT_CALL(*mock_service_, GetApplications(module_.GetModuleID())) +// .WillRepeatedly(Return(apps_)); +// EXPECT_CALL(*mock_service_, GetDeviceHandlerById(kDeviceId)) +// .WillRepeatedly(Return(kDeviceHandle)); +// EXPECT_CALL(*mock_service_, PrimaryDevice()).Times(1).WillOnce(Return(1)); +// EXPECT_CALL(*mock_service_, ResetPrimaryDevice()).Times(1); + +// RCModuleTest::HandleMessage(); +// ASSERT_FALSE(rc_app_extention_->is_on_driver_device()); +//} + +// TEST_F(RCModuleTest, ChangePassengerDeviceToPassenger) { +// Json::Value value(Json::ValueType::objectValue); +// value[json_keys::kMethod] = +// functional_modules::hmi_api::on_device_rank_changed; +// value[json_keys::kParams] = Json::Value(Json::ValueType::objectValue); +// value[json_keys::kParams][message_params::kDevice] = +// Json::Value(Json::ValueType::objectValue); +// value[json_keys::kParams][message_params::kDevice][json_keys::kId] = +// kDeviceId; +// value[json_keys::kParams][message_params::kDevice][message_params::kName] = +// kDeviceName; +// value[json_keys::kParams][message_params::kRank] = "PASSENGER"; +// Json::FastWriter writer; +// std::string json_str = writer.write(value); + +// message_->set_function_name( +// functional_modules::hmi_api::on_device_rank_changed); +// message_->set_message_type(MessageType::kNotification); +// message_->set_json_message(json_str); + +// apps_.push_back(app0_); +// rc_app_extention_->set_is_on_driver_device(false); +// EXPECT_FALSE(rc_app_extention_->is_on_driver_device()); + +// EXPECT_CALL(*app0_, device()).WillOnce(Return(1)); +// EXPECT_CALL(*app0_, QueryInterface(module_.GetModuleID())) +// .WillRepeatedly(Return(rc_app_extention_)); +// EXPECT_CALL(*mock_service_, GetApplications(module_.GetModuleID())) +// .WillRepeatedly(Return(apps_)); +// EXPECT_CALL(*mock_service_, PrimaryDevice()).Times(1).WillOnce(Return(2)); +// EXPECT_CALL(*mock_service_, ResetPrimaryDevice()).Times(0); + +// RCModuleTest::HandleMessage(); +// ASSERT_FALSE(rc_app_extention_->is_on_driver_device()); +//} + +TEST_F(RCModuleTest, CanAppChangeHMILevelPrimary) { + apps_.push_back(app0_); + + rc_app_extention_->set_is_on_driver_device(true); + + EXPECT_CALL(*app0_, QueryInterface(module_.GetModuleID())) + .WillRepeatedly(Return(rc_app_extention_)); + + ASSERT_TRUE(module_.CanAppChangeHMILevel( + app0_, mobile_apis::HMILevel::eType::HMI_FULL)); + ASSERT_TRUE(module_.CanAppChangeHMILevel( + app0_, mobile_apis::HMILevel::eType::HMI_LIMITED)); + ASSERT_TRUE(module_.CanAppChangeHMILevel( + app0_, mobile_apis::HMILevel::eType::HMI_BACKGROUND)); + ASSERT_TRUE(module_.CanAppChangeHMILevel( + app0_, mobile_apis::HMILevel::eType::HMI_NONE)); +} + +TEST_F(RCModuleTest, CanAppChangeHMILevelPassenger) { + apps_.push_back(app0_); + + rc_app_extention_->set_is_on_driver_device(false); + + EXPECT_CALL(*app0_, QueryInterface(module_.GetModuleID())) + .WillRepeatedly(Return(rc_app_extention_)); + + ASSERT_FALSE(module_.CanAppChangeHMILevel( + app0_, mobile_apis::HMILevel::eType::HMI_FULL)); + ASSERT_FALSE(module_.CanAppChangeHMILevel( + app0_, mobile_apis::HMILevel::eType::HMI_LIMITED)); + ASSERT_TRUE(module_.CanAppChangeHMILevel( + app0_, mobile_apis::HMILevel::eType::HMI_BACKGROUND)); + ASSERT_TRUE(module_.CanAppChangeHMILevel( + app0_, mobile_apis::HMILevel::eType::HMI_NONE)); +} +} // namespace remote_control diff --git a/src/components/remote_control/test/src/resource_allocation_manager_impl_test.cc b/src/components/remote_control/test/src/resource_allocation_manager_impl_test.cc new file mode 100644 index 0000000000..7adfea0d52 --- /dev/null +++ b/src/components/remote_control/test/src/resource_allocation_manager_impl_test.cc @@ -0,0 +1,282 @@ +/* + * Copyright (c) 2017, 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 "remote_control/resource_allocation_manager_impl.h" +#include "mock_resource_allocation_manager.h" +#include "mock_remote_control_plugin.h" +#include "remote_control/rc_app_extension.h" +#include "remote_control/rc_module_constants.h" +#include "remote_control/message_helper.h" +#include "functional_module/module_observer.h" +#include "application_manager/mock_application.h" +#include "include/mock_service.h" +#include "utils/shared_ptr.h" +#include "utils/make_shared.h" +#include "interfaces/HMI_API.h" + +using functional_modules::PluginInfo; +using functional_modules::ProcessResult; +using functional_modules::RCFunctionID; +using application_manager::ServicePtr; + +using application_manager::MockService; +using namespace test::components; +using application_manager_test::MockApplication; + +using ::testing::_; +using ::testing::Mock; +using ::testing::NiceMock; +using ::testing::StrictMock; +using ::testing::Return; +using ::testing::ReturnRef; +using ::testing::SaveArg; +using ::testing::Eq; +using ::application_manager::Message; +using ::application_manager::MessageType; +using ::application_manager::ApplicationSharedPtr; +using ::protocol_handler::MessagePriority; + +namespace { +const bool kDeviceHandle = 1u; +const std::string kModuleType1 = "CLIMATE"; +const std::string kModuleType2 = "RADIO"; +const int32_t kConnectionKey = 5; +const int32_t kCorrelationId = 5; +const int kModuleId = 153; +const uint32_t kAppId1 = 11u; +const uint32_t kAppId2 = 22u; +} + +namespace remote_control { + +class RAManagerTest : public ::testing::Test { + public: + RAManagerTest() + : mock_service_(utils::MakeShared<NiceMock<MockService> >()) + , mock_app_1_(utils::MakeShared<NiceMock<MockApplication> >()) + , mock_app_2_(utils::MakeShared<NiceMock<MockApplication> >()) + , message_(utils::MakeShared<Message>(MessagePriority::FromServiceType( + protocol_handler::ServiceType::kRpc))) { + EXPECT_CALL(mock_module_, service()).WillRepeatedly(Return(mock_service_)); + } + + void CheckResultWithHMILevelAndAccessMode( + ResourceAllocationManagerImpl& ra_manager, + mobile_apis::HMILevel::eType app_level, + const remote_control::AcquireResult::eType expected_result, + const hmi_apis::Common_RCAccessMode::eType access_mode) { + // Arrange + EXPECT_CALL(*mock_service_, GetApplication(kAppId1)) + .WillOnce(Return(mock_app_1_)); + ra_manager.SetAccessMode(access_mode); + EXPECT_EQ(remote_control::AcquireResult::ALLOWED, + ra_manager.AcquireResource(kModuleType1, kAppId1)); + EXPECT_CALL(*mock_service_, GetApplication(kAppId2)) + .WillOnce(Return(mock_app_2_)); + EXPECT_CALL(*mock_app_2_, hmi_level()).WillOnce(Return(app_level)); + // Second app tries to get already acquired resource by 1st app + EXPECT_EQ(expected_result, + ra_manager.AcquireResource(kModuleType1, kAppId2)); + } + + protected: + utils::SharedPtr<NiceMock<MockService> > mock_service_; + utils::SharedPtr<NiceMock<MockApplication> > mock_app_1_; + utils::SharedPtr<NiceMock<MockApplication> > mock_app_2_; + application_manager::MessagePtr message_; + remote_control_test::MockRemotePluginInterface mock_module_; + RemotePluginInterface::RCPluginEventDispatcher event_dispatcher_; +}; + +TEST_F(RAManagerTest, AcquireResource_NoAppRegistered_Expect_InUse) { + // Arrange + EXPECT_CALL(*mock_service_, GetApplication(kAppId1)) + .WillOnce(Return(ApplicationSharedPtr())); + ResourceAllocationManagerImpl ra_manager(mock_module_); + // Act & Assert + EXPECT_EQ(remote_control::AcquireResult::IN_USE, + ra_manager.AcquireResource(kModuleType1, kAppId1)); +} + +TEST_F(RAManagerTest, + AcquireResource_AppRegisteredAnyHmiLevelResourceFree_Expect_Allowed) { + // Arrange + EXPECT_CALL(*mock_service_, GetApplication(kAppId1)) + .WillOnce(Return(mock_app_1_)); + ResourceAllocationManagerImpl ra_manager(mock_module_); + // Act & Assert + EXPECT_EQ(remote_control::AcquireResult::ALLOWED, + ra_manager.AcquireResource(kModuleType1, kAppId1)); +} + +TEST_F( + RAManagerTest, + AcquireResource_AppInAnyHmiLevelWantsToAcquireSameResourceTwice_Expect_Allowed) { + // Arrange + EXPECT_CALL(*mock_service_, GetApplication(kAppId1)) + .WillOnce(Return(mock_app_1_)); + ResourceAllocationManagerImpl ra_manager(mock_module_); + EXPECT_EQ(remote_control::AcquireResult::ALLOWED, + ra_manager.AcquireResource(kModuleType1, kAppId1)); + EXPECT_CALL(*mock_service_, GetApplication(kAppId1)) + .WillOnce(Return(mock_app_1_)); + // Same app tries to get already acquired resource + EXPECT_EQ(remote_control::AcquireResult::ALLOWED, + ra_manager.AcquireResource(kModuleType1, kAppId1)); +} + +TEST_F( + RAManagerTest, + AcquireResource_App2_NotInFULLWantsToGetAcquiredResource_Expect_Rejected) { + using namespace mobile_apis; + using namespace hmi_apis; + using namespace remote_control; + const HMILevel::eType app_level = HMILevel::eType::HMI_BACKGROUND; + const AcquireResult::eType expected_result = AcquireResult::REJECTED; + const Common_RCAccessMode::eType access_mode = + Common_RCAccessMode::eType::AUTO_ALLOW; + ResourceAllocationManagerImpl ra_manager(mock_module_); + CheckResultWithHMILevelAndAccessMode( + ra_manager, app_level, expected_result, access_mode); +} + +TEST_F( + RAManagerTest, + AcquireResource_App2_InFULLWantsToGetAcquiredResource_AUTO_DENY_Expect_InUse) { + using namespace mobile_apis; + using namespace hmi_apis; + using namespace remote_control; + const HMILevel::eType app_level = HMILevel::eType::HMI_FULL; + const AcquireResult::eType expected_result = AcquireResult::IN_USE; + const Common_RCAccessMode::eType access_mode = + Common_RCAccessMode::eType::AUTO_DENY; + ResourceAllocationManagerImpl ra_manager(mock_module_); + CheckResultWithHMILevelAndAccessMode( + ra_manager, app_level, expected_result, access_mode); +} + +TEST_F( + RAManagerTest, + AcquireResource_App2_InFULLWantsToGetAcquiredResource_AUTO_ALLOW_Expect_Allowed) { + using namespace mobile_apis; + using namespace hmi_apis; + using namespace remote_control; + const HMILevel::eType app_level = HMILevel::eType::HMI_FULL; + const AcquireResult::eType expected_result = AcquireResult::ALLOWED; + const Common_RCAccessMode::eType access_mode = + Common_RCAccessMode::eType::AUTO_ALLOW; + ResourceAllocationManagerImpl ra_manager(mock_module_); + CheckResultWithHMILevelAndAccessMode( + ra_manager, app_level, expected_result, access_mode); +} + +TEST_F( + RAManagerTest, + AcquireResource_App2_InFULLWantsToGetAcquiredResource_ASK_DRIVER_Expect_AskDriver) { + using namespace mobile_apis; + using namespace hmi_apis; + using namespace remote_control; + const HMILevel::eType app_level = HMILevel::eType::HMI_FULL; + const AcquireResult::eType expected_result = AcquireResult::ASK_DRIVER; + const Common_RCAccessMode::eType access_mode = + Common_RCAccessMode::eType::ASK_DRIVER; + ResourceAllocationManagerImpl ra_manager(mock_module_); + CheckResultWithHMILevelAndAccessMode( + ra_manager, app_level, expected_result, access_mode); +} + +TEST_F(RAManagerTest, + AcquireResource_AcquiredModuleIsRejectedForApp2_ExpectApp2Rejected) { + // Arrange + ResourceAllocationManagerImpl ra_manager(mock_module_); + EXPECT_CALL(*mock_service_, GetApplication(kAppId1)) + .WillOnce(Return(mock_app_1_)); + EXPECT_EQ(AcquireResult::ALLOWED, + ra_manager.AcquireResource(kModuleType1, kAppId1)); + + // Act + ra_manager.OnDriverDisallowed(kModuleType1, kAppId2); + + // Assert + EXPECT_CALL(*mock_service_, GetApplication(kAppId2)) + .WillOnce(Return(mock_app_2_)); + EXPECT_EQ(AcquireResult::REJECTED, + ra_manager.AcquireResource(kModuleType1, kAppId2)); +} + +TEST_F(RAManagerTest, + AcquireResource_App1OccupiedResourceAndDisconnected_ExpectApp2Allowed) { + // Arrange + ResourceAllocationManagerImpl ra_manager(mock_module_); + ra_manager.SetAccessMode(hmi_apis::Common_RCAccessMode::eType::AUTO_DENY); + + EXPECT_CALL(*mock_service_, GetApplication(kAppId1)) + .WillOnce(Return(mock_app_1_)); + EXPECT_EQ(remote_control::AcquireResult::ALLOWED, + ra_manager.AcquireResource(kModuleType1, kAppId1)); + + // Act + ra_manager.OnUnregisterApplication(kAppId1); + + // Assert + EXPECT_CALL(*mock_service_, GetApplication(kAppId2)) + .WillOnce(Return(mock_app_2_)); + EXPECT_EQ(remote_control::AcquireResult::ALLOWED, + ra_manager.AcquireResource(kModuleType1, kAppId2)); +} + +TEST_F(RAManagerTest, AskDriver_ExpectDriverConsentRequestSentToHMI) { + // Arrange + EXPECT_CALL(*mock_service_, GetNextCorrelationID()) + .WillOnce(Return(kCorrelationId)); + EXPECT_CALL(mock_module_, event_dispatcher()) + .WillOnce(ReturnRef(event_dispatcher_)); + application_manager::MessagePtr result_msg; + EXPECT_CALL(*mock_service_, SendMessageToHMI(_)) + .WillOnce(SaveArg<0>(&result_msg)); + ResourceAllocationManagerImpl ra_manager(mock_module_); + AskDriverCallBackPtr ask_driver_callback_ptr = + utils::MakeShared<remote_control_test::MockAskDriverCallBack>(); + ra_manager.AskDriver(kModuleType1, kAppId1, ask_driver_callback_ptr); + // Assertions + const Json::Value message_to_hmi = + MessageHelper::StringToValue(result_msg->json_message()); + EXPECT_EQ(kAppId1, + message_to_hmi[json_keys::kParams][json_keys::kAppId].asUInt()); + EXPECT_EQ(kModuleType1, + message_to_hmi[json_keys::kParams][message_params::kModuleType] + .asString()); + EXPECT_EQ(functional_modules::hmi_api::get_user_consent, + message_to_hmi[json_keys::kMethod].asString()); +} + +} // namespace remote_control diff --git a/src/components/telemetry_monitor/CMakeLists.txt b/src/components/telemetry_monitor/CMakeLists.txt index bb33857ecd..bb419a92e9 100644 --- a/src/components/telemetry_monitor/CMakeLists.txt +++ b/src/components/telemetry_monitor/CMakeLists.txt @@ -39,9 +39,11 @@ include_directories ( ${COMPONENTS_DIR}/connection_handler/include/ ${COMPONENTS_DIR}/transport_manager/include/ ${COMPONENTS_DIR}/application_manager/include/ + ${COMPONENTS_DIR}/remote_control/include/ ${POLICY_PATH}/include/ ${POLICY_GLOBAL_INCLUDE_PATH}/ ${COMPONENTS_DIR}/rpc_base/include/ + ${COMPONENTS_DIR}/functional_module/include/ ${COMPONENTS_DIR}/hmi_message_handler/include/ ${COMPONENTS_DIR}/formatters/include/ ${COMPONENTS_DIR}/media_manager/include/ |