diff --git a/src/components/application_manager/include/application_manager/application.h b/src/components/application_manager/include/application_manager/application.h index 1263fac476b..715faa4ccaf 100644 --- a/src/components/application_manager/include/application_manager/application.h +++ b/src/components/application_manager/include/application_manager/application.h @@ -1163,52 +1163,6 @@ class Application : public virtual InitialApplicationData, */ virtual const std::list& Extensions() const = 0; - /** - * @brief Get map of pending button subscription requests correlation ids - * to button names - * @return pending button subscriptions map - */ - virtual const ButtonSubscriptionsMap& PendingButtonSubscriptions() const = 0; - - /** - * @brief Add pending button subscription request - * @param correlation_id - correlation id of subscription request - * @param button_name - enum value indicating button name - */ - virtual void AddPendingButtonSubscription( - const int32_t correlation_id, - const hmi_apis::Common_ButtonName::eType button_name) = 0; - - /** - * @brief Remove pending button subscription request - * @param correlation_id - correlation id of subscription request - */ - virtual void RemovePendingSubscriptionButton( - const int32_t correlation_id) = 0; - - /** - * @brief Get map of pending button unsubscription requests correlation ids - * to button names - * @return pending button unsubscriptions map - */ - virtual const ButtonSubscriptionsMap& PendingButtonUnsubscriptions() - const = 0; - - /** - * @brief Add pending button unsubscription request - * @param correlation_id - correlation id of unsubscription request - * @param button_name - enum value indicating button name - */ - virtual void AddPendingButtonUnsubscription( - const int32_t correlation_id, - const hmi_apis::Common_ButtonName::eType button_name) = 0; - /** - * @brief Remove pending button unsubscription request - * @param correlation_id - correlation id of unsubscription request - */ - virtual void RemovePendingButtonUnsubscription( - const int32_t correlation_id) = 0; - /** * @brief Get cloud app endpoint for websocket connection * @return cloud app endpoint 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 a24f3bce46f..21e45b45151 100644 --- a/src/components/application_manager/include/application_manager/application_impl.h +++ b/src/components/application_manager/include/application_manager/application_impl.h @@ -510,22 +510,6 @@ class ApplicationImpl : public virtual Application, const smart_objects::SmartObject& get_user_location() const OVERRIDE; - const ButtonSubscriptionsMap& PendingButtonSubscriptions() const OVERRIDE; - - void AddPendingButtonSubscription( - const int32_t correlation_id, - const hmi_apis::Common_ButtonName::eType button_name) OVERRIDE; - - void RemovePendingSubscriptionButton(const int32_t correlation_id) OVERRIDE; - - const ButtonSubscriptionsMap& PendingButtonUnsubscriptions() const OVERRIDE; - - void AddPendingButtonUnsubscription( - const int32_t correlation_id, - const hmi_apis::Common_ButtonName::eType button_name) OVERRIDE; - - void RemovePendingButtonUnsubscription(const int32_t correlation_id) OVERRIDE; - protected: /** * @brief Clean up application folder. Persistent files will stay @@ -596,7 +580,6 @@ class ApplicationImpl : public virtual Application, sync_primitives::Lock video_streaming_suspended_lock_; sync_primitives::Lock audio_streaming_suspended_lock_; sync_primitives::Lock streaming_stop_lock_; - sync_primitives::Lock pending_button_subscription_lock_; bool is_app_allowed_; bool is_app_data_resumption_allowed_; @@ -617,8 +600,6 @@ class ApplicationImpl : public virtual Application, std::string bundle_id_; AppFilesMap app_files_; std::set subscribed_buttons_; - ButtonSubscriptionsMap pending_button_subscriptions_; - ButtonSubscriptionsMap pending_button_unsubscriptions_; UsageStatistics usage_report_; HelpPromptManagerImpl help_prompt_manager_impl_; protocol_handler::MajorProtocolVersion protocol_version_; 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 9191a06c6bc..d9704ec6c44 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 @@ -121,6 +121,9 @@ enum VRTTSSessionChanging { kVRSessionChanging = 0, kTTSSessionChanging }; typedef std::map > ServiceStreamingStatusMap; +typedef std::map + ExpiredButtonRequestsMap; + struct CommandParametersPermissions; typedef std::map DeviceTypes; @@ -1544,6 +1547,16 @@ class ApplicationManagerImpl static std::vector ConvertRejectedParamList( const std::vector& input); + void AddExpiredButtonRequest( + const uint32_t app_id, + const int32_t corr_id, + const hmi_apis::Common_ButtonName::eType button_name) OVERRIDE; + + utils::Optional GetExpiredButtonRequestData( + const int32_t corr_id) const OVERRIDE; + + void DeleteExpiredButtonRequest(const int32_t corr_id) OVERRIDE; + private: const ApplicationManagerSettings& settings_; /** @@ -1705,6 +1718,9 @@ class ApplicationManagerImpl ServiceStreamingStatusMap streaming_application_services_; sync_primitives::Lock streaming_services_lock_; + mutable sync_primitives::Lock expired_button_requests_lock_; + mutable ExpiredButtonRequestsMap expired_button_requests_; + #ifdef BUILD_TESTS public: /** diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/subscribe_button_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/subscribe_button_request.cc index 784703e2d49..07940d972db 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/subscribe_button_request.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/subscribe_button_request.cc @@ -71,37 +71,16 @@ void SubscribeButtonRequest::Run() { subscribe_on_event(hmi_apis::FunctionID::Buttons_SubscribeButton, correlation_id()); - - ApplicationSharedPtr app = - application_manager_.application_by_hmi_app(application_id()); - - if (!app) { - SDL_LOG_ERROR("Application for connection key: " << application_id() - << " was not found"); - return; - } - - app->AddPendingButtonSubscription(correlation_id(), button_name_); - SendRequest(); } void SubscribeButtonRequest::onTimeOut() { SDL_LOG_AUTO_TRACE(); - auto& resume_ctrl = application_manager_.resume_controller(); - - ApplicationSharedPtr app = - application_manager_.application_by_hmi_app(application_id()); - - if (!app) { - SDL_LOG_ERROR("Application for app id: " << application_id() - << " was not found"); - return; - } - - app->RemovePendingSubscriptionButton(correlation_id()); + application_manager_.AddExpiredButtonRequest( + application_id(), correlation_id(), button_name_); + auto& resume_ctrl = application_manager_.resume_controller(); resume_ctrl.HandleOnTimeOut( correlation_id(), static_cast(function_id())); @@ -133,44 +112,25 @@ void SubscribeButtonRequest::on_event(const event_engine::Event& event) { static_cast( message[strings::params][hmi_response::code].asInt()); - const auto pending_button_subscriptions = app->PendingButtonSubscriptions(); - - const auto it = - pending_button_subscriptions.find(event.smart_object_correlation_id()); - - const bool is_pending = it != pending_button_subscriptions.end(); - const mobile_apis::ButtonName::eType btn_id = static_cast( (*message_)[strings::msg_params][strings::button_name].asInt()); if (CommandImpl::IsHMIResultSuccess(hmi_result, - HmiInterfaces::HMI_INTERFACE_Buttons) && - is_pending) { + HmiInterfaces::HMI_INTERFACE_Buttons)) { app->SubscribeToButton(static_cast(btn_id)); - app->RemovePendingSubscriptionButton(correlation_id()); } else if (ShouldUnsubscribeIntertally(hmi_result, *app)) { app->UnsubscribeFromButton( static_cast(btn_id)); - app->RemovePendingSubscriptionButton(correlation_id()); - } else if (!is_pending) { - smart_objects::SmartObjectSPtr msg = - MessageHelper::CreateButtonSubscriptionHandlingRequestToHmi( - application_id(), - static_cast(button_name_), - hmi_apis::FunctionID::Buttons_UnsubscribeButton, - application_manager_); - - rpc_service_.SendMessageToHMI(msg); } } bool SubscribeButtonRequest::ShouldUnsubscribeIntertally( const hmi_apis::Common_Result::eType hmi_result, const app_mngr::Application& app) const { - return (hmi_result != hmi_apis::Common_Result::SUCCESS && - hmi_result != hmi_apis::Common_Result::WARNINGS) && - (app.is_resuming()); + return (!CommandImpl::IsHMIResultSuccess( + hmi_result, HmiInterfaces::HMI_INTERFACE_Buttons) && + app.is_resuming()); } } // namespace hmi diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/subscribe_button_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/subscribe_button_response.cc index 9dc7b3ac450..202cde29c63 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/subscribe_button_response.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/subscribe_button_response.cc @@ -31,6 +31,7 @@ */ #include "sdl_rpc_plugin/commands/hmi/subscribe_button_response.h" #include "application_manager/event_engine/event.h" +#include "application_manager/message_helper.h" namespace sdl_rpc_plugin { using namespace application_manager; @@ -55,6 +56,37 @@ SubscribeButtonResponse::~SubscribeButtonResponse() {} void SubscribeButtonResponse::Run() { SDL_LOG_AUTO_TRACE(); + + hmi_apis::Common_Result::eType hmi_result = + static_cast( + (*message_) + .getElement(strings::params) + .getElement(hmi_response::code) + .asInt()); + + const auto expired_request_data = + application_manager_.GetExpiredButtonRequestData(correlation_id()); + if (expired_request_data) { + const uint32_t app_id = (*expired_request_data).app_id_; + const auto button_name = (*expired_request_data).button_name_; + application_manager_.DeleteExpiredButtonRequest(correlation_id()); + + if (!CommandImpl::IsHMIResultSuccess( + hmi_result, HmiInterfaces::HMI_INTERFACE_Buttons)) { + return; + } + + smart_objects::SmartObjectSPtr msg = + MessageHelper::CreateButtonSubscriptionHandlingRequestToHmi( + app_id, + button_name, + hmi_apis::FunctionID::Buttons_UnsubscribeButton, + application_manager_); + + rpc_service_.SendMessageToHMI(msg); + return; + } + event_engine::Event event(hmi_apis::FunctionID::Buttons_SubscribeButton); event.set_smart_object(*message_); event.raise(application_manager_.event_dispatcher()); diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/unsubscribe_button_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/unsubscribe_button_request.cc index 2412d9ba73a..6399fe6fe5d 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/unsubscribe_button_request.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/unsubscribe_button_request.cc @@ -71,40 +71,19 @@ void UnsubscribeButtonRequest::Run() { subscribe_on_event(hmi_apis::FunctionID::Buttons_UnsubscribeButton, correlation_id()); - - ApplicationSharedPtr app = - application_manager_.application_by_hmi_app(application_id()); - - if (!app) { - SDL_LOG_ERROR("Application for connection key: " << application_id() - << " was not found"); - return; - } - - app->AddPendingButtonUnsubscription(correlation_id(), button_name_); - SendRequest(); } void UnsubscribeButtonRequest::onTimeOut() { SDL_LOG_AUTO_TRACE(); - auto& resume_ctrl = application_manager_.resume_controller(); + application_manager_.AddExpiredButtonRequest( + application_id(), correlation_id(), button_name_); + auto& resume_ctrl = application_manager_.resume_controller(); resume_ctrl.HandleOnTimeOut( correlation_id(), static_cast(function_id())); - - ApplicationSharedPtr app = - application_manager_.application_by_hmi_app(application_id()); - - if (!app) { - SDL_LOG_ERROR("Application for connection key: " << application_id() - << " was not found"); - return; - } - - app->RemovePendingButtonUnsubscription(correlation_id()); } void UnsubscribeButtonRequest::on_event(const event_engine::Event& event) { @@ -120,36 +99,17 @@ void UnsubscribeButtonRequest::on_event(const event_engine::Event& event) { return; } - const auto pending_button_unsubscriptions = - app->PendingButtonUnsubscriptions(); - - const auto it = - pending_button_unsubscriptions.find(event.smart_object_correlation_id()); - - const bool is_pending = it != pending_button_unsubscriptions.end(); - hmi_apis::Common_Result::eType hmi_result = static_cast( message[strings::params][hmi_response::code].asInt()); if (CommandImpl::IsHMIResultSuccess(hmi_result, - HmiInterfaces::HMI_INTERFACE_Buttons) && - is_pending) { + HmiInterfaces::HMI_INTERFACE_Buttons)) { const mobile_apis::ButtonName::eType btn_id = static_cast( (*message_)[strings::msg_params][strings::button_name].asInt()); app->UnsubscribeFromButton( static_cast(btn_id)); - app->RemovePendingButtonUnsubscription(correlation_id()); - } else if (!is_pending) { - smart_objects::SmartObjectSPtr msg = - MessageHelper::CreateButtonSubscriptionHandlingRequestToHmi( - application_id(), - static_cast(button_name_), - hmi_apis::FunctionID::Buttons_SubscribeButton, - application_manager_); - - rpc_service_.SendMessageToHMI(msg); } } diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/unsubscribe_button_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/unsubscribe_button_response.cc index dd18e8acdf1..68b3663ca7b 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/unsubscribe_button_response.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/unsubscribe_button_response.cc @@ -31,6 +31,7 @@ */ #include "sdl_rpc_plugin/commands/hmi/unsubscribe_button_response.h" #include "application_manager/event_engine/event.h" +#include "application_manager/message_helper.h" namespace sdl_rpc_plugin { using namespace application_manager; @@ -56,6 +57,37 @@ UnsubscribeButtonResponse::~UnsubscribeButtonResponse() {} void UnsubscribeButtonResponse::Run() { SDL_LOG_AUTO_TRACE(); + + hmi_apis::Common_Result::eType hmi_result = + static_cast( + (*message_) + .getElement(strings::params) + .getElement(hmi_response::code) + .asInt()); + + const auto expired_request_data = + application_manager_.GetExpiredButtonRequestData(correlation_id()); + if (expired_request_data) { + const uint32_t app_id = (*expired_request_data).app_id_; + const auto button_name = (*expired_request_data).button_name_; + application_manager_.DeleteExpiredButtonRequest(correlation_id()); + + if (!CommandImpl::IsHMIResultSuccess( + hmi_result, HmiInterfaces::HMI_INTERFACE_Buttons)) { + return; + } + + smart_objects::SmartObjectSPtr msg = + MessageHelper::CreateButtonSubscriptionHandlingRequestToHmi( + app_id, + button_name, + hmi_apis::FunctionID::Buttons_SubscribeButton, + application_manager_); + + rpc_service_.SendMessageToHMI(msg); + return; + } + event_engine::Event event(hmi_apis::FunctionID::Buttons_UnsubscribeButton); event.set_smart_object(*message_); event.raise(application_manager_.event_dispatcher()); diff --git a/src/components/application_manager/src/application_impl.cc b/src/components/application_manager/src/application_impl.cc index fb1d4806bd1..2952fd54812 100644 --- a/src/components/application_manager/src/application_impl.cc +++ b/src/components/application_manager/src/application_impl.cc @@ -1386,42 +1386,6 @@ const smart_objects::SmartObject& ApplicationImpl::get_user_location() const { return user_location_; } -const std::map& -ApplicationImpl::PendingButtonSubscriptions() const { - return pending_button_subscriptions_; -} - -const std::map& -ApplicationImpl::PendingButtonUnsubscriptions() const { - return pending_button_unsubscriptions_; -} - -void ApplicationImpl::AddPendingButtonSubscription( - const int32_t correlation_id, - const hmi_apis::Common_ButtonName::eType button_name) { - sync_primitives::AutoLock auto_lock(pending_button_subscription_lock_); - pending_button_subscriptions_[correlation_id] = button_name; -} - -void ApplicationImpl::RemovePendingSubscriptionButton( - const int32_t correlation_id) { - sync_primitives::AutoLock auto_lock(pending_button_subscription_lock_); - pending_button_subscriptions_.erase(correlation_id); -} - -void ApplicationImpl::AddPendingButtonUnsubscription( - const int32_t correlation_id, - const hmi_apis::Common_ButtonName::eType button_name) { - sync_primitives::AutoLock auto_lock(pending_button_subscription_lock_); - pending_button_unsubscriptions_[correlation_id] = button_name; -} - -void ApplicationImpl::RemovePendingButtonUnsubscription( - const int32_t correlation_id) { - sync_primitives::AutoLock auto_lock(pending_button_subscription_lock_); - pending_button_unsubscriptions_.erase(correlation_id); -} - void ApplicationImpl::PushMobileMessage( smart_objects::SmartObjectSPtr mobile_message) { sync_primitives::AutoLock lock(mobile_message_lock_); diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc index d2104dbf1a2..c3a1e9d327c 100644 --- a/src/components/application_manager/src/application_manager_impl.cc +++ b/src/components/application_manager/src/application_manager_impl.cc @@ -3188,6 +3188,11 @@ void ApplicationManagerImpl::UnregisterAllApplications() { resume_controller().OnIgnitionOff(); } request_ctrl_.terminateAllHMIRequests(); + + { + sync_primitives::AutoLock lock(expired_button_requests_lock_); + expired_button_requests_.clear(); + } } void ApplicationManagerImpl::RemoveAppsWaitingForRegistration( @@ -5119,4 +5124,36 @@ void ApplicationManagerImpl::ChangeAppsHMILevel( } } +void ApplicationManagerImpl::AddExpiredButtonRequest( + const uint32_t app_id, + const int32_t corr_id, + const hmi_apis::Common_ButtonName::eType button_name) { + SDL_LOG_AUTO_TRACE(); + + sync_primitives::AutoLock lock(expired_button_requests_lock_); + expired_button_requests_[corr_id] = {app_id, button_name}; +} + +utils::Optional +ApplicationManagerImpl::GetExpiredButtonRequestData( + const int32_t corr_id) const { + SDL_LOG_AUTO_TRACE(); + sync_primitives::AutoLock lock(expired_button_requests_lock_); + + auto found_subscription = expired_button_requests_.find(corr_id); + if (found_subscription == expired_button_requests_.end()) { + return utils::Optional::EMPTY; + } + + return utils::Optional(found_subscription->second); +} + +void ApplicationManagerImpl::DeleteExpiredButtonRequest(const int32_t corr_id) { + SDL_LOG_AUTO_TRACE(); + + sync_primitives::AutoLock lock(expired_button_requests_lock_); + auto found_subscription = expired_button_requests_.find(corr_id); + expired_button_requests_.erase(found_subscription); +} + } // namespace application_manager 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 ae343e9d827..2c9fe688b44 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 @@ -436,16 +436,6 @@ class MockApplication : public ::application_manager::Application { MOCK_METHOD1(set_user_location, void(const smart_objects::SmartObject& user_location)); MOCK_CONST_METHOD0(get_user_location, const smart_objects::SmartObject&()); - MOCK_CONST_METHOD0(PendingButtonSubscriptions, - std::map&()); - MOCK_CONST_METHOD0(PendingButtonUnsubscriptions, - std::map&()); - MOCK_METHOD2(AddPendingButtonSubscription, - void(const int32_t, const hmi_apis::Common_ButtonName::eType)); - MOCK_METHOD1(RemovePendingSubscriptionButton, void(const int32_t)); - MOCK_METHOD2(AddPendingButtonUnsubscription, - void(const int32_t, const hmi_apis::Common_ButtonName::eType)); - MOCK_METHOD1(RemovePendingButtonUnsubscription, void(const int32_t)); }; } // namespace application_manager_test diff --git a/src/components/include/application_manager/application_manager.h b/src/components/include/application_manager/application_manager.h index 54f7ab9f058..32aaf671a18 100644 --- a/src/components/include/application_manager/application_manager.h +++ b/src/components/include/application_manager/application_manager.h @@ -114,6 +114,11 @@ struct ApplicationsPolicyAppIdSorter { } }; +struct ExpiredButtonRequestData { + uint32_t app_id_; + hmi_apis::Common_ButtonName::eType button_name_; +}; + typedef std::set ApplicationSet; typedef std::set @@ -953,6 +958,35 @@ class ApplicationManager { */ virtual bool UnsubscribeAppFromSoftButtons( const commands::MessageSharedPtr response_message) = 0; + + /** + * @brief Save subscribe/unsubscribe button request after timeout to ensure + * possibility to align mobile subscription/unsubscription status with actual + * subscription/unsubscription status on HMI + * @param app_id Application id from request message + * @param corr_id Correlation id + * @param button_name name of button to subscribe/unsubscribe + */ + virtual void AddExpiredButtonRequest( + const uint32_t app_id, + const int32_t corr_id, + const hmi_apis::Common_ButtonName::eType button_name) = 0; + + /** + * @brief Return optional structure with information regarding + * subscribe/unsubscribe button request data + * @param corr_id Correlation id + * @return optional structure with subscribe/unsubscribe button request data + */ + virtual utils::Optional GetExpiredButtonRequestData( + const int32_t corr_id) const = 0; + + /** + * @brief Delete data about already processed expired subscribe/unsubscribe + * button request in case if HMI send response to expired request + * @param corr_id Correlation id + */ + virtual void DeleteExpiredButtonRequest(const int32_t corr_id) = 0; }; } // namespace application_manager diff --git a/src/components/include/test/application_manager/mock_application_manager.h b/src/components/include/test/application_manager/mock_application_manager.h index fd7ddeac15d..3b6c4170313 100644 --- a/src/components/include/test/application_manager/mock_application_manager.h +++ b/src/components/include/test/application_manager/mock_application_manager.h @@ -405,6 +405,15 @@ class MockApplicationManager : public application_manager::ApplicationManager { MOCK_CONST_METHOD0(GetCommandFactory, application_manager::CommandFactory&()); MOCK_CONST_METHOD0(get_current_audio_source, uint32_t()); MOCK_METHOD1(set_current_audio_source, void(const uint32_t)); + MOCK_METHOD3(AddExpiredButtonRequest, + void(const uint32_t app_id, + const int32_t corr_id, + const hmi_apis::Common_ButtonName::eType button_name)); + MOCK_CONST_METHOD1( + GetExpiredButtonRequestData, + utils::Optional( + const int32_t corr_id)); + MOCK_METHOD1(DeleteExpiredButtonRequest, void(const int32_t corr_id)); }; } // namespace application_manager_test