diff options
Diffstat (limited to 'SDL_Core/src/components/application_manager/src/resume_ctrl.cpp')
-rw-r--r-- | SDL_Core/src/components/application_manager/src/resume_ctrl.cpp | 529 |
1 files changed, 529 insertions, 0 deletions
diff --git a/SDL_Core/src/components/application_manager/src/resume_ctrl.cpp b/SDL_Core/src/components/application_manager/src/resume_ctrl.cpp new file mode 100644 index 000000000..74cb2459d --- /dev/null +++ b/SDL_Core/src/components/application_manager/src/resume_ctrl.cpp @@ -0,0 +1,529 @@ +#include <fstream> + +#include "application_manager/resume_ctrl.h" +#include "config_profile/profile.h" +#include "utils/file_system.h" +#include "connection_handler/connection_handler_impl.h" +#include "application_manager/application_manager_impl.h" +#include "application_manager/application.h" +#include "application_manager/message_helper.h" +#include "smart_objects/smart_object.h" +#include "connection_handler/connection.h" +#include "formatters/CFormatterJsonBase.hpp" +#include "application_manager/commands/command_impl.h" + +namespace application_manager { + log4cxx::LoggerPtr ResumeCtrl::logger_ = log4cxx::LoggerPtr( + log4cxx::Logger::getLogger("ResumeCtrl")); +namespace Formatters = NsSmartDeviceLink::NsJSONHandler::Formatters; + +ResumeCtrl::ResumeCtrl(ApplicationManagerImpl* app_mngr) + : app_mngr_(app_mngr), + timer_(this, &ResumeCtrl::onTimer) { +} + +void ResumeCtrl::SaveAllApplications() { + LOG4CXX_INFO(logger_, " ResumeCtrl::SaveApplications()"); + DCHECK(app_mngr_); + + std::set<ApplicationSharedPtr>::iterator it = + app_mngr_->application_list_.begin(); + std::set<ApplicationSharedPtr>::iterator it_end = + app_mngr_->application_list_.end(); + for (; it != it_end; ++it) { + SaveApplication(*it); + } +} + +void ResumeCtrl::SaveApplication(ApplicationConstSharedPtr application) { + LOG4CXX_INFO(logger_, " ResumeCtrl::SaveApplication"); + DCHECK(application.get()); + + Json::Value* json_app = NULL; + const uint32_t app_id = application->mobile_app_id()->asInt(); + for (std::vector<Json::Value>::iterator it = saved_applications_.begin(); + it != saved_applications_.end(); ++it) { + if ((*it)[strings::app_id].asInt() == app_id) { + json_app = &(*it); + LOG4CXX_INFO(logger_, "ResumeCtrl Application with this id" + "is already exist ( update info ) " << app_id); + break; + } + } + + if (json_app == NULL) { + LOG4CXX_INFO(logger_, "ResumeCtrl Application with this ID does not" + "exist. Add new" << app_id); + saved_applications_.push_back(Json::Value()); + json_app = &(saved_applications_.back()); + } + + uint32_t connection_key = application->app_id(); + (*json_app)[strings::app_id] = app_id; + (*json_app)[strings::connection_key] = connection_key; + (*json_app)[strings::hmi_level] = + static_cast<int32_t> (application->hmi_level()); + (*json_app)[strings::ign_off_count] = 0; + (*json_app)[strings::hash_id] = application->curHash(); + (*json_app)[strings::application_commands] = + GetApplicationCommands(connection_key); + (*json_app)[strings::application_choise_sets] = + GetApplicationInteractionChoiseSets(connection_key); + (*json_app)[strings::application_global_properties] = + GetApplicationGlobalProperties(connection_key); + (*json_app)[strings::application_subscribtions] = + GetApplicationSubscriptions(connection_key); + (*json_app)[strings::application_files] = GetApplicationFiles(connection_key); + (*json_app)[strings::time_stamp] = (uint32_t)time(NULL); +} + +void ResumeCtrl::LoadApplications() { + LOG4CXX_INFO(logger_, "ResumeCtrl::LoadApplications"); + DCHECK(app_mngr_); + + const std::string& storage = + profile::Profile::instance()->app_info_storage(); + Json::Value root; + Json::Reader m_reader; + std::ifstream file(file_system::FullPath(storage).c_str(), + std::ios::in); + if (!file.is_open()) { + LOG4CXX_ERROR(logger_, "Error while opening file"); + return; + } + + m_reader.parse(file, root); + if (root.isNull()) { + LOG4CXX_INFO(logger_, "There are no Saved applications"); + return; + } + + for (Json::Value::iterator it = root.begin(); it != root.end(); ++it) { + Json::Value cur_app_data = (*it); + LOG4CXX_INFO(logger_, "Restored Application: " << + cur_app_data.toStyledString()); + saved_applications_.push_back(cur_app_data); + uint32_t session_key = cur_app_data[strings::connection_key].asUInt(); + } +} + +void ResumeCtrl::on_event(const event_engine::Event& event) { + LOG4CXX_INFO(logger_, "ResumeCtrl::on_event "); +} + +bool ResumeCtrl::RestoreApplicationHMILevel(ApplicationSharedPtr application) { + LOG4CXX_INFO(logger_, "ResumeCtrl::RestoreApplicationHMILevel"); + DCHECK(application.get()); + + for (std::vector<Json::Value>::iterator it = saved_applications_.begin(); + it != saved_applications_.end(); ++it) { + if ((*it)[strings::app_id].asInt() == + application->mobile_app_id()->asInt()) { + + mobile_apis::HMILevel::eType saved_hmi_level; + mobile_apis::HMILevel::eType restored_hmi_level; + + saved_hmi_level = static_cast<mobile_apis::HMILevel::eType>( + (*it)[strings::hmi_level].asInt()); + + if (saved_hmi_level == mobile_apis::HMILevel::HMI_FULL) { + restored_hmi_level = app_mngr_->PutApplicationInFull(application); + } else if (saved_hmi_level == mobile_apis::HMILevel::HMI_LIMITED) { + restored_hmi_level = app_mngr_->PutApplicationInLimited(application); + } else { + restored_hmi_level = saved_hmi_level; + application->set_hmi_level(saved_hmi_level); + } + MessageHelper::SendHMIStatusNotification(*(application.get())); + LOG4CXX_INFO(logger_, "Restore Application " + << (*it)[strings::app_id].asInt() + << " to HMILevel " << restored_hmi_level); + return true; + } + } + + return false; +} + +bool ResumeCtrl::RestoreApplicationData(ApplicationSharedPtr application) { + LOG4CXX_INFO(logger_, "RestoreApplicationData"); + DCHECK(application.get()); + + std::vector<Json::Value>::iterator it = saved_applications_.begin(); + for (; it != saved_applications_.end(); ++it) { + if ((*it)[strings::app_id].asInt() == + application->mobile_app_id()->asInt()) { + break; + } + } + if (it == saved_applications_.end()) { + LOG4CXX_WARN(logger_,"Application not saved"); + return false; + } + + Json::Value& saved_app = *it; + MessageHelper::SmartObjectList requests; + + LOG4CXX_INFO(logger_, saved_app.toStyledString()); + Json::Value& app_commands = saved_app[strings::application_commands]; + Json::Value& app_choise_sets = saved_app[strings::application_choise_sets]; + Json::Value& global_properties = saved_app[strings::application_global_properties]; + Json::Value& subscribtions = saved_app[strings::application_subscribtions]; + + + //add commands + for (Json::Value::iterator json_it = app_commands.begin(); + json_it != app_commands.end(); ++json_it) { + Json::Value& json_command = *json_it; + smart_objects::SmartObject message = smart_objects::SmartObject( + smart_objects::SmartType::SmartType_Map); + Formatters::CFormatterJsonBase::jsonValueToObj(json_command, message); + application->AddCommand(message[strings::cmd_id].asUInt(), message); + } + + requests = MessageHelper::CreateAddCommandRequestToHMI(application); + + for (MessageHelper::SmartObjectList::iterator it = requests.begin(); + it != requests.end(); ++it) { + ProcessHMIRequest(*it, true); + } + + //add choisets + for (Json::Value::iterator json_it = app_choise_sets.begin(); + json_it != app_choise_sets.end(); ++json_it) { + Json::Value& json_choiset = *json_it; + smart_objects::SmartObject msg_param = smart_objects::SmartObject( + smart_objects::SmartType::SmartType_Map); + Formatters::CFormatterJsonBase::jsonValueToObj(json_choiset , msg_param); + const int32_t choice_set_id = msg_param + [strings::interaction_choice_set_id].asInt(); + application->AddChoiceSet(choice_set_id, msg_param); + } + + //setglobal properties + if (!global_properties.isNull()) { + smart_objects::SmartObject properties_so = smart_objects::SmartObject( + smart_objects::SmartType::SmartType_Map); + Formatters::CFormatterJsonBase::jsonValueToObj(global_properties , properties_so); + + application->set_vr_help_title( + properties_so.getElement(strings::vr_help_title)); + application->set_vr_help( + properties_so.getElement(strings::vr_help)); + application->set_timeout_prompt( + properties_so.getElement(strings::timeout_prompt)); + application->set_help_prompt( + properties_so.getElement(strings::help_prompt)); + MessageHelper::SendGlobalPropertiesToHMI(application); + } + + //subscribes + if (!subscribtions.isNull()) { + Json::Value& subscribtions_buttons = subscribtions[strings::application_buttons]; + Json::Value& subscribtions_ivi= subscribtions[strings::application_vehicle_info]; + for (Json::Value::iterator json_it = subscribtions_buttons.begin(); + json_it != subscribtions_buttons.end(); ++json_it) { + mobile_apis::ButtonName::eType btn; + btn = static_cast<mobile_apis::ButtonName::eType>((*json_it).asInt()); + application->SubscribeToButton(btn); + } + + for (Json::Value::iterator json_it = subscribtions_ivi.begin(); + json_it != subscribtions_ivi.end(); ++json_it) { + VehicleDataType ivi; + ivi = static_cast<VehicleDataType>((*json_it).asInt()); + LOG4CXX_INFO(logger_, "VehicleDataType :" << ivi); + bool result = application->SubscribeToIVI(ivi); + LOG4CXX_INFO(logger_, "result = :" << result); + } + requests = MessageHelper::GetIVISubscribtionRequests(application->app_id()); + + for (MessageHelper::SmartObjectList::iterator it = requests.begin(); + it != requests.end(); ++it) { + ProcessHMIRequest(*it,true); + } + } + return true; +} + +bool ResumeCtrl::ApplicationIsSaved(const uint32_t app_id) { + LOG4CXX_INFO(logger_, "ResumeCtrl::ApplicationIsSaved " << app_id); + + for (std::vector<Json::Value>::iterator it = saved_applications_.begin(); + it != saved_applications_.end(); ++it) { + if ((*it)[strings::connection_key].asInt() == app_id) { + return true; + } + } + return false; +} + +bool ResumeCtrl::RemoveApplicationFromSaved(ApplicationConstSharedPtr application) { + LOG4CXX_INFO(logger_, "ResumeCtrl::RemoveApplicationFromSaved "); + DCHECK(application.get()); + + for (std::vector<Json::Value>::iterator it = saved_applications_.begin(); + it != saved_applications_.end(); ) { + if ((*it)[strings::app_id].asInt() == application->mobile_app_id()->asInt()) { + saved_applications_.erase(it); + return true; + } else { + ++it; + } + } + return false; +} + +void ResumeCtrl::SavetoFileSystem() { + LOG4CXX_INFO(logger_, "ResumeCtrl::SavetoFileSystem()"); + + const std::string& storage = + profile::Profile::instance()->app_info_storage(); + std::ofstream file(file_system::FullPath(storage).c_str(), + std::ios::out); + Json::Value to_save; + for (std::vector<Json::Value>::iterator it = saved_applications_.begin(); + it != saved_applications_.end(); ++it) { + uint32_t ign_off_count = (*it)[strings::ign_off_count].asUInt(); + if (ign_off_count < kApplicationLifes) { + ign_off_count++; + (*it)[strings::ign_off_count] = ign_off_count; + to_save.append(*it); + } + } + + if (file.is_open()) { + file << to_save.toStyledString(); + } else { + LOG4CXX_ERROR(logger_, "An error occurred during save"); + } + file.close(); +} + + +bool ResumeCtrl::StartResumption(ApplicationSharedPtr application, + uint32_t hash) { + + LOG4CXX_INFO(logger_, "ResumeCtrl::StartResumption " << hash); + DCHECK(application.get()); + sync_primitives::AutoLock auto_lock(queue_lock_); + + std::vector<Json::Value>::iterator it = saved_applications_.begin(); + for (; it != saved_applications_.end(); ++it) { + if ((*it)[strings::app_id].asInt() == + application->mobile_app_id()->asInt()) { + + uint32_t saved_hash = (*it)[strings::hash_id].asUInt(); + uint32_t time_stamp= (*it)[strings::time_stamp].asUInt(); + if (hash == saved_hash) { + RestoreApplicationData(application); + } + + waiting_for_timer_.insert(std::make_pair(application->app_id(), + time_stamp)); + timer_.start(kTimeStep); + return true; + } + } + + return false; +} + +bool ResumeCtrl::CheckApplicationHash(uint32_t app_id, uint32_t hash) { + std::vector<Json::Value>::iterator it = saved_applications_.begin(); + for (; it != saved_applications_.end(); ++it) { + if ((*it)[strings::app_id].asInt() == app_id) { + uint32_t saved_hash = (*it)[strings::hash_id].asUInt(); + if (hash == saved_hash) { + return true; + } + } + } + + return false; +} + +void ResumeCtrl::onTimer() { + LOG4CXX_INFO(logger_, "ResumeCtrl::onTimer()"); + sync_primitives::AutoLock auto_lock(queue_lock_); + + std::set<application_timestamp, TimeStampComparator>::iterator it= + waiting_for_timer_.begin(); + + for (; it != waiting_for_timer_.end(); ++it) { + ApplicationSharedPtr app = + ApplicationManagerImpl::instance()->application((*it).first); + if (!app.get()) { + LOG4CXX_ERROR(logger_, "Invalid app_id = " << (*it).first); + break; + } + + RestoreApplicationHMILevel(app); + RemoveApplicationFromSaved(app); + } + + waiting_for_timer_.clear(); +} + +Json::Value ResumeCtrl::GetApplicationCommands(const uint32_t app_id) { + LOG4CXX_INFO(logger_, "ResumeCtrl::GetApplicationCommands" << app_id); + + ApplicationConstSharedPtr app = + ApplicationManagerImpl::instance()->application(app_id); + DCHECK(app.get()); + + Json::Value result; + const CommandsMap& commands = app->commands_map(); + CommandsMap::const_iterator it = commands.begin(); + for (;it != commands.end(); ++it) { + smart_objects::SmartObject* so = it->second; + Json::Value curr; + Formatters::CFormatterJsonBase::objToJsonValue(*so, curr); + result.append(curr); + LOG4CXX_INFO(logger_, "Converted:" << curr.toStyledString()); + } + return result; +} + +Json::Value ResumeCtrl::GetApplicationInteractionChoiseSets( + const uint32_t app_id) { + LOG4CXX_INFO(logger_, "ResumeCtrl::GetApplicationInteractionChoiseSets" + << app_id); + + Json::Value result; + ApplicationConstSharedPtr app = + ApplicationManagerImpl::instance()->application(app_id); + DCHECK(app.get()); + + const ChoiceSetMap& choices = app->choice_set_map(); + ChoiceSetMap::const_iterator it = choices.begin(); + for ( ;it != choices.end(); ++it) { + smart_objects::SmartObject* so = it->second; + Json::Value curr; + Formatters::CFormatterJsonBase::objToJsonValue(*so, curr); + result.append(curr); + LOG4CXX_INFO(logger_, "Converted:" << curr.toStyledString()); + } + return result; +} + +Json::Value ResumeCtrl::GetApplicationGlobalProperties(const uint32_t app_id) { + LOG4CXX_INFO(logger_, "ResumeCtrl::GetApplicationGlobalProperties" << app_id); + + Json::Value result; + ApplicationConstSharedPtr app = + ApplicationManagerImpl::instance()->application(app_id); + DCHECK(app.get()); + + const smart_objects::SmartObject* help_promt = app->help_prompt(); + const smart_objects::SmartObject* timeout_prompt = app->timeout_prompt(); + const smart_objects::SmartObject* vr_help = app->vr_help(); + const smart_objects::SmartObject* vr_help_title = app->vr_help_title(); + const smart_objects::SmartObject* vr_synonyms = app->vr_synonyms(); + + Json::Value sgp; + sgp[strings::help_prompt] = JsonFromSO(help_promt); + sgp[strings::timeout_prompt] = JsonFromSO(timeout_prompt); + sgp[strings::vr_help] = JsonFromSO(vr_help); + sgp[strings::vr_help_title] = JsonFromSO(vr_help_title); + sgp[strings::vr_synonyms] = JsonFromSO(vr_synonyms); + + return sgp; +} + +Json::Value ResumeCtrl::GetApplicationSubscriptions(const uint32_t app_id) { + LOG4CXX_INFO(logger_, "ResumeCtrl::GetApplicationSubscriptions" << app_id); + + Json::Value result; + ApplicationConstSharedPtr app = + ApplicationManagerImpl::instance()->application(app_id); + DCHECK(app.get()); + + std::set<mobile_apis::ButtonName::eType>::iterator it_button ; + std::set<uint32_t>::iterator it_vehicle; + + for (it_button = app->SubscribedButtons().begin() ; + it_button != app->SubscribedButtons().end(); ++it_button) { + result[strings::application_buttons].append(*it_button); + } + for (it_vehicle = app->SubscribesIVI().begin(); + it_vehicle != app->SubscribesIVI().end(); ++it_vehicle) { + result[strings::application_vehicle_info].append(*it_vehicle); + } + return result; +} + +Json::Value ResumeCtrl::GetApplicationFiles(const uint32_t app_id) { + LOG4CXX_INFO(logger_, "ResumeCtrl::GetApplicationFiles" << app_id); + + Json::Value result; + ApplicationConstSharedPtr app = + ApplicationManagerImpl::instance()->application(app_id); + DCHECK(app.get()); + + const AppFilesMap& app_files = app->getAppFiles(); + for(AppFilesMap::const_iterator file_it = app_files.begin(); + file_it != app_files.end(); file_it++) { + const AppFile& file = file_it->second; + if (file.is_persistent) { + Json::Value file_data; + file_data[strings::persistent_file] = file.is_persistent; + file_data[strings::is_download_complete] = file.is_download_complete; + file_data[strings::sync_file_name] = file.file_name; + result.append(file_data); + } + } + return result; +} + +Json::Value ResumeCtrl::JsonFromSO(const smart_objects::SmartObject *so) { + Json::Value temp; + if (so) { + Formatters::CFormatterJsonBase::objToJsonValue(*so, temp); + } + return temp; +} + +bool ResumeCtrl::ProcessHMIRequest(smart_objects::SmartObject* request, + bool use_events) { + if (use_events) { + const hmi_apis::FunctionID::eType function_id = + static_cast<hmi_apis::FunctionID::eType>( + (*request)[strings::function_id].asInt()); + + const int32_t hmi_correlation_id = + (*request)[strings::correlation_id].asInt(); + subscribe_on_event(function_id, hmi_correlation_id); + } + if (!ApplicationManagerImpl::instance()->ManageHMICommand(request)) { + LOG4CXX_ERROR(logger_, "Unable to send request"); + return true; + } + return false; +} + +void ResumeCtrl::SendHMIRequest( + const hmi_apis::FunctionID::eType& function_id, + const smart_objects::SmartObject* msg_params, bool use_events) { + + NsSmartDeviceLink::NsSmartObjects::SmartObject* result = + MessageHelper::CreateModuleInfoSO(function_id); + int32_t hmi_correlation_id = + (*result)[strings::params][strings::correlation_id].asInt(); + if (use_events) { + subscribe_on_event(function_id, hmi_correlation_id); + } + + if (msg_params) { + (*result)[strings::msg_params] = *msg_params; + } + + if (!ApplicationManagerImpl::instance()->ManageHMICommand(result)) { + LOG4CXX_ERROR(logger_, "Unable to send request"); + } +} + +} // namespace application_manager + + + |