diff options
Diffstat (limited to 'src/components/application_manager/rpc_plugins')
36 files changed, 1023 insertions, 120 deletions
diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/navi_subscribe_way_points_request.h b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/navi_subscribe_way_points_request.h index 052c3c7151..97b6966e70 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/navi_subscribe_way_points_request.h +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/navi_subscribe_way_points_request.h @@ -65,6 +65,8 @@ class NaviSubscribeWayPointsRequest : public app_mngr::commands::RequestToHMI { **/ virtual void Run() OVERRIDE; + void onTimeOut() OVERRIDE; + private: DISALLOW_COPY_AND_ASSIGN(NaviSubscribeWayPointsRequest); }; diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/tts_set_global_properties_request.h b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/tts_set_global_properties_request.h index f416b3a787..98c7977391 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/tts_set_global_properties_request.h +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/tts_set_global_properties_request.h @@ -67,6 +67,8 @@ class TTSSetGlobalPropertiesRequest : public app_mngr::commands::RequestToHMI { **/ virtual void Run(); + virtual void onTimeOut() OVERRIDE; + private: DISALLOW_COPY_AND_ASSIGN(TTSSetGlobalPropertiesRequest); }; diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/ui_add_command_request.h b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/ui_add_command_request.h index e5d2483576..1779249bfe 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/ui_add_command_request.h +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/ui_add_command_request.h @@ -66,6 +66,8 @@ class UIAddCommandRequest : public app_mngr::commands::RequestToHMI { **/ virtual void Run(); + virtual void onTimeOut() OVERRIDE; + private: DISALLOW_COPY_AND_ASSIGN(UIAddCommandRequest); }; diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/ui_add_submenu_request.h b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/ui_add_submenu_request.h index 5de5e41cd6..db48b687cf 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/ui_add_submenu_request.h +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/ui_add_submenu_request.h @@ -66,6 +66,8 @@ class UIAddSubmenuRequest : public app_mngr::commands::RequestToHMI { **/ virtual void Run(); + virtual void onTimeOut() OVERRIDE; + private: DISALLOW_COPY_AND_ASSIGN(UIAddSubmenuRequest); }; diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/ui_set_global_properties_request.h b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/ui_set_global_properties_request.h index 44e8bba450..4ed514ad02 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/ui_set_global_properties_request.h +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/ui_set_global_properties_request.h @@ -67,6 +67,8 @@ class UISetGlobalPropertiesRequest : public app_mngr::commands::RequestToHMI { **/ virtual void Run(); + virtual void onTimeOut() OVERRIDE; + private: DISALLOW_COPY_AND_ASSIGN(UISetGlobalPropertiesRequest); }; diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/vr_add_command_request.h b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/vr_add_command_request.h index 0abb37adbc..1269128c14 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/vr_add_command_request.h +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/hmi/vr_add_command_request.h @@ -61,6 +61,8 @@ class VRAddCommandRequest : public app_mngr::commands::RequestToHMI { **/ virtual ~VRAddCommandRequest(); + void onTimeOut() OVERRIDE; + /** * @brief Execute command **/ diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/register_app_interface_request.h b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/register_app_interface_request.h index 95b7547a54..d8746e3fcd 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/register_app_interface_request.h +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/register_app_interface_request.h @@ -84,11 +84,6 @@ class RegisterAppInterfaceRequest virtual void Run(); /** - * @brief onTimeOut from requrst Controller - **/ - void onTimeOut() OVERRIDE; - - /** * @brief Prepares and sends RegisterAppInterface response to mobile * considering application type **/ @@ -117,10 +112,10 @@ class RegisterAppInterfaceRequest * @brief Prepares and sends RegisterAppInterface response to mobile * considering application type * @param app_type Type of application + * @param add_info - additional information to be sent to mobile app **/ void SendRegisterAppInterfaceResponseToMobile(ApplicationType app_type, - const std::string& add_info, - bool need_restore_vr); + const std::string& add_info); smart_objects::SmartObjectSPtr GetLockScreenIconUrlNotification( const uint32_t connection_key, app_mngr::ApplicationSharedPtr app); diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/sdl_app_extension.h b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/sdl_app_extension.h new file mode 100644 index 0000000000..10ce89b261 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/sdl_app_extension.h @@ -0,0 +1,86 @@ +/* + Copyright (c) 2018, Ford Motor Company + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following + disclaimer in the documentation and/or other materials provided with the + distribution. + + Neither the name of the Ford Motor Company nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_SDL_PLUGIN_INCLUDE_SDL_PLUGIN_SDL_APP_EXTENSION_H +#define SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_SDL_PLUGIN_INCLUDE_SDL_PLUGIN_SDL_APP_EXTENSION_H + +#include <application_manager/application_manager.h> + +namespace sdl_rpc_plugin { +class SDLRPCPlugin; + +namespace app_mngr = application_manager; + +class SDLAppExtension : public app_mngr::AppExtension { + public: + /** + * @brief SDLAppExtension constructor + * @param plugin sdl info plugin + * @param app application that contains this plugin + */ + SDLAppExtension(SDLRPCPlugin& plugin, app_mngr::Application& app); + virtual ~SDLAppExtension(); + + /** + * @brief SaveResumptionData saves vehicle info data + * @param resumption_data plase to store resumption data + */ + void SaveResumptionData(smart_objects::SmartObject& resumption_data) OVERRIDE; + + /** + * @brief ProcessResumption load resumtion data back to plugin during + * resumption + * @param resumption_data resumption data + * @param subscriber callback for subscription + */ + void ProcessResumption(const smart_objects::SmartObject& saved_app, + resumption::Subscriber subscriber) OVERRIDE; + + /** + * @brief Revert the data to the state before Resumption. + * @param subscriptions Subscriptions to be returned + **/ + void RevertResumption( + const smart_objects::SmartObject& subscriptions) OVERRIDE; + + /** + * @brief SDLAppExtensionUID unique identifier of VehicleInfo + * aplication extension + */ + static unsigned SDLAppExtensionUID; + + private: + SDLRPCPlugin& plugin_; + app_mngr::Application& app_; +}; +} +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_SDL_PLUGIN_INCLUDE_SDL_PLUGIN_SDL_APP_EXTENSION_H diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/sdl_pending_resumption_handler.h b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/sdl_pending_resumption_handler.h new file mode 100644 index 0000000000..2dc83202d0 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/sdl_pending_resumption_handler.h @@ -0,0 +1,83 @@ +/* + Copyright (c) 2018, Ford Motor Company + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following + disclaimer in the documentation and/or other materials provided with the + distribution. + + Neither the name of the Ford Motor Company nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_SDL_PLUGIN_INCLUDE_SDL_PLUGIN_SDL_PENDING_RESUMPTION_HANDLER_H +#define SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_SDL_PLUGIN_INCLUDE_SDL_PLUGIN_SDL_PENDING_RESUMPTION_HANDLER_H + +#include "application_manager/event_engine/event_observer.h" +#include "application_manager/resumption/extension_pending_resumption_handler.h" +#include "sdl_rpc_plugin/sdl_app_extension.h" + +namespace sdl_rpc_plugin { + +namespace app_mngr = application_manager; + +class SDLPendingResumptionHandler + : public resumption::ExtensionPendingResumptionHandler { + public: + SDLPendingResumptionHandler( + app_mngr::ApplicationManager& application_manager); + + // EventObserver interface + void on_event(const app_mngr::event_engine::Event& event) OVERRIDE; + + void HandleResumptionSubscriptionRequest( + app_mngr::AppExtension& extension, + resumption::Subscriber& subscriber, + application_manager::Application& app) OVERRIDE; + + void ClearPendingResumptionRequests() OVERRIDE; + + private: + smart_objects::SmartObjectSPtr CreateSubscriptionRequest(); + + struct ResumptionAwaitingHandling { + const uint32_t app_id; + SDLAppExtension& ext; + resumption::Subscriber subscriber; + + ResumptionAwaitingHandling(const uint32_t application_id, + SDLAppExtension& extension, + resumption::Subscriber subscriber_callback) + : app_id(application_id) + , ext(extension) + , subscriber(subscriber_callback) {} + }; + + typedef std::pair<SDLAppExtension, resumption::Subscriber> FreezedResumption; + std::queue<ResumptionAwaitingHandling> freezed_resumptions_; + std::map<uint32_t, smart_objects::SmartObject> pending_requests_; + std::queue<uint32_t> app_ids_; +}; +} + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_SDL_PLUGIN_INCLUDE_SDL_PLUGIN_SDL_PENDING_RESUMPTION_HANDLER_H diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/sdl_rpc_plugin.h b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/sdl_rpc_plugin.h index 6ae3a0b6bc..a5360992ea 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/sdl_rpc_plugin.h +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/sdl_rpc_plugin.h @@ -34,12 +34,16 @@ #define SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_SDL_RPC_PLUGIN_INCLUDE_SDL_RPC_PLUGIN_SDL_RPC_PLUGIN_H #include "application_manager/plugin_manager/rpc_plugin.h" #include "application_manager/command_factory.h" +#include "application_manager/resumption/extension_pending_resumption_handler.h" namespace sdl_rpc_plugin { +class SDLAppExtension; namespace plugins = application_manager::plugin_manager; class SDLRPCPlugin : public plugins::RPCPlugin { // RPCPlugin interface public: + SDLRPCPlugin(); + bool Init(application_manager::ApplicationManager& app_manager, application_manager::rpc_service::RPCService& rpc_service, application_manager::HMICapabilities& hmi_capabilities, @@ -58,8 +62,36 @@ class SDLRPCPlugin : public plugins::RPCPlugin { application_manager::plugin_manager::ApplicationEvent event, application_manager::ApplicationSharedPtr application) OVERRIDE; + /** + * @brief ProcessResumptionSubscription send appropriate subscribe requests + * to HMI + * @param app application for subscription + * @param ext application extension + * @param subscriber callback for subscription + */ + void ProcessResumptionSubscription(application_manager::Application& app, + SDLAppExtension& ext, + resumption::Subscriber subscriber); + + /** + * @brief Revert the data to the state before Resumption. + * @param subscriptions Subscriptions to be returned + **/ + void RevertResumption(application_manager::Application& app); + + /** + * @brief SaveResumptionData saves subscription data + * @param resumption_data plase to store resumption data + */ + void SaveResumptionData(application_manager::Application& app, + smart_objects::SmartObject& resumption_data); + private: std::unique_ptr<application_manager::CommandFactory> command_factory_; + application_manager::ApplicationManager* application_manager_; + using ExtensionPendingResumptionHandlerSPtr = + std::shared_ptr<resumption::ExtensionPendingResumptionHandler>; + ExtensionPendingResumptionHandlerSPtr pending_resumption_handler_; }; } diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/navi_subscribe_way_points_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/navi_subscribe_way_points_request.cc index a4445ebce8..6f21f1ad0d 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/navi_subscribe_way_points_request.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/navi_subscribe_way_points_request.cc @@ -31,6 +31,7 @@ */ #include "sdl_rpc_plugin/commands/hmi/navi_subscribe_way_points_request.h" +#include "application_manager/resumption/resume_ctrl.h" namespace sdl_rpc_plugin { using namespace application_manager; @@ -57,6 +58,14 @@ void NaviSubscribeWayPointsRequest::Run() { SendRequest(); } +void NaviSubscribeWayPointsRequest::onTimeOut() { + auto& resume_ctrl = application_manager_.resume_controller(); + + resume_ctrl.HandleOnTimeOut( + correlation_id(), + static_cast<hmi_apis::FunctionID::eType>(function_id())); +} + } // namespace commands } // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/tts_set_global_properties_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/tts_set_global_properties_request.cc index 8c7443d465..52fd01e256 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/tts_set_global_properties_request.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/tts_set_global_properties_request.cc @@ -31,6 +31,7 @@ */ #include "sdl_rpc_plugin/commands/hmi/tts_set_global_properties_request.h" +#include "application_manager/resumption/resume_ctrl.h" namespace sdl_rpc_plugin { using namespace application_manager; @@ -57,6 +58,13 @@ void TTSSetGlobalPropertiesRequest::Run() { SendRequest(); } +void TTSSetGlobalPropertiesRequest::onTimeOut() { + auto& resume_ctrl = application_manager_.resume_controller(); + resume_ctrl.HandleOnTimeOut( + correlation_id(), + static_cast<hmi_apis::FunctionID::eType>(function_id())); +} + } // namespace commands } // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/ui_add_command_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/ui_add_command_request.cc index 749b3ad56b..2ca2de5591 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/ui_add_command_request.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/ui_add_command_request.cc @@ -31,6 +31,7 @@ */ #include "sdl_rpc_plugin/commands/hmi/ui_add_command_request.h" +#include "application_manager/resumption/resume_ctrl.h" namespace sdl_rpc_plugin { using namespace application_manager; @@ -57,6 +58,14 @@ void UIAddCommandRequest::Run() { SendRequest(); } +void UIAddCommandRequest::onTimeOut() { + auto& resume_ctrl = application_manager_.resume_controller(); + + resume_ctrl.HandleOnTimeOut( + correlation_id(), + static_cast<hmi_apis::FunctionID::eType>(function_id())); +} + } // namespace commands } // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/ui_add_submenu_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/ui_add_submenu_request.cc index de338d4670..19071fa348 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/ui_add_submenu_request.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/ui_add_submenu_request.cc @@ -31,6 +31,7 @@ */ #include "sdl_rpc_plugin/commands/hmi/ui_add_submenu_request.h" +#include "application_manager/resumption/resume_ctrl.h" namespace sdl_rpc_plugin { using namespace application_manager; @@ -57,6 +58,13 @@ void UIAddSubmenuRequest::Run() { SendRequest(); } +void UIAddSubmenuRequest::onTimeOut() { + auto& resume_ctrl = application_manager_.resume_controller(); + resume_ctrl.HandleOnTimeOut( + correlation_id(), + static_cast<hmi_apis::FunctionID::eType>(function_id())); +} + } // namespace commands } // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/ui_set_global_properties_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/ui_set_global_properties_request.cc index 0664404361..1e7a2cf0f0 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/ui_set_global_properties_request.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/ui_set_global_properties_request.cc @@ -31,6 +31,7 @@ */ #include "sdl_rpc_plugin/commands/hmi/ui_set_global_properties_request.h" +#include "application_manager/resumption/resume_ctrl.h" namespace sdl_rpc_plugin { using namespace application_manager; @@ -57,6 +58,13 @@ void UISetGlobalPropertiesRequest::Run() { SendRequest(); } +void UISetGlobalPropertiesRequest::onTimeOut() { + auto& resume_ctrl = application_manager_.resume_controller(); + resume_ctrl.HandleOnTimeOut( + correlation_id(), + static_cast<hmi_apis::FunctionID::eType>(function_id())); +} + } // namespace commands } // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/vr_add_command_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/vr_add_command_request.cc index 72ce387f77..6f01688c9f 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/vr_add_command_request.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/vr_add_command_request.cc @@ -31,6 +31,7 @@ */ #include "sdl_rpc_plugin/commands/hmi/vr_add_command_request.h" +#include "application_manager/resumption/resume_ctrl.h" namespace sdl_rpc_plugin { using namespace application_manager; @@ -57,6 +58,14 @@ void VRAddCommandRequest::Run() { SendRequest(); } +void VRAddCommandRequest::onTimeOut() { + auto& resume_ctrl = application_manager_.resume_controller(); + + resume_ctrl.HandleOnTimeOut( + correlation_id(), + static_cast<hmi_apis::FunctionID::eType>(function_id())); +} + } // namespace commands } // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/add_command_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/add_command_request.cc index 155f819761..9c653d75a4 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/add_command_request.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/add_command_request.cc @@ -36,6 +36,7 @@ #include "application_manager/application.h" #include "application_manager/message_helper.h" +#include "application_manager/resumption/resume_ctrl.h" #include "utils/file_system.h" #include "utils/helpers.h" #include "utils/custom_string.h" @@ -71,6 +72,12 @@ void AddCommandRequest::onTimeOut() { LOG4CXX_AUTO_TRACE(logger_); RemoveCommand(); CommandRequestImpl::onTimeOut(); + + auto& resume_ctrl = application_manager_.resume_controller(); + + resume_ctrl.HandleOnTimeOut( + correlation_id(), + static_cast<hmi_apis::FunctionID::eType>(function_id())); } bool AddCommandRequest::Init() { diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/create_interaction_choice_set_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/create_interaction_choice_set_request.cc index 416f4f2085..f97c583fbd 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/create_interaction_choice_set_request.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/create_interaction_choice_set_request.cc @@ -39,6 +39,7 @@ #include "application_manager/application_impl.h" #include "application_manager/message_helper.h" +#include "application_manager/resumption/resume_ctrl.h" #include "utils/gen_hash.h" #include "utils/helpers.h" @@ -420,6 +421,12 @@ void CreateInteractionChoiceSetRequest::onTimeOut() { CommandRequestImpl::onTimeOut(); DeleteChoices(); + auto& resume_ctrl = application_manager_.resume_controller(); + + resume_ctrl.HandleOnTimeOut( + correlation_id(), + static_cast<hmi_apis::FunctionID::eType>(function_id())); + // We have to keep request alive until receive all responses from HMI // according to SDLAQ-CRS-2976 sync_primitives::AutoLock timeout_lock_(is_timed_out_lock_); diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_request.cc index f98f81d3ff..6ba4219f9e 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_request.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_request.cc @@ -223,10 +223,12 @@ bool RegisterAppInterfaceRequest::ProcessApplicationTransportSwitching() { if (!IsApplicationSwitched()) { return false; } - const auto& msg_params = (*message_)[strings::msg_params]; - const auto& policy_app_id = msg_params[strings::app_id].asString(); + const std::string& policy_app_id = + application_manager_.GetCorrectMobileIDFromMessage(message_); + auto app = application_manager_.application_by_policy_id(policy_app_id); + DCHECK_OR_RETURN(app, false); if (!application_manager_.IsAppInReconnectMode(policy_app_id)) { LOG4CXX_DEBUG(logger_, @@ -251,7 +253,7 @@ bool RegisterAppInterfaceRequest::ProcessApplicationTransportSwitching() { application_manager_.ProcessReconnection(app, connection_key()); result_code_ = mobile_apis::Result::SUCCESS; - SendRegisterAppInterfaceResponseToMobile(app_type, "", false); + SendRegisterAppInterfaceResponseToMobile(app_type, ""); application_manager_.SendHMIStatusNotification(app); @@ -279,18 +281,6 @@ void RegisterAppInterfaceRequest::FillApplicationParams( LOG4CXX_AUTO_TRACE(logger_); const auto& msg_params = (*message_)[strings::msg_params]; const std::string policy_app_id = msg_params[strings::app_id].asString(); - // For resuming application need to restore hmi_app_id from resumeCtrl - resumption::ResumeCtrl& resumer = application_manager_.resume_controller(); - const std::string& device_mac = application->mac_address(); - - // there is side affect with 2 mobile app with the same mobile app_id - if (resumer.IsApplicationSaved(policy_app_id, device_mac)) { - application->set_hmi_application_id( - resumer.GetHMIApplicationID(policy_app_id, device_mac)); - } else { - application->set_hmi_application_id( - application_manager_.GenerateNewHMIAppID()); - } application->set_is_media_application( msg_params[strings::is_media_application].asBool()); @@ -423,20 +413,6 @@ RegisterAppInterfaceRequest::ApplicationDataShouldBeResumed() { return DataResumeResult::RESUME_DATA; } -void RegisterAppInterfaceRequest::onTimeOut() { - LOG4CXX_AUTO_TRACE(logger_); - if (!is_data_resumption_) { - app_mngr::commands::CommandRequestImpl::onTimeOut(); - return; - } - auto& resume_ctrl = application_manager_.resume_controller(); - resume_ctrl.HandleOnTimeOut(application_->app_id()); - result_code_ = mobile_api::Result::RESUME_FAILED; - const std::string info = "HMI does not respond during timeout."; - SendRegisterAppInterfaceResponseToMobile( - ApplicationType::kNewApplication, info, true); -} - void RegisterAppInterfaceRequest::Run() { using namespace helpers; LOG4CXX_AUTO_TRACE(logger_); @@ -558,18 +534,19 @@ void RegisterAppInterfaceRequest::Run() { } // Version negotiation + utils::SemanticVersion ver_4_5(4, 5, 0); utils::SemanticVersion module_version( major_version, minor_version, patch_version); - if (mobile_version < utils::rpc_version_5) { + if (mobile_version <= ver_4_5) { // Mobile versioning did not exist for - // versions before 5.0 - application->set_msg_version(utils::base_rpc_version); + // versions 4.5 and prior. + application_->set_msg_version(ver_4_5); } else if (mobile_version < module_version) { // Use mobile RPC version as negotiated version - application->set_msg_version(mobile_version); + application_->set_msg_version(mobile_version); } else { // Use module version as negotiated version - application->set_msg_version(module_version); + application_->set_msg_version(module_version); } FillApplicationParams(application_); @@ -592,17 +569,23 @@ void RegisterAppInterfaceRequest::Run() { application_manager_.GetPluginManager().ForEachPlugin(on_app_registered); if (DataResumeResult::RESUME_DATA == resume_data_result) { + application_manager_.updateRequestTimeout( + connection_key(), correlation_id(), 0); + sleep(1); is_data_resumption_ = true; + application_->set_is_resuming(true); auto& resume_ctrl = application_manager_.resume_controller(); const auto& msg_params = (*message_)[strings::msg_params]; const auto& hash_id = msg_params[strings::hash_id].asString(); LOG4CXX_WARN(logger_, "Start Data Resumption"); - auto send_response = [this](mobile_apis::Result::eType result_code, - const std::string& info) { + auto app = application_; + auto send_response = [this, app](mobile_apis::Result::eType result_code, + const std::string info) { + LOG4CXX_DEBUG(logger_, "Invoking lambda callback for: " << this); result_code_ = result_code; - SendRegisterAppInterfaceResponseToMobile( - ApplicationType::kNewApplication, info, true); - application_->UpdateHash(); + SendRegisterAppInterfaceResponseToMobile(ApplicationType::kNewApplication, + info); + app->UpdateHash(); }; resume_ctrl.StartResumption(application_, hash_id, send_response); @@ -613,7 +596,6 @@ void RegisterAppInterfaceRequest::Run() { if (mobile_apis::Result::INVALID_ENUM == result_code_) { result_code_ = mobile_apis::Result::SUCCESS; } - if (DataResumeResult::WRONG_HASH == resume_data_result) { add_info = "Hash from RAI does not match to saved resume data."; result_code_ = mobile_apis::Result::RESUME_FAILED; @@ -625,11 +607,9 @@ void RegisterAppInterfaceRequest::Run() { } CheckLanguage(); - const bool need_to_restore_vr = - resume_data_result == DataResumeResult::RESUME_DATA; - SendRegisterAppInterfaceResponseToMobile( - ApplicationType::kNewApplication, add_info, need_to_restore_vr); + SendRegisterAppInterfaceResponseToMobile(ApplicationType::kNewApplication, + add_info); smart_objects::SmartObjectSPtr so = GetLockScreenIconUrlNotification(connection_key(), application_); rpc_service_.ManageMobileCommand(so, SOURCE_SDL); @@ -830,8 +810,7 @@ void FinishSendingRegisterAppInterfaceToMobile( } // Default HMI level should be set before any permissions validation, since - // it - // relies on HMI level. + // it relies on HMI level. app_manager.OnApplicationRegistered(application); (*notify_upd_manager)(); @@ -844,9 +823,7 @@ void FinishSendingRegisterAppInterfaceToMobile( } void RegisterAppInterfaceRequest::SendRegisterAppInterfaceResponseToMobile( - ApplicationType app_type, - const std::string& add_info, - bool need_restore_vr) { + ApplicationType app_type, const std::string& add_info) { LOG4CXX_AUTO_TRACE(logger_); smart_objects::SmartObject response_params(smart_objects::SmartType_Map); @@ -997,38 +974,10 @@ void RegisterAppInterfaceRequest::SendRegisterAppInterfaceResponseToMobile( msg_params_copy, application_manager_, key, notify_upd_manager); } -void RegisterAppInterfaceRequest::FinishSendingRegisterAppInterfaceToMobile( - const smart_objects::SmartObject& msg_params, - ApplicationManager& app_manager, - const uint32_t connection_key, - policy::StatusNotifier notify_upd_manager) { - policy::PolicyHandlerInterface& policy_handler = - app_manager.GetPolicyHandler(); - resumption::ResumeCtrl& resume_ctrl = app_manager.resume_controller(); - auto application = app_manager.application(connection_key); - - if (msg_params.keyExists(strings::app_hmi_type)) { - policy_handler_.SetDefaultHmiTypes(application->policy_app_id(), - &(msg_params[strings::app_hmi_type])); - } - - // Default HMI level should be set before any permissions validation, since it - // relies on HMI level. - app_manager.OnApplicationRegistered(application); - (*notify_upd_manager)(); - - // Start PTU after successfull registration - // Sends OnPermissionChange notification to mobile right after RAI response - // and HMI level set-up - policy_handler.OnAppRegisteredOnMobile(application->policy_app_id()); - - resume_ctrl.StartResumptionOnlyHMILevel(application); -} - DEPRECATED void RegisterAppInterfaceRequest::SendRegisterAppInterfaceResponseToMobile() { - SendRegisterAppInterfaceResponseToMobile( - ApplicationType::kNewApplication, "", false); + SendRegisterAppInterfaceResponseToMobile(ApplicationType::kNewApplication, + ""); } void RegisterAppInterfaceRequest::SendChangeRegistration( diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/subscribe_button_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/subscribe_button_request.cc index f76b6ab210..1c7280f5c1 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/subscribe_button_request.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/subscribe_button_request.cc @@ -77,7 +77,9 @@ void SubscribeButtonRequest::Run() { return; } - if (app->msg_version() < utils::rpc_version_5 && + const utils::SemanticVersion app_msg_version = app->msg_version(); + + if (app_msg_version <= utils::base_rpc_version && btn_id == mobile_apis::ButtonName::OK && app->is_media_application()) { bool ok_supported = CheckHMICapabilities(mobile_apis::ButtonName::OK); bool play_pause_supported = diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/subscribe_way_points_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/subscribe_way_points_request.cc index eb4ca42568..b8af04c25e 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/subscribe_way_points_request.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/subscribe_way_points_request.cc @@ -66,7 +66,7 @@ void SubscribeWayPointsRequest::Run() { return; } - if (application_manager_.IsAppSubscribedForWayPoints(app)) { + if (application_manager_.IsAppSubscribedForWayPoints(*app)) { SendResponse(false, mobile_apis::Result::IGNORED); return; } diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unsubscribe_way_points_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unsubscribe_way_points_request.cc index 40bb1ddfc9..347ea223ca 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unsubscribe_way_points_request.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/unsubscribe_way_points_request.cc @@ -66,7 +66,7 @@ void UnsubscribeWayPointsRequest::Run() { return; } - if (!application_manager_.IsAppSubscribedForWayPoints(app)) { + if (!application_manager_.IsAppSubscribedForWayPoints(*app)) { SendResponse(false, mobile_apis::Result::IGNORED); return; } diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/sdl_app_extension.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/sdl_app_extension.cc new file mode 100644 index 0000000000..5d42743475 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/sdl_app_extension.cc @@ -0,0 +1,78 @@ +/* + Copyright (c) 2018, 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 "sdl_rpc_plugin/sdl_app_extension.h" +#include "sdl_rpc_plugin/sdl_rpc_plugin.h" + +CREATE_LOGGERPTR_GLOBAL(logger_, "SDLAppExtension") + +namespace sdl_rpc_plugin { +namespace strings = application_manager::strings; +unsigned SDLAppExtension::SDLAppExtensionUID = 138; + +SDLAppExtension::SDLAppExtension(SDLRPCPlugin& plugin, + application_manager::Application& app) + : app_mngr::AppExtension(SDLAppExtension::SDLAppExtensionUID) + , plugin_(plugin) + , app_(app) { + LOG4CXX_AUTO_TRACE(logger_); +} + +SDLAppExtension::~SDLAppExtension() { + LOG4CXX_AUTO_TRACE(logger_); +} + +void SDLAppExtension::SaveResumptionData( + smart_objects::SmartObject& resumption_data) { + plugin_.SaveResumptionData(app_, resumption_data); +} + +void SDLAppExtension::ProcessResumption( + const smart_objects::SmartObject& saved_app, + resumption::Subscriber subscriber) { + LOG4CXX_AUTO_TRACE(logger_); + if (!saved_app.keyExists(strings::subscribed_for_way_points)) { + LOG4CXX_ERROR(logger_, "subscribed_for_way_points section does not exist"); + return; + } + const bool subscribed_for_way_points_so = + saved_app[strings::subscribed_for_way_points].asBool(); + if (subscribed_for_way_points_so) { + plugin_.ProcessResumptionSubscription(app_, *this, subscriber); + } +} + +void SDLAppExtension::RevertResumption( + const smart_objects::SmartObject& subscriptions) { + plugin_.RevertResumption(app_); +} +} diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/sdl_pending_resumption_handler.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/sdl_pending_resumption_handler.cc new file mode 100644 index 0000000000..f61e5798e3 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/sdl_pending_resumption_handler.cc @@ -0,0 +1,171 @@ +#include "sdl_rpc_plugin/sdl_pending_resumption_handler.h" +#include "application_manager/event_engine/event_observer.h" +#include "application_manager/resumption/resumption_data_processor.h" +#include "application_manager/message_helper.h" +#include "utils/helpers.h" + +namespace sdl_rpc_plugin { + +CREATE_LOGGERPTR_GLOBAL(logger_, "VehicleInfoPendingResumptionHandler") + +SDLPendingResumptionHandler::SDLPendingResumptionHandler( + application_manager::ApplicationManager& application_manager) + : ExtensionPendingResumptionHandler(application_manager) {} + +smart_objects::SmartObjectSPtr +SDLPendingResumptionHandler::CreateSubscriptionRequest() { + LOG4CXX_AUTO_TRACE(logger_); + auto subscribe_waypoints_msg = + application_manager::MessageHelper::CreateMessageForHMI( + hmi_apis::FunctionID::Navigation_SubscribeWayPoints, + application_manager_.GetNextHMICorrelationID()); + (*subscribe_waypoints_msg)[application_manager::strings::params] + [application_manager::strings::message_type] = + hmi_apis::messageType::request; + return subscribe_waypoints_msg; +} + +void SDLPendingResumptionHandler::ClearPendingResumptionRequests() { + LOG4CXX_AUTO_TRACE(logger_); + using namespace application_manager; + const hmi_apis::FunctionID::eType timed_out_pending_request_fid = + static_cast<hmi_apis::FunctionID::eType>( + pending_requests_.begin() + ->second[strings::params][strings::function_id] + .asInt()); + unsubscribe_from_event(timed_out_pending_request_fid); + pending_requests_.clear(); + + if (!freezed_resumptions_.empty()) { + ResumptionAwaitingHandling freezed_resumption = + freezed_resumptions_.front(); + freezed_resumptions_.pop(); + + auto request = CreateSubscriptionRequest(); + const uint32_t cid = + (*request)[strings::params][strings::correlation_id].asUInt(); + const hmi_apis::FunctionID::eType fid = + static_cast<hmi_apis::FunctionID::eType>( + (*request)[strings::params][strings::function_id].asInt()); + auto resumption_req = MakeResumptionRequest(cid, fid, *request); + auto subscriber = freezed_resumption.subscriber; + subscriber(freezed_resumption.app_id, resumption_req); + LOG4CXX_DEBUG(logger_, + "Subscribing for event with function id: " + << fid << " correlation id: " << cid); + subscribe_on_event(fid, cid); + pending_requests_[cid] = *request; + LOG4CXX_DEBUG(logger_, + "Sending request with fid: " << fid << " and cid: " << cid); + application_manager_.GetRPCService().ManageHMICommand(request); + } +} + +void SDLPendingResumptionHandler::on_event( + const application_manager::event_engine::Event& event) { + using namespace application_manager; + LOG4CXX_AUTO_TRACE(logger_); + + const smart_objects::SmartObject& response = event.smart_object(); + const uint32_t corr_id = event.smart_object_correlation_id(); + + smart_objects::SmartObject pending_request; + if (pending_requests_.find(corr_id) == pending_requests_.end()) { + LOG4CXX_DEBUG(logger_, "corr id" << corr_id << " NOT found"); + return; + } + pending_request = pending_requests_[corr_id]; + pending_requests_.erase(corr_id); + + LOG4CXX_DEBUG(logger_, + "Received event with function id: " + << event.id() << " and correlation id: " << corr_id); + + const hmi_apis::Common_Result::eType result_code = + static_cast<hmi_apis::Common_Result::eType>( + response[strings::params][application_manager::hmi_response::code] + .asInt()); + const bool succesfull_response = + (result_code == hmi_apis::Common_Result::SUCCESS || + result_code == hmi_apis::Common_Result::WARNINGS); + if (succesfull_response) { + LOG4CXX_DEBUG(logger_, "Resumption of subscriptions is successful"); + } else { + LOG4CXX_DEBUG(logger_, "Resumption of subscriptions is NOT successful"); + uint32_t app_id = 0; + if (app_ids_.empty()) { + LOG4CXX_ERROR(logger_, "app_ids is empty"); + return; + } + app_id = app_ids_.front(); + auto app = application_manager_.application(app_id); + if (!app) { + LOG4CXX_ERROR(logger_, "Application NOT found"); + return; + } + application_manager_.UnsubscribeAppFromWayPoints(app); + if (freezed_resumptions_.empty()) { + LOG4CXX_DEBUG(logger_, "freezed resumptions is empty"); + return; + } + + ResumptionAwaitingHandling freezed_resumption = + freezed_resumptions_.front(); + freezed_resumptions_.pop(); + resumption::Subscriber subscriber = freezed_resumption.subscriber; + + auto request = CreateSubscriptionRequest(); + const uint32_t cid = + (*request)[strings::params][strings::correlation_id].asUInt(); + const hmi_apis::FunctionID::eType fid = + static_cast<hmi_apis::FunctionID::eType>( + (*request)[strings::params][strings::function_id].asInt()); + auto resumption_req = MakeResumptionRequest(cid, fid, *request); + subscribe_on_event(fid, cid); + subscriber(freezed_resumption.app_id, resumption_req); + LOG4CXX_DEBUG(logger_, + "Subscribing for event with function id: " + << fid << " correlation id: " << cid); + pending_requests_[cid] = *request; + LOG4CXX_DEBUG(logger_, + "Sending request with fid: " << fid << " and cid: " << cid); + application_manager_.GetRPCService().ManageHMICommand(request); + } +} + +void SDLPendingResumptionHandler::HandleResumptionSubscriptionRequest( + application_manager::AppExtension& extension, + resumption::Subscriber& subscriber, + application_manager::Application& app) { + LOG4CXX_AUTO_TRACE(logger_); + SDLAppExtension& ext = dynamic_cast<SDLAppExtension&>(extension); + smart_objects::SmartObjectSPtr request = CreateSubscriptionRequest(); + smart_objects::SmartObject& request_ref = *request; + const auto function_id = static_cast<hmi_apis::FunctionID::eType>( + request_ref[application_manager::strings::params] + [application_manager::strings::function_id].asInt()); + const uint32_t corr_id = + request_ref[application_manager::strings::params] + [application_manager::strings::correlation_id].asUInt(); + + auto resumption_request = + MakeResumptionRequest(corr_id, function_id, *request); + app_ids_.push(app.app_id()); + if (pending_requests_.empty()) { + LOG4CXX_DEBUG(logger_, + "There are no pending requests for app_id: " << app.app_id()); + pending_requests_[corr_id] = request_ref; + subscribe_on_event(function_id, corr_id); + subscriber(app.app_id(), resumption_request); + LOG4CXX_DEBUG(logger_, + "Sending request with function id: " + << function_id << " and correlation_id: " << corr_id); + application_manager_.GetRPCService().ManageHMICommand(request); + return; + } + LOG4CXX_DEBUG(logger_, + "There are pending requests for app_id: " << app.app_id()); + ResumptionAwaitingHandling frozen_res(app.app_id(), ext, subscriber); + freezed_resumptions_.push(frozen_res); +} +} diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/sdl_rpc_plugin.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/sdl_rpc_plugin.cc index 22b818f5e0..0ed51f2d65 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/sdl_rpc_plugin.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/sdl_rpc_plugin.cc @@ -32,15 +32,25 @@ #include "sdl_rpc_plugin/sdl_rpc_plugin.h" #include "sdl_rpc_plugin/sdl_command_factory.h" +#include "sdl_rpc_plugin/sdl_app_extension.h" +#include "sdl_rpc_plugin/sdl_pending_resumption_handler.h" +#include "application_manager/message_helper.h" namespace sdl_rpc_plugin { +CREATE_LOGGERPTR_GLOBAL(logger_, "SDLRPCPlugin") namespace plugins = application_manager::plugin_manager; +SDLRPCPlugin::SDLRPCPlugin() + : application_manager_(nullptr), pending_resumption_handler_(nullptr) {} + bool SDLRPCPlugin::Init( application_manager::ApplicationManager& app_manager, application_manager::rpc_service::RPCService& rpc_service, application_manager::HMICapabilities& hmi_capabilities, policy::PolicyHandlerInterface& policy_handler) { + application_manager_ = &app_manager; + pending_resumption_handler_ = + std::make_shared<SDLPendingResumptionHandler>(app_manager); command_factory_.reset(new sdl_rpc_plugin::SDLCommandFactory( app_manager, rpc_service, hmi_capabilities, policy_handler)); return true; @@ -66,7 +76,59 @@ void SDLRPCPlugin::OnPolicyEvent( void SDLRPCPlugin::OnApplicationEvent( application_manager::plugin_manager::ApplicationEvent event, - application_manager::ApplicationSharedPtr application) {} + application_manager::ApplicationSharedPtr application) { + LOG4CXX_AUTO_TRACE(logger_); + if (plugins::ApplicationEvent::kApplicationRegistered == event) { + application->AddExtension( + std::make_shared<SDLAppExtension>(*this, *application)); + } +} + +void SDLRPCPlugin::ProcessResumptionSubscription( + application_manager::Application& app, + SDLAppExtension& ext, + resumption::Subscriber subscriber) { + LOG4CXX_AUTO_TRACE(logger_); + application_manager::ApplicationSharedPtr application = + application_manager_->application(app.app_id()); + std::set<uint32_t> apps = + application_manager_->GetAppsSubscribedForWayPoints(); + application_manager_->SubscribeAppForWayPoints(application); + pending_resumption_handler_->HandleResumptionSubscriptionRequest( + ext, subscriber, app); +} + +void SDLRPCPlugin::SaveResumptionData( + application_manager::Application& app, + smart_objects::SmartObject& resumption_data) { + resumption_data[application_manager::strings::subscribed_for_way_points] = + application_manager_->IsAppSubscribedForWayPoints(app); +} + +void SDLRPCPlugin::RevertResumption(application_manager::Application& app) { + application_manager::ApplicationSharedPtr application = + application_manager_->application(app.app_id()); + pending_resumption_handler_->ClearPendingResumptionRequests(); + std::set<uint32_t> apps = + application_manager_->GetAppsSubscribedForWayPoints(); + if (1 == apps.size() && + application_manager_->IsAppSubscribedForWayPoints(*application)) { + auto subscribe_waypoints_msg = + application_manager::MessageHelper::CreateMessageForHMI( + hmi_apis::FunctionID::Navigation_UnsubscribeWayPoints, + application_manager_->GetNextHMICorrelationID()); + (*subscribe_waypoints_msg)[application_manager::strings::params] + [application_manager::strings::message_type] = + hmi_apis::messageType::request; + (*subscribe_waypoints_msg)[application_manager::strings::msg_params] + [application_manager::strings::app_id] = + app.app_id(); + + application_manager_->GetRPCService().ManageHMICommand( + subscribe_waypoints_msg); + } + application_manager_->UnsubscribeAppFromWayPoints(application); +} } // namespace sdl_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/add_command_request_test.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/add_command_request_test.cc index 7c99b5f2b8..af56a4e9ae 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/add_command_request_test.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/add_command_request_test.cc @@ -51,6 +51,7 @@ #include "application_manager/event_engine/event.h" #include "application_manager/mock_hmi_interface.h" #include "application_manager/mock_help_prompt_manager.h" +#include "application_manager/mock_resume_ctrl.h" namespace test { namespace components { @@ -221,6 +222,9 @@ class AddCommandRequestTest mock_rpc_service_, ManageMobileCommand(response, am::commands::Command::CommandSource::SOURCE_SDL)); + ON_CALL(app_mngr_, resume_controller()) + .WillByDefault(ReturnRef(mock_resume_ctrl_)); + EXPECT_CALL(mock_resume_ctrl_, HandleOnTimeOut(_, _)); std::shared_ptr<CommandRequestImpl> base_class_request = static_cast<std::shared_ptr<CommandRequestImpl> >(request_ptr); base_class_request->onTimeOut(); @@ -232,6 +236,7 @@ class AddCommandRequestTest std::shared_ptr<sync_primitives::Lock> lock_ptr_; std::shared_ptr<am_test::MockHelpPromptManager> mock_help_prompt_manager_; MockAppPtr mock_app_; + resumprion_test::MockResumeCtrl mock_resume_ctrl_; }; TEST_F(AddCommandRequestTest, Run_AppNotExisted_EXPECT_AppNotRegistered) { @@ -1092,6 +1097,9 @@ TEST_F(AddCommandRequestTest, EXPECT_CALL(mock_rpc_service_, ManageMobileCommand( response, am::commands::Command::CommandSource::SOURCE_SDL)); + ON_CALL(app_mngr_, resume_controller()) + .WillByDefault(ReturnRef(mock_resume_ctrl_)); + EXPECT_CALL(mock_resume_ctrl_, HandleOnTimeOut(_, _)); std::shared_ptr<CommandRequestImpl> base_class_request = static_cast<std::shared_ptr<CommandRequestImpl> >( CreateCommand<AddCommandRequest>(msg_)); @@ -1142,6 +1150,9 @@ TEST_F(AddCommandRequestTest, OnTimeOut_AppRemoveCommandCalled) { EXPECT_CALL(mock_rpc_service_, ManageMobileCommand( response, am::commands::Command::CommandSource::SOURCE_SDL)); + ON_CALL(app_mngr_, resume_controller()) + .WillByDefault(ReturnRef(mock_resume_ctrl_)); + EXPECT_CALL(mock_resume_ctrl_, HandleOnTimeOut(_, _)); std::shared_ptr<CommandRequestImpl> base_class_request = static_cast<std::shared_ptr<CommandRequestImpl> >(request_ptr); base_class_request->onTimeOut(); diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/create_interaction_choice_set_test.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/create_interaction_choice_set_test.cc index c42be48e57..300a1c3b95 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/create_interaction_choice_set_test.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/create_interaction_choice_set_test.cc @@ -49,6 +49,7 @@ #include "application_manager/event_engine/event.h" #include "application_manager/mock_hmi_interface.h" #include "application_manager/mock_hmi_capabilities.h" +#include "application_manager/mock_resume_ctrl.h" namespace test { namespace components { @@ -157,6 +158,7 @@ class CreateInteractionChoiceSetRequestTest CreateInteractionChoiceSetRequestPtr command_; MockAppPtr mock_app_; std::shared_ptr<sync_primitives::Lock> lock_; + resumprion_test::MockResumeCtrl mock_resume_ctrl_; }; class CreateInteractionChoiceSetResponseTest @@ -184,6 +186,10 @@ TEST_F(CreateInteractionChoiceSetRequestTest, OnTimeout_GENERIC_ERROR) { ManageMobileCommand(_, am::commands::Command::CommandSource::SOURCE_SDL)) .WillOnce(DoAll(SaveArg<0>(&vr_command_result), Return(true))); + ON_CALL(app_mngr_, resume_controller()) + .WillByDefault(ReturnRef(mock_resume_ctrl_)); + EXPECT_CALL(mock_resume_ctrl_, HandleOnTimeOut(_, _)); + req_vr->onTimeOut(); EXPECT_EQ( (*vr_command_result)[strings::msg_params][strings::success].asBool(), @@ -705,6 +711,9 @@ TEST_F(CreateInteractionChoiceSetRequestTest, am::commands::Command::SOURCE_SDL)); EXPECT_CALL(app_mngr_, TerminateRequest(_, _, _)); + ON_CALL(app_mngr_, resume_controller()) + .WillByDefault(ReturnRef(mock_resume_ctrl_)); + EXPECT_CALL(mock_resume_ctrl_, HandleOnTimeOut(_, _)); command_->onTimeOut(); } @@ -749,6 +758,9 @@ TEST_F(CreateInteractionChoiceSetRequestTest, EXPECT_CALL(mock_rpc_service_, ManageMobileCommand(_, _)).Times(0); EXPECT_CALL(app_mngr_, TerminateRequest(_, _, _)); + ON_CALL(app_mngr_, resume_controller()) + .WillByDefault(ReturnRef(mock_resume_ctrl_)); + EXPECT_CALL(mock_resume_ctrl_, HandleOnTimeOut(_, _)); command_->onTimeOut(); } @@ -794,6 +806,9 @@ TEST_F(CreateInteractionChoiceSetRequestTest, OnTimeOut_InvalidApp_UNSUCCESS) { EXPECT_CALL(app_mngr_, application(kConnectionKey)) .WillOnce(Return(invalid_app)); EXPECT_CALL(*mock_app_, RemoveChoiceSet(_)).Times(0); + ON_CALL(app_mngr_, resume_controller()) + .WillByDefault(ReturnRef(mock_resume_ctrl_)); + EXPECT_CALL(mock_resume_ctrl_, HandleOnTimeOut(_, _)); command_->onTimeOut(); } @@ -844,6 +859,9 @@ TEST_F(CreateInteractionChoiceSetRequestTest, EXPECT_CALL(app_mngr_, application(kConnectionKey)) .WillOnce(Return(mock_app_)); EXPECT_CALL(*mock_app_, RemoveChoiceSet(_)); + ON_CALL(app_mngr_, resume_controller()) + .WillByDefault(ReturnRef(mock_resume_ctrl_)); + EXPECT_CALL(mock_resume_ctrl_, HandleOnTimeOut(_, _)); command_->onTimeOut(); } diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/subscribe_way_points_request_test.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/subscribe_way_points_request_test.cc index d08c13b3f3..dff8a9b18b 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/subscribe_way_points_request_test.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/subscribe_way_points_request_test.cc @@ -56,6 +56,7 @@ using ::testing::Return; using ::testing::ReturnRef; using ::testing::DoAll; using ::testing::SaveArg; +using ::testing::Eq; using ::testing::InSequence; namespace am = ::application_manager; using sdl_rpc_plugin::commands::SubscribeWayPointsRequest; @@ -71,7 +72,7 @@ TEST_F(SubscribeWayPointsRequestTest, Run_SUCCESS) { MockAppPtr app(CreateMockApp()); ON_CALL(app_mngr_, application(_)).WillByDefault(Return(app)); - ON_CALL(app_mngr_, IsAppSubscribedForWayPoints(A<am::ApplicationSharedPtr>())) + ON_CALL(app_mngr_, IsAppSubscribedForWayPoints(Ref(*app))) .WillByDefault(Return(false)); ON_CALL(app_mngr_, IsAnyAppSubscribedForWayPoints()) .WillByDefault(Return(true)); diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/unsubscribe_way_points_request_test.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/unsubscribe_way_points_request_test.cc index f345d719c6..c6fd489bb0 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/unsubscribe_way_points_request_test.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/unsubscribe_way_points_request_test.cc @@ -100,9 +100,7 @@ TEST_F(UnsubscribeWayPointsRequestTest, EXPECT_CALL(app_mngr_, application(kConnectionKey)) .WillOnce(Return(mock_app)); - EXPECT_CALL(app_mngr_, - IsAppSubscribedForWayPoints( - ::testing::Matcher<am::ApplicationSharedPtr>(mock_app))) + EXPECT_CALL(app_mngr_, IsAppSubscribedForWayPoints(Ref(*mock_app))) .WillOnce(Return(false)); EXPECT_CALL( @@ -117,9 +115,7 @@ TEST_F(UnsubscribeWayPointsRequestTest, Run_AppSubscribedForWayPoints_SUCCESS) { EXPECT_CALL(app_mngr_, application(kConnectionKey)) .WillOnce(Return(mock_app)); - EXPECT_CALL(app_mngr_, - IsAppSubscribedForWayPoints( - ::testing::Matcher<am::ApplicationSharedPtr>(mock_app))) + EXPECT_CALL(app_mngr_, IsAppSubscribedForWayPoints(Ref(*mock_app))) .WillOnce(Return(true)); EXPECT_CALL(mock_rpc_service_, diff --git a/src/components/application_manager/rpc_plugins/vehicle_info_plugin/include/vehicle_info_plugin/commands/hmi/vi_subscribe_vehicle_data_request.h b/src/components/application_manager/rpc_plugins/vehicle_info_plugin/include/vehicle_info_plugin/commands/hmi/vi_subscribe_vehicle_data_request.h index bd22a313e7..abd9806bd3 100644 --- a/src/components/application_manager/rpc_plugins/vehicle_info_plugin/include/vehicle_info_plugin/commands/hmi/vi_subscribe_vehicle_data_request.h +++ b/src/components/application_manager/rpc_plugins/vehicle_info_plugin/include/vehicle_info_plugin/commands/hmi/vi_subscribe_vehicle_data_request.h @@ -67,6 +67,8 @@ class VISubscribeVehicleDataRequest : public app_mngr::commands::RequestToHMI { **/ virtual void Run(); + void onTimeOut() OVERRIDE; + private: DISALLOW_COPY_AND_ASSIGN(VISubscribeVehicleDataRequest); }; diff --git a/src/components/application_manager/rpc_plugins/vehicle_info_plugin/include/vehicle_info_plugin/vehicle_info_pending_resumption_handler.h b/src/components/application_manager/rpc_plugins/vehicle_info_plugin/include/vehicle_info_plugin/vehicle_info_pending_resumption_handler.h new file mode 100644 index 0000000000..c5847c2148 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/vehicle_info_plugin/include/vehicle_info_plugin/vehicle_info_pending_resumption_handler.h @@ -0,0 +1,63 @@ +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_VEHICLE_INFO_PLUGIN_INCLUDE_VEHICLE_INFO_PLUGIN_PENDING_RESUMPTION_HANDLER_H +#define SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_VEHICLE_INFO_PLUGIN_INCLUDE_VEHICLE_INFO_PLUGIN_PENDING_RESUMPTION_HANDLER_H +#include "application_manager/event_engine/event_observer.h" +#include "application_manager/resumption/extension_pending_resumption_handler.h" +#include "vehicle_info_app_extension.h" + +namespace vehicle_info_plugin { + +namespace app_mngr = application_manager; + +class VehicleInfoPendingResumptionHandler + : public resumption::ExtensionPendingResumptionHandler { + public: + VehicleInfoPendingResumptionHandler( + app_mngr::ApplicationManager& application_manager); + + // EventObserver interface + void on_event(const app_mngr::event_engine::Event& event) OVERRIDE; + + void HandleResumptionSubscriptionRequest(app_mngr::AppExtension& extension, + resumption::Subscriber& subscriber, + app_mngr::Application& app) OVERRIDE; + + std::map<std::string, bool> ExtractSubscribeResults( + const smart_objects::SmartObject& response, + const smart_objects::SmartObject& request) const; + + bool IsResumptionResultSuccessful( + std::map<std::string, bool>& subscription_results); + + void RemoveSucessfulSubscriptions( + std::set<std::string>& subscriptions, + std::set<std::string>& successful_subscriptions); + + std::set<std::string> GetExtensionSubscriptions( + VehicleInfoAppExtension& extension); + + smart_objects::SmartObjectSPtr CreateSubscribeRequestToHMI( + const std::set<std::string>& subscriptions); + + void ClearPendingResumptionRequests() OVERRIDE; + + private: + struct ResumptionAwaitingHandling { + const uint32_t app_id; + VehicleInfoAppExtension& ext; + resumption::Subscriber subscriber; + + ResumptionAwaitingHandling(const uint32_t application_id, + VehicleInfoAppExtension& extension, + resumption::Subscriber subscriber_callback) + : app_id(application_id) + , ext(extension) + , subscriber(subscriber_callback) {} + }; + + typedef std::pair<VehicleInfoAppExtension, resumption::Subscriber> + FreezedResumption; + std::queue<ResumptionAwaitingHandling> freezed_resumptions_; + std::map<uint32_t, smart_objects::SmartObject> pending_requests_; +}; +} // namespace vehicle_info_plugin +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_VEHICLE_INFO_PLUGIN_INCLUDE_VEHICLE_INFO_PLUGIN_PENDING_RESUMPTION_HANDLER_H diff --git a/src/components/application_manager/rpc_plugins/vehicle_info_plugin/include/vehicle_info_plugin/vehicle_info_plugin.h b/src/components/application_manager/rpc_plugins/vehicle_info_plugin/include/vehicle_info_plugin/vehicle_info_plugin.h index 507431a0c8..4c0314c736 100644 --- a/src/components/application_manager/rpc_plugins/vehicle_info_plugin/include/vehicle_info_plugin/vehicle_info_plugin.h +++ b/src/components/application_manager/rpc_plugins/vehicle_info_plugin/include/vehicle_info_plugin/vehicle_info_plugin.h @@ -34,6 +34,7 @@ #define SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_VEHICLE_INFO_PLUGIN_INCLUDE_VEHICLE_INFO_PLUGIN_VEHICLE_INFO_PLUGIN_H #include "application_manager/command_factory.h" +#include "application_manager/resumption/extension_pending_resumption_handler.h" namespace vehicle_info_plugin { class VehicleInfoAppExtension; @@ -92,6 +93,9 @@ class VehicleInfoPlugin : public plugins::RPCPlugin { std::unique_ptr<app_mngr::CommandFactory> command_factory_; app_mngr::ApplicationManager* application_manager_; + using ExtensionPendingResumptionHandlerSPtr = + std::shared_ptr<resumption::ExtensionPendingResumptionHandler>; + ExtensionPendingResumptionHandlerSPtr pending_resumption_handler_; }; } diff --git a/src/components/application_manager/rpc_plugins/vehicle_info_plugin/src/commands/hmi/vi_subscribe_vehicle_data_request.cc b/src/components/application_manager/rpc_plugins/vehicle_info_plugin/src/commands/hmi/vi_subscribe_vehicle_data_request.cc index 60e9dc88c3..5b609dad8a 100644 --- a/src/components/application_manager/rpc_plugins/vehicle_info_plugin/src/commands/hmi/vi_subscribe_vehicle_data_request.cc +++ b/src/components/application_manager/rpc_plugins/vehicle_info_plugin/src/commands/hmi/vi_subscribe_vehicle_data_request.cc @@ -31,6 +31,7 @@ */ #include "vehicle_info_plugin/commands/hmi/vi_subscribe_vehicle_data_request.h" +#include "application_manager/resumption/resume_ctrl.h" namespace vehicle_info_plugin { using namespace application_manager; @@ -57,6 +58,14 @@ void VISubscribeVehicleDataRequest::Run() { SendRequest(); } +void VISubscribeVehicleDataRequest::onTimeOut() { + auto& resume_ctrl = application_manager_.resume_controller(); + + resume_ctrl.HandleOnTimeOut( + correlation_id(), + static_cast<hmi_apis::FunctionID::eType>(function_id())); +} + } // namespace commands } // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/vehicle_info_plugin/src/vehicle_info_pending_resumption_handler.cc b/src/components/application_manager/rpc_plugins/vehicle_info_plugin/src/vehicle_info_pending_resumption_handler.cc new file mode 100644 index 0000000000..ee37c0ba0a --- /dev/null +++ b/src/components/application_manager/rpc_plugins/vehicle_info_plugin/src/vehicle_info_pending_resumption_handler.cc @@ -0,0 +1,275 @@ +#include "vehicle_info_plugin/vehicle_info_pending_resumption_handler.h" +#include "application_manager/event_engine/event_observer.h" +#include "application_manager/resumption/resumption_data_processor.h" +#include "application_manager/message_helper.h" +#include "utils/helpers.h" + +namespace vehicle_info_plugin { + +CREATE_LOGGERPTR_GLOBAL(logger_, "VehicleInfoPendingResumptionHandler") + +VehicleInfoPendingResumptionHandler::VehicleInfoPendingResumptionHandler( + application_manager::ApplicationManager& application_manager) + : ExtensionPendingResumptionHandler(application_manager) {} + +template <class Key, class Value> +std::set<Key> EnumerateKeys(std::map<Key, Value>& container) { + std::set<std::string> keys; + + std::transform( + container.begin(), + container.end(), + std::inserter(keys, keys.end()), + [&](const std::pair<std::string, bool>& pair) { return pair.first; }); + + return keys; +} + +bool VehicleInfoPendingResumptionHandler::IsResumptionResultSuccessful( + std::map<std::string, bool>& subscription_results) { + for (auto ivi_status : subscription_results) { + if (!ivi_status.second) { + return false; + break; + } + } + + return true; +} + +void VehicleInfoPendingResumptionHandler::RemoveSucessfulSubscriptions( + std::set<std::string>& subscriptions, + std::set<std::string>& successful_subscriptions) { + for (auto subscription : subscriptions) { + if (helpers::in_range(successful_subscriptions, subscription)) { + subscriptions.erase(subscription); + } + } +} + +void VehicleInfoPendingResumptionHandler::ClearPendingResumptionRequests() { + LOG4CXX_AUTO_TRACE(logger_); + using namespace application_manager; + const hmi_apis::FunctionID::eType timed_out_pending_request_fid = + static_cast<hmi_apis::FunctionID::eType>( + pending_requests_.begin() + ->second[strings::params][strings::function_id] + .asInt()); + unsubscribe_from_event(timed_out_pending_request_fid); + pending_requests_.clear(); + + if (!freezed_resumptions_.empty()) { + ResumptionAwaitingHandling freezed_resumption = + freezed_resumptions_.front(); + freezed_resumptions_.pop(); + + std::set<std::string> subscriptions = + GetExtensionSubscriptions(freezed_resumption.ext); + + auto request = CreateSubscribeRequestToHMI(subscriptions); + const uint32_t cid = + (*request)[strings::params][strings::correlation_id].asUInt(); + const hmi_apis::FunctionID::eType fid = + static_cast<hmi_apis::FunctionID::eType>( + (*request)[strings::params][strings::function_id].asInt()); + auto resumption_req = MakeResumptionRequest(cid, fid, *request); + auto subscriber = freezed_resumption.subscriber; + subscriber(freezed_resumption.app_id, resumption_req); + LOG4CXX_DEBUG(logger_, + "Subscribing for event with function id: " + << fid << " correlation id: " << cid); + subscribe_on_event(fid, cid); + pending_requests_[cid] = *request; + LOG4CXX_DEBUG(logger_, + "Sending request with fid: " << fid << " and cid: " << cid); + application_manager_.GetRPCService().ManageHMICommand(request); + } +} + +void VehicleInfoPendingResumptionHandler::on_event( + const application_manager::event_engine::Event& event) { + using namespace application_manager; + LOG4CXX_AUTO_TRACE(logger_); + + const smart_objects::SmartObject& response = event.smart_object(); + const uint32_t corr_id = event.smart_object_correlation_id(); + + smart_objects::SmartObject pending_request; + if (pending_requests_.find(corr_id) == pending_requests_.end()) { + LOG4CXX_DEBUG(logger_, "corr id" << corr_id << " NOT found"); + return; + } + pending_request = pending_requests_[corr_id]; + pending_requests_.erase(corr_id); + + LOG4CXX_DEBUG(logger_, + "Received event with function id: " + << event.id() << " and correlation id: " << corr_id); + + if (freezed_resumptions_.empty()) { + LOG4CXX_DEBUG(logger_, "freezed resumptions is empty"); + return; + } + + std::map<std::string, bool> subscription_results = + ExtractSubscribeResults(pending_request, response); + + LOG4CXX_DEBUG(logger_, + "pending_requests_.size()" << pending_requests_.size()); + + std::set<std::string> successful_subscriptions = + EnumerateKeys(subscription_results); + + ResumptionAwaitingHandling freezed_resumption = freezed_resumptions_.front(); + freezed_resumptions_.pop(); + resumption::Subscriber subscriber = freezed_resumption.subscriber; + + std::set<std::string> subscriptions = + GetExtensionSubscriptions(freezed_resumption.ext); + + if (!IsResumptionResultSuccessful(subscription_results)) { + LOG4CXX_DEBUG(logger_, "Resumption of subscriptions is NOT successful"); + } else { + LOG4CXX_DEBUG(logger_, "Resumption of subscriptions is successful"); + RemoveSucessfulSubscriptions(subscriptions, successful_subscriptions); + } + + auto request = CreateSubscribeRequestToHMI(subscriptions); + const uint32_t cid = + (*request)[strings::params][strings::correlation_id].asUInt(); + const hmi_apis::FunctionID::eType fid = + static_cast<hmi_apis::FunctionID::eType>( + (*request)[strings::params][strings::function_id].asInt()); + auto resumption_req = MakeResumptionRequest(cid, fid, *request); + subscribe_on_event(fid, cid); + subscriber(freezed_resumption.app_id, resumption_req); + LOG4CXX_DEBUG(logger_, + "Subscribing for event with function id: " + << fid << " correlation id: " << cid); + pending_requests_[cid] = *request; + LOG4CXX_DEBUG(logger_, + "Sending request with fid: " << fid << " and cid: " << cid); + application_manager_.GetRPCService().ManageHMICommand(request); +} + +std::map<std::string, bool> +VehicleInfoPendingResumptionHandler::ExtractSubscribeResults( + const smart_objects::SmartObject& response, + const smart_objects::SmartObject& request) const { + using namespace application_manager; + const hmi_apis::Common_Result::eType result_code = + static_cast<hmi_apis::Common_Result::eType>( + response[strings::params][application_manager::hmi_response::code] + .asInt()); + bool succesfull_response = (result_code == hmi_apis::Common_Result::SUCCESS || + result_code == hmi_apis::Common_Result::WARNINGS); + const auto response_keys = + response[application_manager::strings::msg_params].enumerate(); + const auto request_keys = + request[application_manager::strings::msg_params].enumerate(); + + auto response_params = response[strings::msg_params]; + + std::map<std::string, bool> subscription_results; + + if (!succesfull_response) { + for (auto key : request_keys) { + subscription_results[key] = false; + } + } + + if (succesfull_response) { + for (auto key : request_keys) { + if (!helpers::in_range(response_keys, key)) { + subscription_results[key] = true; + } else { + const auto kSuccess = + hmi_apis::Common_VehicleDataResultCode::VDRC_SUCCESS; + const auto vd_result_code = + response_params[key][application_manager::strings::result_code] + .asInt(); + subscription_results[key] = vd_result_code == kSuccess; + } + } + } + return subscription_results; +} + +void VehicleInfoPendingResumptionHandler::HandleResumptionSubscriptionRequest( + application_manager::AppExtension& extension, + resumption::Subscriber& subscriber, + application_manager::Application& app) { + LOG4CXX_AUTO_TRACE(logger_); + + VehicleInfoAppExtension& ext = + dynamic_cast<VehicleInfoAppExtension&>(extension); + + std::set<std::string> subscriptions = GetExtensionSubscriptions(ext); + + smart_objects::SmartObjectSPtr request = + CreateSubscribeRequestToHMI(subscriptions); + + smart_objects::SmartObject& request_ref = *request; + const auto function_id = static_cast<hmi_apis::FunctionID::eType>( + request_ref[application_manager::strings::params] + [application_manager::strings::function_id].asInt()); + const uint32_t corr_id = + request_ref[application_manager::strings::params] + [application_manager::strings::correlation_id].asUInt(); + + auto resumption_request = + MakeResumptionRequest(corr_id, function_id, *request); + + if (pending_requests_.empty()) { + LOG4CXX_DEBUG(logger_, + "There are no pending requests for app_id: " << app.app_id()); + pending_requests_[corr_id] = request_ref; + subscribe_on_event(function_id, corr_id); + subscriber(app.app_id(), resumption_request); + LOG4CXX_DEBUG(logger_, + "Sending request with function id: " + << function_id << " and correlation_id: " << corr_id); + application_manager_.GetRPCService().ManageHMICommand(request); + return; + } else { + LOG4CXX_DEBUG(logger_, + "There are pending requests for app_id: " << app.app_id()); + ResumptionAwaitingHandling frozen_res(app.app_id(), ext, subscriber); + freezed_resumptions_.push(frozen_res); + } +} + +std::set<std::string> +VehicleInfoPendingResumptionHandler::GetExtensionSubscriptions( + VehicleInfoAppExtension& extension) { + std::set<std::string> subscriptions; + for (auto& ivi : application_manager::MessageHelper::vehicle_data()) { + const auto it = extension.Subscriptions().find(ivi.second); + if (extension.Subscriptions().end() != it) { + subscriptions.insert(ivi.first); + } + } + return subscriptions; +} + +smart_objects::SmartObjectSPtr +VehicleInfoPendingResumptionHandler::CreateSubscribeRequestToHMI( + const std::set<std::string>& subscriptions) { + LOG4CXX_AUTO_TRACE(logger_); + using namespace application_manager; + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + for (const auto& ivi_data : subscriptions) { + msg_params[ivi_data] = true; + } + + smart_objects::SmartObjectSPtr request = + application_manager::MessageHelper::CreateModuleInfoSO( + hmi_apis::FunctionID::VehicleInfo_SubscribeVehicleData, + application_manager_); + (*request)[strings::msg_params] = msg_params; + + return request; +} +} diff --git a/src/components/application_manager/rpc_plugins/vehicle_info_plugin/src/vehicle_info_plugin.cc b/src/components/application_manager/rpc_plugins/vehicle_info_plugin/src/vehicle_info_plugin.cc index 1e0311e6e4..e0bb598841 100644 --- a/src/components/application_manager/rpc_plugins/vehicle_info_plugin/src/vehicle_info_plugin.cc +++ b/src/components/application_manager/rpc_plugins/vehicle_info_plugin/src/vehicle_info_plugin.cc @@ -37,13 +37,15 @@ #include "application_manager/message_helper.h" #include "application_manager/message_helper.h" #include "application_manager/resumption/resumption_data_processor.h" +#include "vehicle_info_plugin/vehicle_info_pending_resumption_handler.h" namespace vehicle_info_plugin { CREATE_LOGGERPTR_GLOBAL(logger_, "VehicleInfoPlugin") namespace strings = application_manager::strings; -VehicleInfoPlugin::VehicleInfoPlugin() : application_manager_(nullptr) {} +VehicleInfoPlugin::VehicleInfoPlugin() + : application_manager_(nullptr), pending_resumption_handler_(nullptr) {} bool VehicleInfoPlugin::Init( application_manager::ApplicationManager& app_manager, @@ -51,6 +53,8 @@ bool VehicleInfoPlugin::Init( application_manager::HMICapabilities& hmi_capabilities, policy::PolicyHandlerInterface& policy_handler) { application_manager_ = &app_manager; + pending_resumption_handler_ = + std::make_shared<VehicleInfoPendingResumptionHandler>(app_manager); command_factory_.reset(new vehicle_info_plugin::VehicleInfoCommandFactory( app_manager, rpc_service, hmi_capabilities, policy_handler)); return true; @@ -89,27 +93,8 @@ void VehicleInfoPlugin::ProcessResumptionSubscription( resumption::Subscriber subscriber) { LOG4CXX_AUTO_TRACE(logger_); - std::set<std::string> subscriptions; - for (auto& ivi : application_manager::MessageHelper::vehicle_data()) { - const auto it = ext.Subscriptions().find(ivi.second); - if (ext.Subscriptions().end() != it) { - subscriptions.insert(ivi.first); - } - } - - smart_objects::SmartObjectSPtr request = - CreateSubscriptionRequest(subscriptions); - - resumption::ResumptionRequest resumption_request; - resumption_request.request_ids.correlation_id = - (*request)[strings::params][strings::correlation_id].asInt(); - resumption_request.request_ids.function_id = - hmi_apis::FunctionID::VehicleInfo_SubscribeVehicleData; - resumption_request.message = *request; - - subscriber(app.app_id(), resumption_request); - - application_manager_->GetRPCService().ManageHMICommand(request); + pending_resumption_handler_->HandleResumptionSubscriptionRequest( + ext, subscriber, app); } void VehicleInfoPlugin::RevertResumption( @@ -117,6 +102,8 @@ void VehicleInfoPlugin::RevertResumption( const std::set<std::string>& list_of_subscriptions) { LOG4CXX_AUTO_TRACE(logger_); + pending_resumption_handler_->ClearPendingResumptionRequests(); + std::set<std::string> subscriptions_to_revert; for (auto& ivi_data : list_of_subscriptions) { if (!IsSubscribedAppExist(ivi_data)) { @@ -172,6 +159,7 @@ smart_objects::SmartObjectSPtr VehicleInfoPlugin::CreateUnsubscriptionRequest( } bool VehicleInfoPlugin::IsSubscribedAppExist(const std::string& ivi) { + LOG4CXX_AUTO_TRACE(logger_); auto applications = application_manager_->applications(); const auto it = application_manager::MessageHelper::vehicle_data().find(ivi); DCHECK_OR_RETURN( diff --git a/src/components/application_manager/rpc_plugins/vehicle_info_plugin/test/commands/mobile/unsubscribe_vehicle_request_test.cc b/src/components/application_manager/rpc_plugins/vehicle_info_plugin/test/commands/mobile/unsubscribe_vehicle_request_test.cc index 323334de2d..d2235cca47 100644 --- a/src/components/application_manager/rpc_plugins/vehicle_info_plugin/test/commands/mobile/unsubscribe_vehicle_request_test.cc +++ b/src/components/application_manager/rpc_plugins/vehicle_info_plugin/test/commands/mobile/unsubscribe_vehicle_request_test.cc @@ -78,6 +78,8 @@ class UnsubscribeVehicleRequestTest protected: void UnsubscribeSuccessfully(); void SetUp() OVERRIDE { + ON_CALL(app_mngr_, event_dispatcher()) + .WillByDefault(ReturnRef(event_dispatcher_)); vi_plugin_.Init(app_mngr_, mock_rpc_service_, mock_hmi_capabilities_, @@ -107,7 +109,6 @@ TEST_F(UnsubscribeVehicleRequestTest, Run_AppNotRegistered_UNSUCCESS) { mock_rpc_service_, ManageMobileCommand( MobileResultCodeIs(mobile_result::APPLICATION_NOT_REGISTERED), _)); - command->Run(); } |