diff options
author | Andriy Byzhynar <abyzhynar@luxoft.com> | 2018-07-23 16:00:03 +0300 |
---|---|---|
committer | Alexander <akutsan@luxoft.com> | 2018-08-21 12:30:03 +0300 |
commit | 5ca9746469583369244adda2e1ce1fd5a5f03e27 (patch) | |
tree | 1b51f0c163bd3a78c0dc41582aa9272816569639 | |
parent | b003a5f4bf1859190bc00c138a8e97f9f83f19e5 (diff) | |
download | sdl_core-5ca9746469583369244adda2e1ce1fd5a5f03e27.tar.gz |
Implement resumption during Low Voltage
Implemented resumption logic during Low Voltage
(used app_info.dat file for resumption.Configurable in smartdevicelink.ini
file)
17 files changed, 535 insertions, 49 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 5f485b76eb..4f604f940e 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 @@ -1238,10 +1238,10 @@ class ApplicationManagerImpl */ void SendOnSDLClose(); - /* + /** * @brief returns true if low voltage state is active */ - bool IsLowVoltage(); + bool IsLowVoltage() const OVERRIDE; /** * @brief Allows to process postponed commands for application diff --git a/src/components/application_manager/include/application_manager/resumption/resume_ctrl.h b/src/components/application_manager/include/application_manager/resumption/resume_ctrl.h index 90c6c5c208..f9a60c862b 100644 --- a/src/components/application_manager/include/application_manager/resumption/resume_ctrl.h +++ b/src/components/application_manager/include/application_manager/resumption/resume_ctrl.h @@ -34,7 +34,7 @@ #define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_RESUMPTION_RESUME_CTRL_H_ #include <stdint.h> - +#include <time.h> #include "application_manager/resumption/resumption_data.h" namespace application_manager { @@ -125,6 +125,16 @@ class ResumeCtrl { virtual void OnAwake() = 0; /** + * @brief Saves Low Voltage signal timestamp + */ + virtual void SaveLowVoltageTime() = 0; + + /** + * @brief Saves Wake Up signal timestamp + */ + virtual void SaveWakeUpTime() = 0; + + /** * @brief Checks if SDL has already received OnExitAllApplication notification * with "SUSPEND" reason * @@ -134,13 +144,19 @@ class ResumeCtrl { virtual bool is_suspended() const = 0; /** - * @brief Method stops timer "RsmCtrlPercist" when SDL + * @brief Method stops timer "RsmCtrlPersist" when SDL * receives OnExitAllApplication notification * with reason "SUSPEND" */ virtual void StopSavePersistentDataTimer() = 0; /** + * @brief Method starts timer "RsmCtrlPersist" when + * SDL receives onAwakeSDL notification + */ + virtual void StartSavePersistentDataTimer() = 0; + + /** * @brief Start timer for resumption applications * Restore D1-D5 data * @param application that is need to be restored diff --git a/src/components/application_manager/include/application_manager/resumption/resume_ctrl_impl.h b/src/components/application_manager/include/application_manager/resumption/resume_ctrl_impl.h index 17aabb6d60..85e232fe92 100644 --- a/src/components/application_manager/include/application_manager/resumption/resume_ctrl_impl.h +++ b/src/components/application_manager/include/application_manager/resumption/resume_ctrl_impl.h @@ -33,6 +33,8 @@ #ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_RESUMPTION_RESUME_CTRL_IMPL_H_ #define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_RESUMPTION_RESUME_CTRL_IMPL_H_ +#include "application_manager/resumption/resume_ctrl.h" + #include <stdint.h> #include <vector> #include <map> @@ -46,7 +48,6 @@ #include "smart_objects/smart_object.h" #include "application_manager/application.h" #include "application_manager/resumption/resumption_data.h" -#include "application_manager/resumption/resume_ctrl.h" #include "utils/timer.h" namespace resumption { @@ -138,6 +139,10 @@ class ResumeCtrlImpl : public ResumeCtrl, */ void OnAwake() OVERRIDE; + void SaveLowVoltageTime() OVERRIDE; + + void SaveWakeUpTime() OVERRIDE; + /** * @brief Checks if SDL has already received OnExitAllApplication notification * with "SUSPEND" reason @@ -155,6 +160,13 @@ class ResumeCtrlImpl : public ResumeCtrl, void StopSavePersistentDataTimer() OVERRIDE; /** + * @brief Check if all IGNITION OFF and IGNITION ON records + * saved in resumption data base + * @return True if all records saved, otherwise False + */ + bool CheckIgnCyclesData() const; + + /** * @brief Method stops restore_hmi_level_timer_ "RsmCtrlRstore" in OnSuspend() */ void StopRestoreHmiLevelTimer(); @@ -300,7 +312,7 @@ class ResumeCtrlImpl : public ResumeCtrl, * @brief Method starts timer "RsmCtrlPercist" when * SDL receives onAwakeSDL notification */ - void StartSavePersistentDataTimer(); + void StartSavePersistentDataTimer() OVERRIDE; #ifdef BUILD_TESTS void set_resumption_storage( @@ -310,6 +322,30 @@ class ResumeCtrlImpl : public ResumeCtrl, #endif // BUILD_TESTS private: /** + * @brief Returns Low Voltage signal timestamp + * @return Low Voltage event timestamp if event LOW VOLTAGE event occures + * otherwise 0 + */ + time_t LowVoltageTime() const; + + /** + * @brief Returns Wake Up signal timestamp + * @return Wake Up timestamp if Wake Up signal occures + * otherwise 0 + */ + time_t WakeUpTime() const; + + /** + * @brief Resets Low Voltage signal timestamp to zero + */ + void ResetLowVoltageTime(); + + /** + * @brief Resets Wake Up signal timestamp to zero + */ + void ResetWakeUpTime(); + + /** * @brief restores saved data of application * @param application contains application for which restores data * @return true if success, otherwise return false @@ -390,11 +426,30 @@ class ResumeCtrlImpl : public ResumeCtrl, void AddWayPointsSubscription(app_mngr::ApplicationSharedPtr application, const smart_objects::SmartObject& saved_app); + /** + * @brief Checks if saved HMI level is allowed for resumption + * by Ignition Cycle restrictions + * @param saved_app application specific section from backup file + * @return True if allowed , otherwise - False + */ bool CheckIgnCycleRestrictions(const smart_objects::SmartObject& saved_app); - bool DisconnectedJustBeforeIgnOff( + /** + * @brief Checks if saved HMI level is allowed for resumption + * by Low Voltage restrictions + * @param saved_app application specific section from backup file + * @return True if allowed , otherwise - False + */ + bool CheckLowVoltageRestrictions(const smart_objects::SmartObject& saved_app); + + DEPRECATED bool DisconnectedJustBeforeIgnOff( const smart_objects::SmartObject& saved_app); + /** + * @brief Checks if saved HMI level is applicable for resumption + * @param saved_app application specific section from backup file + * @return True fs allowed , otherwise - False + */ bool CheckAppRestrictions(app_mngr::ApplicationConstSharedPtr application, const smart_objects::SmartObject& saved_app); @@ -409,10 +464,38 @@ class ResumeCtrlImpl : public ResumeCtrl, /** * @brief CheckDelayAfterIgnOn should check if SDL was started less - * then N seconds ago. N will be readed from profile. + * than N seconds ago. N will be read from profile. * @return true if SDL started N seconds ago, otherwise return false */ - bool CheckDelayAfterIgnOn(); + bool CheckDelayAfterIgnOn() const; + + /** + * @brief CheckDelayBeforeIgnOff checks if app was unregistered less + * than N seconds before Ignition OFF. N will be read from profile. + * @return true if app was disconnected within timeframe of N seconds before + * Ignition Off, + * otherwise return false + */ + bool CheckDelayBeforeIgnOff( + const smart_objects::SmartObject& saved_app) const; + + /** + * @brief CheckDelayAfterWakeUp should check if app was registered + * during the first N seconds after WakeUp signal. N will be read from + * profile. + * @return true if app registered within N seconds after WakeUp, otherwise + * return false + */ + bool CheckDelayAfterWakeUp() const; + + /** + * @brief CheckDelayBeforeLowVoltage checks if app was unregistered within + * N seconds before Low Voltage signal. N will be read from profile. + * @return true if app was disconnected within timeframe of N seconds before + * Low Voltage , otherwise return false + */ + bool CheckDelayBeforeLowVoltage( + const smart_objects::SmartObject& saved_app) const; typedef std::pair<uint32_t, uint32_t> application_timestamp; @@ -447,7 +530,7 @@ class ResumeCtrlImpl : public ResumeCtrl, * @brief Get the last ignition off time from LastState * @return the last ignition off time from LastState */ - time_t GetIgnOffTime(); + time_t GetIgnOffTime() const; /** * @brief Setup IgnOff time to LastState @@ -535,6 +618,8 @@ class ResumeCtrlImpl : public ResumeCtrl, bool is_data_saved_; bool is_suspended_; time_t launch_time_; + time_t low_voltage_time_; + time_t wake_up_time_; std::shared_ptr<ResumptionData> resumption_storage_; application_manager::ApplicationManager& application_manager_; }; diff --git a/src/components/application_manager/include/application_manager/resumption/resumption_data.h b/src/components/application_manager/include/application_manager/resumption/resumption_data.h index 5ecfaf3c11..ee866719c8 100644 --- a/src/components/application_manager/include/application_manager/resumption/resumption_data.h +++ b/src/components/application_manager/include/application_manager/resumption/resumption_data.h @@ -111,6 +111,30 @@ class ResumptionData { DEPRECATED virtual void OnAwake() = 0; /** + * @brief Increments global ignition on counter + * by 1 + */ + virtual void IncrementGlobalIgnOnCounter() = 0; + + /** + * @brief Get the global ignition on counter + * @return the global ignition on counter + */ + virtual uint32_t GetGlobalIgnOnCounter() const = 0; + + /** + * @brief Increments global ignition off counter + * by 1 + */ + virtual void IncrementGlobalIgnOffCounter() = 0; + + /** + * @brief Get the global ignition off counter + * @return the global ignition off counter + */ + virtual uint32_t GetGlobalIgnOffCounter() const = 0; + + /** * @brief Retrieves hash ID for the given mobile app ID * and device ID from stored information. * @param policy_app_id - mobile application id diff --git a/src/components/application_manager/include/application_manager/resumption/resumption_data_db.h b/src/components/application_manager/include/application_manager/resumption/resumption_data_db.h index 780aac82c1..08e9b04e62 100644 --- a/src/components/application_manager/include/application_manager/resumption/resumption_data_db.h +++ b/src/components/application_manager/include/application_manager/resumption/resumption_data_db.h @@ -111,6 +111,30 @@ class ResumptionDataDB : public ResumptionData { const std::string& device_id) const; /** + * @brief Increments global ignition on counter + * by 1 + */ + void IncrementGlobalIgnOnCounter() OVERRIDE; + + /** + * @brief Get the global ignition on counter + * @return the global ignition on counter + */ + virtual uint32_t GetGlobalIgnOnCounter() const OVERRIDE; + + /** + * @brief Increments global ignition off counter + * by 1 + */ + virtual void IncrementGlobalIgnOffCounter() OVERRIDE; + + /** + * @brief Get the global ignition off counter + * @return the global ignition off counter + */ + virtual uint32_t GetGlobalIgnOffCounter() const OVERRIDE; + + /** * @brief Increments ignition counter for all registered applications * and remember ign_off time stamp */ diff --git a/src/components/application_manager/include/application_manager/resumption/resumption_data_json.h b/src/components/application_manager/include/application_manager/resumption/resumption_data_json.h index 82ec1d9e5c..1a48ff20d5 100644 --- a/src/components/application_manager/include/application_manager/resumption/resumption_data_json.h +++ b/src/components/application_manager/include/application_manager/resumption/resumption_data_json.h @@ -146,6 +146,30 @@ class ResumptionDataJson : public ResumptionData { virtual uint32_t GetIgnOffTime() const; /** + * @brief Increments global ignition on counter + * by 1 + */ + void IncrementGlobalIgnOnCounter() OVERRIDE; + + /** + * @brief Get the global ignition on counter + * @return the global ignition on counter + */ + virtual uint32_t GetGlobalIgnOnCounter() const OVERRIDE; + + /** + * @brief Increments global ignition off counter + * by 1 + */ + virtual void IncrementGlobalIgnOffCounter() OVERRIDE; + + /** + * @brief Get the global ignition off counter + * @return the global ignition off counter + */ + virtual uint32_t GetGlobalIgnOffCounter() const OVERRIDE; + + /** * @brief Checks if saved data have application * @param policy_app_id - mobile application id * @param device_id - contains id of device on which is running application diff --git a/src/components/application_manager/include/application_manager/smart_object_keys.h b/src/components/application_manager/include/application_manager/smart_object_keys.h index d0a3c1ed96..90c9d403f7 100644 --- a/src/components/application_manager/include/application_manager/smart_object_keys.h +++ b/src/components/application_manager/include/application_manager/smart_object_keys.h @@ -313,6 +313,9 @@ extern const char* resume_vr_grammars; extern const char* ign_off_count; +extern const char* global_ign_on_counter; +extern const char* global_ign_off_counter; + extern const char* connection_info; extern const char* is_download_complete; diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc index 374b5bb8b2..6ff0689408 100644 --- a/src/components/application_manager/src/application_manager_impl.cc +++ b/src/components/application_manager/src/application_manager_impl.cc @@ -178,7 +178,7 @@ ApplicationManagerImpl::ApplicationManagerImpl( , is_low_voltage_(false) , apps_size_(0) , is_stopping_(false) { - std::srand(std::time(0)); + std::srand(std::time(nullptr)); AddPolicyObserver(this); dir_type_to_string_map_ = {{TYPE_STORAGE, "Storage"}, @@ -405,6 +405,7 @@ void ApplicationManagerImpl::OnApplicationSwitched(ApplicationSharedPtr app) { bool ApplicationManagerImpl::IsAppTypeExistsInFullOrLimited( ApplicationConstSharedPtr app) const { + LOG4CXX_AUTO_TRACE(logger_); bool voice_state = app->is_voice_communication_supported(); bool media_state = app->is_media_application(); bool navi_state = app->is_navi(); @@ -2622,11 +2623,13 @@ void ApplicationManagerImpl::UnregisterApplication( return; } + if (is_resuming) { resume_controller().SaveApplication(app_to_remove); } else { resume_controller().RemoveApplicationFromSaved(app_to_remove); } + (hmi_capabilities_->get_hmi_language_handler()) .OnUnregisterApplication(app_id); AppV4DevicePredicate finder(handle); @@ -2730,14 +2733,24 @@ bool ApplicationManagerImpl::is_audio_pass_thru_active() const { void ApplicationManagerImpl::OnLowVoltage() { LOG4CXX_AUTO_TRACE(logger_); is_low_voltage_ = true; + resume_ctrl_->SaveLowVoltageTime(); + resume_ctrl_->StopSavePersistentDataTimer(); request_ctrl_.OnLowVoltage(); } -bool ApplicationManagerImpl::IsLowVoltage() { - LOG4CXX_TRACE(logger_, "result: " << is_low_voltage_); +bool ApplicationManagerImpl::IsLowVoltage() const { + LOG4CXX_TRACE(logger_, "Result: " << is_low_voltage_); return is_low_voltage_; } +void ApplicationManagerImpl::OnWakeUp() { + LOG4CXX_AUTO_TRACE(logger_); + is_low_voltage_ = false; + resume_ctrl_->SaveWakeUpTime(); + resume_ctrl_->StartSavePersistentDataTimer(); + request_ctrl_.OnWakeUp(); +} + std::string ApplicationManagerImpl::GetHashedAppID( uint32_t connection_key, const std::string& mobile_app_id) const { connection_handler::DeviceHandle device_id = 0; @@ -3156,12 +3169,6 @@ policy::DeviceConsent ApplicationManagerImpl::GetUserConsentForDevice( return GetPolicyHandler().GetUserConsentForDevice(device_id); } -void ApplicationManagerImpl::OnWakeUp() { - LOG4CXX_AUTO_TRACE(logger_); - is_low_voltage_ = false; - request_ctrl_.OnWakeUp(); -} - mobile_apis::Result::eType ApplicationManagerImpl::SaveBinary( const std::vector<uint8_t>& binary_data, const std::string& file_path, 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 42dc335878..d52a495d17 100644 --- a/src/components/application_manager/src/resumption/resume_ctrl_impl.cc +++ b/src/components/application_manager/src/resumption/resume_ctrl_impl.cc @@ -74,7 +74,9 @@ ResumeCtrlImpl::ResumeCtrlImpl(ApplicationManager& application_manager) , is_resumption_active_(false) , is_data_saved_(false) , is_suspended_(false) - , launch_time_(time(NULL)) + , launch_time_(time(nullptr)) + , low_voltage_time_(0) + , wake_up_time_(0) , application_manager_(application_manager) {} #ifdef BUILD_TESTS void ResumeCtrlImpl::set_resumption_storage( @@ -144,9 +146,13 @@ void ResumeCtrlImpl::SaveAllApplications() { void ResumeCtrlImpl::SaveApplication(ApplicationSharedPtr application) { LOG4CXX_AUTO_TRACE(logger_); DCHECK_OR_RETURN_VOID(application); - LOG4CXX_INFO(logger_, - "application with appID " << application->app_id() - << " will be saved"); + if (application_manager_.IsLowVoltage()) { + LOG4CXX_DEBUG(logger_, "Low Voltage state is active"); + return; + } + LOG4CXX_DEBUG(logger_, + "application with appID " << application->app_id() + << " will be saved"); resumption_storage_->SaveApplication(application); } @@ -310,6 +316,10 @@ uint32_t ResumeCtrlImpl::GetHMIApplicationID( bool ResumeCtrlImpl::RemoveApplicationFromSaved( ApplicationConstSharedPtr application) { + if (application_manager_.IsLowVoltage()) { + LOG4CXX_DEBUG(logger_, "Low Voltage state is active"); + return false; + } const std::string& device_mac = application->mac_address(); return resumption_storage_->RemoveApplicationFromSaved( application->policy_app_id(), device_mac); @@ -323,8 +333,10 @@ void ResumeCtrlImpl::OnSuspend() { void ResumeCtrlImpl::OnIgnitionOff() { LOG4CXX_AUTO_TRACE(logger_); - resumption_storage_->IncrementIgnOffCount(); - FinalPersistData(); + if (!application_manager_.IsLowVoltage()) { + resumption_storage_->IncrementIgnOffCount(); + FinalPersistData(); + } } void ResumeCtrlImpl::OnAwake() { @@ -334,6 +346,37 @@ void ResumeCtrlImpl::OnAwake() { StartSavePersistentDataTimer(); } +void ResumeCtrlImpl::SaveLowVoltageTime() { + ResetLowVoltageTime(); + low_voltage_time_ = time(nullptr); + LOG4CXX_DEBUG(logger_, + "Low Voltage timestamp : " << low_voltage_time_ << " saved"); +} + +void ResumeCtrlImpl::ResetLowVoltageTime() { + low_voltage_time_ = 0; + LOG4CXX_DEBUG(logger_, "Resetting Low Voltage timestamp"); +} + +void ResumeCtrlImpl::SaveWakeUpTime() { + ResetWakeUpTime(); + wake_up_time_ = std::time(nullptr); + LOG4CXX_DEBUG(logger_, "Wake Up timestamp : " << wake_up_time_ << " saved"); +} + +void ResumeCtrlImpl::ResetWakeUpTime() { + wake_up_time_ = 0; + LOG4CXX_DEBUG(logger_, "Resetting Wake Up timestamp"); +} + +time_t ResumeCtrlImpl::LowVoltageTime() const { + return low_voltage_time_; +} + +time_t ResumeCtrlImpl::WakeUpTime() const { + return wake_up_time_; +} + bool ResumeCtrlImpl::is_suspended() const { return is_suspended_; } @@ -440,12 +483,25 @@ void ResumeCtrlImpl::StartAppHmiStateResumption( LOG4CXX_ERROR(logger_, "Application was not saved"); return; } - const uint32_t ign_off_count = saved_app[strings::ign_off_count].asUInt(); - bool restore_data_allowed = false; - restore_data_allowed = - CheckAppRestrictions(application, saved_app) && - ((0 == ign_off_count) || CheckIgnCycleRestrictions(saved_app)); - if (restore_data_allowed) { + + const bool is_hmi_level_applicable_to_resume = + CheckAppRestrictions(application, saved_app); + + if (!is_hmi_level_applicable_to_resume) { + LOG4CXX_DEBUG(logger_, "No applicable HMI level found for resuming"); + return; + } + + 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; + + if (restore_hmi_level_allowed) { LOG4CXX_INFO(logger_, "Resume application " << application->policy_app_id()); RestoreAppHMIState(application); @@ -716,21 +772,39 @@ void ResumeCtrlImpl::AddSubscriptions( bool ResumeCtrlImpl::CheckIgnCycleRestrictions( const smart_objects::SmartObject& saved_app) { LOG4CXX_AUTO_TRACE(logger_); - bool result = true; if (!CheckDelayAfterIgnOn()) { - LOG4CXX_INFO(logger_, "Application was connected long after ign on"); - result = false; + LOG4CXX_DEBUG(logger_, "Application was connected long after ign on"); + return false; } - if (!DisconnectedJustBeforeIgnOff(saved_app)) { - LOG4CXX_INFO(logger_, "Application was dissconnected long before ign off"); - result = false; + if (!CheckDelayBeforeIgnOff(saved_app)) { + LOG4CXX_DEBUG(logger_, "Application was disconnected long before ign off"); + return false; } - return result; + return true; } -bool ResumeCtrlImpl::DisconnectedJustBeforeIgnOff( +bool ResumeCtrlImpl::CheckLowVoltageRestrictions( + const smart_objects::SmartObject& saved_app) { + LOG4CXX_AUTO_TRACE(logger_); + + if (!CheckDelayBeforeLowVoltage(saved_app)) { + LOG4CXX_DEBUG(logger_, + "Application was disconnected long before low voltage"); + return false; + } + + if (!CheckDelayAfterWakeUp()) { + LOG4CXX_DEBUG(logger_, "Application was connected long after wake up"); + return false; + } + + LOG4CXX_DEBUG(logger_, "HMI Level resuming in not restricted by Low Voltage"); + return true; +} + +DEPRECATED bool ResumeCtrlImpl::DisconnectedJustBeforeIgnOff( const smart_objects::SmartObject& saved_app) { using namespace date_time; LOG4CXX_AUTO_TRACE(logger_); @@ -738,8 +812,9 @@ bool ResumeCtrlImpl::DisconnectedJustBeforeIgnOff( const time_t time_stamp = static_cast<time_t>(saved_app[strings::time_stamp].asInt()); - time_t ign_off_time = + const time_t ign_off_time = static_cast<time_t>(resumption_storage_->GetIgnOffTime()); + const uint32_t sec_spent_before_ign = labs(ign_off_time - time_stamp); LOG4CXX_DEBUG( logger_, @@ -752,6 +827,107 @@ bool ResumeCtrlImpl::DisconnectedJustBeforeIgnOff( application_manager_.get_settings().resumption_delay_before_ign(); } +bool ResumeCtrlImpl::CheckDelayBeforeIgnOff( + const smart_objects::SmartObject& saved_app) const { + using namespace date_time; + LOG4CXX_AUTO_TRACE(logger_); + DCHECK_OR_RETURN(saved_app.keyExists(strings::time_stamp), false); + + const time_t time_stamp = + static_cast<time_t>(saved_app[strings::time_stamp].asInt()); + const time_t ign_off_time = + static_cast<time_t>(resumption_storage_->GetIgnOffTime()); + + if (CheckIgnCyclesData() && 0 == ign_off_time) { + LOG4CXX_DEBUG( + logger_, "No IGNITION OFF records found: This is first Ignition cycle"); + return true; + } + + // This means that ignition off timestamp was not saved + // Possible reasons: Low Voltage event, core crash etc. + if (ign_off_time < time_stamp) { + LOG4CXX_DEBUG(logger_, "Last IGNITION OFF record missed"); + return true; + } + + const uint32_t sec_spent_before_ign = labs(ign_off_time - time_stamp); + LOG4CXX_DEBUG( + logger_, + "ign_off_time " + << ign_off_time << "; app_disconnect_time " << time_stamp + << "; sec_spent_before_ign " << sec_spent_before_ign + << "; resumption_delay_before_ign " + << application_manager_.get_settings().resumption_delay_before_ign()); + return sec_spent_before_ign <= + application_manager_.get_settings().resumption_delay_before_ign(); +} + +bool ResumeCtrlImpl::CheckDelayBeforeLowVoltage( + const smart_objects::SmartObject& saved_app) const { + using namespace date_time; + LOG4CXX_AUTO_TRACE(logger_); + DCHECK_OR_RETURN(saved_app.keyExists(strings::time_stamp), false); + + if (0 == LowVoltageTime()) { + LOG4CXX_DEBUG(logger_, "No Low Voltage signal timestamp saved"); + return true; + } + + const time_t unregistration_time_stamp = + static_cast<time_t>(saved_app[strings::time_stamp].asInt()); + const time_t low_voltage_timestamp = static_cast<time_t>(LowVoltageTime()); + const int32_t sec_spent_before_low_voltage = + (low_voltage_timestamp - unregistration_time_stamp); + if (0 > sec_spent_before_low_voltage) { + LOG4CXX_DEBUG(logger_, + "Low Voltage time: " + << low_voltage_timestamp + << "; App disconnect time: " << unregistration_time_stamp + << "; Secs between app disconnect and low voltage event " + << sec_spent_before_low_voltage); + return true; + } + + const uint32_t secs_between_app_disconnect_and_low_voltage = + static_cast<uint32_t>(sec_spent_before_low_voltage); + const uint32_t wait_time = + application_manager_.get_settings().resumption_delay_before_ign(); + LOG4CXX_DEBUG(logger_, + "Low Voltage time: " + << low_voltage_timestamp + << "; App disconnect time: " << unregistration_time_stamp + << "; Secs between app disconnect and low voltage event " + << secs_between_app_disconnect_and_low_voltage + << "; Timeout for HMI level resuming: " << wait_time); + return secs_between_app_disconnect_and_low_voltage <= wait_time; +} + +bool ResumeCtrlImpl::CheckDelayAfterWakeUp() const { + using namespace date_time; + LOG4CXX_AUTO_TRACE(logger_); + + if (0 == WakeUpTime()) { + LOG4CXX_DEBUG(logger_, "No WakeUp signal timestamp saved"); + return true; + } + + const time_t current_time = time(nullptr); + const time_t wake_up_timestamp = static_cast<time_t>(WakeUpTime()); + + const uint32_t seconds_from_wake_up_signal = + labs(current_time - wake_up_timestamp); + const uint32_t wait_time = + application_manager_.get_settings().resumption_delay_after_ign(); + LOG4CXX_DEBUG( + logger_, + "Current time: " << current_time << "; WakeUp Signal time: " + << wake_up_timestamp << "; Seconds passed from wake up: " + << seconds_from_wake_up_signal + << "; Timeout for HMI level resuming: " << wait_time); + return seconds_from_wake_up_signal <= wait_time; +} + bool ResumeCtrlImpl::CheckAppRestrictions( ApplicationConstSharedPtr application, const smart_objects::SmartObject& saved_app) { @@ -773,9 +949,10 @@ bool ResumeCtrlImpl::CheckAppRestrictions( ? true : false; LOG4CXX_DEBUG(logger_, - "is_media_app " << application->is_media_application() - << "; hmi_level " << hmi_level << " result " - << result); + "is_media_app: " << application->is_media_application() + << "; hmi_level: " << hmi_level << "; result: " + << (result ? "Applicable for resume" + : "Non-applicable for resume")); return result; } @@ -788,11 +965,35 @@ bool ResumeCtrlImpl::CheckIcons(ApplicationSharedPtr application, return mobile_apis::Result::INVALID_DATA != verify_images; } -bool ResumeCtrlImpl::CheckDelayAfterIgnOn() { +bool ResumeCtrlImpl::CheckIgnCyclesData() const { + LOG4CXX_AUTO_TRACE(logger_); + const uint32_t global_ign_off_count = + resumption_storage_->GetGlobalIgnOffCounter(); + const uint32_t global_ign_on_count = + resumption_storage_->GetGlobalIgnOnCounter(); + const uint32_t diff = global_ign_on_count - global_ign_off_count; + const bool is_ign_off_record_missed = diff >= 2; + if (is_ign_off_record_missed) { + LOG4CXX_WARN(logger_, + "Some IGN OFF records missed. Possibly due to Low Voltage"); + return false; + } + return true; +} + +bool ResumeCtrlImpl::CheckDelayAfterIgnOn() const { using namespace date_time; LOG4CXX_AUTO_TRACE(logger_); - const time_t curr_time = time(NULL); + const time_t ign_off_time = GetIgnOffTime(); + + if (CheckIgnCyclesData() && 0 == ign_off_time) { + LOG4CXX_DEBUG( + logger_, "No IGNITION OFF records found: This is first Ignition cycle"); + return true; + } + const time_t curr_time = time(nullptr); const time_t sdl_launch_time = LaunchTime(); + const uint32_t seconds_from_sdl_start = labs(curr_time - sdl_launch_time); const uint32_t wait_time = application_manager_.get_settings().resumption_delay_after_ign(); @@ -808,7 +1009,7 @@ time_t ResumeCtrlImpl::LaunchTime() const { return launch_time_; } -time_t ResumeCtrlImpl::GetIgnOffTime() { +time_t ResumeCtrlImpl::GetIgnOffTime() const { return resumption_storage_->GetIgnOffTime(); } @@ -856,6 +1057,8 @@ void ResumeCtrlImpl::AddToResumptionTimerQueue(const uint32_t app_id) { "Application ID " << app_id << " have been added" " to resumption queue."); if (run_resumption) { + LOG4CXX_DEBUG(logger_, + "Application ID " << app_id << " will be restored by timer"); restore_hmi_level_timer_.Start( application_manager_.get_settings().app_resuming_timeout(), timer::kSingleShot); diff --git a/src/components/application_manager/src/resumption/resumption_data_db.cc b/src/components/application_manager/src/resumption/resumption_data_db.cc index 2fe7330a9c..90c8a20e83 100644 --- a/src/components/application_manager/src/resumption/resumption_data_db.cc +++ b/src/components/application_manager/src/resumption/resumption_data_db.cc @@ -380,6 +380,20 @@ uint32_t ResumptionDataDB::GetIgnOffTime() const { return SelectIgnOffTime(); } +uint32_t ResumptionDataDB::GetGlobalIgnOnCounter() const { + return 0; +} + +uint32_t ResumptionDataDB::GetGlobalIgnOffCounter() const { + return 0; +} + +void ResumptionDataDB::IncrementGlobalIgnOffCounter() { +} + +void ResumptionDataDB::IncrementGlobalIgnOnCounter() { +} + ssize_t ResumptionDataDB::IsApplicationSaved( const std::string& policy_app_id, const std::string& device_id) const { LOG4CXX_AUTO_TRACE(logger_); diff --git a/src/components/application_manager/src/resumption/resumption_data_json.cc b/src/components/application_manager/src/resumption/resumption_data_json.cc index b6a50fd5de..e11f482ad6 100644 --- a/src/components/application_manager/src/resumption/resumption_data_json.cc +++ b/src/components/application_manager/src/resumption/resumption_data_json.cc @@ -149,6 +149,7 @@ void ResumptionDataJson::IncrementIgnOffCount() { using namespace app_mngr; LOG4CXX_AUTO_TRACE(logger_); sync_primitives::AutoLock autolock(resumption_lock_); + IncrementGlobalIgnOffCounter(); Json::Value to_save = Json::arrayValue; for (Json::Value::iterator it = GetSavedApplications().begin(); it != GetSavedApplications().end(); @@ -283,6 +284,69 @@ uint32_t ResumptionDataJson::GetIgnOffTime() const { return resumption[strings::last_ign_off_time].asUInt(); } +uint32_t ResumptionDataJson::GetGlobalIgnOnCounter() const { + using namespace app_mngr; + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock autolock(resumption_lock_); + Json::Value& resumption = GetResumptionData(); + if (resumption.isMember(strings::global_ign_on_counter)) { + return resumption[strings::global_ign_on_counter].asUInt(); + } + return 1; +} + +uint32_t ResumptionDataJson::GetGlobalIgnOffCounter() const { + using namespace app_mngr; + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock autolock(resumption_lock_); + Json::Value& resumption = GetResumptionData(); + if (resumption.isMember(strings::global_ign_off_counter)) { + return resumption[strings::global_ign_off_counter].asUInt(); + } + return 0; +} + +void ResumptionDataJson::IncrementGlobalIgnOffCounter() { + using namespace app_mngr; + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock autolock(resumption_lock_); + Json::Value& resumption = GetResumptionData(); + if (resumption.isMember(strings::global_ign_off_counter)) { + const uint32_t global_ign_off_counter = + resumption[strings::global_ign_off_counter].asUInt(); + LOG4CXX_DEBUG(logger_, + "Global IGN OFF counter in resumption data: " + << global_ign_off_counter); + resumption[strings::global_ign_off_counter] = global_ign_off_counter + 1; + LOG4CXX_DEBUG(logger_, + "Global IGN OFF counter new value: " + << resumption[strings::global_ign_off_counter].asUInt()); + } else { + resumption[strings::global_ign_off_counter] = 1; + } +} + +void ResumptionDataJson::IncrementGlobalIgnOnCounter() { + using namespace app_mngr; + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock autolock(resumption_lock_); + Json::Value& resumption = GetResumptionData(); + if (resumption.isMember(strings::global_ign_on_counter)) { + const uint32_t global_ign_on_counter = + resumption[strings::global_ign_on_counter].asUInt(); + LOG4CXX_DEBUG( + logger_, + "Global IGN ON counter in resumption data: " << global_ign_on_counter); + resumption[strings::global_ign_on_counter] = global_ign_on_counter + 1; + LOG4CXX_DEBUG(logger_, + "Global IGN ON counter new value: " + << resumption[strings::global_ign_on_counter].asUInt()); + } else { + resumption[strings::global_ign_on_counter] = 1; + } + last_state().SaveStateToFileSystem(); +} + ssize_t ResumptionDataJson::IsApplicationSaved( const std::string& policy_app_id, const std::string& device_id) const { LOG4CXX_AUTO_TRACE(logger_); @@ -454,6 +518,7 @@ void ResumptionDataJson::SetLastIgnOffTime(time_t ign_off_time) { bool ResumptionDataJson::Init() { LOG4CXX_AUTO_TRACE(logger_); + IncrementGlobalIgnOnCounter(); return true; } diff --git a/src/components/application_manager/src/smart_object_keys.cc b/src/components/application_manager/src/smart_object_keys.cc index 006b8c9249..ebc114347e 100644 --- a/src/components/application_manager/src/smart_object_keys.cc +++ b/src/components/application_manager/src/smart_object_keys.cc @@ -276,6 +276,8 @@ const char* last_ign_off_time = "last_ign_off_time"; const char* resume_vr_grammars = "resumeVrGrammars"; const char* ign_off_count = "ign_off_count"; +const char* global_ign_on_counter = "global_ign_on_counter"; +const char* global_ign_off_counter = "global_ign_off_counter"; const char* suspend_count = "suspend_count"; const char* connection_info = "connection_info"; diff --git a/src/components/application_manager/src/state_controller_impl.cc b/src/components/application_manager/src/state_controller_impl.cc index f7a147d6df..3d44709657 100644 --- a/src/components/application_manager/src/state_controller_impl.cc +++ b/src/components/application_manager/src/state_controller_impl.cc @@ -458,6 +458,8 @@ mobile_apis::HMILevel::eType StateControllerImpl::GetAvailableHmiLevel( LOG4CXX_AUTO_TRACE(logger_); mobile_apis::HMILevel::eType result = hmi_level; + LOG4CXX_DEBUG(logger_, "HMI Level: " << hmi_level); + if (!IsStreamableHMILevel(hmi_level)) { return result; } @@ -465,6 +467,7 @@ mobile_apis::HMILevel::eType StateControllerImpl::GetAvailableHmiLevel( const bool is_audio_app = app->IsAudioApplication(); const bool does_audio_app_with_same_type_exist = app_mngr_.IsAppTypeExistsInFullOrLimited(app); + if (mobile_apis::HMILevel::HMI_LIMITED == hmi_level) { if (!is_audio_app || does_audio_app_with_same_type_exist) { result = app_mngr_.GetDefaultHmiLevel(app); diff --git a/src/components/application_manager/test/include/application_manager/mock_resume_ctrl.h b/src/components/application_manager/test/include/application_manager/mock_resume_ctrl.h index 3c4a3806d6..0fa7a898be 100644 --- a/src/components/application_manager/test/include/application_manager/mock_resume_ctrl.h +++ b/src/components/application_manager/test/include/application_manager/mock_resume_ctrl.h @@ -50,8 +50,15 @@ class MockResumeCtrl : public resumption::ResumeCtrl { MOCK_METHOD0(OnSuspend, void()); MOCK_METHOD0(OnIgnitionOff, void()); MOCK_METHOD0(OnAwake, void()); + MOCK_CONST_METHOD0(LowVoltageTime, time_t()); + MOCK_CONST_METHOD0(WakeUpTime, time_t()); + MOCK_METHOD0(SaveLowVoltageTime, void()); + MOCK_METHOD0(SaveWakeUpTime, void()); + MOCK_METHOD0(ResetLowVoltageTime, void()); + MOCK_METHOD0(ResetWakeUpTime, void()); MOCK_CONST_METHOD0(is_suspended, bool()); MOCK_METHOD0(StopSavePersistentDataTimer, void()); + MOCK_METHOD0(StartSavePersistentDataTimer, void()); MOCK_METHOD2(StartResumption, bool(app_mngr::ApplicationSharedPtr application, const std::string& hash)); diff --git a/src/components/application_manager/test/include/application_manager/mock_resumption_data.h b/src/components/application_manager/test/include/application_manager/mock_resumption_data.h index cfec034653..a3ac670fa4 100644 --- a/src/components/application_manager/test/include/application_manager/mock_resumption_data.h +++ b/src/components/application_manager/test/include/application_manager/mock_resumption_data.h @@ -66,6 +66,11 @@ class MockResumptionData : public ::resumption::ResumptionData { const std::string& device_id, std::string& hash_id)); MOCK_METHOD0(OnAwake, void()); + MOCK_METHOD0(IncrementGlobalIgnOnCounter, void()); + MOCK_CONST_METHOD0(GetGlobalIgnOnCounter, uint32_t()); + MOCK_METHOD0(IncrementGlobalIgnOffCounter, void()); + MOCK_CONST_METHOD0(GetGlobalIgnOffCounter, uint32_t()); + MOCK_METHOD0(DecrementIgnOffCount, void()); MOCK_CONST_METHOD3(GetSavedApplication, bool(const std::string& policy_app_id, diff --git a/src/components/include/application_manager/application_manager.h b/src/components/include/application_manager/application_manager.h index 8397fbf790..ed9d3c0114 100644 --- a/src/components/include/application_manager/application_manager.h +++ b/src/components/include/application_manager/application_manager.h @@ -33,6 +33,7 @@ #ifndef SRC_COMPONENTS_INCLUDE_APPLICATION_MANAGER_APPLICATION_MANAGER_H_ #define SRC_COMPONENTS_INCLUDE_APPLICATION_MANAGER_APPLICATION_MANAGER_H_ +#include <ctime> #include <string> #include <vector> #include <set> @@ -424,6 +425,11 @@ class ApplicationManager { */ virtual void EndNaviServices(uint32_t app_id) = 0; + /** + * @brief returns true if low voltage state is active + */ + virtual bool IsLowVoltage() const = 0; + /* @brief Starts audio passthru process * @deprecated Use BeginAudioPassThru(uint32_t app_id) instead * @@ -498,8 +504,6 @@ class ApplicationManager { virtual bool IsStopping() const = 0; - virtual bool IsLowVoltage() = 0; - virtual void RemoveAppFromTTSGlobalPropertiesList(const uint32_t app_id) = 0; virtual mobile_apis::Result::eType SaveBinary( 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 5900b760a6..25340d7c2a 100644 --- a/src/components/include/test/application_manager/mock_application_manager.h +++ b/src/components/include/test/application_manager/mock_application_manager.h @@ -140,6 +140,7 @@ class MockApplicationManager : public application_manager::ApplicationManager { void(const smart_objects::SmartObject& sm_object, const uint32_t connection_key)); MOCK_CONST_METHOD0(is_attenuated_supported, bool()); + MOCK_CONST_METHOD0(IsLowVoltage, bool()); MOCK_CONST_METHOD1(IsAppTypeExistsInFullOrLimited, bool(application_manager::ApplicationConstSharedPtr app)); MOCK_METHOD1(OnApplicationRegistered, @@ -180,7 +181,6 @@ class MockApplicationManager : public application_manager::ApplicationManager { MOCK_CONST_METHOD1(IsAppsQueriedFrom, bool(const connection_handler::DeviceHandle handle)); MOCK_CONST_METHOD0(IsStopping, bool()); - MOCK_METHOD0(IsLowVoltage, bool()); MOCK_METHOD1(RemoveAppFromTTSGlobalPropertiesList, void(const uint32_t app_id)); MOCK_METHOD4( |