diff options
Diffstat (limited to 'src/components/application_manager/src/resumption/resume_ctrl_impl.cc')
-rw-r--r-- | src/components/application_manager/src/resumption/resume_ctrl_impl.cc | 240 |
1 files changed, 207 insertions, 33 deletions
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 fff1aefed3..2d5f1b6638 100644 --- a/src/components/application_manager/src/resumption/resume_ctrl_impl.cc +++ b/src/components/application_manager/src/resumption/resume_ctrl_impl.cc @@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. */ #include "application_manager/resumption/resume_ctrl_impl.h" +#include "application_manager/display_capabilities_builder.h" #include <algorithm> #include <fstream> @@ -90,7 +91,7 @@ bool ResumeCtrlImpl::get_resumption_active() const { } #endif // BUILD_TESTS -bool ResumeCtrlImpl::Init(resumption::LastState& last_state) { +bool ResumeCtrlImpl::Init(resumption::LastStateWrapperPtr last_state_wrapper) { bool use_db = application_manager_.get_settings().use_db_for_resumption(); if (use_db) { resumption_storage_.reset( @@ -119,7 +120,7 @@ bool ResumeCtrlImpl::Init(resumption::LastState& last_state) { } } else { resumption_storage_.reset( - new ResumptionDataJson(last_state, application_manager_)); + new ResumptionDataJson(last_state_wrapper, application_manager_)); if (!resumption_storage_->Init()) { LOG4CXX_DEBUG(logger_, "Resumption storage initialisation failed"); return false; @@ -159,7 +160,13 @@ void ResumeCtrlImpl::SaveApplication(ApplicationSharedPtr application) { } void ResumeCtrlImpl::on_event(const event_engine::Event& event) { - LOG4CXX_DEBUG(logger_, "Event received" << event.id()); + LOG4CXX_DEBUG(logger_, "Event received: " << event.id()); + + if (hmi_apis::FunctionID::UI_CreateWindow == event.id()) { + LOG4CXX_INFO(logger_, "Received UI_CreateWindow event"); + const auto& response_message = event.smart_object(); + RestoreWidgetsHMIState(response_message); + } } bool ResumeCtrlImpl::RestoreAppHMIState(ApplicationSharedPtr application) { @@ -207,8 +214,20 @@ bool ResumeCtrlImpl::RestoreAppHMIState(ApplicationSharedPtr application) { "High-bandwidth transport not available, app will resume into : " << saved_hmi_level); } - - return SetAppHMIState(application, saved_hmi_level, true); + const bool app_exists_in_full_or_limited = + application_manager_.get_full_or_limited_application().use_count() != + 0; + const bool app_hmi_state_is_set = + SetAppHMIState(application, saved_hmi_level, true); + size_t restored_widgets = 0; + if (app_hmi_state_is_set && + application->is_app_data_resumption_allowed()) { + restored_widgets = RestoreAppWidgets(application, saved_app); + } + if (0 == restored_widgets && app_exists_in_full_or_limited) { + LOG4CXX_DEBUG(logger_, "App exists in full or limited. Do not resume"); + return false; + } } else { result = false; LOG4CXX_ERROR(logger_, "saved app data corrupted"); @@ -219,6 +238,89 @@ bool ResumeCtrlImpl::RestoreAppHMIState(ApplicationSharedPtr application) { return result; } +void ResumeCtrlImpl::RestoreWidgetsHMIState( + const smart_objects::SmartObject& response_message) { + LOG4CXX_AUTO_TRACE(logger_); + const auto correlation_id = + response_message[strings::params][strings::correlation_id].asInt(); + const auto& request = requests_msg_.find(correlation_id); + if (requests_msg_.end() == request) { + LOG4CXX_ERROR(logger_, + "Request UI_CreateWindow for correlation id: " + << correlation_id << " not found"); + return; + } + + const auto& msg_params = (*request->second)[strings::msg_params]; + const auto hmi_app_id = msg_params[strings::app_id].asInt(); + auto application = application_manager_.application_by_hmi_app(hmi_app_id); + if (!application) { + LOG4CXX_ERROR(logger_, + "Application is not registered by hmi id: " << hmi_app_id); + requests_msg_.erase(request); + return; + } + const WindowID window_id = msg_params[strings::window_id].asInt(); + + const auto result_code = static_cast<hmi_apis::Common_Result::eType>( + response_message[strings::params][hmi_response::code].asInt()); + if (hmi_apis::Common_Result::SUCCESS != result_code) { + LOG4CXX_ERROR(logger_, + "UI_CreateWindow for correlation id: " + << correlation_id + << " failed with code: " << result_code); + requests_msg_.erase(request); + auto& builder = application->display_capabilities_builder(); + builder.StopWaitingForWindow(window_id); + return; + } + + smart_objects::SmartObject window_info(smart_objects::SmartType_Map); + auto fill_optional_param = [&window_info, + &msg_params](const std::string& key) { + if (msg_params.keyExists(key)) { + window_info[key] = msg_params[key].asString(); + } + }; + fill_optional_param(strings::associated_service_type); + fill_optional_param(strings::duplicate_updates_from_window_id); + + const auto window_name = msg_params[strings::window_name].asString(); + window_info[strings::window_name] = window_name; + application->SetWindowInfo(window_id, window_info); + + const auto window_type = static_cast<mobile_apis::WindowType::eType>( + msg_params[strings::window_type].asInt()); + // State should be initialized with INVALID_ENUM value to let state controller + // trigger OnHmiStatus notifiation sending + auto initial_state = application_manager_.CreateRegularState( + application, + window_type, + mobile_apis::HMILevel::INVALID_ENUM, + mobile_apis::AudioStreamingState::INVALID_ENUM, + mobile_apis::VideoStreamingState::INVALID_ENUM, + mobile_api::SystemContext::INVALID_ENUM); + application->SetInitialState(window_id, window_name, initial_state); + + // Default HMI level for all windows except the main one is always NONE + application_manager_.state_controller().OnAppWindowAdded( + application, window_id, window_type, mobile_apis::HMILevel::HMI_NONE); + + requests_msg_.erase(request); +} + +void ResumeCtrlImpl::ProcessSystemCapabilityUpdated( + Application& app, const smart_objects::SmartObject& display_capabilities) { + LOG4CXX_AUTO_TRACE(logger_); + + auto notification = MessageHelper::CreateDisplayCapabilityUpdateToMobile( + display_capabilities, app); + + application_manager_.GetRPCService().ManageMobileCommand( + notification, commands::Command::SOURCE_SDL); + app.set_is_resuming(false); +} + bool ResumeCtrlImpl::SetupDefaultHMILevel(ApplicationSharedPtr application) { LOG4CXX_AUTO_TRACE(logger_); DCHECK_OR_RETURN(application, false); @@ -252,7 +354,9 @@ void ResumeCtrlImpl::ApplicationResumptiOnTimer() { LOG4CXX_ERROR(logger_, "Invalid app_id = " << *it); continue; } - StartAppHmiStateResumption(app); + if (!StartAppHmiStateResumption(app)) { + app->set_is_resuming(false); + } } is_resumption_active_ = false; waiting_for_timer_.clear(); @@ -262,6 +366,7 @@ void ResumeCtrlImpl::ApplicationResumptiOnTimer() { void ResumeCtrlImpl::OnAppActivated(ApplicationSharedPtr application) { if (is_resumption_active_) { RemoveFromResumption(application->app_id()); + application->set_is_resuming(false); } } @@ -272,6 +377,10 @@ void ResumeCtrlImpl::RemoveFromResumption(uint32_t app_id) { queue_lock_.Release(); } +bool ResumeCtrlImpl::Init(LastState&) { + return false; +} + bool ResumeCtrlImpl::SetAppHMIState( ApplicationSharedPtr application, const mobile_apis::HMILevel::eType hmi_level, @@ -291,15 +400,39 @@ bool ResumeCtrlImpl::SetAppHMIState( SetupDefaultHMILevel(application); return false; } - application->set_is_resuming(true); - application_manager_.state_controller().SetRegularState(application, - hmi_level); + + application_manager_.state_controller().SetRegularState( + application, mobile_apis::PredefinedWindows::DEFAULT_WINDOW, hmi_level); LOG4CXX_INFO(logger_, "Application with policy id " << application->policy_app_id() << " got HMI level " << hmi_level); + return true; } +size_t ResumeCtrlImpl::RestoreAppWidgets( + application_manager::ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app) { + using namespace mobile_apis; + LOG4CXX_AUTO_TRACE(logger_); + DCHECK(application); + if (!saved_app.keyExists(strings::windows_info)) { + LOG4CXX_ERROR(logger_, "windows_info section does not exist"); + return 0; + } + const auto& windows_info = saved_app[strings::windows_info]; + auto request_list = MessageHelper::CreateUICreateWindowRequestsToHMI( + application, application_manager_, windows_info); + + requests_msg_.clear(); + for (auto& request : request_list) { + requests_msg_.insert(std::make_pair( + (*request)[strings::params][strings::correlation_id].asInt(), request)); + } + ProcessHMIRequests(request_list); + return request_list.size(); +} + bool ResumeCtrlImpl::IsHMIApplicationIdExist(uint32_t hmi_app_id) { LOG4CXX_DEBUG(logger_, "hmi_app_id :" << hmi_app_id); return resumption_storage_->IsHMIApplicationIdExist(hmi_app_id); @@ -335,6 +468,7 @@ void ResumeCtrlImpl::OnSuspend() { void ResumeCtrlImpl::OnIgnitionOff() { LOG4CXX_AUTO_TRACE(logger_); + DCHECK_OR_RETURN_VOID(resumption_storage_); if (!application_manager_.IsLowVoltage()) { resumption_storage_->IncrementIgnOffCount(); resumption_storage_->ResetGlobalIgnOnCount(); @@ -399,6 +533,8 @@ bool ResumeCtrlImpl::StartResumption(ApplicationSharedPtr application, << " hmi_app_id = " << application->hmi_app_id() << " policy_id = " << application->policy_app_id() << " received hash = " << hash); + application->set_is_resuming(true); + if (!application->is_cloud_app()) { // Default HMI Level is already set before resumption in // ApplicationManager::OnApplicationRegistered, and handling low bandwidth @@ -421,17 +557,18 @@ bool ResumeCtrlImpl::StartResumption(ApplicationSharedPtr application, bool ResumeCtrlImpl::StartResumptionOnlyHMILevel( ApplicationSharedPtr application) { - // sync_primitives::AutoLock lock(resumtion_lock_); LOG4CXX_AUTO_TRACE(logger_); if (!application) { LOG4CXX_WARN(logger_, "Application does not exist."); return false; } + + application->set_is_resuming(true); LOG4CXX_DEBUG(logger_, - "HMI level resumption requested for application id " - << application->app_id() << "with hmi_app_id " - << application->hmi_app_id() << ", policy_app_id " - << application->policy_app_id()); + "HMI level resumption requested for application id: " + << application->app_id() + << " with hmi_app_id: " << application->hmi_app_id() + << ", policy_app_id " << application->policy_app_id()); if (!application->is_cloud_app()) { // Default HMI Level is already set before resumption in // ApplicationManager::OnApplicationRegistered, and handling low bandwidth @@ -444,7 +581,6 @@ bool ResumeCtrlImpl::StartResumptionOnlyHMILevel( bool result = resumption_storage_->GetSavedApplication( application->policy_app_id(), device_mac, saved_app); if (result) { - // sync_primitives::AutoUnlock unlock(lock); AddToResumptionTimerQueue(application->app_id()); } LOG4CXX_INFO(logger_, "StartResumptionOnlyHMILevel::Result = " << result); @@ -473,18 +609,18 @@ void ResumeCtrlImpl::RetryResumption(const uint32_t app_id) { AddToResumptionTimerQueue(app_id); } -void ResumeCtrlImpl::StartAppHmiStateResumption( +bool ResumeCtrlImpl::StartAppHmiStateResumption( ApplicationSharedPtr application) { using namespace date_time; LOG4CXX_AUTO_TRACE(logger_); - DCHECK_OR_RETURN_VOID(application); + DCHECK_OR_RETURN(application, false); smart_objects::SmartObject saved_app; const std::string& device_mac = application->mac_address(); - const bool result = resumption_storage_->GetSavedApplication( + const bool get_saved_app_result = resumption_storage_->GetSavedApplication( application->policy_app_id(), device_mac, saved_app); - if (!result) { + if (!get_saved_app_result) { LOG4CXX_ERROR(logger_, "Application was not saved"); - return; + return false; } const bool is_hmi_level_applicable_to_resume = @@ -492,33 +628,39 @@ void ResumeCtrlImpl::StartAppHmiStateResumption( if (!is_hmi_level_applicable_to_resume) { LOG4CXX_DEBUG(logger_, "No applicable HMI level found for resuming"); - return; + return false; } - const bool is_resume_allowed_by_low_voltage = CheckLowVoltageRestrictions(saved_app); const bool is_hmi_level_allowed_by_ign_cycle = CheckIgnCycleRestrictions(saved_app); - const bool restore_hmi_level_allowed = - is_resume_allowed_by_low_voltage && is_hmi_level_allowed_by_ign_cycle; + const bool is_app_revoked = + application_manager_.GetPolicyHandler().IsApplicationRevoked( + application->policy_app_id()); + + const bool restore_hmi_level_allowed = is_resume_allowed_by_low_voltage && + is_hmi_level_allowed_by_ign_cycle && + !is_app_revoked; if (restore_hmi_level_allowed) { LOG4CXX_INFO(logger_, "Resume application " << application->policy_app_id()); - RestoreAppHMIState(application); + const bool hmi_state_restore_result = RestoreAppHMIState(application); if (mobile_apis::HMILevel::eType::INVALID_ENUM != application->deferred_resumption_hmi_level()) { // the application has not been fully resumed - return; + return false; } RemoveApplicationFromSaved(application); + return hmi_state_restore_result; } else { LOG4CXX_INFO( logger_, "Do not need to resume application " << application->policy_app_id()); } + return true; } void ResumeCtrlImpl::ResetLaunchTime() { @@ -561,9 +703,14 @@ bool ResumeCtrlImpl::CheckApplicationHash(ApplicationSharedPtr application, "app_id : " << application->app_id() << " hash : " << hash); smart_objects::SmartObject saved_app; const std::string& device_mac = application->mac_address(); - bool result = resumption_storage_->GetSavedApplication( + const bool get_app_result = resumption_storage_->GetSavedApplication( application->policy_app_id(), device_mac, saved_app); - return result ? saved_app[strings::hash_id].asString() == hash : false; + const bool check_result = + get_app_result ? saved_app[strings::hash_id].asString() == hash : false; + if (check_result) { + application->set_app_data_resumption_allowance(true); + } + return check_result; } void ResumeCtrlImpl::SaveDataOnTimer() { @@ -584,6 +731,7 @@ void ResumeCtrlImpl::SaveDataOnTimer() { void ResumeCtrlImpl::FinalPersistData() { LOG4CXX_AUTO_TRACE(logger_); + DCHECK_OR_RETURN_VOID(resumption_storage_); StopSavePersistentDataTimer(); SaveAllApplications(); resumption_storage_->Persist(); @@ -628,6 +776,27 @@ bool ResumeCtrlImpl::RestoreApplicationData(ApplicationSharedPtr application) { return result; } +void ResumeCtrlImpl::StartWaitingForDisplayCapabilitiesUpdate( + app_mngr::ApplicationSharedPtr application) { + LOG4CXX_AUTO_TRACE(logger_); + smart_objects::SmartObject saved_app(smart_objects::SmartType_Map); + resumption_storage_->GetSavedApplication( + application->policy_app_id(), application->mac_address(), saved_app); + auto resume_callback = + [this](Application& app, + const smart_objects::SmartObject& display_capabilities) -> void { + LOG4CXX_AUTO_TRACE(logger_); + ProcessSystemCapabilityUpdated(app, display_capabilities); + }; + auto& builder = application->display_capabilities_builder(); + + smart_objects::SmartObject windows_info(smart_objects::SmartType_Null); + if (saved_app.keyExists(strings::windows_info)) { + windows_info = saved_app[strings::windows_info]; + } + builder.InitBuilder(resume_callback, windows_info); +} + void ResumeCtrlImpl::AddFiles(ApplicationSharedPtr application, const smart_objects::SmartObject& saved_app) { LOG4CXX_AUTO_TRACE(logger_); @@ -681,15 +850,19 @@ void ResumeCtrlImpl::AddCommands(ApplicationSharedPtr application, if (saved_app.keyExists(strings::application_commands)) { 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]; + + for (size_t cmd_num = 0; cmd_num < app_commands.length(); ++cmd_num) { + const smart_objects::SmartObject& command = app_commands[cmd_num]; const uint32_t cmd_id = command[strings::cmd_id].asUInt(); const bool is_resumption = true; - - application->AddCommand(cmd_id, command); + application->AddCommand( + commands::CommandImpl::CalcCommandInternalConsecutiveNumber( + application), + command); application->help_prompt_manager().OnVrCommandAdded( cmd_id, command, is_resumption); } + ProcessHMIRequests(MessageHelper::CreateAddCommandRequestToHMI( application, application_manager_)); } else { @@ -1006,7 +1179,8 @@ bool ResumeCtrlImpl::ProcessHMIRequest(smart_objects::SmartObjectSPtr request, (*request)[strings::correlation_id].asInt(); subscribe_on_event(function_id, hmi_correlation_id); } - if (!application_manager_.GetRPCService().ManageHMICommand(request)) { + if (!application_manager_.GetRPCService().ManageHMICommand( + request, commands::Command::SOURCE_SDL_TO_HMI)) { LOG4CXX_ERROR(logger_, "Unable to send request"); return false; } |