summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Oleynik (GitHub) <aoleynik@luxoft.com>2017-09-29 10:22:15 +0300
committerAndriy Byzhynar <AByzhynar@luxoft.com>2018-01-18 11:28:38 +0200
commit53625d990e5ae307e84091140152c165ca7afc3b (patch)
treeb437a1ad7e85010164b45c718ea1e5deac5d5238
parentebbd8f665f8dd11276acb21af965a8f9bb808bd5 (diff)
downloadsdl_core-53625d990e5ae307e84091140152c165ca7afc3b.tar.gz
Initial implementation of resumption during switching
-rw-r--r--src/components/application_manager/include/application_manager/application_manager_impl.h7
-rw-r--r--src/components/application_manager/include/application_manager/message_helper.h28
-rw-r--r--src/components/application_manager/src/application_manager_impl.cc122
-rw-r--r--src/components/application_manager/src/commands/mobile/register_app_interface_request.cc22
-rw-r--r--src/components/application_manager/src/message_helper/message_helper.cc266
-rw-r--r--src/components/application_manager/test/application_manager_impl_test.cc165
-rw-r--r--src/components/application_manager/test/commands/mobile/register_app_interface_request_test.cc140
-rw-r--r--src/components/application_manager/test/include/application_manager/mock_message_helper.h23
-rw-r--r--src/components/application_manager/test/mock_message_helper.cc42
-rw-r--r--src/components/include/application_manager/application_manager.h7
-rw-r--r--src/components/include/test/application_manager/mock_application_manager.h3
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