diff options
author | BSolonenko <BSolonenko@luxoft.com> | 2018-08-02 17:07:37 +0300 |
---|---|---|
committer | Alexander Kutsan (GitHub) <akutsan@luxoft.com> | 2018-08-09 12:43:44 +0300 |
commit | 90110d141600749ebe4f6222f8342d40ad09543d (patch) | |
tree | 935ddd29bbb798ac6892b8e117c077b7efc9a8c3 | |
parent | 22988e9174b5e0d3bc00bd28336878bfa11e7a96 (diff) | |
download | sdl_core-90110d141600749ebe4f6222f8342d40ad09543d.tar.gz |
Added resumption and revert resumption process.
Created ResumptionDataProcessor class.
Added ResumptionDataProcessor in resume_ctrl_impl.
5 files changed, 833 insertions, 5 deletions
diff --git a/src/components/application_manager/include/application_manager/resumption/resume_ctrl_impl.h b/src/components/application_manager/include/application_manager/resumption/resume_ctrl_impl.h index 7b9970471e..7a79699ecd 100644 --- a/src/components/application_manager/include/application_manager/resumption/resume_ctrl_impl.h +++ b/src/components/application_manager/include/application_manager/resumption/resume_ctrl_impl.h @@ -45,6 +45,7 @@ #include "smart_objects/smart_object.h" #include "application_manager/application.h" #include "application_manager/resumption/resumption_data.h" +#include "application_manager/resumption/resumption_data_processor.h" #include "application_manager/resumption/resume_ctrl.h" #include "utils/timer.h" @@ -453,6 +454,7 @@ class ResumeCtrlImpl : public ResumeCtrl { time_t launch_time_; std::shared_ptr<ResumptionData> resumption_storage_; application_manager::ApplicationManager& application_manager_; + ResumptionDataProcessor resumption_data_processor_; }; } // namespace resumption diff --git a/src/components/application_manager/include/application_manager/resumption/resumption_data_processor.h b/src/components/application_manager/include/application_manager/resumption/resumption_data_processor.h new file mode 100644 index 0000000000..6e309af44b --- /dev/null +++ b/src/components/application_manager/include/application_manager/resumption/resumption_data_processor.h @@ -0,0 +1,272 @@ +/* + 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_INCLUDE_APPLICATION_MANAGER_RESUMPTION_RESUMPTION_PROCESS_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_RESUMPTION_RESUMPTION_PROCESS_ + +#include <map> +#include <vector> +#include <functional> + +#include "smart_objects/smart_object.h" +#include "application_manager/application.h" +#include "application_manager/event_engine/event_observer.h" + +namespace resumption { + +namespace app_mngr = application_manager; + +struct ResumptionRequest { + hmi_apis::FunctionID::eType function_id; + int32_t correlation_id; + smart_objects::SmartObject message; +}; + +struct ApplicationResumptionStatus { + std::vector<ResumptionRequest> list_of_sent_requests; + std::vector<ResumptionRequest> error_requests; + std::vector<ResumptionRequest> successful_requests; +}; + +/** + * @brief Contains logic for the resumption and revert resumption data of + * applications. + */ +class ResumptionDataProcessor : public app_mngr::event_engine::EventObserver { + public: + /** + * @brief allows to create ResumptionDataProcessor object + */ + explicit ResumptionDataProcessor( + application_manager::ApplicationManager& application_manager); + + /** + * @brief allows to destroy ResumptionDataProcessor object + */ + ~ResumptionDataProcessor(); + + /** + * @brief Running resumption data process from saved_app to application. + * @param application application which will be resumed + * @param saved_app application specific section from backup file + */ + void Restore(app_mngr::ApplicationSharedPtr application, + smart_objects::SmartObject& saved_app); + + /** + * @brief Event, that raised if application get resumption response from HMI + * @param event : event object, that contains smart_object HMI response + * message + */ + void on_event(const app_mngr::event_engine::Event& event) OVERRIDE; + + private: + /** + * @brief Revert the data to the state before Resumption + * @param app_id application id + */ + void RevertRestoredData(const int32_t app_id); + + /** + * @brief subscribe to events for the application and save request + * @param app_id application id + * @param request for saving + */ + void WaitForResponse(const int32_t app_id, const ResumptionRequest& request); + + /** + * @brief Process specified HMI request + * @param request Request to process + * @param use_events Process request events or not flag + * @return TRUE on success, otherwise FALSE + */ + void ProcessHMIRequest(smart_objects::SmartObjectSPtr request, + bool subscribe_on_response); + + /** + * @brief Process list of HMI requests using ProcessHMIRequest method + * @param requests List of requests to process + */ + void ProcessHMIRequests(const smart_objects::SmartObjectList& requests); + + /** + * @brief AddFiles allows to add files for the application + * which should be resumed + * @param application application which will be resumed + * @param saved_app application specific section from backup file + */ + void AddFiles(app_mngr::ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app); + + /** + * @brief Deleting files that have been resumed + * @param app_id application id + */ + void DeleteFiles(const int32_t app_id); + + /** + * @brief AddSubmenues allows to add sub-menus for the application + * which should be resumed + * @param application application which will be resumed + * @param saved_app application specific section from backup file + */ + void AddSubmenues(app_mngr::ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app); + + /** + * @brief Deleting sub-menus that have been resumed + * @param app_id application id + */ + void DeleteSubmenues(const int32_t app_id); + + /** + * @brief AddCommands allows to add commands for the application + * which should be resumed + * @param application application which will be resumed + * @param saved_app application specific section from backup file + */ + void AddCommands(app_mngr::ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app); + + /** + * @brief Deleting all commands that have been resumed + * @param app_id application id + */ + void DeleteCommands(const int32_t app_id); + + /** + * @brief Deleting UI commands that have been resumed + * @param app_id application id + */ + void DeleteUICommands(const ResumptionRequest& request); + + /** + * @brief Deleting VR commands that have been resumed + * @param app_id application id + */ + void DeleteVRCommands(const ResumptionRequest& request); + + /** + * @brief AddChoicesets allows to add choice sets for the application + * which should be resumed + * @param application application which will be resumed + * @param saved_app application specific section from backup file + */ + void AddChoicesets(app_mngr::ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app); + + /** + * @brief Deleting choice sets that have been resumed + * @param app_id application id + */ + void DeleteChoicesets(const int32_t app_id); + + /** + * @brief SetGlobalProperties allows to restore global properties. + * @param application application which will be resumed + * @param saved_app application specific section from backup file + */ + void SetGlobalProperties(app_mngr::ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app); + + /** + * @brief Reset global properties that have been resumed + * @param app_id application id + */ + void DeleteGlobalProperties(const int32_t app_id); + + /** + * @brief AddSubscriptions allows to restore subscriptions + * @param application application which will be resumed + * @param saved_app application specific section from backup file + */ + void AddSubscriptions(app_mngr::ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app); + + /** + * @brief AddSubscriptions allows to restore subscriptions + * @param application application which will be resumed + * @param saved_app application specific section from backup file + */ + void AddButtonsSubscriptions(app_mngr::ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app); + + /** + * @brief AddSubscriptions allows to restore subscriptions + * @param application application which will be resumed + * @param saved_app application specific section from backup file + */ + void AddPluginsSubscriptions(app_mngr::ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app); + + /** + * @brief Deleting subscriptions have been resumed + * @param app_id application id + */ + void DeleteSubscriptions(const int32_t app_id); + + /** + * @brief Deleting buttons subscriptions have been resumed + * @param app_id application id + */ + void DeleteButtonsSubscriptions(app_mngr::ApplicationSharedPtr application); + + /** + * @brief Deleting plugins subscriptions have been resumed + * @param app_id application id + */ + void DeletePluginsSubscriptions(app_mngr::ApplicationSharedPtr application); + + /** + * @brief AddWayPointsSubscription allows to restore subscription + * for WayPoints + * @param application application which will be resumed + * @param saved_app application specific section from backup file + */ + void AddWayPointsSubscription(app_mngr::ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app); + + /** + * @brief Deleting subscription for WayPoints have been resumed + * @param app_id application id + */ + void DeleteWayPointsSubscription(const int32_t app_id); + + /** + * @brief A map of the IDs and Application Resumption Status for these ID + **/ + app_mngr::ApplicationManager& application_manager_; + std::map<std::int32_t, ApplicationResumptionStatus> resumption_status_; +}; + +} // namespace resumption + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_RESUMPTION_RESUMPTION_PROCESS_ diff --git a/src/components/application_manager/src/message_helper/message_helper.cc b/src/components/application_manager/src/message_helper/message_helper.cc index 052d619fcc..5c0d257fdd 100644 --- a/src/components/application_manager/src/message_helper/message_helper.cc +++ b/src/components/application_manager/src/message_helper/message_helper.cc @@ -1335,10 +1335,11 @@ smart_objects::SmartObjectList MessageHelper::CreateAddCommandRequestToHMI( // VR Interface if ((*i->second).keyExists(strings::vr_commands)) { - SendAddVRCommandToHMI(i->first, - (*i->second)[strings::vr_commands], - app->app_id(), - app_mngr); + requests.push_back( + CreateAddVRCommandToHMI(/*cmd_id = */ i->first, + (*i->second)[strings::vr_commands], + app->app_id(), + app_mngr)); } } return requests; diff --git a/src/components/application_manager/src/resumption/resume_ctrl_impl.cc b/src/components/application_manager/src/resumption/resume_ctrl_impl.cc index 1fd88f0ee1..290c0995c8 100644 --- a/src/components/application_manager/src/resumption/resume_ctrl_impl.cc +++ b/src/components/application_manager/src/resumption/resume_ctrl_impl.cc @@ -74,7 +74,8 @@ ResumeCtrlImpl::ResumeCtrlImpl(ApplicationManager& application_manager) , is_data_saved_(false) , is_suspended_(false) , launch_time_(time(NULL)) - , application_manager_(application_manager) {} + , application_manager_(application_manager) + , resumption_data_processor_(application_manager) {} #ifdef BUILD_TESTS void ResumeCtrlImpl::set_resumption_storage( std::shared_ptr<ResumptionData> mock_storage) { @@ -547,6 +548,9 @@ bool ResumeCtrlImpl::RestoreApplicationData(ApplicationSharedPtr application) { if (saved_app.keyExists(strings::grammar_id)) { const uint32_t app_grammar_id = saved_app[strings::grammar_id].asUInt(); application->set_grammar_id(app_grammar_id); + + resumption_data_processor_.Restore(application, saved_app); + result = true; } else { LOG4CXX_WARN(logger_, diff --git a/src/components/application_manager/src/resumption/resumption_data_processor.cc b/src/components/application_manager/src/resumption/resumption_data_processor.cc new file mode 100644 index 0000000000..81b40924ab --- /dev/null +++ b/src/components/application_manager/src/resumption/resumption_data_processor.cc @@ -0,0 +1,549 @@ +/* + 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 <algorithm> + +#include "application_manager/resumption/resumption_data_processor.h" +#include "application_manager/application_manager.h" +#include "application_manager/smart_object_keys.h" +#include "application_manager/message_helper.h" +#include "application_manager/event_engine/event_observer.h" + +namespace resumption { + +using app_mngr::ApplicationSharedPtr; +using app_mngr::AppFile; +using app_mngr::MessageHelper; +using app_mngr::ChoiceSetMap; +using app_mngr::ButtonSubscriptions; +namespace strings = app_mngr::strings; +namespace event_engine = app_mngr::event_engine; + +CREATE_LOGGERPTR_GLOBAL(logger_, "Resumption") + +ResumptionDataProcessor::ResumptionDataProcessor( + app_mngr::ApplicationManager& application_manager) + : event_engine::EventObserver(application_manager.event_dispatcher()) + , application_manager_(application_manager) {} + +ResumptionDataProcessor::~ResumptionDataProcessor() {} + +void ResumptionDataProcessor::Restore(ApplicationSharedPtr application, + smart_objects::SmartObject& saved_app) { + LOG4CXX_AUTO_TRACE(logger_); + AddFiles(application, saved_app); + AddSubmenues(application, saved_app); + AddCommands(application, saved_app); + AddChoicesets(application, saved_app); + SetGlobalProperties(application, saved_app); + AddSubscriptions(application, saved_app); + AddWayPointsSubscription(application, saved_app); +} + +void ResumptionDataProcessor::on_event(const event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + const smart_objects::SmartObject& response = event.smart_object(); + + const int32_t app_id = + response[strings::msg_params][strings::app_id].asUInt(); + + ApplicationResumptionStatus& status = resumption_status_[app_id]; + std::vector<ResumptionRequest>& list_of_sent_requests = + status.list_of_sent_requests; + + auto request_ptr = std::find_if( + list_of_sent_requests.begin(), + list_of_sent_requests.end(), + [&event](const ResumptionRequest& request) { + return request.correlation_id == event.smart_object_correlation_id() && + request.function_id == event.id(); + }); + + if (list_of_sent_requests.end() == request_ptr) { + LOG4CXX_ERROR(logger_, "Request not found"); + return; + } + + const bool is_success = response[strings::params][strings::success].asBool(); + + if (is_success) { + status.successful_requests.push_back(*request_ptr); + } else { + status.error_requests.push_back(*request_ptr); + } + list_of_sent_requests.erase(request_ptr); + + if (!list_of_sent_requests.empty()) { + LOG4CXX_DEBUG(logger_, "is not the last response for this application"); + return; + } + + if (status.error_requests.empty()) { + LOG4CXX_DEBUG(logger_, "Resumption for app " << app_id << "successful"); + } + if (!status.error_requests.empty()) { + LOG4CXX_ERROR(logger_, "Resumption for app " << app_id << "failed"); + RevertRestoredData(app_id); + } + resumption_status_.erase(app_id); +} + +void ResumptionDataProcessor::RevertRestoredData(const int32_t app_id) { + LOG4CXX_AUTO_TRACE(logger_); + DeleteFiles(app_id); + DeleteSubmenues(app_id); + DeleteCommands(app_id); + DeleteChoicesets(app_id); + DeleteGlobalProperties(app_id); + DeleteSubscriptions(app_id); + DeleteWayPointsSubscription(app_id); +} + +void ResumptionDataProcessor::WaitForResponse( + const int32_t app_id, const ResumptionRequest& request) { + LOG4CXX_AUTO_TRACE(logger_); + subscribe_on_event(request.function_id, request.correlation_id); + resumption_status_[app_id].list_of_sent_requests.push_back(request); +} + +void ResumptionDataProcessor::ProcessHMIRequest( + smart_objects::SmartObjectSPtr request, bool subscribe_on_response) { + LOG4CXX_AUTO_TRACE(logger_); + if (subscribe_on_response) { + auto function_id = static_cast<hmi_apis::FunctionID::eType>( + (*request)[strings::function_id].asInt()); + + const int32_t hmi_correlation_id = + (*request)[strings::correlation_id].asInt(); + + const int32_t app_id = + (*request)[strings::msg_params][strings::app_id].asInt(); + + ResumptionRequest wait_for_response; + wait_for_response.correlation_id = hmi_correlation_id; + wait_for_response.function_id = function_id; + wait_for_response.message = *request; + + WaitForResponse(app_id, wait_for_response); + } + if (!application_manager_.GetRPCService().ManageHMICommand(request)) { + LOG4CXX_ERROR(logger_, "Unable to send request"); + } +} + +void ResumptionDataProcessor::ProcessHMIRequests( + const smart_objects::SmartObjectList& requests) { + LOG4CXX_AUTO_TRACE(logger_); + if(requests.empty()){ + LOG4CXX_DEBUG(logger_,"requests list is empty"); + return; + } + + for (const auto& it : requests) { + ProcessHMIRequest(it, /*subscribe_on_response = */ true); + } +} + +void ResumptionDataProcessor::AddFiles( + ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app) { + LOG4CXX_AUTO_TRACE(logger_); + if (!saved_app.keyExists(strings::application_files)) { + LOG4CXX_ERROR(logger_, "application_files section is not exists"); + return; + } + + const smart_objects::SmartObject& application_files = + saved_app[strings::application_files]; + + for (size_t i = 0; i < application_files.length(); ++i) { + const smart_objects::SmartObject& file_data = application_files[i]; + const bool is_persistent = file_data.keyExists(strings::persistent_file) && + file_data[strings::persistent_file].asBool(); + if (is_persistent) { + AppFile file; + file.is_persistent = is_persistent; + file.is_download_complete = + file_data[strings::is_download_complete].asBool(); + file.file_name = file_data[strings::sync_file_name].asString(); + file.file_type = static_cast<mobile_apis::FileType::eType>( + file_data[strings::file_type].asInt()); + application->AddFile(file); + } + } +} + +void ResumptionDataProcessor::DeleteFiles(const int32_t app_id) { + LOG4CXX_AUTO_TRACE(logger_); + ApplicationSharedPtr application = application_manager_.application(app_id); + while (!application->getAppFiles().empty()) { + application->DeleteFile(application->getAppFiles().begin()->first); + } +} + +void ResumptionDataProcessor::AddSubmenues( + ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app) { + LOG4CXX_AUTO_TRACE(logger_); + + if (!saved_app.keyExists(strings::application_submenus)) { + LOG4CXX_ERROR(logger_, "application_submenus section is not exists"); + return; + } + + const smart_objects::SmartObject& app_submenus = + saved_app[strings::application_submenus]; + + for (size_t i = 0; i < app_submenus.length(); ++i) { + const smart_objects::SmartObject& submenu = app_submenus[i]; + application->AddSubMenu(submenu[strings::menu_id].asUInt(), submenu); + } + + ProcessHMIRequests(MessageHelper::CreateAddSubMenuRequestToHMI( + application, application_manager_.GetNextHMICorrelationID())); +} + +void ResumptionDataProcessor::DeleteSubmenues(const int32_t app_id) { + LOG4CXX_AUTO_TRACE(logger_); + ApplicationResumptionStatus& status = resumption_status_[app_id]; + ApplicationSharedPtr application = application_manager_.application(app_id); + for (auto request : status.successful_requests) { + if (hmi_apis::FunctionID::UI_AddSubMenu == request.function_id) { + smart_objects::SmartObjectSPtr ui_sub_menu = + MessageHelper::CreateMessageForHMI( + hmi_apis::messageType::request, + application_manager_.GetNextHMICorrelationID()); + + (*ui_sub_menu)[strings::params][strings::function_id] = + hmi_apis::FunctionID::UI_DeleteSubMenu; + + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + msg_params[strings::menu_id] = + request.message[strings::msg_params][strings::menu_id]; + msg_params[strings::app_id] = + request.message[strings::msg_params][strings::app_id]; + + (*ui_sub_menu)[strings::msg_params] = msg_params; + + application->RemoveSubMenu(msg_params[strings::menu_id].asInt()); + ProcessHMIRequest(ui_sub_menu, /*subscribe_on_response = */ false); + } + } +} + +void ResumptionDataProcessor::AddCommands( + ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app) { + LOG4CXX_AUTO_TRACE(logger_); + if (!saved_app.keyExists(strings::application_commands)) { + LOG4CXX_ERROR(logger_, "application_commands section is not exists"); + } + + const smart_objects::SmartObject& app_commands = + saved_app[strings::application_commands]; + + for (size_t i = 0; i < app_commands.length(); ++i) { + const smart_objects::SmartObject& command = app_commands[i]; + const uint32_t cmd_id = command[strings::cmd_id].asUInt(); + + application->AddCommand(cmd_id, command); + application->help_prompt_manager().OnVrCommandAdded( + cmd_id, command, /*is_resumption =*/true); + } + + ProcessHMIRequests(MessageHelper::CreateAddCommandRequestToHMI( + application, application_manager_)); +} + +void ResumptionDataProcessor::DeleteCommands(const int32_t app_id) { + LOG4CXX_AUTO_TRACE(logger_); + ApplicationSharedPtr application = application_manager_.application(app_id); + ApplicationResumptionStatus& status = resumption_status_[app_id]; + + for (auto request : status.successful_requests) { + const uint32_t cmd_id = + request.message[strings::msg_params][strings::cmd_id].asUInt(); + + if (hmi_apis::FunctionID::UI_AddCommand == request.function_id) { + DeleteUICommands(request); + } + if (hmi_apis::FunctionID::VR_AddCommand == request.function_id) { + DeleteVRCommands(request); + } + + application->RemoveCommand(cmd_id); + application->help_prompt_manager().OnVrCommandDeleted( + cmd_id, /*is_resumption = */ true); + } +} + +void ResumptionDataProcessor::DeleteUICommands( + const ResumptionRequest& request) { + LOG4CXX_AUTO_TRACE(logger_); + smart_objects::SmartObjectSPtr ui_command = + MessageHelper::CreateMessageForHMI( + hmi_apis::messageType::request, + application_manager_.GetNextHMICorrelationID()); + + (*ui_command)[strings::params][strings::function_id] = + hmi_apis::FunctionID::UI_DeleteCommand; + + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + const uint32_t cmd_id = + request.message[strings::msg_params][strings::cmd_id].asUInt(); + + msg_params[strings::cmd_id] = cmd_id; + msg_params[strings::app_id] = + request.message[strings::msg_params][strings::app_id]; + + (*ui_command)[strings::msg_params] = msg_params; + + ProcessHMIRequest(ui_command, /*subscribe_on_response = */ false); +} + +void ResumptionDataProcessor::DeleteVRCommands( + const ResumptionRequest& request) { + LOG4CXX_AUTO_TRACE(logger_); + smart_objects::SmartObjectSPtr vr_command = + MessageHelper::CreateMessageForHMI( + hmi_apis::messageType::request, + application_manager_.GetNextHMICorrelationID()); + + (*vr_command)[strings::params][strings::function_id] = + hmi_apis::FunctionID::VR_DeleteCommand; + + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + + const uint32_t cmd_id = + request.message[strings::msg_params][strings::cmd_id].asUInt(); + + msg_params[strings::cmd_id] = cmd_id; + msg_params[strings::app_id] = + request.message[strings::msg_params][strings::app_id]; + msg_params[strings::type] = + request.message[strings::msg_params][strings::type]; + msg_params[strings::grammar_id] = + request.message[strings::msg_params][strings::grammar_id]; + + (*vr_command)[strings::msg_params] = msg_params; + + ProcessHMIRequest(vr_command, /*subscribe_on_response = */ false); +} + +void ResumptionDataProcessor::AddChoicesets( + ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app) { + LOG4CXX_AUTO_TRACE(logger_); + if (!saved_app.keyExists(strings::application_choice_sets)) { + LOG4CXX_ERROR(logger_, "There is no any choicesets"); + } + + const smart_objects::SmartObject& app_choice_sets = + saved_app[strings::application_choice_sets]; + + for (size_t i = 0; i < app_choice_sets.length(); ++i) { + const smart_objects::SmartObject& choice_set = app_choice_sets[i]; + const int32_t choice_set_id = + choice_set[strings::interaction_choice_set_id].asInt(); + application->AddChoiceSet(choice_set_id, choice_set); + } + + ProcessHMIRequests(MessageHelper::CreateAddVRCommandRequestFromChoiceToHMI( + application, application_manager_)); +} + +void ResumptionDataProcessor::DeleteChoicesets(const int32_t app_id) { + LOG4CXX_AUTO_TRACE(logger_); + ApplicationSharedPtr application = application_manager_.application(app_id); + + const DataAccessor<ChoiceSetMap> accessor = application->choice_set_map(); + const ChoiceSetMap& choices = accessor.GetData(); + while (!choices.empty()) { + application->RemoveChoiceSet(choices.begin()->first); + } +} + +void ResumptionDataProcessor::SetGlobalProperties( + ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app) { + LOG4CXX_AUTO_TRACE(logger_); + if (!saved_app.keyExists(strings::application_global_properties)) { + LOG4CXX_DEBUG(logger_, + "application_global_properties section is not exists"); + return; + } + + const smart_objects::SmartObject& properties_so = + saved_app[strings::application_global_properties]; + application->load_global_properties(properties_so); + + ProcessHMIRequests(MessageHelper::CreateGlobalPropertiesRequestsToHMI( + application, application_manager_.GetNextHMICorrelationID())); +} + +void ResumptionDataProcessor::DeleteGlobalProperties(const int32_t app_id) { + LOG4CXX_AUTO_TRACE(logger_); +} + +void ResumptionDataProcessor::AddWayPointsSubscription( + app_mngr::ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app) { + LOG4CXX_AUTO_TRACE(logger_); + if (saved_app.keyExists(strings::subscribed_for_way_points)) { + LOG4CXX_DEBUG(logger_, "subscribed_for_way_points section is not exists"); + return; + } + + const smart_objects::SmartObject& subscribed_for_way_points_so = + saved_app[strings::subscribed_for_way_points]; + if (true == subscribed_for_way_points_so.asBool()) { + application_manager_.SubscribeAppForWayPoints(application); + } +} + +void ResumptionDataProcessor::DeleteWayPointsSubscription( + const int32_t app_id) { + LOG4CXX_AUTO_TRACE(logger_); + if (application_manager_.IsAppSubscribedForWayPoints(app_id)) { + application_manager_.UnsubscribeAppFromWayPoints(app_id); + } +} + +void ResumptionDataProcessor::AddSubscriptions( + ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app) { + LOG4CXX_AUTO_TRACE(logger_); + + AddButtonsSubscriptions(application, saved_app); + AddPluginsSubscriptions(application, saved_app); +} + +void ResumptionDataProcessor::AddButtonsSubscriptions( + ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app) { + LOG4CXX_AUTO_TRACE(logger_); + + if (!saved_app.keyExists(strings::application_subscriptions)) { + LOG4CXX_DEBUG(logger_, "application_subscriptions section is not exists"); + return; + } + + const smart_objects::SmartObject& subscriptions = + saved_app[strings::application_subscriptions]; + + if (subscriptions.keyExists(strings::application_buttons)) { + const smart_objects::SmartObject& subscriptions_buttons = + subscriptions[strings::application_buttons]; + mobile_apis::ButtonName::eType btn; + for (size_t i = 0; i < subscriptions_buttons.length(); ++i) { + btn = static_cast<mobile_apis::ButtonName::eType>( + (subscriptions_buttons[i]).asInt()); + application->SubscribeToButton(btn); + } + } + + MessageHelper::SendAllOnButtonSubscriptionNotificationsForApp( + application, application_manager_); +} + +void ResumptionDataProcessor::AddPluginsSubscriptions( + ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app) { + LOG4CXX_AUTO_TRACE(logger_); + + for (auto& extension : application->Extensions()) { + extension->ProcessResumption( + saved_app, + [this](const int32_t app_id, const ResumptionRequest request) { + this->WaitForResponse(app_id, request); + }); + } +} + +void ResumptionDataProcessor::DeleteSubscriptions(const int32_t app_id) { + LOG4CXX_AUTO_TRACE(logger_); + ApplicationSharedPtr application = application_manager_.application(app_id); + DeleteButtonsSubscriptions(application); + DeletePluginsSubscriptions(application); +} + +void ResumptionDataProcessor::DeleteButtonsSubscriptions( + ApplicationSharedPtr application) { + LOG4CXX_AUTO_TRACE(logger_); + DataAccessor<ButtonSubscriptions> button_accessor = + application->SubscribedButtons(); + ButtonSubscriptions button_subscriptions = button_accessor.GetData(); + while (!button_subscriptions.empty()) { + auto btn = button_subscriptions.begin(); + MessageHelper::SendOnButtonSubscriptionNotification( + application->hmi_app_id(), + static_cast<hmi_apis::Common_ButtonName::eType>(*btn), + /*is_subscribed = */ false, + application_manager_); + application->UnsubscribeFromButton( + static_cast<mobile_apis::ButtonName::eType>(*btn)); + } + + MessageHelper::SendOnButtonSubscriptionNotification( + application->hmi_app_id(), + hmi_apis::Common_ButtonName::CUSTOM_BUTTON, + /*is_subscribed = */ false, + application_manager_); + application->SubscribeToButton(mobile_apis::ButtonName::CUSTOM_BUTTON); +} + +void ResumptionDataProcessor::DeletePluginsSubscriptions( + application_manager::ApplicationSharedPtr application) { + LOG4CXX_AUTO_TRACE(logger_); + smart_objects::SmartObject extension_subscriptions; + + ApplicationResumptionStatus& status = + resumption_status_[application->app_id()]; + for (auto request : status.successful_requests) { + if (hmi_apis::FunctionID::VehicleInfo_SubscribeVehicleData == + request.function_id) { + extension_subscriptions[strings::application_vehicle_info] = + request.message; + } + } + + for (auto& extension : application->Extensions()) { + extension->RevertResumption(extension_subscriptions); + } +} + +} // namespce resumption |