diff options
author | Andrey Oleynik (GitHub) <aoleynik@luxoft.com> | 2017-09-29 10:22:15 +0300 |
---|---|---|
committer | Andriy Byzhynar <AByzhynar@luxoft.com> | 2018-01-18 11:28:38 +0200 |
commit | 53625d990e5ae307e84091140152c165ca7afc3b (patch) | |
tree | b437a1ad7e85010164b45c718ea1e5deac5d5238 | |
parent | ebbd8f665f8dd11276acb21af965a8f9bb808bd5 (diff) | |
download | sdl_core-53625d990e5ae307e84091140152c165ca7afc3b.tar.gz |
Initial implementation of resumption during switching
11 files changed, 796 insertions, 29 deletions
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 f0c8d459a1..d2d43594ee 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 @@ -1290,6 +1290,13 @@ class ApplicationManagerImpl */ void ClearAppsPersistentData(); + /** + * @brief RecallApplicationData removes application commands, subscriptions, + * menues etc. and notifies HMI to remove same on its side + * @param app Application to recall data from + */ + void RecallApplicationData(ApplicationSharedPtr app) FINAL; + StateController& state_controller() OVERRIDE; const ApplicationManagerSettings& get_settings() const OVERRIDE; virtual event_engine::EventDispatcher& event_dispatcher() OVERRIDE; diff --git a/src/components/application_manager/include/application_manager/message_helper.h b/src/components/application_manager/include/application_manager/message_helper.h index a0b70435b0..15cd5846ca 100644 --- a/src/components/application_manager/include/application_manager/message_helper.h +++ b/src/components/application_manager/include/application_manager/message_helper.h @@ -701,6 +701,30 @@ class MessageHelper { int32_t connection_key, mobile_api::AppInterfaceUnregisteredReason::eType reason); + static void SendDeleteCommandRequest(smart_objects::SmartObject* cmd, + ApplicationSharedPtr application, + ApplicationManager& app_mngr); + + static void SendDeleteSubmenuRequest(smart_objects::SmartObject* cmd, + ApplicationSharedPtr application, + ApplicationManager& app_mngr); + + static void SendDeleteChoiceSetRequest(smart_objects::SmartObject* cmd, + ApplicationSharedPtr application, + ApplicationManager& app_mngr); + + static void SendResetPropertiesRequest(ApplicationSharedPtr application, + ApplicationManager& app_mngr); + + static void SendUnsubscribeButtonNotification( + mobile_apis::ButtonName::eType button, + ApplicationSharedPtr application, + ApplicationManager& app_mngr); + + static void SendUnsubscribeIVIRequest(uint32_t ivi_id, + ApplicationSharedPtr application, + ApplicationManager& app_mngr); + #ifdef SDL_REMOTE_CONTROL /** * @brief Sends HMI status notification to mobile @@ -734,6 +758,10 @@ class MessageHelper { static smart_objects::SmartObjectSPtr CreateRequestObject( const uint32_t correlation_id); + // To merge with prior method + static smart_objects::SmartObjectSPtr CreateNotificationObject( + const uint32_t correlation_id); + /** * @brief Allows to fill SO according to the current permissions. * @param permissions application permissions. diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc index fe9d2d8370..e082b34005 100644 --- a/src/components/application_manager/src/application_manager_impl.cc +++ b/src/components/application_manager/src/application_manager_impl.cc @@ -1106,6 +1106,11 @@ void ApplicationManagerImpl::OnDeviceSwitchingStart( apps_data_accessor.GetData().end(), std::back_inserter(reregister_wait_list_), std::bind1st(std::ptr_fun(&device_id_comparator), device_uid)); + + for (auto i = reregister_wait_list_.begin(); reregister_wait_list_.end() != i; + ++i) { + resume_ctrl_->SaveApplication(*i); + } } void ApplicationManagerImpl::OnDeviceSwitchFinish( @@ -2920,6 +2925,123 @@ void ApplicationManagerImpl::ClearAppsPersistentData() { } } +void ApplicationManagerImpl::RecallApplicationData(ApplicationSharedPtr app) { + LOG4CXX_AUTO_TRACE(logger_); + DCHECK_OR_RETURN_VOID(app); + + UnsubscribeAppFromWayPoints(app->app_id()); + if (!IsAnyAppSubscribedForWayPoints()) { + MessageHelper::SendUnsubscribedWayPoints(*this); + } + + // Removing commands + CommandsMap cmap = app->commands_map().GetData(); + + for (auto cmd : cmap) { + MessageHelper::SendDeleteCommandRequest(cmd.second, app, *this); + app->RemoveCommand(cmd.first); + } + // End removing commands + + // Removing submenues + SubMenuMap smap = app->sub_menu_map().GetData(); + + for (auto smenu : smap) { + MessageHelper::SendDeleteSubmenuRequest(smenu.second, app, *this); + app->RemoveSubMenu(smenu.first); + } + // End removing submenues + + // Removing choice sets + ChoiceSetMap csmap = app->choice_set_map().GetData(); + + for (auto choice : csmap) { + MessageHelper::SendDeleteChoiceSetRequest(choice.second, app, *this); + app->RemoveChoiceSet(choice.first); + } + // End removing choice sets + + // Reset global properties + // Help prompt reset + smart_objects::SmartObject empty_so = + smart_objects::SmartObject(smart_objects::SmartType_Array); + app->set_help_prompt(empty_so); + + // Timeout prompt reset + const std::vector<std::string>& time_out_promt = + get_settings().time_out_promt(); + + smart_objects::SmartObject so_time_out_promt = + smart_objects::SmartObject(smart_objects::SmartType_Array); + + for (uint32_t i = 0; i < time_out_promt.size(); ++i) { + smart_objects::SmartObject timeoutPrompt = + smart_objects::SmartObject(smart_objects::SmartType_Map); + timeoutPrompt[strings::text] = time_out_promt[i]; + timeoutPrompt[strings::type] = hmi_apis::Common_SpeechCapabilities::SC_TEXT; + so_time_out_promt[i] = timeoutPrompt; + } + + app->set_timeout_prompt(so_time_out_promt); + + // VR help title reset + app->reset_vr_help_title(); + + // VR help reset + app->reset_vr_help(); + + // Keyboard properties reset + app->set_keyboard_props(empty_so); + + // Menu icon reset + app->set_menu_icon(empty_so); + + // Menu title reset + app->set_menu_title(empty_so); + + MessageHelper::SendResetPropertiesRequest(app, *this); + // End reset global properties + + // Removing buttons subscriptions + ButtonSubscriptions buttons = app->SubscribedButtons().GetData(); + + for (auto button : buttons) { + if (mobile_apis::ButtonName::CUSTOM_BUTTON == button) { + continue; + } + MessageHelper::SendUnsubscribeButtonNotification(button, app, *this); + app->UnsubscribeFromButton(button); + } + // End removing buttons subscriptions + + // Removing IVI subscriptions + VehicleInfoSubscriptions ivi = app->SubscribedIVI().GetData(); + + for (auto i : ivi) { + app->UnsubscribeFromIVI(i); + SubscribedToIVIPredicate p(static_cast<int32_t>(i)); + auto app = FindApp(applications(), p); + if (!app) { + MessageHelper::SendUnsubscribeIVIRequest(i, app, *this); + } + } + // End removing IVI subscriptions + + // Removing files + // Except icons folder + auto files = app->getAppFiles(); + const auto icon_file = app->app_icon_path(); + for (auto file : files) { + auto file_name = file.first; + if (icon_file == file_name) { + continue; + } + app->DeleteFile(file_name); + file_system::DeleteFile(file_name); + } + // End removing files +} + void ApplicationManagerImpl::SendOnSDLClose() { LOG4CXX_AUTO_TRACE(logger_); diff --git a/src/components/application_manager/src/commands/mobile/register_app_interface_request.cc b/src/components/application_manager/src/commands/mobile/register_app_interface_request.cc index 775811fce0..eebabb1ae7 100644 --- a/src/components/application_manager/src/commands/mobile/register_app_interface_request.cc +++ b/src/components/application_manager/src/commands/mobile/register_app_interface_request.cc @@ -639,14 +639,6 @@ void RegisterAppInterfaceRequest::SendRegisterAppInterfaceResponseToMobile( response_params[strings::system_software_version] = ccpu_version; } - if (AppicationType::kSwitchedApplication == app_type) { - LOG4CXX_DEBUG(logger_, - "Application has been switched from another transport."); - - SendResponse(true, result_code, NULL, &response_params); - return; - } - bool resumption = (*message_)[strings::msg_params].keyExists(strings::hash_id); @@ -677,6 +669,20 @@ void RegisterAppInterfaceRequest::SendRegisterAppInterfaceResponseToMobile( result_code = result_checking_app_hmi_type_; } + if (AppicationType::kSwitchedApplication == app_type) { + LOG4CXX_DEBUG(logger_, + "Application has been switched from another transport."); + + if (!resumption || mobile_apis::Result::RESUME_FAILED == result_code) { + application_manager_.RecallApplicationData(application); + resumer.RemoveApplicationFromSaved(application); + result_code = mobile_apis::Result::RESUME_FAILED; + } + + SendResponse(true, result_code, add_info.c_str(), &response_params); + return; + } + // in case application exist in resumption we need to send resumeVrgrammars if (false == resumption) { resumption = resumer.IsApplicationSaved(application->policy_app_id(), 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 af9c221a4f..cb9b111360 100644 --- a/src/components/application_manager/src/message_helper/message_helper.cc +++ b/src/components/application_manager/src/message_helper/message_helper.cc @@ -42,6 +42,7 @@ #include <algorithm> #include <utility> #include <map> +#include <functional> #include "application_manager/application.h" #include "application_manager/application_manager.h" @@ -327,6 +328,23 @@ smart_objects::SmartObjectSPtr MessageHelper::CreateRequestObject( return request; } +smart_objects::SmartObjectSPtr MessageHelper::CreateNotificationObject( + const uint32_t correlation_id) { + using namespace smart_objects; + + SmartObjectSPtr message = utils::MakeShared<SmartObject>(SmartType_Map); + SmartObject& ref = *message; + + ref[strings::params][strings::message_type] = + static_cast<int>(hmi_apis::messageType::notification); + ref[strings::params][strings::protocol_version] = + commands::CommandImpl::protocol_version_; + ref[strings::params][strings::protocol_type] = + commands::CommandImpl::hmi_protocol_type_; + ref[strings::params][strings::correlation_id] = correlation_id; + return message; +} + smart_objects::SmartObjectSPtr MessageHelper::CreateHashUpdateNotification( const uint32_t app_id) { LOG4CXX_AUTO_TRACE(logger_); @@ -400,6 +418,254 @@ MessageHelper::GetOnAppInterfaceUnregisteredNotificationToMobile( return notification; } +void MessageHelper::SendDeleteCommandRequest(smart_objects::SmartObject* cmd, + ApplicationSharedPtr application, + ApplicationManager& app_mngr) { + LOG4CXX_AUTO_TRACE(logger_); + DCHECK_OR_RETURN_VOID(cmd); + using namespace smart_objects; + SmartObject msg_params = SmartObject(smart_objects::SmartType_Map); + + msg_params[strings::cmd_id] = (*cmd)[strings::msg_params][strings::cmd_id]; + msg_params[strings::app_id] = application->app_id(); + + if ((*cmd).keyExists(strings::menu_params)) { + SmartObjectSPtr message = + CreateRequestObject(app_mngr.GetNextHMICorrelationID()); + DCHECK(message); + + SmartObject& object = *message; + object[strings::params][strings::function_id] = + hmi_apis::FunctionID::UI_DeleteCommand; + + object[strings::msg_params] = msg_params; + + app_mngr.ManageHMICommand(message); + } + + if ((*cmd).keyExists(strings::vr_commands)) { + msg_params[strings::grammar_id] = application->get_grammar_id(); + msg_params[strings::type] = hmi_apis::Common_VRCommandType::Command; + + SmartObjectSPtr message = + CreateRequestObject(app_mngr.GetNextHMICorrelationID()); + DCHECK(message); + + SmartObject& object = *message; + object[strings::params][strings::function_id] = + hmi_apis::FunctionID::VR_DeleteCommand; + + object[strings::msg_params] = msg_params; + + app_mngr.ManageHMICommand(message); + } +} + +void MessageHelper::SendDeleteSubmenuRequest(smart_objects::SmartObject* cmd, + ApplicationSharedPtr application, + ApplicationManager& app_mngr) { + LOG4CXX_AUTO_TRACE(logger_); + DCHECK_OR_RETURN_VOID(cmd); + using namespace smart_objects; + + SmartObject msg_params = SmartObject(smart_objects::SmartType_Map); + + msg_params[strings::menu_id] = (*cmd)[strings::msg_params][strings::menu_id]; + msg_params[strings::app_id] = application->app_id(); + + SmartObjectSPtr message = + CreateRequestObject(app_mngr.GetNextHMICorrelationID()); + DCHECK(message); + + SmartObject& object = *message; + object[strings::params][strings::function_id] = + hmi_apis::FunctionID::UI_DeleteSubMenu; + + object[strings::msg_params] = msg_params; + + app_mngr.ManageHMICommand(message); + + // Same is deleted with SendDeleteCommandRequest? + const DataAccessor<CommandsMap> accessor = application->commands_map(); + const CommandsMap& commands = accessor.GetData(); + CommandsMap::const_iterator it = commands.begin(); + + for (; commands.end() != it; ++it) { + if (!(*it->second).keyExists(strings::vr_commands)) { + continue; + } + + if ((*cmd)[strings::msg_params][strings::menu_id].asInt() == + (*it->second)[strings::menu_params][hmi_request::parent_id].asInt()) { + SmartObject msg_params = SmartObject(smart_objects::SmartType_Map); + msg_params[strings::cmd_id] = (*it->second)[strings::cmd_id].asInt(); + msg_params[strings::app_id] = application->app_id(); + msg_params[strings::grammar_id] = application->get_grammar_id(); + msg_params[strings::type] = hmi_apis::Common_VRCommandType::Command; + + SmartObjectSPtr message = + CreateRequestObject(app_mngr.GetNextHMICorrelationID()); + DCHECK(message); + + SmartObject& object = *message; + object[strings::params][strings::function_id] = + hmi_apis::FunctionID::VR_DeleteCommand; + + object[strings::msg_params] = msg_params; + + app_mngr.ManageHMICommand(message); + } + } +} + +void MessageHelper::SendDeleteChoiceSetRequest(smart_objects::SmartObject* cmd, + ApplicationSharedPtr application, + ApplicationManager& app_mngr) { + LOG4CXX_AUTO_TRACE(logger_); + DCHECK_OR_RETURN_VOID(cmd); + using namespace smart_objects; + + // Same is deleted with SendDeleteCommandRequest? + + SmartObject msg_params = SmartObject(smart_objects::SmartType_Map); + + msg_params[strings::app_id] = application->app_id(); + msg_params[strings::type] = hmi_apis::Common_VRCommandType::Choice; + msg_params[strings::grammar_id] = (*cmd)[strings::grammar_id]; + cmd = &((*cmd)[strings::choice_set]); + for (uint32_t i = 0; i < (*cmd).length(); ++i) { + msg_params[strings::cmd_id] = (*cmd)[i][strings::choice_id]; + + SmartObjectSPtr message = + CreateRequestObject(app_mngr.GetNextHMICorrelationID()); + DCHECK(message); + + SmartObject& object = *message; + object[strings::params][strings::function_id] = + hmi_apis::FunctionID::VR_DeleteCommand; + + object[strings::msg_params] = msg_params; + + app_mngr.ManageHMICommand(message); + } +} + +void MessageHelper::SendResetPropertiesRequest(ApplicationSharedPtr application, + ApplicationManager& app_mngr) { + LOG4CXX_AUTO_TRACE(logger_); + using namespace smart_objects; + + { + SmartObject msg_params = SmartObject(smart_objects::SmartType_Map); + + msg_params = *MessageHelper::CreateAppVrHelp(application); + msg_params[hmi_request::menu_title] = ""; + + smart_objects::SmartObject key_board_properties = + smart_objects::SmartObject(smart_objects::SmartType_Map); + key_board_properties[strings::language] = + static_cast<int32_t>(hmi_apis::Common_Language::EN_US); + key_board_properties[hmi_request::keyboard_layout] = + static_cast<int32_t>(hmi_apis::Common_KeyboardLayout::QWERTY); + + key_board_properties[hmi_request::auto_complete_text] = ""; + msg_params[hmi_request::keyboard_properties] = key_board_properties; + + msg_params[strings::app_id] = application->app_id(); + + SmartObjectSPtr message = + CreateRequestObject(app_mngr.GetNextHMICorrelationID()); + DCHECK(message); + + SmartObject& object = *message; + object[strings::params][strings::function_id] = + hmi_apis::FunctionID::UI_SetGlobalProperties; + + object[strings::msg_params] = msg_params; + + app_mngr.ManageHMICommand(message); + } + + { + SmartObject msg_params = SmartObject(smart_objects::SmartType_Map); + + msg_params[strings::help_prompt] = application->help_prompt(); + msg_params[strings::timeout_prompt] = application->timeout_prompt(); + msg_params[strings::app_id] = application->app_id(); + + SmartObjectSPtr message = + CreateRequestObject(app_mngr.GetNextHMICorrelationID()); + DCHECK(message); + + SmartObject& object = *message; + object[strings::params][strings::function_id] = + hmi_apis::FunctionID::TTS_SetGlobalProperties; + + object[strings::msg_params] = msg_params; + + app_mngr.ManageHMICommand(message); + } +} + +void MessageHelper::SendUnsubscribeButtonNotification( + mobile_apis::ButtonName::eType button, + ApplicationSharedPtr application, + ApplicationManager& app_mngr) { + using namespace smart_objects; + using namespace hmi_apis; + + SmartObject msg_params = SmartObject(SmartType_Map); + msg_params[strings::app_id] = application->app_id(); + msg_params[strings::name] = button; + msg_params[strings::is_suscribed] = false; + + SmartObjectSPtr message = + CreateNotificationObject(app_mngr.GetNextHMICorrelationID()); + DCHECK(message); + + SmartObject& object = *message; + object[strings::params][strings::function_id] = + hmi_apis::FunctionID::Buttons_OnButtonSubscription; + + object[strings::msg_params] = msg_params; + + app_mngr.ManageHMICommand(message); +} + +void MessageHelper::SendUnsubscribeIVIRequest(uint32_t ivi_id, + ApplicationSharedPtr application, + ApplicationManager& app_mngr) { + using namespace smart_objects; + + std::string key_name; + for (auto item : vehicle_data_) { + if (ivi_id == item.second) { + key_name = item.first; + break; + } + } + + if (key_name.empty()) { + return; + } + + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + msg_params[key_name] = true; + + SmartObjectSPtr message = + CreateRequestObject(app_mngr.GetNextHMICorrelationID()); + DCHECK(message); + + SmartObject& object = *message; + object[strings::params][strings::function_id] = + hmi_apis::FunctionID::VehicleInfo_UnsubscribeVehicleData; + + object[strings::msg_params] = msg_params; + + app_mngr.ManageHMICommand(message); +} + const VehicleData& MessageHelper::vehicle_data() { return vehicle_data_; } diff --git a/src/components/application_manager/test/application_manager_impl_test.cc b/src/components/application_manager/test/application_manager_impl_test.cc index 37346f897b..a06089e8e7 100644 --- a/src/components/application_manager/test/application_manager_impl_test.cc +++ b/src/components/application_manager/test/application_manager_impl_test.cc @@ -32,6 +32,8 @@ #include <stdint.h> #include <memory> #include <set> +#include <string> +#include <vector> #include <bson_object.h> #include "gtest/gtest.h" @@ -83,6 +85,7 @@ ACTION_P6(InvokeMemberFuncWithArg4, ptr, memberFunc, a, b, c, d) { namespace { const std::string kDirectoryName = "./test_storage"; const uint32_t kTimeout = 10000u; +const std::vector<std::string> kTimeoutPrompt{"timeoutPrompt"}; sync_primitives::Lock state_lock_; sync_primitives::ConditionalVariable state_condition_; } // namespace @@ -133,6 +136,9 @@ class ApplicationManagerImplTest : public ::testing::Test { .WillByDefault(Return(stop_streaming_timeout)); ON_CALL(mock_application_manager_settings_, default_timeout()) .WillByDefault(ReturnRef(kTimeout)); + ON_CALL(mock_application_manager_settings_, time_out_promt()) + .WillByDefault(ReturnRef(kTimeoutPrompt)); + app_manager_impl_.reset(new am::ApplicationManagerImpl( mock_application_manager_settings_, mock_policy_settings_)); mock_app_ptr_ = utils::SharedPtr<MockApplication>(new MockApplication()); @@ -155,7 +161,6 @@ class ApplicationManagerImplTest : public ::testing::Test { std::auto_ptr<am::ApplicationManagerImpl> app_manager_impl_; application_manager::MockMessageHelper* mock_message_helper_; uint32_t app_id_; - application_manager::MessageHelper* message_helper_; utils::SharedPtr<MockApplication> mock_app_ptr_; }; @@ -756,6 +761,164 @@ TEST_F(ApplicationManagerImplTest, EXPECT_EQ(new_application_id, app_impl->app_id()); } +TEST_F(ApplicationManagerImplTest, RecallApplicationData_ExpectAppDataReset) { + const uint32_t application_id = 1; + const std::string policy_app_id = "p_app_id"; + const std::string mac_address = "MA:CA:DD:RE:SS"; + const connection_handler::DeviceHandle device_id = 1; + const custom_str::CustomString app_name(""); + + ApplicationSharedPtr app_impl = new ApplicationImpl( + application_id, + policy_app_id, + mac_address, + device_id, + app_name, + utils::SharedPtr<usage_statistics::StatisticsManager>( + new usage_statistics_test::MockStatisticsManager()), + *app_manager_impl_); + + app_manager_impl_->AddMockApplication(app_impl); + + const uint32_t cmd_id = 1; + const uint32_t menu_id = 2; + const uint32_t choice_set_id = 3; + const VehicleDataType vi = VehicleDataType::ACCPEDAL; + const mobile_apis::ButtonName::eType button = mobile_apis::ButtonName::AC; + + smart_objects::SmartObject cmd; + cmd[strings::msg_params][strings::cmd_id] = cmd_id; + cmd[strings::msg_params][strings::vr_commands][0] = "vrCmd"; + cmd[strings::msg_params][strings::menu_id] = menu_id; + cmd[strings::msg_params][strings::interaction_choice_set_id] = choice_set_id; + + app_impl->AddCommand(cmd_id, cmd[strings::msg_params]); + app_impl->AddSubMenu(menu_id, cmd[strings::menu_params]); + app_impl->AddChoiceSet(choice_set_id, cmd[strings::msg_params]); + EXPECT_TRUE(app_impl->SubscribeToIVI(static_cast<uint32_t>(vi))); + EXPECT_TRUE(app_impl->SubscribeToButton(button)); + + const std::string some_string = "some_string"; + smart_objects::SmartObject dummy_data = + smart_objects::SmartObject(smart_objects::SmartType_String); + dummy_data = some_string; + app_impl->set_help_prompt(dummy_data); + app_impl->set_timeout_prompt(dummy_data); + app_impl->set_vr_help(dummy_data); + app_impl->set_vr_help_title(dummy_data); + app_impl->set_keyboard_props(dummy_data); + app_impl->set_menu_title(dummy_data); + app_impl->set_menu_icon(dummy_data); + + const bool persistent = false; + const bool downloaded = true; + const std::string filename = "filename"; + AppFile file(filename, persistent, downloaded, mobile_apis::FileType::BINARY); + + app_impl->AddFile(file); + + EXPECT_TRUE(NULL != app_impl->FindCommand(cmd_id)); + EXPECT_TRUE(NULL != app_impl->FindSubMenu(menu_id)); + EXPECT_TRUE(NULL != app_impl->FindChoiceSet(choice_set_id)); + EXPECT_TRUE(app_impl->IsSubscribedToButton(button)); + EXPECT_TRUE(app_impl->IsSubscribedToIVI(static_cast<uint32_t>(vi))); + auto help_prompt = app_impl->help_prompt(); + EXPECT_TRUE(help_prompt->asString() == some_string); + auto timeout_prompt = app_impl->timeout_prompt(); + EXPECT_TRUE(timeout_prompt->asString() == some_string); + auto vr_help = app_impl->vr_help(); + EXPECT_TRUE(vr_help->asString() == some_string); + auto vr_help_title = app_impl->vr_help_title(); + EXPECT_TRUE(vr_help_title->asString() == some_string); + auto kb_properties = app_impl->keyboard_props(); + EXPECT_TRUE(kb_properties->asString() == some_string); + auto menu_title = app_impl->menu_title(); + EXPECT_TRUE(menu_title->asString() == some_string); + auto menu_icon = app_impl->menu_icon(); + EXPECT_TRUE(menu_icon->asString() == some_string); + auto file_ptr = app_impl->GetFile(filename); + EXPECT_TRUE(NULL != file_ptr); + EXPECT_TRUE(file_ptr->file_name == filename); + + // Act + app_manager_impl_->RecallApplicationData(app_impl); + EXPECT_FALSE(NULL != app_impl->FindCommand(cmd_id)); + EXPECT_FALSE(NULL != app_impl->FindSubMenu(menu_id)); + EXPECT_FALSE(NULL != app_impl->FindChoiceSet(choice_set_id)); + EXPECT_FALSE(app_impl->IsSubscribedToButton(button)); + EXPECT_FALSE(app_impl->IsSubscribedToIVI(static_cast<uint32_t>(vi))); + help_prompt = app_impl->help_prompt(); + EXPECT_FALSE(help_prompt->asString() == some_string); + timeout_prompt = app_impl->timeout_prompt(); + EXPECT_FALSE(timeout_prompt->asString() == some_string); + vr_help = app_impl->vr_help(); + EXPECT_TRUE(vr_help == NULL); + vr_help_title = app_impl->vr_help_title(); + EXPECT_TRUE(vr_help_title == NULL); + kb_properties = app_impl->keyboard_props(); + EXPECT_FALSE(kb_properties->asString() == some_string); + menu_title = app_impl->menu_title(); + EXPECT_FALSE(menu_title->asString() == some_string); + menu_icon = app_impl->menu_icon(); + EXPECT_FALSE(menu_icon->asString() == some_string); + file_ptr = app_impl->GetFile(filename); + EXPECT_TRUE(NULL == file_ptr); +} + +TEST_F(ApplicationManagerImplTest, + RecallApplicationData_ExpectHMICleanupRequests) { + const uint32_t application_id = 1; + const std::string policy_app_id = "p_app_id"; + const std::string mac_address = "MA:CA:DD:RE:SS"; + const connection_handler::DeviceHandle device_id = 1; + const custom_str::CustomString app_name(""); + + ApplicationSharedPtr app_impl = new ApplicationImpl( + application_id, + policy_app_id, + mac_address, + device_id, + app_name, + utils::SharedPtr<usage_statistics::StatisticsManager>( + new usage_statistics_test::MockStatisticsManager()), + *app_manager_impl_); + + app_manager_impl_->AddMockApplication(app_impl); + + const uint32_t cmd_id = 1; + const uint32_t menu_id = 2; + const uint32_t choice_set_id = 3; + smart_objects::SmartObject cmd; + cmd[strings::msg_params][strings::cmd_id] = cmd_id; + cmd[strings::msg_params][strings::vr_commands][0] = "vrCmd"; + cmd[strings::msg_params][strings::menu_id] = menu_id; + cmd[strings::msg_params][strings::interaction_choice_set_id] = choice_set_id; + + app_impl->AddCommand(cmd_id, cmd[strings::msg_params]); + app_impl->AddSubMenu(menu_id, cmd[strings::menu_params]); + app_impl->AddChoiceSet(choice_set_id, cmd[strings::msg_params]); + app_impl->SubscribeToIVI(static_cast<uint32_t>(VehicleDataType::ACCPEDAL)); + app_impl->SubscribeToButton(mobile_apis::ButtonName::AC); + + EXPECT_CALL(*mock_message_helper_, SendUnsubscribedWayPoints(_)); + + EXPECT_CALL(*mock_message_helper_, SendDeleteCommandRequest(_, _, _)); + + EXPECT_CALL(*mock_message_helper_, SendDeleteSubmenuRequest(_, _, _)); + + EXPECT_CALL(*mock_message_helper_, SendDeleteChoiceSetRequest(_, _, _)); + + EXPECT_CALL(*mock_message_helper_, SendResetPropertiesRequest(_, _)); + + EXPECT_CALL(*mock_message_helper_, + SendUnsubscribeButtonNotification(_, _, _)); + + EXPECT_CALL(*mock_message_helper_, SendUnsubscribeIVIRequest(_, _, _)); + + // Act + app_manager_impl_->RecallApplicationData(app_impl); +} + } // application_manager_test } // namespace components } // namespace test diff --git a/src/components/application_manager/test/commands/mobile/register_app_interface_request_test.cc b/src/components/application_manager/test/commands/mobile/register_app_interface_request_test.cc index 629583bf21..31b4c30862 100644 --- a/src/components/application_manager/test/commands/mobile/register_app_interface_request_test.cc +++ b/src/components/application_manager/test/commands/mobile/register_app_interface_request_test.cc @@ -171,6 +171,37 @@ class RegisterAppInterfaceRequestTest .WillByDefault(Return(am::HmiInterfaces::HMI_INTERFACE_UI)); } + void SetCommonExpectionsOnSwitchedApplication( + mobile_apis::Result::eType response_result_code) { + EXPECT_CALL(mock_policy_handler_, AddApplication(_, _)).Times(0); + + EXPECT_CALL( + app_mngr_, + ManageMobileCommand(MobileResultCodeIs(response_result_code), _)); + + EXPECT_CALL(app_mngr_, + ManageHMICommand(HMIResultCodeIs( + hmi_apis::FunctionID::BasicCommunication_OnAppRegistered))) + .Times(0); + + EXPECT_CALL(app_mngr_, + ManageHMICommand(HMIResultCodeIs( + hmi_apis::FunctionID::Buttons_OnButtonSubscription))) + .Times(0); + + EXPECT_CALL(app_mngr_, + ManageHMICommand(HMIResultCodeIs( + hmi_apis::FunctionID::UI_ChangeRegistration))).Times(0); + + EXPECT_CALL(app_mngr_, + ManageHMICommand(HMIResultCodeIs( + hmi_apis::FunctionID::TTS_ChangeRegistration))).Times(0); + + EXPECT_CALL(app_mngr_, + ManageHMICommand(HMIResultCodeIs( + hmi_apis::FunctionID::VR_ChangeRegistration))).Times(0); + } + MessageSharedPtr msg_; SharedPtr<RegisterAppInterfaceRequest> command_; @@ -358,8 +389,12 @@ TEST_F(RegisterAppInterfaceRequestTest, } TEST_F(RegisterAppInterfaceRequestTest, - RegisterAppInterfaceRequest_Reregister) { + SwitchApplication_CorrectHash_ExpectNoCleanupSuccess) { InitBasicMessage(); + + const std::string request_hash_id = "abc123"; + (*msg_)[am::strings::msg_params][am::strings::hash_id] = request_hash_id; + MockAppPtr mock_app = CreateBasicMockedApp(); EXPECT_CALL(app_mngr_, application_by_policy_id(kAppId)) .WillRepeatedly(Return(mock_app)); @@ -370,36 +405,101 @@ TEST_F(RegisterAppInterfaceRequestTest, EXPECT_CALL(app_mngr_, RegisterApplication(msg_)).Times(0); - EXPECT_CALL(mock_policy_handler_, AddApplication(_, _)).Times(0); + EXPECT_CALL( + mock_resume_crt_, + CheckApplicationHash( + MockAppPtr::static_pointer_cast<application_manager::Application>( + mock_app), + request_hash_id)).WillOnce(Return(true)); + + EXPECT_CALL( + mock_resume_crt_, + CheckPersistenceFilesForResumption( + MockAppPtr::static_pointer_cast<application_manager::Application>( + mock_app))).WillOnce(Return(true)); + + EXPECT_CALL(mock_resume_crt_, RemoveApplicationFromSaved(_)).Times(0); + + EXPECT_CALL(app_mngr_, RecallApplicationData(_)).Times(0); EXPECT_CALL(app_mngr_, application(kConnectionKey)) .WillRepeatedly(Return(mock_app)); + SetCommonExpectionsOnSwitchedApplication(mobile_apis::Result::SUCCESS); + + command_->Run(); +} + +TEST_F(RegisterAppInterfaceRequestTest, + SwitchApplication_WrongHash_ExpectCleanupResumeFailed) { + InitBasicMessage(); + + const std::string request_hash_id = "abc123"; + (*msg_)[am::strings::msg_params][am::strings::hash_id] = request_hash_id; + + MockAppPtr mock_app = CreateBasicMockedApp(); + EXPECT_CALL(app_mngr_, application_by_policy_id(kAppId)) + .WillRepeatedly(Return(mock_app)); + + EXPECT_CALL(app_mngr_, IsAppInReconnectMode(kAppId)).WillOnce(Return(true)); + + EXPECT_CALL(app_mngr_, ProcessReconnection(_, kConnectionKey)); + + EXPECT_CALL( + mock_resume_crt_, + CheckApplicationHash( + MockAppPtr::static_pointer_cast<application_manager::Application>( + mock_app), + request_hash_id)).WillOnce(Return(false)); + + EXPECT_CALL(mock_resume_crt_, + RemoveApplicationFromSaved(MockAppPtr::static_pointer_cast< + const application_manager::Application>(mock_app))); + EXPECT_CALL( app_mngr_, - ManageMobileCommand(MobileResultCodeIs(mobile_apis::Result::SUCCESS), _)); + RecallApplicationData( + MockAppPtr::static_pointer_cast<application_manager::Application>( + mock_app))); - EXPECT_CALL(app_mngr_, - ManageHMICommand(HMIResultCodeIs( - hmi_apis::FunctionID::BasicCommunication_OnAppRegistered))) - .Times(0); + EXPECT_CALL(app_mngr_, RegisterApplication(msg_)).Times(0); - EXPECT_CALL(app_mngr_, - ManageHMICommand(HMIResultCodeIs( - hmi_apis::FunctionID::Buttons_OnButtonSubscription))) - .Times(0); + EXPECT_CALL(app_mngr_, application(kConnectionKey)) + .WillRepeatedly(Return(mock_app)); - EXPECT_CALL(app_mngr_, - ManageHMICommand(HMIResultCodeIs( - hmi_apis::FunctionID::UI_ChangeRegistration))).Times(0); + SetCommonExpectionsOnSwitchedApplication(mobile_apis::Result::RESUME_FAILED); - EXPECT_CALL(app_mngr_, - ManageHMICommand(HMIResultCodeIs( - hmi_apis::FunctionID::TTS_ChangeRegistration))).Times(0); + command_->Run(); +} - EXPECT_CALL(app_mngr_, - ManageHMICommand(HMIResultCodeIs( - hmi_apis::FunctionID::VR_ChangeRegistration))).Times(0); +TEST_F(RegisterAppInterfaceRequestTest, + SwitchApplication_NoHash_ExpectCleanupResumeFailed) { + InitBasicMessage(); + + MockAppPtr mock_app = CreateBasicMockedApp(); + EXPECT_CALL(app_mngr_, application_by_policy_id(kAppId)) + .WillRepeatedly(Return(mock_app)); + + EXPECT_CALL(app_mngr_, IsAppInReconnectMode(kAppId)).WillOnce(Return(true)); + + EXPECT_CALL(app_mngr_, ProcessReconnection(_, kConnectionKey)); + + EXPECT_CALL(mock_resume_crt_, + RemoveApplicationFromSaved(MockAppPtr::static_pointer_cast< + const application_manager::Application>(mock_app))); + + EXPECT_CALL( + app_mngr_, + RecallApplicationData( + MockAppPtr::static_pointer_cast<application_manager::Application>( + mock_app))); + + EXPECT_CALL(app_mngr_, RegisterApplication(msg_)).Times(0); + + EXPECT_CALL(app_mngr_, application(kConnectionKey)) + .WillRepeatedly(Return(mock_app)); + + SetCommonExpectionsOnSwitchedApplication(mobile_apis::Result::RESUME_FAILED); command_->Run(); } diff --git a/src/components/application_manager/test/include/application_manager/mock_message_helper.h b/src/components/application_manager/test/include/application_manager/mock_message_helper.h index f927f6bb72..e03ff343fb 100644 --- a/src/components/application_manager/test/include/application_manager/mock_message_helper.h +++ b/src/components/application_manager/test/include/application_manager/mock_message_helper.h @@ -268,6 +268,29 @@ class MockMessageHelper { MOCK_METHOD2(GetDeviceMacAddressForHandle, std::string(const uint32_t device_handle, const ApplicationManager& app_mngr)); + MOCK_METHOD3(SendDeleteCommandRequest, + void(smart_objects::SmartObject* cmd, + ApplicationSharedPtr application, + ApplicationManager& app_mngr)); + MOCK_METHOD3(SendDeleteSubmenuRequest, + void(smart_objects::SmartObject* cmd, + ApplicationSharedPtr application, + ApplicationManager& app_mngr)); + MOCK_METHOD3(SendDeleteChoiceSetRequest, + void(smart_objects::SmartObject* cmd, + ApplicationSharedPtr application, + ApplicationManager& app_mngr)); + MOCK_METHOD2(SendResetPropertiesRequest, + void(ApplicationSharedPtr application, + ApplicationManager& app_mngr)); + MOCK_METHOD3(SendUnsubscribeButtonNotification, + void(mobile_apis::ButtonName::eType button, + ApplicationSharedPtr application, + ApplicationManager& app_mngr)); + MOCK_METHOD3(SendUnsubscribeIVIRequest, + void(uint32_t ivi_id, + ApplicationSharedPtr application, + ApplicationManager& app_mngr)); static MockMessageHelper* message_helper_mock(); }; diff --git a/src/components/application_manager/test/mock_message_helper.cc b/src/components/application_manager/test/mock_message_helper.cc index 5f221a105b..6805d43693 100644 --- a/src/components/application_manager/test/mock_message_helper.cc +++ b/src/components/application_manager/test/mock_message_helper.cc @@ -501,4 +501,46 @@ std::string MessageHelper::GetDeviceMacAddressForHandle( device_handle, app_mngr); } +void MessageHelper::SendDeleteCommandRequest(smart_objects::SmartObject* cmd, + ApplicationSharedPtr application, + ApplicationManager& app_mngr) { + return MockMessageHelper::message_helper_mock()->SendDeleteCommandRequest( + cmd, application, app_mngr); +} + +void MessageHelper::SendDeleteSubmenuRequest(smart_objects::SmartObject* cmd, + ApplicationSharedPtr application, + ApplicationManager& app_mngr) { + return MockMessageHelper::message_helper_mock()->SendDeleteSubmenuRequest( + cmd, application, app_mngr); +} + +void MessageHelper::SendDeleteChoiceSetRequest(smart_objects::SmartObject* cmd, + ApplicationSharedPtr application, + ApplicationManager& app_mngr) { + return MockMessageHelper::message_helper_mock()->SendDeleteChoiceSetRequest( + cmd, application, app_mngr); +} + +void MessageHelper::SendResetPropertiesRequest(ApplicationSharedPtr application, + ApplicationManager& app_mngr) { + return MockMessageHelper::message_helper_mock()->SendResetPropertiesRequest( + application, app_mngr); +} + +void MessageHelper::SendUnsubscribeButtonNotification( + mobile_apis::ButtonName::eType button, + ApplicationSharedPtr application, + ApplicationManager& app_mngr) { + return MockMessageHelper::message_helper_mock() + ->SendUnsubscribeButtonNotification(button, application, app_mngr); +} + +void MessageHelper::SendUnsubscribeIVIRequest(uint32_t ivi_id, + ApplicationSharedPtr application, + ApplicationManager& app_mngr) { + return MockMessageHelper::message_helper_mock()->SendUnsubscribeIVIRequest( + ivi_id, application, app_mngr); +} + } // namespace application_manager diff --git a/src/components/include/application_manager/application_manager.h b/src/components/include/application_manager/application_manager.h index be872109b3..fcaac86ac8 100644 --- a/src/components/include/application_manager/application_manager.h +++ b/src/components/include/application_manager/application_manager.h @@ -682,6 +682,13 @@ class ApplicationManager { virtual void OnTimerSendTTSGlobalProperties() = 0; virtual void OnLowVoltage() = 0; virtual void OnWakeUp() = 0; + + /** + * @brief RecallApplicationData removes application commands, subscriptions, + * menues etc. + * @param app Application to recall data from + */ + virtual void RecallApplicationData(ApplicationSharedPtr app) = 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 df360eaa94..cba00fec40 100644 --- a/src/components/include/test/application_manager/mock_application_manager.h +++ b/src/components/include/test/application_manager/mock_application_manager.h @@ -301,6 +301,9 @@ class MockApplicationManager : public application_manager::ApplicationManager { const uint32_t connection_key)); MOCK_CONST_METHOD1(IsAppInReconnectMode, bool(const std::string& policy_app_id)); + + MOCK_METHOD1(RecallApplicationData, + void(application_manager::ApplicationSharedPtr)); }; } // namespace application_manager_test |