summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordtrunov <dtrunov@luxoft.com>2015-02-27 17:43:07 +0200
committerdtrunov <dtrunov@luxoft.com>2015-06-23 15:09:11 +0300
commit81d5b783c174d192ec89aa99fe35a87851b83ff7 (patch)
tree2d1ec92f3f77b0b2b13ad27e0a297c60c31fc973 /src
parente533d78381ff2102742710fcfae4b83a55bc77b2 (diff)
downloadsdl_core-81d5b783c174d192ec89aa99fe35a87851b83ff7.tar.gz
Resumption with DB
Diffstat (limited to 'src')
-rw-r--r--src/components/application_manager/include/application_manager/application.h19
-rw-r--r--src/components/application_manager/include/application_manager/application_impl.h6
-rw-r--r--src/components/application_manager/include/application_manager/message_helper.h7
-rw-r--r--src/components/application_manager/include/application_manager/resume_ctrl.h113
-rw-r--r--src/components/application_manager/include/application_manager/resumption/resume_ctrl.h520
-rw-r--r--src/components/application_manager/include/application_manager/resumption/resumption_data.h297
-rw-r--r--src/components/application_manager/include/application_manager/resumption/resumption_data_db.h258
-rw-r--r--src/components/application_manager/include/application_manager/resumption/resumption_data_json.h228
-rw-r--r--src/components/application_manager/include/application_manager/resumption/resumption_sql_queries.h59
-rw-r--r--src/components/application_manager/include/application_manager/smart_object_keys.h4
-rw-r--r--src/components/application_manager/src/application_impl.cc13
-rw-r--r--src/components/application_manager/src/application_manager_impl.cc1
-rw-r--r--src/components/application_manager/src/commands/mobile/register_app_interface_request.cc19
-rw-r--r--src/components/application_manager/src/message_helper.cc48
-rw-r--r--src/components/application_manager/src/resume_ctrl.cpp523
-rw-r--r--src/components/application_manager/src/resumption/resume_ctrl.cc1305
-rw-r--r--src/components/application_manager/src/resumption/resumption_data.cc320
-rw-r--r--src/components/application_manager/src/resumption/resumption_data_db.cc345
-rw-r--r--src/components/application_manager/src/resumption/resumption_data_json.cc475
-rw-r--r--src/components/application_manager/src/resumption/resumption_sql_queries.cc98
-rw-r--r--src/components/utils/include/utils/qdb_wrapper/sql_query.h7
-rw-r--r--src/components/utils/include/utils/sqlite_wrapper/sql_query.h7
-rw-r--r--src/components/utils/src/qdb_wrapper/sql_query.cc9
-rw-r--r--src/components/utils/src/sqlite_wrapper/sql_query.cc5
24 files changed, 4329 insertions, 357 deletions
diff --git a/src/components/application_manager/include/application_manager/application.h b/src/components/application_manager/include/application_manager/application.h
index d92c6a35c4..8173552a3b 100644
--- a/src/components/application_manager/include/application_manager/application.h
+++ b/src/components/application_manager/include/application_manager/application.h
@@ -70,6 +70,11 @@ enum APIVersion {
kAPIV4 = 4
};
+enum StateApplicationData {
+ kNotSavedDataForResumption,
+ kSavedDataForResumption
+};
+
enum TLimitSource {
POLICY_TABLE = 0,
CONFIG_FILE
@@ -394,6 +399,20 @@ class Application : public virtual InitialApplicationData,
*/
virtual void UpdateHash() = 0;
+ /**
+ * @brief method is called when SDL is saving application data for resumption
+ * @return TRUE if data of application need to save for resumption, otherwise
+ * return FALSE
+ */
+ virtual StateApplicationData is_application_data_changed() const = 0;
+
+ /**
+ * @brief method is called after SDL saved application data for resumption
+ * @param state_application_data contains FALSE after saving data
+ */
+ virtual void set_is_application_data_changed(
+ StateApplicationData state_application_data) = 0;
+
virtual void CloseActiveMessage() = 0;
virtual bool IsFullscreen() const = 0;
virtual void ChangeSupportingAppHMIType() = 0;
diff --git a/src/components/application_manager/include/application_manager/application_impl.h b/src/components/application_manager/include/application_manager/application_impl.h
index 895bb1fa98..a0b187f8d0 100644
--- a/src/components/application_manager/include/application_manager/application_impl.h
+++ b/src/components/application_manager/include/application_manager/application_impl.h
@@ -195,6 +195,11 @@ class ApplicationImpl : public virtual InitialApplicationDataImpl,
virtual void UnsubscribeFromSoftButtons(int32_t cmd_id);
+ virtual StateApplicationData is_application_data_changed() const;
+
+ virtual void set_is_application_data_changed(
+ StateApplicationData state_application_data);
+
/**
* @brief Check's if it is media, voice communication or navigation application
*
@@ -300,6 +305,7 @@ class ApplicationImpl : public virtual InitialApplicationDataImpl,
bool tts_properties_in_none_;
bool tts_properties_in_full_;
bool is_foreground_;
+ StateApplicationData is_application_data_changed_;
uint32_t put_file_in_none_count_;
uint32_t delete_file_in_none_count_;
uint32_t list_files_in_none_count_;
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 9b8093dc53..bcaa78ed3e 100644
--- a/src/components/application_manager/include/application_manager/message_helper.h
+++ b/src/components/application_manager/include/application_manager/message_helper.h
@@ -214,6 +214,13 @@ class MessageHelper {
static smart_objects::SmartObjectList CreateAddCommandRequestToHMI(ApplicationConstSharedPtr app);
/**
+ * @brief prepares commands in order to send it to HMI
+ * @param app applicaton instace
+ */
+ static smart_objects::SmartObjectList CreateAddVRCommandRequestFromChoiceToHMI(
+ ApplicationConstSharedPtr app);
+
+ /**
* @brief Sends UI_ChangeRegistration to HMI with list of AppHMIType
* @param app applicaton instace
*/
diff --git a/src/components/application_manager/include/application_manager/resume_ctrl.h b/src/components/application_manager/include/application_manager/resume_ctrl.h
index 99d694570c..d42675cdfb 100644
--- a/src/components/application_manager/include/application_manager/resume_ctrl.h
+++ b/src/components/application_manager/include/application_manager/resume_ctrl.h
@@ -76,13 +76,13 @@ class ResumeCtrl: public event_engine::EventObserver {
* @brief Save all applications info to the file system
*/
void SaveAllApplications();
-
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* @brief Save application persistent info for future resuming
* @param application is application witch need to be saved
*/
void SaveApplication(ApplicationConstSharedPtr application);
-
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* @brief Set application HMI Level as saved
* @param application is application witch HMI Level is need to restore
@@ -116,21 +116,14 @@ class ResumeCtrl: public event_engine::EventObserver {
* @return true if success, otherwise return false
*/
bool RestoreApplicationData(ApplicationSharedPtr application);
-
- /**
- * @brief Check if Resume controller have saved instance of application
- * @param application is application witch need to be checked
- * @return true if exist, false otherwise
- */
- bool ApplicationIsSaved(ApplicationConstSharedPtr application);
-
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* @brief Remove application from list of saved applications
* @param mobile_app_id application witch need to be removed
* @return return true, if success, otherwise return false
*/
bool RemoveApplicationFromSaved(const std::string& mobile_app_id);
-
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* @brief Increments ignition counter for all registered applications
* and remember ign_off time stamp
@@ -194,19 +187,22 @@ class ResumeCtrl: public event_engine::EventObserver {
/**
* @brief Check if Resume controller have saved instance of application
* @param mobile_app_id - mobile application id
+ * @param device_id - contains id of device on which is running application
* @return true if exist, false otherwise
*/
- bool IsApplicationSaved(const std::string& mobile_app_id);
+ bool IsApplicationSaved(const std::string& mobile_app_id,
+ const std::string& device_id);
/**
* @brief Function is used for application resume. HMI app ID must be
* the same(PASA VCA module use it for stored app info).
* Retrieves HMI app ID for the given mobile app ID from stored information.
- *
* @param mobile_app_id - mobile application id
+ * @param device_id - contains id of device on which is running application
* @return HMI app ID
*/
- uint32_t GetHMIApplicationID(const std::string& mobile_app_id);
+ uint32_t GetHMIApplicationID(const std::string& mobile_app_id,
+ const std::string& device_id);
/**
* @brief SaveDataOnTimer :
@@ -215,8 +211,6 @@ class ResumeCtrl: public event_engine::EventObserver {
*/
void SaveDataOnTimer();
- void ClearResumptionInfo();
-
void ApplicationsDataUpdated() {
is_data_saved = false;
}
@@ -261,34 +255,29 @@ class ResumeCtrl: public event_engine::EventObserver {
*/
time_t launch_time() const;
- /**
- * @brief Check device MAC address
- *
- * @param application that is need to be restored
- * @param saved_device_mac Saved device MAC address
- *
- * @return TRUE on success, otherwise FALSE
- */
- bool IsDeviceMacAddressEqual(ApplicationSharedPtr application,
- const std::string& saved_device_mac);
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* @brief Get Resumption section of LastState
* @return Resumption section of LastState in Json
*/
Json::Value& GetResumptionData();
-
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* @brief Get applications for resumption of LastState
* @return applications for resumption of LastState
*/
Json::Value& GetSavedApplications();
-
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* @brief Get the last ignition off time from LastState
* @return the last ignition off time from LastState
*/
time_t GetIgnOffTime();
-
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* @brief Setup IgnOff time to LastState
* @param ign_off_time - igition off time
@@ -313,8 +302,8 @@ class ResumeCtrl: public event_engine::EventObserver {
ApplicationConstSharedPtr application);
Json::Value GetApplicationFiles(
ApplicationConstSharedPtr application);
- Json::Value GetApplicationShow(
- ApplicationConstSharedPtr application);
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
Json::Value JsonFromSO(const smart_objects::SmartObject *so);
@@ -327,7 +316,7 @@ class ResumeCtrl: public event_engine::EventObserver {
bool use_events = false);
void InsertToTimerQueue(uint32_t app_id, uint32_t time_stamp);
-
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* @brief AddFiles allows to add files for the application
* which should be resumed
@@ -337,7 +326,8 @@ class ResumeCtrl: public event_engine::EventObserver {
* @param saved_app application specific section from backup file
*/
void AddFiles(ApplicationSharedPtr application, const Json::Value& saved_app);
-
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* @brief AddSubmenues allows to add sub menues for the application
* which should be resumed
@@ -347,7 +337,8 @@ class ResumeCtrl: public event_engine::EventObserver {
* @param saved_app application specific section from backup file
*/
void AddSubmenues(ApplicationSharedPtr application, const Json::Value& saved_app);
-
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* @brief AddCommands allows to add commands for the application
* which should be resumed
@@ -357,7 +348,8 @@ class ResumeCtrl: public event_engine::EventObserver {
* @param saved_app application specific section from backup file
*/
void AddCommands(ApplicationSharedPtr application, const Json::Value& saved_app);
-
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* @brief AddChoicesets allows to add choice sets for the application
* which should be resumed
@@ -367,7 +359,8 @@ class ResumeCtrl: public event_engine::EventObserver {
* @param saved_app application specific section from backup file
*/
void AddChoicesets(ApplicationSharedPtr application, const Json::Value& saved_app);
-
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* @brief SetGlobalProperties allows to restore global properties.
*
@@ -376,7 +369,8 @@ class ResumeCtrl: public event_engine::EventObserver {
* @param saved_app application specific section from backup file
*/
void SetGlobalProperties(ApplicationSharedPtr application, const Json::Value& saved_app);
-
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* @brief AddSubscriptions allows to restore subscriptions
*
@@ -385,7 +379,7 @@ class ResumeCtrl: public event_engine::EventObserver {
* @param saved_app application specific section from backup file
*/
void AddSubscriptions(ApplicationSharedPtr application, const Json::Value& saved_app);
-
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* @brief ProcessHMIRequests allows to process obtained requests.
*
@@ -395,15 +389,14 @@ class ResumeCtrl: public event_engine::EventObserver {
/**
* @brief CheckIcons allows to check application icons
- *
* @param application application under resumtion application
- *
- * @param json_object
- *
+ * @param smar_obj contains obj with image
* @return true in case icons exists, false otherwise
*/
- bool CheckIcons(ApplicationSharedPtr application, const Json::Value& json_object);
+ bool CheckIcons(ApplicationSharedPtr application,
+ const smart_objects::SmartObject& smart_obj);
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* @brief GetFromSavedOrAppend allows to get existed record about application
* or adds the new one.
@@ -413,14 +406,14 @@ class ResumeCtrl: public event_engine::EventObserver {
* @return the reference to the record in applications array.
*/
Json::Value& GetFromSavedOrAppend(const std::string& mobile_app_id);
-
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* @brief CheckIgnCycleRestrictions checks if is needed to resume HMI state
* by ign cycle restrictions
- * @param json_app - saved application
+ * @param saved_app - saved application
* @return true if resumptions allowed, otherwise return false
*/
- bool CheckIgnCycleRestrictions(const Json::Value& json_app);
+ bool CheckIgnCycleRestrictions(const smart_objects::SmartObject& saved_app);
/**
* @brief DisconnectedInLastIgnCycle should check if was connected in prev ign cycle
@@ -433,11 +426,11 @@ class ResumeCtrl: public event_engine::EventObserver {
* @brief DisconnectedJustBeforeIgnOff should check if application
* was dissconnected in N secconds delay before ign off.
* N will be readed from profile
- * @param json_app - saved applicationa
+ * @param saved_app - saved application
* @return was dissconnected in N secconds delay before ign off
* otherwise return false
*/
- bool DisconnectedJustBeforeIgnOff(const Json::Value& json_app);
+ bool DisconnectedJustBeforeIgnOff(const smart_objects::SmartObject& saved_app);
/**
* @brief CheckDelayAfterIgnOn should check if SDL was started less
@@ -449,11 +442,12 @@ class ResumeCtrl: public event_engine::EventObserver {
/**
* @brief CheckAppRestrictions checks if is needed to resume HMI state
* by application type and saved app_level
- * @param json_app - saved application
+ * @param saved_app - saved application
* @return true if resumptions allowed, otherwise return false
*/
bool CheckAppRestrictions(ApplicationSharedPtr application,
- const Json::Value& json_app);
+ const smart_objects::SmartObject& saved_app);
+ /////////////////////////////////////////////////////////////////////////////////////////////
/**
* @brief GetObjectIndex allows to obtain specified obbject index from
* applications arrays.
@@ -463,6 +457,7 @@ class ResumeCtrl: public event_engine::EventObserver {
* @return application's index of or -1 if it doesn't exists
*/
int GetObjectIndex(const std::string& mobile_app_id);
+ /////////////////////////////////////////////////////////////////////////////////////////////
/**
* @brief Timer callback for restoring HMI Level
@@ -474,7 +469,7 @@ class ResumeCtrl: public event_engine::EventObserver {
* @brief Loads data on start up
*/
void LoadResumeData();
-
+ /////////////////////////////////////////////////////////////////////////////////////////////
/*
* @brief Return true if application resumption data is valid,
* otherwise false
@@ -482,6 +477,22 @@ class ResumeCtrl: public event_engine::EventObserver {
* @param index application index in the resumption list
*/
bool IsResumptionDataValid(uint32_t index);
+ /////////////////////////////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * @brief Adds app to resumption list
+ *
+ * app_id Application to resume
+ */
+ void AddToResumption(uint32_t app_id);
+
+ /**
+ * @brief Removes app from resumption list
+ *
+ * app_id Application to remove
+ */
+ void RemoveFromResumption(uint32_t app_id);
template<typename Iterator>
Json::Value Append(Iterator first,
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
new file mode 100644
index 0000000000..7e81b975eb
--- /dev/null
+++ b/src/components/application_manager/include/application_manager/resumption/resume_ctrl.h
@@ -0,0 +1,520 @@
+/*
+ * Copyright (c) 2015, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_RESUME_CTRL_H
+#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_RESUME_CTRL_H
+
+#include <stdint.h>
+#include <vector>
+#include <map>
+#include <set>
+#include <list>
+
+
+#include "interfaces/HMI_API.h"
+#include "interfaces/HMI_API_schema.h"
+#include "interfaces/MOBILE_API_schema.h"
+#include "connection_handler/connection_handler_observer.h"
+#include "connection_handler/device.h"
+#include "application_manager/event_engine/event_observer.h"
+#include "smart_objects/smart_object.h"
+#include "application_manager/application.h"
+#include "utils/timer_thread.h"
+
+namespace application_manager {
+
+namespace resumption {
+
+namespace smart_objects = NsSmartDeviceLink::NsSmartObjects;
+
+class ApplicationManagerImpl;
+class Application;
+class ResumeCtrl: public event_engine::EventObserver {
+
+ public:
+
+ /**
+ * @brief Constructor
+ * @param app_mngr ApplicationManager pointer
+ */
+ explicit ResumeCtrl(ApplicationManagerImpl* app_mngr);
+
+ /**
+ * @brief Event, that raised if application get resumption response from HMI
+ * @param event : event object, that contains smart_object with HMI message
+ */
+ virtual void on_event(const event_engine::Event& event);
+
+ /**
+ * @brief Save all applications info to the file system
+ */
+ void SaveAllApplications();
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ /**
+ * @brief Save application persistent info for future resuming
+ * @param application is application witch need to be saved
+ */
+ void SaveApplication(ApplicationConstSharedPtr application);
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ /**
+ * @brief Set application HMI Level as saved
+ * @param application is application witch HMI Level is need to restore
+ * @return true if success, otherwise return false
+ */
+ bool RestoreAppHMIState(ApplicationSharedPtr application);
+
+ /**
+ * @brief Set application HMI Level as stored in policy
+ * @param application is application witch HMI Level is need to setup
+ * @return true if success, otherwise return false
+ */
+ bool SetupDefaultHMILevel(ApplicationSharedPtr application);
+
+ /**
+ * @brief Setup HmiLevel for application
+ * Do routine of setting up hmi_level
+ * @param application is application witch HMI Level is need to setup
+ * @param hmi_level HMI Level is needed to setup
+ * @param hmi_level AudioStreamingState is needed to setup
+ * @param check_policy indicate if policy data consent must be verified
+ * @return true if success, otherwise return false
+ */
+ bool SetAppHMIState(ApplicationSharedPtr application,
+ const mobile_apis::HMILevel::eType hmi_level,
+ bool check_policy = true);
+
+ /**
+ * @brief Set application HMI Level as saved
+ * @param application is application witch HMI Level is need to restore
+ * @return true if success, otherwise return false
+ */
+ bool RestoreApplicationData(ApplicationSharedPtr application);
+
+ /**
+ * @brief Check if Resume controller have saved instance of application
+ * @param application is application witch need to be checked
+ * @return true if exist, false otherwise
+ */
+ bool ApplicationIsSaved(ApplicationConstSharedPtr application);
+
+ /**
+ * @brief Remove application from list of saved applications
+ * @param application is application witch need to be removed
+ * @return return true, if success, otherwise return false
+ */
+ bool RemoveApplicationFromSaved(ApplicationConstSharedPtr application);
+
+ /**
+ * @brief Increments ignition counter for all registered applications
+ * and remember ign_off time stamp
+ */
+ void Suspend();
+
+ /**
+ * @brief Increments ignition counter for all registered applications
+ * and remember ign_off time stamp
+ */
+ void OnAwake();
+
+ /**
+ * @brief Method starts timer "RsmCtrlPercist" when SDL receives onAwakeSDL notification
+ */
+ void StartSavePersistentDataTimer();
+
+ /**
+ * @brief Method stops timer "RsmCtrlPercist" when SDL receives OnExitAllApplication notification
+ * with reason "SUSPEND"
+ */
+ void StopSavePersistentDataTimer();
+
+ /**
+ * @brief Start timer for resumption applications
+ * Restore D1-D5 data
+ * @param application that is need to be restored
+ * @return true if it was saved, otherwise return false
+ */
+ bool StartResumption(ApplicationSharedPtr application, const std::string& hash);
+
+ /**
+ * @brief Start timer for resumption applications
+ * Does not restore D1-D5 data
+ * @param application that is need to be restored
+ * @return true if it was saved, otherwise return false
+ */
+ bool StartResumptionOnlyHMILevel(ApplicationSharedPtr application);
+
+ /**
+ * @brief Check if there are all files need for resumption
+ * @param application that is need to be restored
+ * @return true if it all files exist, otherwise return false
+ */
+ bool CheckPersistenceFilesForResumption(ApplicationSharedPtr application);
+
+ /**
+ * @brief Check application hash
+ * @param application that is need to be restored
+ * @return true if it was saved, otherwise return false
+ */
+ bool CheckApplicationHash(ApplicationSharedPtr application, const std::string& hash);
+
+ /**
+ * @brief Check if Resume controller have saved application with hmi app id
+ * @param hmi_app_id - hmi application id
+ * @return true if exist, false otherwise
+ */
+ bool IsHMIApplicationIdExist(uint32_t hmi_app_id);
+
+ /**
+ * @brief Check if Resume controller have saved instance of application
+ * @param mobile_app_id - mobile application id
+ * @return true if exist, false otherwise
+ */
+ bool IsApplicationSaved(const std::string& mobile_app_id);
+
+ /**
+ * @brief Function is used for application resume. HMI app ID must be
+ * the same(PASA VCA module use it for stored app info).
+ * Retrieves HMI app ID for the given mobile app ID from stored information.
+ *
+ * @param mobile_app_id - mobile application id
+ * @return HMI app ID
+ */
+ uint32_t GetHMIApplicationID(const std::string& mobile_app_id);
+
+ /**
+ * @brief SaveDataOnTimer :
+ * Timer callback for persisting ResumptionData each N seconds
+ * N gets from property
+ */
+ void SaveDataOnTimer();
+
+ void ClearResumptionInfo();
+
+ void ApplicationsDataUpdated() {
+ is_data_saved = false;
+ }
+
+ /**
+ * @brief Resume HMI Level and audio streaming state if needed
+ * @param application - application to restore hmi level
+ * and audio streaming state
+ */
+ void StartAppHmiStateResumption(ApplicationSharedPtr application);
+ /**
+ * @brief Update launch_time_ to current
+ */
+ void ResetLaunchTime();
+
+ private:
+
+
+ typedef std::pair<uint32_t, uint32_t> application_timestamp;
+
+ std::set<ApplicationSharedPtr> retrieve_application();
+
+ /**
+ * @brief This struct need to map
+ * timestamp and application from correlationID
+ */
+ struct ResumingApp {
+ uint32_t old_session_key; // session key is the same as app_id
+ ApplicationSharedPtr app;
+ };
+
+ struct TimeStampComparator {
+ bool operator() (const application_timestamp& lhs,
+ const application_timestamp& rhs) const{
+ return lhs.second < rhs.second;
+ }
+ };
+
+ /**
+ * @brief geter for launch_time_
+ * @return value of launch_time_
+ */
+ time_t launch_time() const;
+
+ /**
+ * @brief Check device MAC address
+ *
+ * @param application that is need to be restored
+ * @param saved_device_mac Saved device MAC address
+ *
+ * @return TRUE on success, otherwise FALSE
+ */
+ bool IsDeviceMacAddressEqual(ApplicationSharedPtr application,
+ const std::string& saved_device_mac);
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ /**
+ * @brief Get Resumption section of LastState
+ * @return Resumption section of LastState in Json
+ */
+ Json::Value& GetResumptionData();
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ /**
+ * @brief Get applications for resumption of LastState
+ * @return applications for resumption of LastState
+ */
+ Json::Value& GetSavedApplications();
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ /**
+ * @brief Get the last ignition off time from LastState
+ * @return the last ignition off time from LastState
+ */
+ time_t GetIgnOffTime();
+
+ /**
+ * @brief Setup IgnOff time to LastState
+ * @param ign_off_time - igition off time
+ */
+ void SetLastIgnOffTime(time_t ign_off_time);
+
+ /**
+ * @brief Set applications for resumption to LastState
+ * @parems apps_json applications to write in LastState
+ */
+ void SetSavedApplication(Json::Value& apps_json);
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ Json::Value GetApplicationCommands(
+ ApplicationConstSharedPtr application);
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ Json::Value GetApplicationSubMenus(
+ ApplicationConstSharedPtr application);
+ Json::Value GetApplicationInteractionChoiseSets(
+ ApplicationConstSharedPtr application);
+ Json::Value GetApplicationGlobalProperties(
+ ApplicationConstSharedPtr application);
+ Json::Value GetApplicationSubscriptions(
+ ApplicationConstSharedPtr application);
+ Json::Value GetApplicationFiles(
+ ApplicationConstSharedPtr application);
+ Json::Value GetApplicationShow(
+ ApplicationConstSharedPtr application);
+
+ Json::Value JsonFromSO(const smart_objects::SmartObject *so);
+
+ void SendHMIRequest(const hmi_apis::FunctionID::eType& function_id,
+ const smart_objects::SmartObject* msg_params = NULL,
+ bool use_events = false);
+
+ bool ProcessHMIRequest(
+ smart_objects::SmartObjectSPtr request = NULL,
+ bool use_events = false);
+
+ void InsertToTimerQueue(uint32_t app_id, uint32_t time_stamp);
+
+ /**
+ * @brief AddFiles allows to add files for the application
+ * which should be resumed
+ *
+ * @param application application which will be resumed
+ *
+ * @param saved_app application specific section from backup file
+ */
+ void AddFiles(ApplicationSharedPtr application, const Json::Value& saved_app);
+
+ /**
+ * @brief AddSubmenues allows to add sub menues for the application
+ * which should be resumed
+ *
+ * @param application application which will be resumed
+ *
+ * @param saved_app application specific section from backup file
+ */
+ void AddSubmenues(ApplicationSharedPtr application, const Json::Value& saved_app);
+
+ /**
+ * @brief AddCommands allows to add commands for the application
+ * which should be resumed
+ *
+ * @param application application which will be resumed
+ *
+ * @param saved_app application specific section from backup file
+ */
+ void AddCommands(ApplicationSharedPtr application, const Json::Value& saved_app);
+
+ /**
+ * @brief AddChoicesets allows to add choice sets for the application
+ * which should be resumed
+ *
+ * @param application application which will be resumed
+ *
+ * @param saved_app application specific section from backup file
+ */
+ void AddChoicesets(ApplicationSharedPtr application, const Json::Value& saved_app);
+
+ /**
+ * @brief SetGlobalProperties allows to restore global properties.
+ *
+ * @param application application which will be resumed
+ *
+ * @param saved_app application specific section from backup file
+ */
+ void SetGlobalProperties(ApplicationSharedPtr application, const Json::Value& saved_app);
+
+ /**
+ * @brief AddSubscriptions allows to restore subscriptions
+ *
+ * @param application application which will be resumed
+ *
+ * @param saved_app application specific section from backup file
+ */
+ void AddSubscriptions(ApplicationSharedPtr application, const Json::Value& saved_app);
+
+ /**
+ * @brief ProcessHMIRequests allows to process obtained requests.
+ *
+ * @param requests request that should be processed.
+ */
+ void ProcessHMIRequests(const smart_objects::SmartObjectList& requests);
+
+ /**
+ * @brief CheckIcons allows to check application icons
+ *
+ * @param application application under resumtion application
+ *
+ * @param json_object
+ *
+ * @return true in case icons exists, false otherwise
+ */
+ bool CheckIcons(ApplicationSharedPtr application, const Json::Value& json_object);
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ /**
+ * @brief GetFromSavedOrAppend allows to get existed record about application
+ * or adds the new one.
+ *
+ * @param mobile_app_id application id.
+ *
+ * @return the reference to the record in applications array.
+ */
+ Json::Value& GetFromSavedOrAppend(const std::string& mobile_app_id);
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ /**
+ * @brief CheckIgnCycleRestrictions checks if is needed to resume HMI state
+ * by ign cycle restrictions
+ * @param json_app - saved application
+ * @return true if resumptions allowed, otherwise return false
+ */
+ bool CheckIgnCycleRestrictions(const Json::Value& json_app);
+
+ /**
+ * @brief DisconnectedInLastIgnCycle should check if was connected in prev ign cycle
+ * @param json_app - saved applicationa
+ * @return true if app connected in frep ign_cycle otherwise return false
+ */
+ bool DisconnectedInLastIgnCycle(const Json::Value& json_app);
+
+ /**
+ * @brief DisconnectedJustBeforeIgnOff should check if application
+ * was dissconnected in N secconds delay before ign off.
+ * N will be readed from profile
+ * @param json_app - saved applicationa
+ * @return was dissconnected in N secconds delay before ign off
+ * otherwise return false
+ */
+ bool DisconnectedJustBeforeIgnOff(const Json::Value& json_app);
+
+ /**
+ * @brief CheckDelayAfterIgnOn should check if SDL was started less
+ * then N secconds ago. N will be readed from profile.
+ * @return true if SDL started N secconds ago, otherwise return false
+ */
+ bool CheckDelayAfterIgnOn();
+
+ /**
+ * @brief CheckAppRestrictions checks if is needed to resume HMI state
+ * by application type and saved app_level
+ * @param json_app - saved application
+ * @return true if resumptions allowed, otherwise return false
+ */
+ bool CheckAppRestrictions(ApplicationSharedPtr application,
+ const Json::Value& json_app);
+ /**
+ * @brief GetObjectIndex allows to obtain specified obbject index from
+ * applications arrays.
+ *
+ * @param mobile_app_id application id that should be found.
+ *
+ * @return application's index of or -1 if it doesn't exists
+ */
+ int GetObjectIndex(const std::string& mobile_app_id);
+
+ /**
+ * @brief Timer callback for restoring HMI Level
+ *
+ */
+ void ApplicationResumptiOnTimer();
+
+ /*
+ * @brief Loads data on start up
+ */
+ void LoadResumeData();
+
+ template<typename Iterator>
+ Json::Value Append(Iterator first,
+ Iterator last,
+ const std::string& key,
+ Json::Value& result) {
+ while (first != last) {
+ result[key].append(*first);
+ ++first;
+ }
+ return result;
+ }
+
+ /**
+ * @brief times of IGN_OFF that zombie application have to be saved.
+ */
+ static const uint32_t kApplicationLifes = 3;
+
+ /**
+ *@brief Mapping applications to time_stamps
+ * wait for timer to resume HMI Level
+ *
+ */
+ mutable sync_primitives::Lock queue_lock_;
+ sync_primitives::Lock resumtion_lock_;
+ ApplicationManagerImpl* app_mngr_;
+ timer::TimerThread<ResumeCtrl> save_persistent_data_timer_;
+ timer::TimerThread<ResumeCtrl> restore_hmi_level_timer_;
+ std::vector<uint32_t> waiting_for_timer_;
+ bool is_data_saved;
+ time_t launch_time_;
+ ResumptionData* resumption_storage_;
+};
+
+} // namespace resumption
+} // namespace application_manager
+#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_RESUME_CTRL_H
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
new file mode 100644
index 0000000000..bf6494896d
--- /dev/null
+++ b/src/components/application_manager/include/application_manager/resumption/resumption_data.h
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_RESUMPTION_RESUMPTION_DATA_H_
+#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_RESUMPTION_RESUMPTION_DATA_H_
+
+namespace application_manager {
+namespace resumption {
+class ResumptionData {
+ public:
+ /**
+ * @brief Save application persistent info for future resuming
+ * @param application is application witch need to be saved
+ */
+ virtual void SaveApplication(ApplicationConstSharedPtr application) = 0;
+
+ /**
+ * @brief Returns HMI level of application from saved data
+ * @param m_app_id contains mobile application id of application
+ * @param device_id contains id of device on which is running application
+ * @return HMI level if saved data does not contain HMI level method
+ * returns -1
+ */
+ virtual int GetStoredHMILevel(const std::string& m_app_id,
+ const std::string& device_id) = 0;
+
+ /**
+ * @brief restores saved data of application
+ * @param application contains application for which restores data
+ * @return true if success, otherwise return false
+ */
+ virtual bool RestoreApplicationData(ApplicationSharedPtr application) = 0;
+
+ /**
+ * @brief Check if saved data of applications have hmi app id
+ * @param hmi_app_id - hmi application id
+ * @return true if exist, false otherwise
+ */
+ virtual bool IsHMIApplicationIdExist(uint32_t hmi_app_id) = 0;
+
+ /**
+ * @brief Checks if saved data have application
+ * and removes this data if it is not valid
+ * @param mobile_app_id - mobile application id
+ * @param device_id - contains id of device on which is running application
+ * @return true if data exists and data is valid, false otherwise
+ */
+ virtual bool CheckSavedApplication(const std::string& mobile_app_id,
+ const std::string& device_id) = 0;
+
+ /**
+ * @brief Retrieves HMI app ID for the given mobile app ID
+ * and device ID from stored information.
+ * @param mobile_app_id - mobile application id
+ * @param device_id - contains id of device on which is running application
+ * @return HMI app ID
+ */
+ virtual uint32_t GetHMIApplicationID(const std::string& mobile_app_id,
+ const std::string& device_id) = 0;
+
+ /**
+ * @brief Increments ignition counter for all registered applications
+ * and remember ign_off time stamp
+ */
+ virtual void Suspend() = 0;
+
+ /**
+ * @brief Retrieves hash ID for the given mobile app ID
+ * and device ID from stored information.
+ * @param mobile_app_id - mobile application id
+ * @param device_id - contains id of device on which is running application
+ * @param hash_id - parameter which will contain HASH id from saved application
+ * @return TRUE if application will be found in saved data otherwise
+ * returns FALSE
+ */
+ virtual bool GetHashId(const std::string& mobile_app_id,
+ const std::string& device_id,
+ std::string& hash_id) = 0;
+
+ /**
+ * @brief Increments ignition counter for all registered applications
+ * and remember ign_off time stamp
+ */
+ virtual void OnAwake() = 0;
+
+ /**
+ * @brief Retrieves data of saved appliction for the given mobile app ID
+ * and device ID
+ * @param mobile_app_id - mobile application id
+ * @param device_id - contains id of device on which is running application
+ * @param saved_app - parameter which will contain data of saved application
+ * @return TRUE if application will be found in saved data otherwise
+ * returns FALSE
+ */
+ virtual bool GetSavedApplication(const std::string& mobile_app_id,
+ const std::string& device_id,
+ smart_objects::SmartObject& saved_app) = 0;
+
+ /**
+ * @brief Remove application from list of saved applications
+ * @param mobile_app_id application witch need to be removed
+ * @param device_id - contains id of device on which is running application
+ * @return return true, if success, otherwise return false
+ */
+ virtual bool RemoveApplicationFromSaved(const std::string& mobile_app_id,
+ const std::string& device_id) = 0;
+
+ /**
+ * @brief Get the last ignition off time from LastState
+ * @return the last ignition off time from LastState
+ */
+ virtual uint32_t GetIgnOffTime() = 0;
+
+ /**
+ * @brief Checks if saved data have application
+ * @param mobile_app_id - mobile application id
+ * @param device_id - contains id of device on which is running application
+ * @return index if data of application exists, otherwise returns -1
+ */
+ virtual int IsApplicationSaved(const std::string& mobile_app_id,
+ const std::string& device_id) = 0;
+
+ /**
+ * @brief Retrieves data from saved application
+ * @param will be contain data for resume_ctrl
+ */
+ virtual void GetDataForLoadResumeData(smart_objects::SmartObject& saved_data) = 0;
+
+ /**
+ * @brief Changed HMI level for saved application
+ * @param mobile_app_id - mobile application id
+ * @param device_id - contains id of device on which is running application
+ * @param hmi_level - contains new hmi level for saved application
+ */
+ virtual void SetHMILevelForSavedApplication(const std::string& mobile_app_id,
+ const std::string& device_id,
+ int32_t hmi_level) = 0;
+
+ virtual ~ResumptionData() {};
+
+
+
+ protected:
+
+ /**
+ * @brief Do selection of commands from application
+ * @param application contains application of which selection commands
+ * @return list of commands
+ */
+ smart_objects::SmartObject GetApplicationCommands(
+ ApplicationConstSharedPtr application);
+
+ /**
+ * @brief Do selection of submenues from application
+ * @param application contains application of which selection submenues
+ * @return list of submenues
+ */
+ smart_objects::SmartObject GetApplicationSubMenus(
+ ApplicationConstSharedPtr application);
+
+ /**
+ * @brief Do selection of interactionChoiceSet from application
+ * @param application contains application of which selection interactionChoiceSet
+ * @return list of interaction choice set
+ */
+ smart_objects::SmartObject GetApplicationInteractionChoiseSets(
+ ApplicationConstSharedPtr application);
+
+ /**
+ * @brief Do selection of global properties from application
+ * @param application contains application of which selection global properties
+ * @return global properties of application
+ */
+ smart_objects::SmartObject GetApplicationGlobalProperties(
+ ApplicationConstSharedPtr application);
+
+ /**
+ * @brief Do selection of subscriptions from application
+ * @param application contains application of which selection subscriptions
+ * @return subscriptions of application
+ */
+ smart_objects::SmartObject GetApplicationSubscriptions(
+ ApplicationConstSharedPtr application);
+
+ /**
+ * @brief Do selection of files from application
+ * @param application contains application of which selection files
+ * @return files of application
+ */
+ smart_objects::SmartObject GetApplicationFiles(
+ ApplicationConstSharedPtr application);
+
+ /**
+ * @brief AddFiles allows to add files for the application
+ * which should be resumed
+ * @param application application which will be resumed
+ * @param saved_app application specific section from backup file
+ */
+ void AddFiles(ApplicationSharedPtr application,
+ const smart_objects::SmartObject& saved_app);
+
+ /**
+ * @brief AddSubmenues allows to add sub menues for the application
+ * which should be resumed
+ * @param application application which will be resumed
+ * @param saved_app application specific section from backup file
+ */
+ void AddSubmenues(ApplicationSharedPtr application,
+ const smart_objects::SmartObject& saved_app);
+
+ /**
+ * @brief AddCommands allows to add commands for the application
+ * which should be resumed
+ * @param application application which will be resumed
+ * @param saved_app application specific section from backup file
+ */
+ void AddCommands(ApplicationSharedPtr application,
+ const smart_objects::SmartObject& saved_app);
+
+ /**
+ * @brief AddChoicesets allows to add choice sets for the application
+ * which should be resumed
+ * @param application application which will be resumed
+ * @param saved_app application specific section from backup file
+ */
+ void AddChoicesets(ApplicationSharedPtr application,
+ const smart_objects::SmartObject& saved_app);
+
+ /**
+ * @brief SetGlobalProperties allows to restore global properties.
+ * @param application application which will be resumed
+ * @param saved_app application specific section from backup file
+ */
+ void SetGlobalProperties(ApplicationSharedPtr application,
+ const smart_objects::SmartObject& saved_app);
+
+ /**
+ * @brief AddSubscriptions allows to restore subscriptions
+ * @param application application which will be resumed
+ * @param saved_app application specific section from backup file
+ */
+ void AddSubscriptions(ApplicationSharedPtr application,
+ const smart_objects::SmartObject& saved_app);
+
+ /**
+ * @brief checks pointer that it is not equal NULL
+ * @param contains pointer which need to check
+ * @return smartObject from pointer
+ */
+ smart_objects::SmartObject PointerToSmartObj (smart_objects::SmartObject* ptr);
+
+ template<typename Iterator>
+ void Append(Iterator first,
+ Iterator last,
+ const std::string& key,
+ smart_objects::SmartObject& result) {
+ int i = 0;
+ result[key] = smart_objects::SmartObject(smart_objects::SmartType_Array);
+ while (first != last) {
+ result[key][i++] = *first;
+ ++first;
+ }
+ }
+};
+} // namespace resumption
+} // namespace application_manager
+
+#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_RESUMPTION_RESUMPTION_DATA_H_
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
new file mode 100644
index 0000000000..a18495a4c0
--- /dev/null
+++ b/src/components/application_manager/include/application_manager/resumption/resumption_data_db.h
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_RESUMPTION_RESUMPTION_DATA_DB_H_
+#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_RESUMPTION_RESUMPTION_DATA_DB_H_
+
+namespace application_manager {
+namespace resumption {
+class ResumptionDataDB : public ResumptionData {
+ public:
+ /**
+ * @brief Save application persistent info for future resuming to db
+ * @param application is application witch need to be saved
+ */
+ virtual void SaveApplication(ApplicationConstSharedPtr application);
+
+ /**
+ * @brief Returns HMI level of application from saved data
+ * @param m_app_id contains mobile application id of application
+ * @param device_id contains id of device on which is running application
+ * @return HMI level if saved data does not contain HMI level method
+ * returns -1
+ */
+ virtual int GetStoredHMILevel(const std::string& m_app_id,
+ const std::string& device_id); ////////////////////////////////////////
+
+ /**
+ * @brief restores saved data of application
+ * @param application contains application for which restores data
+ * @return true if success, otherwise return false
+ */
+ virtual bool RestoreApplicationData(ApplicationSharedPtr application);
+
+ /**
+ * @brief Check if saved data of applications have hmi app id
+ * @param hmi_app_id - hmi application id
+ * @return true if exist, false otherwise
+ */
+ virtual bool IsHMIApplicationIdExist(uint32_t hmi_app_id); ////////////////////////////////////////////
+
+ /**
+ * @brief Checks if saved data have application
+ * @param mobile_app_id - mobile application id
+ * @param device_id - contains id of device on which is running application
+ * @return true if data exists, false otherwise
+ */
+ virtual bool CheckSavedApplication(const std::string& mobile_app_id, ////////////////////////////////////////////
+ const std::string& device_id);
+
+ /**
+ * @brief Retrieves HMI app ID for the given mobile app ID
+ * and device ID from stored information.
+ * @param mobile_app_id - mobile application id
+ * @param device_id - contains id of device on which is running application
+ * @return HMI app ID
+ */
+ virtual uint32_t GetHMIApplicationID(const std::string& mobile_app_id, ////////////////////////////////////////////
+ const std::string& device_id);
+
+ /**
+ * @brief Increments ignition counter for all registered applications
+ * and remember ign_off time stamp
+ */
+ virtual void Suspend(); ////////////////////////////////////////////
+
+ /**
+ * @brief Retrieves hash ID for the given mobile app ID
+ * and device ID from stored information.
+ * @param mobile_app_id - mobile application id
+ * @param device_id - contains id of device on which is running application
+ * @param hash_id - parameter which will contain HASH id from saved application
+ * @return TRUE if application will be found in saved data otherwise
+ * returns FALSE
+ */
+ virtual bool GetHashId(const std::string& mobile_app_id, ////////////////////////////////////////////
+ const std::string& device_id,
+ std::string& hash_id);
+
+ /**
+ * @brief Increments ignition counter for all registered applications
+ * and remember ign_off time stamp
+ */
+ virtual void OnAwake(); ////////////////////////////////////////////
+
+ /**
+ * @brief Retrieves data of saved appliction for the given mobile app ID
+ * and device ID
+ * @param mobile_app_id - mobile application id
+ * @param device_id - contains id of device on which is running application
+ * @param saved_app - parameter which will contain data of saved application
+ * @return TRUE if application will be found in saved data otherwise
+ * returns FALSE
+ */
+ virtual bool GetSavedApplication(const std::string& mobile_app_id,
+ const std::string& device_id,
+ smart_objects::SmartObject& saved_app);
+
+ /**
+ * @brief Remove application from list of saved applications
+ * @param mobile_app_id application witch need to be removed
+ * @param device_id - contains id of device on which is running application
+ * @return return true, if success, otherwise return false
+ */
+ virtual bool RemoveApplicationFromSaved(const std::string& mobile_app_id, ////////////////////////////////////////////
+ const std::string& device_id);
+
+ /**
+ * @brief Get the last ignition off time from LastState
+ * @return the last ignition off time from LastState
+ */
+ virtual uint32_t GetIgnOffTime(); ////////////////////////////////////////////
+
+ /**
+ * @brief Checks if saved data have application
+ * @param mobile_app_id - mobile application id
+ * @param device_id - contains id of device on which is running application
+ * @return 0 if saved data contains application otherwise returns -1
+ */
+ virtual int IsApplicationSaved(const std::string& mobile_app_id, ////////////////////////////////////////////
+ const std::string& device_id);
+
+ /**
+ * @brief Retrieves data from saved application
+ * @param will contain data for resume_ctrl
+ */
+ virtual void GetDataForLoadResumeData(smart_objects::SmartObject& saved_data); ////////////////////////////////////////////
+
+ /**
+ * @brief Changed HMI level for saved application
+ * @param mobile_app_id - mobile application id
+ * @param device_id - contains id of device on which is running application
+ * @param hmi_level - contains new hmi level for saved application
+ */
+ virtual void SetHMILevelForSavedApplication(const std::string& mobile_app_id, ////////////////////////////////////////////
+ const std::string& device_id,
+ int32_t hmi_level);
+
+ virtual ~ResumptionDataDB();
+ private:
+
+ /**
+ * @brief Retrieves hmi level from db
+ * @param mobile_app_id - mobile application id
+ * @param device_id - contains id of device on which is running application
+ * @param hmi_level - will contains hmi level for saved application
+ * @return true if application with mobile id and device id has hmi level
+ * otherwise returns false
+ */
+ bool SelectHMILevel(const std::string& m_app_id, const std::string& device_id,
+ int& hmi_level);
+ /**
+ * @brief Checks existence HMI id in DB
+ * @param hmi_app_id - HMI id
+ * return true if hmiID is same with saved hmiID otherwise returns false
+ */
+ bool CheckExistenceHMIId(const uint32_t hmi_app_id);
+
+ /**
+ * @brief Select HMI id from saved application
+ * @param mobile_app_id - mobile application id
+ * @param device_id - contains id of device on which is running application
+ * @param hmi_id - will contains hmi id from saved application
+ */
+ void SelectHMIId(const std::string& mobile_app_id, const std::string& device_id,
+ uint32_t& hmi_id);
+
+ /**
+ * @brief Select hash id from saved application
+ * @param mobile_app_id - mobile application id
+ * @param device_id - contains id of device on which is running application
+ * @param hash_id - will contains hash id from saved application
+ */
+ bool SelectHashId(const std::string& mobile_app_id,
+ const std::string& device_id,
+ std::string& hash_id);
+
+ /**
+ * @brief Select Ign off time
+ * @return Ign off time from saved data
+ */
+ uint32_t SelectIgnOffTime();
+
+ /**
+ * @brief Checks existence application in DB
+ * @param mobile_app_id - mobile application id
+ * @param device_id - contains id of device on which is running application
+ * @return true if saved data contains application otherwise returns false
+ */
+ bool CheckExistenceApplication(const std::string& mobile_app_id,
+ const std::string& device_id);
+
+ /**
+ * @brief Retrieves data from saved application
+ * @param will contain data for resume_ctrl
+ */
+ void SelectDataForLoadResumeData(smart_objects::SmartObject& saved_data);
+
+ /**
+ * @brief Updates HMI level of saved application
+ * @param mobile_app_id - mobile application id
+ * @param device_id - contains id of device on which is running application
+ * @param hmi_level - contains hmi level for saved appliction
+ */
+ void UpdateHmiLevel(const std::string& mobile_app_id,
+ const std::string& device_id,
+ int32_t hmi_level);
+
+ /**
+ * @brief Delete saved application from db
+ * @param mobile_app_id - mobile application id
+ * @param device_id - contains id of device on which is running application
+ * @return true if application was found and deleted otherwise returns
+ * false
+ */
+ bool DeleteSavedApplication(const std::string& mobile_app_id,
+ const std::string& device_id);
+ /**
+ * @brief Updates ignition of count on saved applications after onAwake
+ * notification
+ */
+ void UpdateDataOnAwake();
+
+
+
+};
+} // namespace resumption
+} // namespace application_manager
+
+#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_RESUMPTION_RESUMPTION_DATA_DB_H_
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
new file mode 100644
index 0000000000..6344b72228
--- /dev/null
+++ b/src/components/application_manager/include/application_manager/resumption/resumption_data_json.h
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_RESUMPTION_RESUMPTION_DATA_JSON_H_
+#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_RESUMPTION_RESUMPTION_DATA_JSON_H_
+
+namespace application_manager {
+namespace resumption {
+class ResumptionDataJson : public ResumptionData {
+ public:
+ /**
+ * @brief Save application persistent info for future resuming on json format
+ * @param application is application witch need to be saved
+ */
+ virtual void SaveApplication(ApplicationConstSharedPtr application);
+
+ /**
+ * @brief Returns HMI level of application from saved data
+ * @param m_app_id contains mobile application id of application
+ * @param device_id contains device id
+ * @return HMI level if saved data does not contain HMI level method
+ * returns -1
+ */
+ virtual int GetStoredHMILevel(const std::string& m_app_id,
+ const std::string& device_id);
+
+ /**
+ * @brief restores saved data of application
+ * @param application contains application for which restores data
+ * @return true if success, otherwise return false
+ */
+ virtual bool RestoreApplicationData(ApplicationSharedPtr application);
+
+ /**
+ * @brief Check if saved data of applications have hmi app id
+ * @param hmi_app_id - hmi application id
+ * @return true if exist, false otherwise
+ */
+ virtual bool IsHMIApplicationIdExist(uint32_t hmi_app_id);
+
+ /**
+ * @brief Checks if saved data have application
+ * and removes this data if it is not valid
+ * @param mobile_app_id - mobile application id
+ * @param device_id - contains id of device on which is running application
+ * @return true if data exists and data is valid, false otherwise
+ */
+ virtual bool CheckSavedApplication(const std::string& mobile_app_id,
+ const std::string& device_id);
+
+ /**
+ * @brief Retrieves HMI app ID for the given mobile app ID
+ * and device ID from stored information.
+ * @param mobile_app_id - mobile application id
+ * @param device_id - contains id of device on which is running application
+ * @return HMI app ID
+ */
+ virtual uint32_t GetHMIApplicationID(const std::string& mobile_app_id,
+ const std::string& device_id);
+
+ /**
+ * @brief Increments ignition counter for all registered applications
+ * and remember ign_off time stamp
+ */
+ virtual void Suspend();
+
+ /**
+ * @brief Increments ignition counter for all registered applications
+ * and remember ign_off time stamp
+ */
+ virtual void OnAwake();
+
+ /**
+ * @brief Retrieves hash ID for the given mobile app ID
+ * and device ID from stored information.
+ * @param mobile_app_id - mobile application id
+ * @param device_id - contains id of device on which is running application
+ * @param hash_id - parameter which will contain HASH id from saved application
+ * @return TRUE if application will be found in saved data otherwise
+ * returns FALSE
+ */
+ virtual bool GetHashId(const std::string& mobile_app_id,
+ const std::string& device_id,
+ std::string& hash_id);
+
+ /**
+ * @brief Retrieves data of saved appliction for the given mobile app ID
+ * and device ID
+ * @param mobile_app_id - mobile application id
+ * @param device_id - contains id of device on which is running application
+ * @param saved_app - parameter which will contain data of saved application
+ * @return TRUE if application will be found in saved data otherwise
+ * returns FALSE
+ */
+ virtual bool GetSavedApplication(const std::string& mobile_app_id,
+ const std::string& device_id,
+ smart_objects::SmartObject& saved_app);
+
+ /**
+ * @brief Remove application from list of saved applications
+ * @param mobile_app_id application witch need to be removed
+ * @param device_id - contains id of device on which is running application
+ * @return return true, if success, otherwise return false
+ */
+ virtual bool RemoveApplicationFromSaved(const std::string& mobile_app_id,
+ const std::string& device_id);
+
+ /**
+ * @brief Get the last ignition off time from LastState
+ * @return the last ignition off time from LastState
+ */
+ virtual uint32_t GetIgnOffTime();
+
+ /**
+ * @brief Checks if saved data have application
+ * @param mobile_app_id - mobile application id
+ * @param device_id - contains id of device on which is running application
+ * @return index if data of application exists, otherwise returns -1
+ */
+ virtual int IsApplicationSaved(const std::string& mobile_app_id,
+ const std::string& device_id);
+
+ /**
+ * @brief Retrieves data from saved application
+ * @param will be contain data for resume_ctrl
+ */
+ virtual void GetDataForLoadResumeData(smart_objects::SmartObject& saved_data);
+
+ /**
+ * @brief Changed HMI level for saved application
+ * @param mobile_app_id - mobile application id
+ * @param device_id - contains id of device on which is running application
+ * @param hmi_level - contains new hmi level for saved application
+ */
+ virtual void SetHMILevelForSavedApplication(const std::string& mobile_app_id,
+ const std::string& device_id,
+ int32_t hmi_level);
+
+
+ virtual ~ResumptionDataJson();
+ private:
+
+ /**
+ * @brief GetFromSavedOrAppend allows to get existed record about application
+ * or adds the new one.
+ * @param mobile_app_id application id.
+ * @param device_id unique id of device.
+ * @return the reference to the record in applications array.
+ */
+ Json::Value& GetFromSavedOrAppend(const std::string& mobile_app_id,
+ const std::string& device_id);
+
+ /**
+ * @brief Get applications for resumption of LastState
+ * @return applications for resumption of LastState
+ */
+ Json::Value& GetSavedApplications();
+
+ /**
+ * @brief Get Resumption section of LastState
+ * @return Resumption section of LastState in Json
+ */
+ Json::Value& GetResumptionData();
+
+ /**
+ * @brief GetObjectIndex allows to obtain specified object index from
+ * applications arrays.
+ * @param mobile_app_id application id that should be found.
+ * @param device_id unique id of device.
+ * @return application's index of or -1 if it doesn't exists
+ */
+ int GetObjectIndex(const std::string& mobile_app_id,
+ const std::string& device_id);
+
+ /**
+ * @brief Return true if application resumption data is valid,
+ * otherwise false
+ * @param index application index in the resumption list
+ */
+ bool IsResumptionJSONDataValid(uint32_t index);
+
+ /**
+ * @brief Set applications for resumption to LastState
+ * @parems apps_json applications to write in LastState
+ */
+ void SetSavedApplication(Json::Value& apps_json);
+
+ /**
+ * @brief Setup IgnOff time to LastState
+ * @param ign_off_time - igition off time
+ */
+ void SetLastIgnOffTime(time_t ign_off_time);
+
+
+};
+} // namespace resumption
+} // namespace application_manager
+
+#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_RESUMPTION_RESUMPTION_DATA_JSON_H_
diff --git a/src/components/application_manager/include/application_manager/resumption/resumption_sql_queries.h b/src/components/application_manager/include/application_manager/resumption/resumption_sql_queries.h
new file mode 100644
index 0000000000..a2be40b8a2
--- /dev/null
+++ b/src/components/application_manager/include/application_manager/resumption/resumption_sql_queries.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_RESUMPTION_RESUMPTION_SQL_QUERY_H_
+#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_RESUMPTION_RESUMPTION_SQL_QUERY_H_
+
+#include <string>
+
+namespace application_manager {
+namespace resumption {
+
+extern const std::string kCreateSchema;
+extern const std::string kSelectHMILevel;
+extern const std::string kCheckHMIId;
+extern const std::string kSelectHMIId;
+extern const std::string kSelectHashId;
+extern const std::string kSelectIgnOffTime;
+extern const std::string kCheckApplication;
+extern const std::string kSelectDataForLoadResumeData;
+extern const std::string kUpdateHMILevel;
+extern const std::string kDeleteApplication;
+extern const std::string kUpdateIgnOffCount;
+extern const std::string kDeleteApplicationsAccordingWithIgnOffCount;
+extern const std::string kUpdateSuspendData;
+extern const std::string KUpdateLastIgnOffTime;
+
+} // namespace resumption
+} // namespace application_manager
+
+#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_RESUMPTION_RESUMPTION_SQL_QUERY_H_
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 f609f2c2df..84311dde22 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
@@ -52,7 +52,7 @@ const char method_name[] = "methodName";
const char info[] = "info";
const char app_id[] = "appID";
const char hmi_app_id[] = "hmiAppID";
-const char device_mac[] = "deviceMAC";
+const char device_id[] = "deviceID";
const char url[] = "url";
const char urlScheme[] = "urlScheme";
const char packageName[] = "packageName";
@@ -250,7 +250,7 @@ const char priority[] = "priority";
//resuming
const char application_commands[] = "applicationCommands";
const char application_submenus[] = "applicationSubMenus";
-const char application_choise_sets[] = "applicationChoiceSets";
+const char application_choice_sets[] = "applicationChoiceSets";
const char application_global_properties[] = "globalProperties";
const char application_vehicle_info[] = "vehicleInfo";
const char application_buttons[] = "buttons";
diff --git a/src/components/application_manager/src/application_impl.cc b/src/components/application_manager/src/application_impl.cc
index d45cc50bd4..11ad1a54e8 100644
--- a/src/components/application_manager/src/application_impl.cc
+++ b/src/components/application_manager/src/application_impl.cc
@@ -96,6 +96,8 @@ ApplicationImpl::ApplicationImpl(uint32_t application_id,
has_been_activated_(false),
tts_properties_in_none_(false),
tts_properties_in_full_(false),
+ is_application_data_changed_(
+ StateApplicationData::kNotSaveDataForResumption),
put_file_in_none_count_(0),
delete_file_in_none_count_(0),
list_files_in_none_count_(0),
@@ -778,9 +780,20 @@ const std::string& ApplicationImpl::curHash() const {
return hash_val_;
}
+StateApplicationData ApplicationImpl::is_application_data_changed() const {
+ return is_application_data_changed_;
+}
+
+void ApplicationImpl::set_is_application_data_changed(
+ StateApplicationData state_application_data) {
+ is_application_data_changed_ = state_application_data;
+}
+
void ApplicationImpl::UpdateHash() {
LOG4CXX_AUTO_TRACE(logger_);
hash_val_ = utils::gen_hash(profile::Profile::instance()->hash_string_size());
+ is_application_data_changed_ =
+ StateApplicationData::kNotSaveDataForResumption;
MessageHelper::SendHashUpdateNotification(app_id());
}
diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc
index 2af9b9128f..2a54a26619 100644
--- a/src/components/application_manager/src/application_manager_impl.cc
+++ b/src/components/application_manager/src/application_manager_impl.cc
@@ -2189,7 +2189,6 @@ void ApplicationManagerImpl::HeadUnitReset(
}
}
-
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 05c74092ef..77bf827305 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
@@ -227,6 +227,21 @@ void RegisterAppInterfaceRequest::Run() {
msg_params[strings::app_name].asString() <<
" hasn't been registered!");
} else {
+
+ // For resuming application need to restore hmi_app_id from resumeCtrl
+ const std::string mobile_app_id = msg_params[strings::app_id].asString();
+ const std::string device_id =
+ MessageHelper::GetDeviceMacAddressForHandle(application->device());
+ ResumeCtrl& resumer = ApplicationManagerImpl::instance()->resume_controller();
+
+ // there is side affect with 2 mobile app with the same mobile app_id
+ if (resumer.IsApplicationSaved(mobile_app_id, device_id)) {
+ app->set_hmi_application_id(
+ resumer.GetHMIApplicationID(mobile_app_id, device_id));
+ } else {
+ app->set_hmi_application_id(
+ ApplicationManagerImpl::instance()->GenerateNewHMIAppID());
+ }
app->set_is_media_application(
msg_params[strings::is_media_application].asBool());
@@ -492,7 +507,9 @@ void RegisterAppInterfaceRequest::SendRegisterAppInterfaceResponseToMobile(
// in case application exist in resumption we need to send resumeVrgrammars
if (false == resumption) {
- resumption = resumer.IsApplicationSaved(application->mobile_app_id());
+ resumption = resumer.IsApplicationSaved(
+ application->mobile_app_id(),
+ MessageHelper::GetDeviceMacAddressForHandle(application->device()));
}
diff --git a/src/components/application_manager/src/message_helper.cc b/src/components/application_manager/src/message_helper.cc
index 19229b9b12..a8f4e7fd37 100644
--- a/src/components/application_manager/src/message_helper.cc
+++ b/src/components/application_manager/src/message_helper.cc
@@ -1155,6 +1155,54 @@ smart_objects::SmartObjectList MessageHelper::CreateAddCommandRequestToHMI(
return requests;
}
+static smart_objects::SmartObjectList
+MessageHelper::CreateAddVRCommandRequestFromChoiceToHMI(ApplicationConstSharedPtr app) {
+ smart_objects::SmartObjectList requests;
+ if (!app) {
+ LOG4CXX_ERROR(logger_, "Invalid application");
+ return requests;
+ }
+ const DataAccessor<ChoiceSetMap> accessor = app->choice_set_map();
+ const ChoiceSetMap& choices = accessor.GetData();
+ ChoiceSetMap::const_iterator it = choices.begin();
+ for (; choices.end() != it; ++it) {
+ const uint32_t choice_grammar_id = (*(it->second))[strings::grammar_id].asUint();
+ const size_t size = (*(it->second))[strings::choice_set].length();
+ for (size_t j = 0; j < size; ++j) {
+ smart_objects::SmartObjectSPtr vr_command = new smart_objects::SmartObject(
+ smart_objects::SmartType_Map);
+ if (!vr_command) {
+ return requests;
+ }
+ (*vr_command)[strings::params][strings::function_id] =
+ static_cast<int>(hmi_apis::FunctionID::VR_AddCommand);
+ (*vr_command)[strings::params][strings::message_type] =
+ static_cast<int>(hmi_apis::messageType::request);
+ (*vr_command)[strings::params][strings::protocol_version] =
+ commands::CommandImpl::protocol_version_;
+ (*vr_command)[strings::params][strings::protocol_type] =
+ commands::CommandImpl::hmi_protocol_type_;
+ (*vr_command)[strings::params][strings::correlation_id] =
+ ApplicationManagerImpl::instance()->GetNextHMICorrelationID();
+ smart_objects::SmartObject msg_params = smart_objects::SmartObject(
+ smart_objects::SmartType_Map);
+ msg_params[strings::app_id] = application->app_id();
+ msg_params[strings::cmd_id] =
+ (*(it->second))[strings::choice_set][j][strings::choice_id];
+ msg_params[strings::vr_commands] = smart_objects::SmartObject(
+ smart_objects::SmartType_Array);
+ msg_params[strings::vr_commands] =
+ (*(it->second))[strings::choice_set][j][strings::vr_commands];
+
+ msg_params[strings::type] = hmi_apis::Common_VRCommandType::Choice;
+ msg_params[strings::grammar_id] = choice_grammar_id;
+ (*vr_command)[strings::msg_params] = msg_params;
+ requests.push_back(vr_command);
+ }
+ }
+ return requests;
+}
+
smart_objects::SmartObjectSPtr MessageHelper::CreateChangeRegistration(
int32_t function_id, int32_t language, uint32_t app_id,
const smart_objects::SmartObject* app_types) {
diff --git a/src/components/application_manager/src/resume_ctrl.cpp b/src/components/application_manager/src/resume_ctrl.cpp
index 6dd46aa3de..6e7f2b473f 100644
--- a/src/components/application_manager/src/resume_ctrl.cpp
+++ b/src/components/application_manager/src/resume_ctrl.cpp
@@ -71,13 +71,23 @@ ResumeCtrl::ResumeCtrl(ApplicationManagerImpl* app_mngr)
void ResumeCtrl::SaveAllApplications() {
LOG4CXX_AUTO_TRACE(logger_);
- std::set<ApplicationSharedPtr> apps(retrieve_application());
- std::for_each(apps.begin(),
- apps.end(),
- std::bind1st(std::mem_fun(&ResumeCtrl::SaveApplication), this));
- // remove old
+ std::set<ApplicationSharedPtr> apps(retrieve_application());
+ std::set<ApplicationSharedPtr>::iterator it_begin = apps.begin();
+ std::set<ApplicationSharedPtr>::iterator it_end = apps.end();
+
+ resumtion_lock_.Acquire();
+ for (; it_begin != it_end; ++it_begin) {
+ if (StateApplicationData::kNotSavedDataForResumption ==
+ ((*it_begin)->is_application_data_changed())) {
+ resumption_storage->SaveApplication();
+ (*it_begin)->set_is_application_data_changed(
+ StateApplicationData::kSavedDataForResumption);
+ }
+ }
+ resumtion_lock_.Release();
}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ResumeCtrl::SaveApplication(ApplicationConstSharedPtr application) {
DCHECK(application.get());
@@ -99,7 +109,7 @@ void ResumeCtrl::SaveApplication(ApplicationConstSharedPtr application) {
resumtion_lock_.Acquire();
Json::Value& json_app = GetFromSavedOrAppend(m_app_id);
- json_app[strings::device_mac] =
+ json_app[strings::device_id] =
MessageHelper::GetDeviceMacAddressForHandle(application->device());
json_app[strings::app_id] = m_app_id;
json_app[strings::grammar_id] = grammar_id;
@@ -114,7 +124,7 @@ void ResumeCtrl::SaveApplication(ApplicationConstSharedPtr application) {
GetApplicationCommands(application);
json_app[strings::application_submenus] =
GetApplicationSubMenus(application);
- json_app[strings::application_choise_sets] =
+ json_app[strings::application_choice_sets] =
GetApplicationInteractionChoiseSets(application);
json_app[strings::application_global_properties] =
GetApplicationGlobalProperties(application);
@@ -126,13 +136,16 @@ void ResumeCtrl::SaveApplication(ApplicationConstSharedPtr application) {
resumtion_lock_.Release();
}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ResumeCtrl::on_event(const event_engine::Event& event) {
LOG4CXX_TRACE(logger_, "Response from HMI command");
}
+
bool ResumeCtrl::RestoreAppHMIState(ApplicationSharedPtr application) {
LOG4CXX_AUTO_TRACE(logger_);
+
using namespace mobile_apis;
if (!application) {
LOG4CXX_ERROR(logger_, " RestoreApplicationHMILevel() application pointer in invalid");
@@ -140,20 +153,13 @@ bool ResumeCtrl::RestoreAppHMIState(ApplicationSharedPtr application) {
}
LOG4CXX_DEBUG(logger_, "ENTER app_id : " << application->app_id());
- sync_primitives::AutoLock lock(resumtion_lock_);
- const int idx = GetObjectIndex(application->mobile_app_id());
- if (-1 != idx) {
- const Json::Value& json_app = GetSavedApplications()[idx];
- if (json_app.isMember(strings::hmi_level)) {
+ const HMILevel::eType saved_hmi_level = static_cast<mobile_apis::HMILevel::eType>(
+ resumption_storage->GetStoredHMILevel(application->mobile_app_id(),
+ MessageHelper::GetDeviceMacAddressForHandle(application->device())));
- const HMILevel::eType saved_hmi_level =
- static_cast<mobile_apis::HMILevel::eType>(
- json_app[strings::hmi_level].asInt());
- LOG4CXX_DEBUG(logger_, "Saved HMI Level is : " << saved_hmi_level);
- return SetAppHMIState(application, saved_hmi_level);
- } else {
- LOG4CXX_FATAL(logger_, "There are some unknown keys among the stored apps");
- }
+ if (mobile_apis::HMILevel::INVALID_ENUM != saved_hmi_level) {
+ LOG4CXX_DEBUG(logger_, "Saved HMI Level is : " << saved_hmi_level);
+ return SetAppHMIState(application, saved_hmi_level);
}
LOG4CXX_INFO(logger_, "Failed to restore application HMILevel");
return false;
@@ -247,48 +253,31 @@ bool ResumeCtrl::SetAppHMIState(ApplicationSharedPtr application,
return true;
}
+
bool ResumeCtrl::RestoreApplicationData(ApplicationSharedPtr application) {
LOG4CXX_AUTO_TRACE(logger_);
- if (!application.valid()) {
- LOG4CXX_ERROR(logger_, "Application pointer in invalid");
- return false;
- }
-
- LOG4CXX_DEBUG(logger_, "ENTER app_id : " << application->app_id());
sync_primitives::AutoLock lock(resumtion_lock_);
- const int idx = GetObjectIndex(application->mobile_app_id());
- if (-1 == idx) {
- LOG4CXX_WARN(logger_, "Application not saved");
- return false;
- }
-
- const Json::Value& saved_app = GetSavedApplications()[idx];
- if(saved_app.isMember(strings::grammar_id)) {
- const uint32_t app_grammar_id = saved_app[strings::grammar_id].asUInt();
- application->set_grammar_id(app_grammar_id);
-
- AddFiles(application, saved_app);
- AddSubmenues(application, saved_app);
- AddCommands(application, saved_app);
- AddChoicesets(application, saved_app);
- SetGlobalProperties(application, saved_app);
- AddSubscriptions(application, saved_app);
+ const bool result = resumption_storage->RestoreApplicationData(application);
+ if (result) {
+ ProcessHMIRequests(MessageHelper::CreateAddSubMenuRequestToHMI(application));
+ ProcessHMIRequests(MessageHelper::CreateAddCommandRequestToHMI(application));
+ ProcessHMIRequests(
+ MessageHelper::CreateAddVRCommandRequestFromChoiceToHMI(application));
+ MessageHelper::SendGlobalPropertiesToHMI(application);
+ ProcessHMIRequests(MessageHelper::GetIVISubscriptionRequests(application));
}
- return true;
+ return result;
}
bool ResumeCtrl::IsHMIApplicationIdExist(uint32_t hmi_app_id) {
LOG4CXX_TRACE(logger_, "ENTER hmi_app_id :" << hmi_app_id);
+
sync_primitives::AutoLock lock(resumtion_lock_);
- for (Json::Value::iterator it = GetSavedApplications().begin();
- it != GetSavedApplications().end(); ++it) {
- if ((*it).isMember(strings::hmi_app_id)) {
- if ((*it)[strings::hmi_app_id].asUInt() == hmi_app_id) {
- return true;
- }
- }
+ if (resumption_storage->IsHMIApplicationIdExist(hmi_app_id)) {
+ return true;
}
+
ApplicationManagerImpl::ApplicationListAccessor accessor;
ApplicationManagerImpl::ApplictionSet apps(accessor.applications());
ApplicationManagerImpl::ApplictionSetIt it = apps.begin();
@@ -304,44 +293,22 @@ bool ResumeCtrl::IsHMIApplicationIdExist(uint32_t hmi_app_id) {
return false;
}
-bool ResumeCtrl::IsApplicationSaved(const std::string& mobile_app_id) {
+bool ResumeCtrl::IsApplicationSaved(const std::string& mobile_app_id,
+ const std::string& device_id) {
LOG4CXX_TRACE(logger_, "ENTER mobile_app_id :" << mobile_app_id);
sync_primitives::AutoLock lock(resumtion_lock_);
- int index = GetObjectIndex(mobile_app_id);
- if (-1 == index) {
- return false;
- }
-
- if (!IsResumptionDataValid(index)) {
- LOG4CXX_INFO(logger_, "Resumption data for app " << mobile_app_id <<
- " is corrupted. Remove application from resumption list");
- RemoveApplicationFromSaved(mobile_app_id);
- return false;
- }
-
- return true;
+ return resumption_storage->CheckSavedApplication(mobile_app_id, device_id);
}
-uint32_t ResumeCtrl::GetHMIApplicationID(const std::string& mobile_app_id) {
+uint32_t ResumeCtrl::GetHMIApplicationID(const std::string& mobile_app_id,
+ const std::string& device_id) {
LOG4CXX_AUTO_TRACE(logger_);
- uint32_t hmi_app_id = 0;
sync_primitives::AutoLock lock(resumtion_lock_);
- const int idx = GetObjectIndex(mobile_app_id);
- if (-1 == idx) {
- LOG4CXX_WARN(logger_, "Application not saved");
- return hmi_app_id;
- }
-
- const Json::Value& json_app = GetSavedApplications()[idx];
- if (json_app.isMember(strings::app_id)) {
- hmi_app_id = json_app[strings::hmi_app_id].asUInt();
- }
- LOG4CXX_DEBUG(logger_, "hmi_app_id :" << hmi_app_id);
- return hmi_app_id;
+ return resumption_storage->GetHMIApplicationID(mobile_app_id, device_id);
}
-
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool ResumeCtrl::RemoveApplicationFromSaved(const std::string& mobile_app_id) {
LOG4CXX_TRACE(logger_, "Remove mobile_app_id " << mobile_app_id);
sync_primitives::AutoLock lock(resumtion_lock_);
@@ -373,54 +340,22 @@ bool ResumeCtrl::RemoveApplicationFromSaved(const std::string& mobile_app_id) {
LOG4CXX_TRACE(logger_, "EXIT result: " << (result ? "true" : "false"));
return result;
}
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ResumeCtrl::Suspend() {
LOG4CXX_AUTO_TRACE(logger_);
+
StopSavePersistentDataTimer();
SaveAllApplications();
- Json::Value to_save;
sync_primitives::AutoLock lock(resumtion_lock_);
- for (Json::Value::iterator it = GetSavedApplications().begin();
- it != GetSavedApplications().end(); ++it) {
- if ((*it).isMember(strings::suspend_count)) {
- const uint32_t suspend_count = (*it)[strings::suspend_count].asUInt();
- (*it)[strings::suspend_count] = suspend_count + 1;
- } else {
- LOG4CXX_WARN(logger_, "Unknown key among saved applications");
- (*it)[strings::suspend_count] = 1;
- }
- if ((*it).isMember(strings::ign_off_count)) {
- const uint32_t ign_off_count = (*it)[strings::ign_off_count].asUInt();
- if (ign_off_count < kApplicationLifes) {
- (*it)[strings::ign_off_count] = ign_off_count + 1;
- to_save.append(*it);
- }
- } else {
- LOG4CXX_WARN(logger_, "Unknown key among saved applications");
- (*it)[strings::ign_off_count] = 1;
- }
- }
- SetSavedApplication(to_save);
- SetLastIgnOffTime(time(NULL));
- LOG4CXX_DEBUG(logger_,
- GetResumptionData().toStyledString());
- resumption::LastState::instance()->SaveToFileSystem();
+ resumption_storage->Suspend();
}
void ResumeCtrl::OnAwake() {
LOG4CXX_AUTO_TRACE(logger_);
sync_primitives::AutoLock lock(resumtion_lock_);
- for (Json::Value::iterator it = GetSavedApplications().begin();
- it != GetSavedApplications().end(); ++it) {
- if ((*it).isMember(strings::ign_off_count)) {
- const uint32_t ign_off_count = (*it)[strings::ign_off_count].asUInt();
- (*it)[strings::ign_off_count] = ign_off_count - 1;
- } else {
- LOG4CXX_WARN(logger_, "Unknown key among saved applications");
- (*it)[strings::ign_off_count] = 0;
- }
- }
+ resumption_storage->OnAwake();
ResetLaunchTime();
StartSavePersistentDataTimer();
}
@@ -459,35 +394,32 @@ bool ResumeCtrl::StartResumption(ApplicationSharedPtr application,
<< "received hash = " << hash);
sync_primitives::AutoLock lock(resumtion_lock_);
- const int idx = GetObjectIndex(application->mobile_app_id());
- if (-1 == idx) {
- LOG4CXX_WARN(logger_, "Application not saved");
+ std::string saved_hash;
+ bool result = resumption_storage->GetHashId(
+ application->mobile_app_id(),
+ MessageHelper::GetDeviceMacAddressForHandle(application->device()),
+ saved_hash);
+
+ if (!result) {
return false;
}
- const Json::Value& json_app = GetSavedApplications()[idx];
- LOG4CXX_DEBUG(logger_, "Saved_application_data: " << json_app.toStyledString());
- if (json_app.isMember(strings::hash_id) && json_app.isMember(strings::time_stamp)) {
- const std::string& saved_hash = json_app[strings::hash_id].asString();
-
- if (saved_hash == hash) {
- RestoreApplicationData(application);
- }
- application->UpdateHash();
-
- queue_lock_.Acquire();
- waiting_for_timer_.push_back(application->app_id());
- queue_lock_.Release();
- if (!is_resumption_active_) {
- is_resumption_active_ = true;
- restore_hmi_level_timer_.start(
- profile::Profile::instance()->app_resuming_timeout());
- }
- } else {
- LOG4CXX_INFO(logger_, "There are some unknown keys in the dictionary.");
- return false;
+ if (saved_hash == hash) {
+ RestoreApplicationData(application);
}
+ application->UpdateHash();
+ sync_primitives::AutoUnlock unlock(lock);
+ AddToResumption(application->app_id());
+
+ queue_lock_.Acquire();
+ waiting_for_timer_.push_back(application->app_id());
+ queue_lock_.Release();
+ if (!is_resumption_active_) {
+ is_resumption_active_ = true;
+ restore_hmi_level_timer_.start(
+ profile::Profile::instance()->app_resuming_timeout());
+ }
return true;
}
@@ -496,35 +428,42 @@ void ResumeCtrl::StartAppHmiStateResumption(ApplicationSharedPtr application) {
using namespace profile;
using namespace date_time;
DCHECK_OR_RETURN_VOID(application);
- const int idx = GetObjectIndex(application->mobile_app_id());
- DCHECK_OR_RETURN_VOID(idx != -1);
- const Json::Value& json_app = GetSavedApplications()[idx];
+ smart_objects::SmartObject saved_app(smart_objects::SmartType_Map);
+ sync_primitives::AutoLock lock(resumtion_lock_);
+ bool result = resumption_storage->GetSavedApplication(
+ application->mobile_app_id(),
+ MessageHelper::GetDeviceMacAddressForHandle(application->device()),
+ saved_app);
+ DCHECK_OR_RETURN_VOID(result);
- if (!json_app.isMember(strings::ign_off_count)) {
+ if (!saved_app.keyExists(strings::ign_off_count)) {
LOG4CXX_INFO(logger_, "Do not need to resume application "
<< application->app_id());
SetupDefaultHMILevel(application);
return;
}
- // check if if is resumption during one IGN cycle
- const uint32_t ign_off_count = json_app[strings::ign_off_count].asUInt();
+ // check if is resumption during one IGN cycle
+ const uint32_t ign_off_count = saved_app[strings::ign_off_count].asUInt();
+ const std::string m_app_id = application->mobile_app_id();
+ const std::string device_id =
+ MessageHelper::GetDeviceMacAddressForHandle(application->device());
if (0 == ign_off_count) {
- if (CheckAppRestrictions(application, json_app)) {
+ if (CheckAppRestrictions(application, saved_app)) {
LOG4CXX_INFO(logger_, "Resume application after short IGN cycle");
RestoreAppHMIState(application);
- RemoveApplicationFromSaved(application->mobile_app_id());
+ resumption_storage->RemoveApplicationFromSaved(m_app_id, device_id);
} else {
LOG4CXX_INFO(logger_, "Do not need to resume application "
<< application->app_id());
- }
+ }
} else {
- if (CheckIgnCycleRestrictions(json_app) &&
- CheckAppRestrictions(application, json_app)) {
+ if (CheckIgnCycleRestrictions(saved_app) &&
+ CheckAppRestrictions(application, saved_app)) {
LOG4CXX_INFO(logger_, "Resume application after IGN cycle");
RestoreAppHMIState(application);
- RemoveApplicationFromSaved(application->mobile_app_id());
+ resumption_storage->RemoveApplicationFromSaved(m_app_id, device_id);
} else {
LOG4CXX_INFO(logger_, "Do not need to resume application "
<< application->app_id());
@@ -551,8 +490,9 @@ bool ResumeCtrl::StartResumptionOnlyHMILevel(ApplicationSharedPtr application) {
<< application->mobile_app_id());
sync_primitives::AutoLock lock(resumtion_lock_);
- const int idx = GetObjectIndex(application->mobile_app_id());
- if (-1 == idx) {
+ if (-1 == (resumption_storage->IsApplicationSaved(
+ application->mobile_app_id,
+ MessageHelper::GetDeviceMacAddressForHandle(application->device())))) {
LOG4CXX_WARN(logger_, "Application not saved");
return false;
}
@@ -578,28 +518,31 @@ bool ResumeCtrl::CheckPersistenceFilesForResumption(ApplicationSharedPtr applica
}
LOG4CXX_DEBUG(logger_, "Process app_id = " << application->app_id());
+ smart_objects::SmartObject saved_app(smart_objects::SmartType_Map);
sync_primitives::AutoLock lock(resumtion_lock_);
- const int idx = GetObjectIndex(application->mobile_app_id());
- if (-1 == idx) {
+ bool result = resumption_storage->GetSavedApplication(
+ application->mobile_app_id(),
+ MessageHelper::GetDeviceMacAddressForHandle(application->device()),
+ saved_app);
+
+ if (!result) {
LOG4CXX_WARN(logger_, "Application not saved");
return false;
}
- const Json::Value& saved_app = GetSavedApplications()[idx];
-
- if (!saved_app.isMember(strings::application_commands) ||
- !saved_app.isMember(strings::application_choise_sets)) {
- LOG4CXX_WARN(logger_, "application_commands or "
- "application_choise_sets are not exists");
- return false;
- }
+ if (!saved_app.keyExists(strings::application_commands) ||
+ !saved_app.keyExists(strings::application_choice_sets)) {
+ LOG4CXX_WARN(logger_, "application_commands or "
+ "application_choice_sets are not exists");
+ return false;
+ }
- if (!CheckIcons(application, saved_app[strings::application_commands])) {
- return false;
- }
- if (!CheckIcons(application, saved_app[strings::application_choise_sets])) {
- return false;
- }
+ if (!CheckIcons(application, saved_app[strings::application_commands])) {
+ return false;
+ }
+ if (!CheckIcons(application, saved_app[strings::application_choice_sets])) {
+ return false;
+ }
LOG4CXX_DEBUG(logger_, " result = true");
return true;
}
@@ -615,25 +558,23 @@ bool ResumeCtrl::CheckApplicationHash(ApplicationSharedPtr application,
<< " hash : " << hash);
sync_primitives::AutoLock lock(resumtion_lock_);
+ std::string saved_hash;
+ bool result = resumption_storage->GetHashId(
+ application->mobile_app_id(),
+ MessageHelper::GetDeviceMacAddressForHandle(application->device()),
+ saved_hash);
+
const int idx = GetObjectIndex(application->mobile_app_id());
- if (-1 == idx) {
- LOG4CXX_WARN(logger_, "Application not saved");
+ if (!result) {
return false;
}
const Json::Value& json_app = GetSavedApplications()[idx];
-
- if (json_app.isMember(strings::hash_id)) {
- const std::string& saved_hash = json_app[strings::hash_id].asString();
-
- LOG4CXX_TRACE(logger_, "Found saved application : " << json_app.toStyledString());
- LOG4CXX_INFO(logger_, "received hash = " << hash);
- LOG4CXX_INFO(logger_, "saved hash = " << saved_hash);
- if (hash == saved_hash) {
- return true;
- }
+ LOG4CXX_INFO(logger_, "received hash = " << hash);
+ LOG4CXX_INFO(logger_, "saved hash = " << saved_hash);
+ if (hash == saved_hash) {
+ return true;
}
-
return false;
}
@@ -651,13 +592,8 @@ void ResumeCtrl::SaveDataOnTimer() {
}
}
-bool ResumeCtrl::IsDeviceMacAddressEqual(ApplicationSharedPtr application,
- const std::string& saved_device_mac) {
- const std::string device_mac =
- MessageHelper::GetDeviceMacAddressForHandle(application->device());
- return device_mac == saved_device_mac;
-}
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Json::Value&ResumeCtrl::GetResumptionData() {
LOG4CXX_AUTO_TRACE(logger_);
Json::Value& last_state = resumption::LastState::instance()->dictionary;
@@ -672,7 +608,8 @@ Json::Value&ResumeCtrl::GetResumptionData() {
}
return resumption;
}
-
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Json::Value& ResumeCtrl::GetSavedApplications() {
LOG4CXX_AUTO_TRACE(logger_);
Json::Value& resumption = GetResumptionData();
@@ -687,7 +624,8 @@ Json::Value& ResumeCtrl::GetSavedApplications() {
}
return resume_app_list;
}
-
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
time_t ResumeCtrl::GetIgnOffTime() {
LOG4CXX_AUTO_TRACE(logger_);
Json::Value& resumption = GetResumptionData();
@@ -699,28 +637,22 @@ time_t ResumeCtrl::GetIgnOffTime() {
resumption[strings::last_ign_off_time].asUInt());
return last_ign_off;
}
-
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ResumeCtrl::SetLastIgnOffTime(time_t ign_off_time) {
LOG4CXX_AUTO_TRACE(logger_);
LOG4CXX_WARN(logger_, "ign_off_time = " << ign_off_time);
Json::Value& resumption = GetResumptionData();
resumption[strings::last_ign_off_time] = static_cast<uint32_t>(ign_off_time);
}
-
-
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ResumeCtrl::SetSavedApplication(Json::Value& apps_json) {
Json::Value& app_list = GetSavedApplications();
app_list = apps_json;
}
-
-void ResumeCtrl::ClearResumptionInfo() {
- LOG4CXX_AUTO_TRACE(logger_);
- Json::Value empty_json;
-
- SetSavedApplication(empty_json);
- resumption::LastState::instance()->SaveToFileSystem();
-}
-
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Json::Value ResumeCtrl::GetApplicationCommands(
ApplicationConstSharedPtr application) {
LOG4CXX_AUTO_TRACE(logger_);
@@ -741,7 +673,8 @@ Json::Value ResumeCtrl::GetApplicationCommands(
}
return result;
}
-
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Json::Value ResumeCtrl::GetApplicationSubMenus(
ApplicationConstSharedPtr application) {
LOG4CXX_AUTO_TRACE(logger_);
@@ -762,7 +695,8 @@ Json::Value ResumeCtrl::GetApplicationSubMenus(
}
return result;
}
-
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Json::Value ResumeCtrl::GetApplicationInteractionChoiseSets(
ApplicationConstSharedPtr application) {
DCHECK(application.get());
@@ -781,7 +715,8 @@ Json::Value ResumeCtrl::GetApplicationInteractionChoiseSets(
}
return result;
}
-
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Json::Value ResumeCtrl::GetApplicationGlobalProperties(
ApplicationConstSharedPtr application) {
LOG4CXX_AUTO_TRACE(logger_);
@@ -811,7 +746,8 @@ Json::Value ResumeCtrl::GetApplicationGlobalProperties(
sgp[strings::menu_icon] = JsonFromSO(menu_icon);
return sgp;
}
-
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Json::Value ResumeCtrl::GetApplicationSubscriptions(
ApplicationConstSharedPtr application) {
LOG4CXX_AUTO_TRACE(logger_);
@@ -855,29 +791,7 @@ Json::Value ResumeCtrl::GetApplicationFiles(
}
return result;
}
-
-Json::Value ResumeCtrl::GetApplicationShow(
- ApplicationConstSharedPtr application) {
- DCHECK(application.get());
- LOG4CXX_TRACE(logger_, "ENTER app_id:"
- << application->app_id());
-
- Json::Value result;
- const smart_objects::SmartObject* show_so = application->show_command();
- if (!show_so) {
- return result;
- }
- result = JsonFromSO(show_so);
- 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::SmartObjectSPtr request,
bool use_events) {
@@ -898,6 +812,7 @@ bool ResumeCtrl::ProcessHMIRequest(smart_objects::SmartObjectSPtr request,
return false;
}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ResumeCtrl::AddFiles(ApplicationSharedPtr application, const Json::Value& saved_app) {
LOG4CXX_AUTO_TRACE(logger_);
if (saved_app.isMember(strings::application_files)) {
@@ -922,7 +837,8 @@ void ResumeCtrl::AddFiles(ApplicationSharedPtr application, const Json::Value& s
LOG4CXX_FATAL(logger_, "application_files section is not exists");
}
}
-
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ResumeCtrl::AddSubmenues(ApplicationSharedPtr application, const Json::Value& saved_app) {
LOG4CXX_AUTO_TRACE(logger_);
if (saved_app.isMember(strings::application_submenus)) {
@@ -940,7 +856,8 @@ void ResumeCtrl::AddSubmenues(ApplicationSharedPtr application, const Json::Valu
LOG4CXX_FATAL(logger_, "application_submenus section is not exists");
}
}
-
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ResumeCtrl::AddCommands(ApplicationSharedPtr application, const Json::Value& saved_app) {
LOG4CXX_AUTO_TRACE(logger_);
if (saved_app.isMember(strings::application_commands)) {
@@ -958,11 +875,11 @@ void ResumeCtrl::AddCommands(ApplicationSharedPtr application, const Json::Value
LOG4CXX_FATAL(logger_, "application_commands section is not exists");
}
}
-
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ResumeCtrl::AddChoicesets(ApplicationSharedPtr application, const Json::Value& saved_app) {
- LOG4CXX_AUTO_TRACE(logger_);
- if (saved_app.isMember(strings::application_choise_sets)) {
- const Json::Value& app_choise_sets = saved_app[strings::application_choise_sets];
+ if(saved_app.isMember(strings::application_choice_sets)) {
+ const Json::Value& app_choise_sets = saved_app[strings::application_choice_sets];
for (Json::Value::iterator json_it = app_choise_sets.begin();
json_it != app_choise_sets.end(); ++json_it) {
const Json::Value& json_choiset = *json_it;
@@ -993,7 +910,8 @@ void ResumeCtrl::AddChoicesets(ApplicationSharedPtr application, const Json::Val
LOG4CXX_FATAL(logger_, "There is no any choicesets");
}
}
-
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ResumeCtrl::SetGlobalProperties(ApplicationSharedPtr application, const Json::Value& saved_app) {
LOG4CXX_AUTO_TRACE(logger_);
const Json::Value& global_properties = saved_app[strings::application_global_properties];
@@ -1004,7 +922,8 @@ void ResumeCtrl::SetGlobalProperties(ApplicationSharedPtr application, const Jso
MessageHelper::SendGlobalPropertiesToHMI(application);
}
}
-
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ResumeCtrl::AddSubscriptions(ApplicationSharedPtr application, const Json::Value& saved_app) {
LOG4CXX_AUTO_TRACE(logger_);
if (saved_app.isMember(strings::application_subscribtions)) {
@@ -1032,6 +951,7 @@ void ResumeCtrl::AddSubscriptions(ApplicationSharedPtr application, const Json::
MessageHelper::SendAllOnButtonSubscriptionNotificationsForApp(application);
}
}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ResumeCtrl::ProcessHMIRequests(const smart_objects::SmartObjectList& requests) {
for (smart_objects::SmartObjectList::const_iterator it = requests.begin(),
@@ -1042,30 +962,28 @@ void ResumeCtrl::ProcessHMIRequests(const smart_objects::SmartObjectList& reques
}
bool ResumeCtrl::CheckIcons(ApplicationSharedPtr application,
- const Json::Value& json_object) {
+ const smart_objects::SmartObject& smart_obj) {
LOG4CXX_AUTO_TRACE(logger_);
bool result = true;
- if (!json_object.isNull()) {
- Json::Value::const_iterator json_it = json_object.begin();
- for (;json_it != json_object.end() && result; ++json_it) {
- const Json::Value& json_command = *json_it;
- if (!json_command.isNull()) {
- smart_objects::SmartObject message(smart_objects::SmartType::SmartType_Map);
- Formatters::CFormatterJsonBase::jsonValueToObj(json_command, message);
+ if (smart_objects::SmartType_Null != smart_obj.getType()) {
+ size_t length_obj = smart_obj.length();
+ for (size_t i = 0; i < length_obj && result; ++i) {
+ const smart_objects::SmartObject& so_command = smart_obj[i];
+ if (smart_objects::SmartType_Null != so_command.getType()) {
const mobile_apis::Result::eType verify_images =
MessageHelper::VerifyImageFiles(message, application);
result = (mobile_apis::Result::INVALID_DATA != verify_images);
} else {
- LOG4CXX_WARN(logger_, "Invalid json object");
+ LOG4CXX_WARN(logger_, "Invalid smart object");
}
}
} else {
- LOG4CXX_WARN(logger_, "Passed json object is null");
+ LOG4CXX_WARN(logger_, "Passed smart object is null");
}
LOG4CXX_DEBUG(logger_, "CheckIcons result " << result);
return result;
}
-
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Json::Value& ResumeCtrl::GetFromSavedOrAppend(const std::string& mobile_app_id) {
LOG4CXX_AUTO_TRACE(logger_);
for (Json::Value::iterator it = GetSavedApplications().begin();
@@ -1077,8 +995,9 @@ Json::Value& ResumeCtrl::GetFromSavedOrAppend(const std::string& mobile_app_id)
return GetSavedApplications().append(Json::Value());
}
-
-bool ResumeCtrl::CheckIgnCycleRestrictions(const Json::Value& json_app) {
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+bool ResumeCtrl::CheckIgnCycleRestrictions(
+ const smart_objects::SmartObject& saved_app) {
LOG4CXX_AUTO_TRACE(logger_);
bool result = true;
@@ -1087,30 +1006,23 @@ bool ResumeCtrl::CheckIgnCycleRestrictions(const Json::Value& json_app) {
result = false;
}
- if (!DisconnectedJustBeforeIgnOff(json_app)) {
+ if (!DisconnectedJustBeforeIgnOff(saved_app)) {
LOG4CXX_INFO(logger_, "Application was dissconnected long before ign off");
result = false;
}
return result;
}
-bool ResumeCtrl::DisconnectedInLastIgnCycle(const Json::Value& json_app) {
- LOG4CXX_AUTO_TRACE(logger_);
- DCHECK_OR_RETURN(json_app.isMember(strings::suspend_count), false);
- const uint32_t suspend_count = json_app[strings::suspend_count].asUInt();
- LOG4CXX_DEBUG(logger_, " suspend_count " << suspend_count);
- return (1 == suspend_count);
-}
-
-bool ResumeCtrl::DisconnectedJustBeforeIgnOff(const Json::Value& json_app) {
+bool ResumeCtrl::DisconnectedJustBeforeIgnOff(const smart_objects::SmartObject& saved_app) {
using namespace date_time;
using namespace profile;
LOG4CXX_AUTO_TRACE(logger_);
- DCHECK_OR_RETURN(json_app.isMember(strings::time_stamp), false);
+ DCHECK_OR_RETURN(saved_app.keyExists(strings::time_stamp), false);
const time_t time_stamp =
- static_cast<time_t>(json_app[strings::time_stamp].asUInt());
- time_t ign_off_time = GetIgnOffTime();
+ static_cast<time_t>(saved_app[strings::time_stamp].asUInt());
+ 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_,"ign_off_time " << ign_off_time
<< "; app_disconnect_time " << time_stamp
@@ -1138,14 +1050,14 @@ bool ResumeCtrl::CheckDelayAfterIgnOn() {
}
bool ResumeCtrl::CheckAppRestrictions(ApplicationSharedPtr application,
- const Json::Value& json_app) {
+ const smart_objects::SmartObject& saved_app) {
using namespace mobile_apis;
LOG4CXX_AUTO_TRACE(logger_);
- DCHECK_OR_RETURN(json_app.isMember(strings::hmi_level), false);
+ DCHECK_OR_RETURN(saved_app.keyExists(strings::hmi_level), false);
const bool is_media_app = application->is_media_application();
const HMILevel::eType hmi_level =
- static_cast<HMILevel::eType>(json_app[strings::hmi_level].asInt());
+ static_cast<HMILevel::eType>(saved_app[strings::hmi_level].asInt());
LOG4CXX_DEBUG(logger_, "is_media_app " << is_media_app
<< "; hmi_level " << hmi_level);
@@ -1157,7 +1069,7 @@ bool ResumeCtrl::CheckAppRestrictions(ApplicationSharedPtr application,
}
return false;
}
-
+/////////////////////////////////////////////////////////////////////////////////////////////
int ResumeCtrl::GetObjectIndex(const std::string& mobile_app_id) {
LOG4CXX_AUTO_TRACE(logger_);
@@ -1174,6 +1086,7 @@ int ResumeCtrl::GetObjectIndex(const std::string& mobile_app_id) {
}
return -1;
}
+/////////////////////////////////////////////////////////////////////////////////////////////
time_t ResumeCtrl::launch_time() const {
return launch_time_;
}
@@ -1207,60 +1120,65 @@ void ResumeCtrl::LoadResumeData() {
sync_primitives::AutoLock lock(resumtion_lock_);
- Json::Value& resume_app_list = GetSavedApplications();
- Json::Value::iterator full_app = resume_app_list.end();
+ smart_objects::SmartObject so_applications_data;
+ resumption_storage->GetDataForLoadResumeData(so_applications_data);
+ size_t length = so_applications_data.length();
+ smart_objects::SmartObject* full_app = NULL;
+ smart_objects::SmartObject* limited_app = NULL;
+
time_t time_stamp_full = 0;
- Json::Value::iterator limited_app = resume_app_list.end();
time_t time_stamp_limited = 0;
+ // only apps with first IGN should be resumed
+ const int32_t first_ign = 1;
- Json::Value::iterator it = resume_app_list.begin();
- for (; it != resume_app_list.end(); ++it) {
- if ((*it).isMember(strings::ign_off_count) &&
- (*it).isMember(strings::hmi_level)) {
-
- // only apps with first IGN should be resumed
- const int32_t first_ign = 1;
- if (first_ign == (*it)[strings::ign_off_count].asInt()) {
+ for (size_t i = 0; i < length; ++i) {
- const mobile_apis::HMILevel::eType saved_hmi_level =
- static_cast<mobile_apis::HMILevel::eType>((*it)[strings::hmi_level].asInt());
+ if (first_ign == so_applications_data[i][strings::ign_off_count].asInt()) {
- const time_t saved_time_stamp =
- static_cast<time_t>((*it)[strings::time_stamp].asUInt());
+ const mobile_apis::HMILevel::eType saved_hmi_level =
+ static_cast<mobile_apis::HMILevel::eType>(
+ so_application_data[i][strings::hmi_level].asInt());
+ const time_t saved_time_stamp = static_cast<time_t>(
+ so_application_data[i][strings::time_stamp].asUInt());
- if (mobile_apis::HMILevel::HMI_FULL == saved_hmi_level) {
- if (time_stamp_full < saved_time_stamp) {
+ if (mobile_apis::HMILevel::HMI_FULL == saved_hmi_level) {
+ if (time_stamp_full < saved_time_stamp) {
time_stamp_full = saved_time_stamp;
- full_app = it;
- }
+ full_app = &(so_application_data[i]);
+ }
}
- if (mobile_apis::HMILevel::HMI_LIMITED == saved_hmi_level) {
- if (time_stamp_limited < saved_time_stamp) {
+ if (mobile_apis::HMILevel::HMI_LIMITED == saved_hmi_level) {
+ if (time_stamp_limited < saved_time_stamp) {
time_stamp_limited = saved_time_stamp;
- limited_app = it;
- }
+ limited_app = &(so_application_data[i]);
}
}
-
- // set invalid HMI level for all
- (*it)[strings::hmi_level] =
- static_cast<int32_t>(mobile_apis::HMILevel::INVALID_ENUM);
}
+ // set invalid HMI level for all
+ resumption_storage->SetHMILevelForSavedApplication(
+ so_application_data[i][strings::app_id].asString(),
+ so_application_data[i][strings::device_id].asString(),
+ static_cast<int32_t>(mobile_apis::HMILevel::INVALID_ENUM));
+
}
- if (full_app != resume_app_list.end()) {
- (*full_app)[strings::hmi_level] =
- static_cast<int32_t>(mobile_apis::HMILevel::HMI_FULL);
+ if (full_app != NULL) {
+ resumption_storage->SetHMILevelForSavedApplication(
+ (*full_app)[strings::app_id].asString(),
+ (*full_app)[strings::device_id].asString(),
+ static_cast<int32_t>(mobile_apis::HMILevel::HMI_FULL));
}
- if (limited_app != resume_app_list.end()) {
- (*limited_app)[strings::hmi_level] =
- static_cast<int32_t>(mobile_apis::HMILevel::HMI_LIMITED);
+ if (limited_app != NULL) {
+ resumption_storage->SetHMILevelForSavedApplication(
+ (*limited_app)[strings::app_id].asString(),
+ (*limited_app)[strings::device_id].asString(),
+ static_cast<int32_t>(mobile_apis::HMILevel::HMI_LIMITED));
}
- LOG4CXX_DEBUG(logger_, GetResumptionData().toStyledString());
}
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool ResumeCtrl::IsResumptionDataValid(uint32_t index) {
const Json::Value& json_app = GetSavedApplications()[index];
if (!json_app.isMember(strings::app_id) ||
@@ -1280,6 +1198,7 @@ bool ResumeCtrl::IsResumptionDataValid(uint32_t index) {
return true;
}
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
uint32_t ResumeCtrl::SendHMIRequest(
const hmi_apis::FunctionID::eType& function_id,
diff --git a/src/components/application_manager/src/resumption/resume_ctrl.cc b/src/components/application_manager/src/resumption/resume_ctrl.cc
new file mode 100644
index 0000000000..fe6ba78891
--- /dev/null
+++ b/src/components/application_manager/src/resumption/resume_ctrl.cc
@@ -0,0 +1,1305 @@
+/*
+ Copyright (c) 2015, Ford Motor Company
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided with the
+ distribution.
+
+ Neither the name of the Ford Motor Company nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "application_manager/resume_ctrl.h"
+
+#include <fstream>
+#include <algorithm>
+
+#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"
+#include "resumption/last_state.h"
+#include "policy/policy_manager_impl.h"
+#include "application_manager/policies/policy_handler.h"
+
+namespace application_manager {
+
+namespace resumption {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "ResumeCtrl")
+
+namespace Formatters = NsSmartDeviceLink::NsJSONHandler::Formatters;
+
+ResumeCtrl::ResumeCtrl(ApplicationManagerImpl* app_mngr)
+ : resumtion_lock_(true),
+ app_mngr_(app_mngr),
+ save_persistent_data_timer_("RsmCtrlPercist",
+ this, &ResumeCtrl::SaveDataOnTimer, true),
+ restore_hmi_level_timer_("RsmCtrlRstore",
+ this, &ResumeCtrl::ApplicationResumptiOnTimer),
+ is_data_saved(true),
+ launch_time_(time(NULL)) {
+ LoadResumeData();
+ save_persistent_data_timer_.start(profile::Profile::instance()->app_resumption_save_persistent_data_timeout());
+}
+
+void ResumeCtrl::SaveAllApplications() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ std::set<ApplicationSharedPtr> apps(retrieve_application());
+ std::set<ApplicationSharedPtr>::iterator it_begin = apps.begin();
+ std::set<ApplicationSharedPtr>::iterator it_end = apps.end();
+
+ resumtion_lock_.Acquire();
+ for (; it_begin != it_end; ++it_begin) {
+ if (StateApplicationData::kNotSavedDataForResumption ==
+ ((*it_begin)->is_application_data_changed())) {
+ resumption_storage->SaveApplication();
+ (*it_begin)->set_is_application_data_changed(
+ StateApplicationData::kSavedDataForResumption);
+ }
+ }
+ resumtion_lock_.Release();
+}
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void ResumeCtrl::SaveApplication(ApplicationConstSharedPtr application) {
+ DCHECK(application.get());
+
+ if (!application) {
+ LOG4CXX_FATAL(logger_, "Application object is NULL.");
+ return;
+ }
+
+ const std::string& m_app_id = application->mobile_app_id();
+ LOG4CXX_TRACE(logger_, "ENTER app_id : " << application->app_id()
+ << " mobile app_id : " << m_app_id);
+
+ const std::string hash = application->curHash(); // let's make a copy not to depend on application
+ const uint32_t grammar_id = application->get_grammar_id();
+ const uint32_t time_stamp = (uint32_t)time(NULL);
+
+ const mobile_apis::HMILevel::eType hmi_level = application->hmi_level();
+
+ resumtion_lock_.Acquire();
+ Json::Value& json_app = GetFromSavedOrAppend(m_app_id);
+
+ json_app[strings::device_mac] =
+ MessageHelper::GetDeviceMacAddressForHandle(application->device());
+ json_app[strings::app_id] = m_app_id;
+ json_app[strings::grammar_id] = grammar_id;
+ json_app[strings::connection_key] = application->app_id();
+ json_app[strings::hmi_app_id] = application->hmi_app_id();
+ json_app[strings::is_media_application] = application->IsAudioApplication();
+ json_app[strings::hmi_level] = static_cast<int32_t> (hmi_level);
+ json_app[strings::ign_off_count] = 0;
+ json_app[strings::suspend_count] = 0;
+ json_app[strings::hash_id] = hash;
+ json_app[strings::application_commands] =
+ GetApplicationCommands(application);
+ json_app[strings::application_submenus] =
+ GetApplicationSubMenus(application);
+ json_app[strings::application_choice_sets] =
+ GetApplicationInteractionChoiseSets(application);
+ json_app[strings::application_global_properties] =
+ GetApplicationGlobalProperties(application);
+ json_app[strings::application_subscribtions] =
+ GetApplicationSubscriptions(application);
+ json_app[strings::application_files] = GetApplicationFiles(application);
+ json_app[strings::time_stamp] = time_stamp;
+ LOG4CXX_DEBUG(logger_, "SaveApplication : " << json_app.toStyledString());
+
+ resumtion_lock_.Release();
+}
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void ResumeCtrl::on_event(const event_engine::Event& event) {
+ LOG4CXX_TRACE(logger_, "Response from HMI command");
+}
+
+bool ResumeCtrl::RestoreAppHMIState(ApplicationSharedPtr application) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ using namespace mobile_apis;
+ if (!application) {
+ LOG4CXX_ERROR(logger_, " RestoreApplicationHMILevel() application pointer in invalid");
+ return false;
+ }
+ LOG4CXX_DEBUG(logger_, "ENTER app_id : " << application->app_id());
+
+ sync_primitives::AutoLock lock(resumtion_lock_);
+ const int idx = GetObjectIndex(application->mobile_app_id());
+ if (-1 != idx) {
+ const Json::Value& json_app = GetSavedApplications()[idx];
+ if (json_app.isMember(strings::hmi_level)) {
+
+ const HMILevel::eType saved_hmi_level =
+ static_cast<mobile_apis::HMILevel::eType>(
+ json_app[strings::hmi_level].asInt());
+ LOG4CXX_DEBUG(logger_, "Saved HMI Level is : " << saved_hmi_level);
+ return SetAppHMIState(application, saved_hmi_level);
+ } else {
+ LOG4CXX_FATAL(logger_, "There are some unknown keys among the stored apps");
+ }
+ }
+ LOG4CXX_INFO(logger_, "Failed to restore application HMILevel");
+ return false;
+}
+
+bool ResumeCtrl::SetupDefaultHMILevel(ApplicationSharedPtr application) {
+ if (false == application.valid()) {
+ LOG4CXX_ERROR(logger_, "SetupDefaultHMILevel application pointer is invalid");
+ return false;
+ }
+ LOG4CXX_TRACE(logger_, "ENTER app_id : " << application->app_id());
+ mobile_apis::HMILevel::eType default_hmi = ApplicationManagerImpl::instance()-> GetDefaultHmiLevel(application);
+ bool result = SetAppHMIState(application, default_hmi, false);
+ return result;
+}
+
+bool ResumeCtrl::SetAppHMIState(ApplicationSharedPtr application,
+ const mobile_apis::HMILevel::eType hmi_level,
+ bool check_policy) {
+ using namespace mobile_apis;
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (false == application.valid()) {
+ LOG4CXX_ERROR(logger_, "Application pointer in invalid");
+ return false;
+ }
+ LOG4CXX_TRACE(logger_, " ENTER Params : ( " << application->app_id()
+ << "," << hmi_level
+ << "," << check_policy << " )");
+ const std::string device_id =
+ MessageHelper::GetDeviceMacAddressForHandle(application->device());
+
+ if (check_policy &&
+ policy::PolicyHandler::instance()->GetUserConsentForDevice(device_id)
+ != policy::DeviceConsent::kDeviceAllowed) {
+ LOG4CXX_ERROR(logger_, "Resumption abort. Data consent wasn't allowed");
+ SetupDefaultHMILevel(application);
+ return false;
+ }
+ HMILevel::eType restored_hmi_level = hmi_level;
+
+ if ((hmi_level == application->hmi_level()) &&
+ (hmi_level != mobile_apis::HMILevel::HMI_NONE)) {
+ LOG4CXX_DEBUG(logger_, "Hmi level " << hmi_level << " should not be set to "
+ << application->mobile_app_id()
+ <<" current hmi_level is " << application->hmi_level());
+ return false;
+ }
+
+ if (HMILevel::HMI_FULL == hmi_level) {
+ restored_hmi_level = app_mngr_->IsHmiLevelFullAllowed(application);
+ } else if (HMILevel::HMI_LIMITED == hmi_level) {
+ bool allowed_limited = true;
+ ApplicationManagerImpl::ApplicationListAccessor accessor;
+ ApplicationManagerImpl::ApplictionSetConstIt it = accessor.begin();
+ for (; accessor.end() != it && allowed_limited; ++it) {
+ const ApplicationSharedPtr curr_app = *it;
+ if (curr_app->is_media_application()) {
+ if (curr_app->hmi_level() == HMILevel::HMI_FULL ||
+ curr_app->hmi_level() == HMILevel::HMI_LIMITED) {
+ allowed_limited = false;
+ }
+ }
+ }
+ if (allowed_limited) {
+ restored_hmi_level = HMILevel::HMI_LIMITED;
+ } else {
+ restored_hmi_level =
+ ApplicationManagerImpl::instance()->GetDefaultHmiLevel(application);
+ }
+ }
+
+ const AudioStreamingState::eType restored_audio_state =
+ HMILevel::HMI_FULL == restored_hmi_level ||
+ HMILevel::HMI_LIMITED == restored_hmi_level ? AudioStreamingState::AUDIBLE:
+ AudioStreamingState::NOT_AUDIBLE;
+
+ application->set_audio_streaming_state(restored_audio_state);
+
+ if (HMILevel::HMI_FULL == restored_hmi_level) {
+ MessageHelper::SendActivateAppToHMI(application->app_id());
+ } else {
+ if (HMILevel::HMI_LIMITED == restored_hmi_level) {
+ MessageHelper::SendOnResumeAudioSourceToHMI(application->app_id());
+ }
+ application->set_hmi_level(restored_hmi_level);
+ MessageHelper::SendHMIStatusNotification(*(application.get()));
+ }
+ LOG4CXX_INFO(logger_, "Set up application "
+ << application->mobile_app_id()
+ << " to HMILevel " << hmi_level);
+ return true;
+}
+
+bool ResumeCtrl::RestoreApplicationData(ApplicationSharedPtr application) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (!application.valid()) {
+ LOG4CXX_ERROR(logger_, "Application pointer in invalid");
+ return false;
+ }
+
+ LOG4CXX_DEBUG(logger_, "ENTER app_id : " << application->app_id());
+
+ sync_primitives::AutoLock lock(resumtion_lock_);
+ const int idx = GetObjectIndex(application->mobile_app_id());
+ if (-1 == idx) {
+ LOG4CXX_WARN(logger_, "Application not saved");
+ return false;
+ }
+
+ const Json::Value& saved_app = GetSavedApplications()[idx];
+ if(saved_app.isMember(strings::grammar_id)) {
+ const uint32_t app_grammar_id = saved_app[strings::grammar_id].asUInt();
+ application->set_grammar_id(app_grammar_id);
+
+ AddFiles(application, saved_app);
+ AddSubmenues(application, saved_app);
+ AddCommands(application, saved_app);
+ AddChoicesets(application, saved_app);
+ SetGlobalProperties(application, saved_app);
+ AddSubscriptions(application, saved_app);
+ }
+ return true;
+}
+
+bool ResumeCtrl::IsHMIApplicationIdExist(uint32_t hmi_app_id) {
+ LOG4CXX_TRACE(logger_, "ENTER hmi_app_id :" << hmi_app_id);
+ sync_primitives::AutoLock lock(resumtion_lock_);
+ for (Json::Value::iterator it = GetSavedApplications().begin();
+ it != GetSavedApplications().end(); ++it) {
+ if ((*it).isMember(strings::hmi_app_id)) {
+ if ((*it)[strings::hmi_app_id].asUInt() == hmi_app_id) {
+ return true;
+ }
+ }
+ }
+ ApplicationManagerImpl::ApplicationListAccessor accessor;
+ ApplicationManagerImpl::ApplictionSet apps(accessor.applications());
+ ApplicationManagerImpl::ApplictionSetIt it = apps.begin();
+ ApplicationManagerImpl::ApplictionSetIt it_end = apps.end();
+
+ for (;it != it_end; ++it) {
+ if (hmi_app_id == (*it)->hmi_app_id()) {
+ LOG4CXX_TRACE(logger_, "EXIT result = true");
+ return true;
+ }
+ }
+ LOG4CXX_TRACE(logger_, "EXIT result = false");
+ return false;
+}
+
+bool ResumeCtrl::IsApplicationSaved(const std::string& mobile_app_id) {
+ LOG4CXX_TRACE(logger_, "ENTER mobile_app_id :" << mobile_app_id);
+ bool result = false;
+ sync_primitives::AutoLock lock(resumtion_lock_);
+ int index = GetObjectIndex(mobile_app_id);
+ if (-1 != index) {
+ result = true;
+ }
+ LOG4CXX_TRACE(logger_, "EXIT result: " <<
+ (result ? "true" : "false"));
+ return result;
+}
+
+uint32_t ResumeCtrl::GetHMIApplicationID(const std::string& mobile_app_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ uint32_t hmi_app_id = 0;
+
+ sync_primitives::AutoLock lock(resumtion_lock_);
+ const int idx = GetObjectIndex(mobile_app_id);
+ if (-1 == idx) {
+ LOG4CXX_WARN(logger_, "Application not saved");
+ return hmi_app_id;
+ }
+
+ const Json::Value& json_app = GetSavedApplications()[idx];
+ if (json_app.isMember(strings::app_id)) {
+ hmi_app_id = json_app[strings::hmi_app_id].asUInt();
+ }
+ LOG4CXX_DEBUG(logger_, "hmi_app_id :" << hmi_app_id);
+ return hmi_app_id;
+}
+
+bool ResumeCtrl::RemoveApplicationFromSaved(ApplicationConstSharedPtr application) {
+ if (false == application.valid()) {
+ LOG4CXX_ERROR(logger_, "Application pointer in invalid");
+ return false;
+ }
+ LOG4CXX_TRACE(logger_, "ENTER app_id :" << application->app_id()
+ << "; mobile_app_id " << application->mobile_app_id());
+
+ bool result = false;
+ std::vector<Json::Value> temp;
+ sync_primitives::AutoLock lock(resumtion_lock_);
+ for (Json::Value::iterator it = GetSavedApplications().begin();
+ it != GetSavedApplications().end(); ++it) {
+ if ((*it).isMember(strings::app_id)) {
+ const std::string& saved_m_app_id = (*it)[strings::app_id].asString();
+
+ if (saved_m_app_id != application->mobile_app_id()) {
+ temp.push_back((*it));
+ } else {
+ result = true;
+ }
+ }
+ }
+
+ if (false == result) {
+ LOG4CXX_TRACE(logger_, "EXIT result: " << (result ? "true" : "false"));
+ return result;
+ }
+
+ GetSavedApplications().clear();
+ for (std::vector<Json::Value>::iterator it = temp.begin();
+ it != temp.end(); ++it) {
+ GetSavedApplications().append((*it));
+ }
+ LOG4CXX_TRACE(logger_, "EXIT result: " << (result ? "true" : "false"));
+ return result;
+}
+
+void ResumeCtrl::Suspend() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ StopSavePersistentDataTimer();
+ SaveAllApplications();
+ Json::Value to_save;
+ sync_primitives::AutoLock lock(resumtion_lock_);
+ for (Json::Value::iterator it = GetSavedApplications().begin();
+ it != GetSavedApplications().end(); ++it) {
+ if ((*it).isMember(strings::suspend_count)) {
+ const uint32_t suspend_count = (*it)[strings::suspend_count].asUInt();
+ (*it)[strings::suspend_count] = suspend_count + 1;
+ } else {
+ LOG4CXX_WARN(logger_, "Unknown key among saved applications");
+ (*it)[strings::suspend_count] = 1;
+ }
+ if ((*it).isMember(strings::ign_off_count)) {
+ const uint32_t ign_off_count = (*it)[strings::ign_off_count].asUInt();
+ if (ign_off_count < kApplicationLifes) {
+ (*it)[strings::ign_off_count] = ign_off_count + 1;
+ to_save.append(*it);
+ }
+ } else {
+ LOG4CXX_WARN(logger_, "Unknown key among saved applications");
+ (*it)[strings::ign_off_count] = 1;
+ }
+ }
+ SetSavedApplication(to_save);
+ SetLastIgnOffTime(time(NULL));
+ LOG4CXX_DEBUG(logger_,
+ GetResumptionData().toStyledString());
+ resumption::LastState::instance()->SaveToFileSystem();
+}
+
+void ResumeCtrl::OnAwake() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ sync_primitives::AutoLock lock(resumtion_lock_);
+ for (Json::Value::iterator it = GetSavedApplications().begin();
+ it != GetSavedApplications().end(); ++it) {
+ if ((*it).isMember(strings::ign_off_count)) {
+ const uint32_t ign_off_count = (*it)[strings::ign_off_count].asUInt();
+ (*it)[strings::ign_off_count] = ign_off_count - 1;
+ } else {
+ LOG4CXX_WARN(logger_, "Unknown key among saved applications");
+ (*it)[strings::ign_off_count] = 0;
+ }
+ }
+ ResetLaunchTime();
+ StartSavePersistentDataTimer();
+}
+
+
+
+void ResumeCtrl::StartSavePersistentDataTimer() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (!save_persistent_data_timer_.isRunning()) {
+ save_persistent_data_timer_.start(
+ profile::Profile::instance()->app_resumption_save_persistent_data_timeout());
+ }
+}
+
+void ResumeCtrl::StopSavePersistentDataTimer() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (save_persistent_data_timer_.isRunning()) {
+ save_persistent_data_timer_.stop();
+ }
+}
+
+
+bool ResumeCtrl::StartResumption(ApplicationSharedPtr application,
+ const std::string& hash) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (!application) {
+ LOG4CXX_WARN(logger_, "Application not exist");
+ return false;
+ }
+
+ SetupDefaultHMILevel(application);
+
+ LOG4CXX_DEBUG(logger_, " Resume app_id = " << application->app_id()
+ << " hmi_app_id = " << application->hmi_app_id()
+ << " mobile_id = " << application->mobile_app_id()
+ << "received hash = " << hash);
+
+ sync_primitives::AutoLock lock(resumtion_lock_);
+ const int idx = GetObjectIndex(application->mobile_app_id());
+ if (-1 == idx) {
+ LOG4CXX_WARN(logger_, "Application not saved");
+ return false;
+ }
+
+ const Json::Value& json_app = GetSavedApplications()[idx];
+ LOG4CXX_DEBUG(logger_, "Saved_application_data: " << json_app.toStyledString());
+ if (json_app.isMember(strings::hash_id) && json_app.isMember(strings::time_stamp)) {
+ const std::string& saved_hash = json_app[strings::hash_id].asString();
+
+ if (saved_hash == hash) {
+ RestoreApplicationData(application);
+ }
+ application->UpdateHash();
+ ApplicationManagerImpl::ApplicationListAccessor accessor;
+ if (!restore_hmi_level_timer_.isRunning() &&
+ accessor.applications().size() > 1) {
+ // if there is already registered app resume without delays
+ StartAppHmiStateResumption(application);
+ } else {
+ queue_lock_.Acquire();
+ waiting_for_timer_.push_back(application->app_id());
+ queue_lock_.Release();
+ restore_hmi_level_timer_.start(profile::Profile::instance()->app_resuming_timeout());
+ }
+ } else {
+ LOG4CXX_INFO(logger_, "There are some unknown keys in the dictionary.");
+ return false;
+ }
+
+ return true;
+}
+
+void ResumeCtrl::StartAppHmiStateResumption(ApplicationSharedPtr application) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ using namespace profile;
+ using namespace date_time;
+ DCHECK_OR_RETURN_VOID(application);
+ const int idx = GetObjectIndex(application->mobile_app_id());
+ DCHECK_OR_RETURN_VOID(idx != -1);
+ const Json::Value& json_app = GetSavedApplications()[idx];
+
+ if (!json_app.isMember(strings::ign_off_count)) {
+ LOG4CXX_INFO(logger_, "Do not need to resume application "
+ << application->app_id());
+ SetupDefaultHMILevel(application);
+ return;
+ }
+
+ // check if if is resumption during one IGN cycle
+ const uint32_t ign_off_count = json_app[strings::ign_off_count].asUInt();
+
+ if (0 == ign_off_count) {
+ if (CheckAppRestrictions(application, json_app)) {
+ LOG4CXX_INFO(logger_, "Resume application after short IGN cycle");
+ RestoreAppHMIState(application);
+ RemoveApplicationFromSaved(application);
+ } else {
+ LOG4CXX_INFO(logger_, "Do not need to resume application "
+ << application->app_id());
+ }
+ } else {
+ if (CheckIgnCycleRestrictions(json_app) &&
+ CheckAppRestrictions(application, json_app)) {
+ LOG4CXX_INFO(logger_, "Resume application after IGN cycle");
+ RestoreAppHMIState(application);
+ RemoveApplicationFromSaved(application);
+ } else {
+ LOG4CXX_INFO(logger_, "Do not need to resume application "
+ << application->app_id());
+ }
+ }
+}
+
+std::set<ApplicationSharedPtr> ResumeCtrl::retrieve_application() {
+ ApplicationManagerImpl::ApplicationListAccessor accessor;
+ return std::set<ApplicationSharedPtr>(accessor.begin(), accessor.end());
+}
+
+bool ResumeCtrl::StartResumptionOnlyHMILevel(ApplicationSharedPtr application) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (!application.valid()) {
+ LOG4CXX_WARN(logger_, "Application do not exists");
+ return false;
+ }
+
+ SetupDefaultHMILevel(application);
+
+ LOG4CXX_DEBUG(logger_, "ENTER app_id = " << application->app_id()
+ << "mobile_id = "
+ << application->mobile_app_id());
+
+ sync_primitives::AutoLock lock(resumtion_lock_);
+ const int idx = GetObjectIndex(application->mobile_app_id());
+ if (-1 == idx) {
+ LOG4CXX_WARN(logger_, "Application not saved");
+ return false;
+ }
+
+ ApplicationManagerImpl::ApplicationListAccessor accessor;
+ if (!restore_hmi_level_timer_.isRunning() &&
+ accessor.applications().size() > 1) {
+ StartAppHmiStateResumption(application);
+ } else {
+ queue_lock_.Acquire();
+ waiting_for_timer_.push_back(application->app_id());
+ queue_lock_.Release();
+ restore_hmi_level_timer_.start(profile::Profile::instance()->app_resuming_timeout());
+ }
+
+ return true;
+}
+
+bool ResumeCtrl::CheckPersistenceFilesForResumption(ApplicationSharedPtr application) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ if (!application.valid()) {
+ LOG4CXX_WARN(logger_, "Application do not exists");
+ return false;
+ }
+ LOG4CXX_DEBUG(logger_, "Process app_id = " << application->app_id());
+
+ sync_primitives::AutoLock lock(resumtion_lock_);
+ const int idx = GetObjectIndex(application->mobile_app_id());
+ if (-1 == idx) {
+ LOG4CXX_WARN(logger_, "Application not saved");
+ return false;
+ }
+
+ const Json::Value& saved_app = GetSavedApplications()[idx];
+
+ if (!saved_app.isMember(strings::application_commands) ||
+ !saved_app.isMember(strings::application_choice_sets)) {
+ LOG4CXX_WARN(logger_, "application_commands or "
+ "application_choice_sets are not exists");
+ return false;
+ }
+
+ if (!CheckIcons(application, saved_app[strings::application_commands])) {
+ return false;
+ }
+ if (!CheckIcons(application, saved_app[strings::application_choice_sets])) {
+ return false;
+ }
+ LOG4CXX_DEBUG(logger_, " result = true");
+ return true;
+}
+
+bool ResumeCtrl::CheckApplicationHash(ApplicationSharedPtr application,
+ const std::string& hash) {
+ if (!application) {
+ LOG4CXX_ERROR(logger_, "Application pointer is invalid");
+ return false;
+ }
+
+ LOG4CXX_DEBUG(logger_, "ENTER app_id : " << application->app_id()
+ << " hash : " << hash);
+
+ sync_primitives::AutoLock lock(resumtion_lock_);
+ const int idx = GetObjectIndex(application->mobile_app_id());
+ if (-1 == idx) {
+ LOG4CXX_WARN(logger_, "Application not saved");
+ return false;
+ }
+
+ const Json::Value& json_app = GetSavedApplications()[idx];
+
+ if (json_app.isMember(strings::hash_id)) {
+ const std::string& saved_hash = json_app[strings::hash_id].asString();
+
+ LOG4CXX_TRACE(logger_, "Found saved application : " << json_app.toStyledString());
+ LOG4CXX_INFO(logger_, "received hash = " << hash);
+ LOG4CXX_INFO(logger_, "saved hash = " << saved_hash);
+ if (hash == saved_hash) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void ResumeCtrl::SaveDataOnTimer() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (restore_hmi_level_timer_.isRunning()) {
+ LOG4CXX_WARN(logger_, "Resumption timer is active skip saving");
+ return;
+ }
+
+ if (false == is_data_saved) {
+ SaveAllApplications();
+ is_data_saved = true;
+ resumption::LastState::instance()->SaveToFileSystem();
+ }
+}
+
+bool ResumeCtrl::IsDeviceMacAddressEqual(ApplicationSharedPtr application,
+ const std::string& saved_device_mac) {
+ const std::string device_mac =
+ MessageHelper::GetDeviceMacAddressForHandle(application->device());
+ return device_mac == saved_device_mac;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+Json::Value&ResumeCtrl::GetResumptionData() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ Json::Value& last_state = resumption::LastState::instance()->dictionary;
+ if (!last_state.isMember(strings::resumption)) {
+ last_state[strings::resumption] = Json::Value(Json::objectValue);
+ LOG4CXX_WARN(logger_, "resumption section is missed");
+ }
+ Json::Value& resumption = last_state[strings::resumption];
+ if (!resumption.isObject()) {
+ LOG4CXX_ERROR(logger_, "resumption type INVALID rewrite");
+ resumption = Json::Value(Json::objectValue);
+ }
+ return resumption;
+}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+Json::Value& ResumeCtrl::GetSavedApplications() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ Json::Value& resumption = GetResumptionData();
+ if (!resumption.isMember(strings::resume_app_list)) {
+ resumption[strings::resume_app_list] = Json::Value(Json::arrayValue);
+ LOG4CXX_WARN(logger_, "app_list section is missed");
+ }
+ Json::Value& resume_app_list = resumption[strings::resume_app_list];
+ if (!resume_app_list.isArray()) {
+ LOG4CXX_ERROR(logger_, "resume_app_list type INVALID rewrite");
+ resume_app_list = Json::Value(Json::arrayValue);
+ }
+ return resume_app_list;
+}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+time_t ResumeCtrl::GetIgnOffTime() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ Json::Value& resumption = GetResumptionData();
+ if (!resumption.isMember(strings::last_ign_off_time)) {
+ resumption[strings::last_ign_off_time] = 0;
+ LOG4CXX_WARN(logger_, "last_save_time section is missed");
+ }
+ time_t last_ign_off = static_cast<time_t>(
+ resumption[strings::last_ign_off_time].asUInt());
+ return last_ign_off;
+}
+
+void ResumeCtrl::SetLastIgnOffTime(time_t ign_off_time) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_WARN(logger_, "ign_off_time = " << ign_off_time);
+ Json::Value& resumption = GetResumptionData();
+ resumption[strings::last_ign_off_time] = static_cast<uint32_t>(ign_off_time);
+}
+
+
+void ResumeCtrl::SetSavedApplication(Json::Value& apps_json) {
+ Json::Value& app_list = GetSavedApplications();
+ app_list = apps_json;
+}
+
+void ResumeCtrl::ClearResumptionInfo() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ Json::Value empty_json;
+
+ SetSavedApplication(empty_json);
+ resumption::LastState::instance()->SaveToFileSystem();
+}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+Json::Value ResumeCtrl::GetApplicationCommands(
+ ApplicationConstSharedPtr application) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ Json::Value result;
+ DCHECK(application.get());
+ if (!application) {
+ LOG4CXX_ERROR(logger_, "NULL Pointer App");
+ return result;
+ }
+ const DataAccessor<CommandsMap> accessor = application->commands_map();
+ const CommandsMap& commands = accessor.GetData();
+ 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);
+ }
+ return result;
+}
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+Json::Value ResumeCtrl::GetApplicationSubMenus(
+ ApplicationConstSharedPtr application) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ Json::Value result;
+ DCHECK(application.get());
+ if (!application) {
+ LOG4CXX_ERROR(logger_, "NULL Pointer App");
+ return result;
+ }
+ const DataAccessor<SubMenuMap> accessor = application->sub_menu_map();
+ const SubMenuMap& sub_menus = accessor.GetData();
+ SubMenuMap::const_iterator it = sub_menus.begin();
+ for (;it != sub_menus.end(); ++it) {
+ smart_objects::SmartObject* so = it->second;
+ Json::Value curr;
+ Formatters::CFormatterJsonBase::objToJsonValue(*so, curr);
+ result.append(curr);
+ }
+ return result;
+}
+
+Json::Value ResumeCtrl::GetApplicationInteractionChoiseSets(
+ ApplicationConstSharedPtr application) {
+ DCHECK(application.get());
+ LOG4CXX_TRACE(logger_, "ENTER app_id:"
+ << application->app_id());
+
+ Json::Value result;
+ const DataAccessor<ChoiceSetMap> accessor = application->choice_set_map();
+ const ChoiceSetMap& choices = accessor.GetData();
+ 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);
+ }
+ return result;
+}
+
+Json::Value ResumeCtrl::GetApplicationGlobalProperties(
+ ApplicationConstSharedPtr application) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ Json::Value sgp;
+ DCHECK(application.get());
+ if (!application) {
+ LOG4CXX_ERROR(logger_, "NULL Pointer App");
+ return sgp;
+ }
+
+ const smart_objects::SmartObject* help_promt = application->help_prompt();
+ const smart_objects::SmartObject* timeout_prompt = application->timeout_prompt();
+ const smart_objects::SmartObject* vr_help = application->vr_help();
+ const smart_objects::SmartObject* vr_help_title = application->vr_help_title();
+ const smart_objects::SmartObject* vr_synonyms = application->vr_synonyms();
+ const smart_objects::SmartObject* keyboard_props = application->keyboard_props();
+ const smart_objects::SmartObject* menu_title = application->menu_title();
+ const smart_objects::SmartObject* menu_icon = application->menu_icon();
+
+ 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);
+ sgp[strings::keyboard_properties] = JsonFromSO(keyboard_props);
+ sgp[strings::menu_title] = JsonFromSO(menu_title);
+ sgp[strings::menu_icon] = JsonFromSO(menu_icon);
+ return sgp;
+}
+
+Json::Value ResumeCtrl::GetApplicationSubscriptions(
+ ApplicationConstSharedPtr application) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ Json::Value result;
+ DCHECK(application.get());
+ if (!application) {
+ LOG4CXX_ERROR(logger_, "NULL Pointer App");
+ return result;
+ }
+ LOG4CXX_DEBUG(logger_, "app_id:" << application->app_id());
+ LOG4CXX_DEBUG(logger_, "SubscribedButtons:" << application->SubscribedButtons().size());
+ Append(application->SubscribedButtons().begin(),
+ application->SubscribedButtons().end(),
+ strings::application_buttons, result);
+ LOG4CXX_DEBUG(logger_, "SubscribesIVI:" << application->SubscribesIVI().size());
+ Append(application->SubscribesIVI().begin(),
+ application->SubscribesIVI().end(),
+ strings::application_vehicle_info, result);
+ return result;
+}
+
+Json::Value ResumeCtrl::GetApplicationFiles(
+ ApplicationConstSharedPtr application) {
+ DCHECK(application.get());
+ LOG4CXX_TRACE(logger_, "ENTER app_id:"
+ << application->app_id());
+
+ Json::Value result;
+ const AppFilesMap& app_files = application->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;
+ file_data[strings::file_type] = file.file_type;
+ result.append(file_data);
+ }
+ }
+ return result;
+}
+
+Json::Value ResumeCtrl::GetApplicationShow(
+ ApplicationConstSharedPtr application) {
+ DCHECK(application.get());
+ LOG4CXX_TRACE(logger_, "ENTER app_id:"
+ << application->app_id());
+
+ Json::Value result;
+ const smart_objects::SmartObject* show_so = application->show_command();
+ if (!show_so) {
+ return result;
+ }
+ result = JsonFromSO(show_so);
+ 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::SmartObjectSPtr request,
+ bool use_events) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ 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::AddFiles(ApplicationSharedPtr application, const Json::Value& saved_app) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (saved_app.isMember(strings::application_files)) {
+ const Json::Value& application_files = saved_app[strings::application_files];
+ for (Json::Value::iterator json_it = application_files.begin();
+ json_it != application_files.end(); ++json_it) {
+ const Json::Value& file_data = *json_it;
+
+ const bool is_persistent = file_data.isMember(strings::persistent_file) &&
+ file_data[strings::persistent_file].asBool();
+ if (is_persistent) {
+ AppFile file;
+ file.is_persistent = is_persistent;
+ file.is_download_complete = file_data[strings::is_download_complete].asBool();
+ file.file_name = file_data[strings::sync_file_name].asString();
+ file.file_type = static_cast<mobile_apis::FileType::eType> (
+ file_data[strings::file_type].asInt());
+ application->AddFile(file);
+ }
+ }
+ } else {
+ LOG4CXX_FATAL(logger_, "application_files section is not exists");
+ }
+}
+
+void ResumeCtrl::AddSubmenues(ApplicationSharedPtr application, const Json::Value& saved_app) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (saved_app.isMember(strings::application_submenus)) {
+ const Json::Value& app_submenus = saved_app[strings::application_submenus];
+ for (Json::Value::iterator json_it = app_submenus.begin();
+ json_it != app_submenus.end(); ++json_it) {
+ const Json::Value& json_submenu = *json_it;
+ smart_objects::SmartObject message(smart_objects::SmartType::SmartType_Map);
+ Formatters::CFormatterJsonBase::jsonValueToObj(json_submenu, message);
+ application->AddSubMenu(message[strings::menu_id].asUInt(), message);
+ }
+
+ ProcessHMIRequests(MessageHelper::CreateAddSubMenuRequestToHMI(application));
+ } else {
+ LOG4CXX_FATAL(logger_, "application_submenus section is not exists");
+ }
+}
+
+void ResumeCtrl::AddCommands(ApplicationSharedPtr application, const Json::Value& saved_app) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (saved_app.isMember(strings::application_commands)) {
+ const Json::Value& app_commands = saved_app[strings::application_commands];
+ for (Json::Value::iterator json_it = app_commands.begin();
+ json_it != app_commands.end(); ++json_it) {
+ const Json::Value& json_command = *json_it;
+ smart_objects::SmartObject message(smart_objects::SmartType::SmartType_Map);
+ Formatters::CFormatterJsonBase::jsonValueToObj(json_command, message);
+ application->AddCommand(message[strings::cmd_id].asUInt(), message);
+ }
+
+ ProcessHMIRequests(MessageHelper::CreateAddCommandRequestToHMI(application));
+ } else {
+ LOG4CXX_FATAL(logger_, "application_commands section is not exists");
+ }
+}
+
+void ResumeCtrl::AddChoicesets(ApplicationSharedPtr application, const Json::Value& saved_app) {
+ if(saved_app.isMember(strings::application_choice_sets)) {
+ const Json::Value& app_choise_sets = saved_app[strings::application_choice_sets];
+ for (Json::Value::iterator json_it = app_choise_sets.begin();
+ json_it != app_choise_sets.end(); ++json_it) {
+ const Json::Value& json_choiset = *json_it;
+ smart_objects::SmartObject msg_param(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();
+ uint32_t choice_grammar_id = msg_param[strings::grammar_id].asUInt();
+ application->AddChoiceSet(choice_set_id, msg_param);
+
+ const size_t size = msg_param[strings::choice_set].length();
+ for (size_t j = 0; j < size; ++j) {
+ smart_objects::SmartObject choise_params(smart_objects::SmartType_Map);
+ choise_params[strings::app_id] = application->app_id();
+ choise_params[strings::cmd_id] =
+ msg_param[strings::choice_set][j][strings::choice_id];
+ choise_params[strings::vr_commands] = smart_objects::SmartObject(
+ smart_objects::SmartType_Array);
+ choise_params[strings::vr_commands] =
+ msg_param[strings::choice_set][j][strings::vr_commands];
+
+ choise_params[strings::type] = hmi_apis::Common_VRCommandType::Choice;
+ choise_params[strings::grammar_id] = choice_grammar_id;
+ SendHMIRequest(hmi_apis::FunctionID::VR_AddCommand, &choise_params);
+ }
+ }
+ } else {
+ LOG4CXX_FATAL(logger_, "There is no any choicesets");
+ }
+}
+
+void ResumeCtrl::SetGlobalProperties(ApplicationSharedPtr application, const Json::Value& saved_app) {
+ const Json::Value& global_properties = saved_app[strings::application_global_properties];
+ if (!global_properties.isNull()) {
+ smart_objects::SmartObject properties_so(smart_objects::SmartType::SmartType_Map);
+ Formatters::CFormatterJsonBase::jsonValueToObj(global_properties , properties_so);
+ application->load_global_properties(properties_so);
+ MessageHelper::SendGlobalPropertiesToHMI(application);
+ }
+}
+
+void ResumeCtrl::AddSubscriptions(ApplicationSharedPtr application, const Json::Value& saved_app) {
+ if (saved_app.isMember(strings::application_subscribtions)) {
+ const Json::Value& subscribtions = saved_app[strings::application_subscribtions];
+
+ if (subscribtions.isMember(strings::application_buttons)) {
+ const Json::Value& subscribtions_buttons = subscribtions[strings::application_buttons];
+ mobile_apis::ButtonName::eType btn;
+ for (Json::Value::iterator json_it = subscribtions_buttons.begin();
+ json_it != subscribtions_buttons.end(); ++json_it) {
+ btn = static_cast<mobile_apis::ButtonName::eType>((*json_it).asInt());
+ application->SubscribeToButton(btn);
+ }
+ }
+ if (subscribtions.isMember(strings::application_vehicle_info)) {
+ const Json::Value& subscribtions_ivi= subscribtions[strings::application_vehicle_info];
+ VehicleDataType ivi;
+ for (Json::Value::iterator json_it = subscribtions_ivi.begin();
+ json_it != subscribtions_ivi.end(); ++json_it) {
+ ivi = static_cast<VehicleDataType>((*json_it).asInt());
+ application->SubscribeToIVI(ivi);
+ }
+ }
+
+ ProcessHMIRequests(MessageHelper::GetIVISubscriptionRequests(application));
+ }
+}
+
+void ResumeCtrl::ProcessHMIRequests(const smart_objects::SmartObjectList& requests) {
+ for (smart_objects::SmartObjectList::const_iterator it = requests.begin(),
+ total = requests.end();
+ it != total; ++it) {
+ ProcessHMIRequest(*it, true);
+ }
+}
+
+bool ResumeCtrl::CheckIcons(ApplicationSharedPtr application,
+ const Json::Value& json_object) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ bool result = true;
+ if (!json_object.isNull()) {
+ Json::Value::const_iterator json_it = json_object.begin();
+ for (;json_it != json_object.end() && result; ++json_it) {
+ const Json::Value& json_command = *json_it;
+ if (!json_command.isNull()) {
+ smart_objects::SmartObject message(smart_objects::SmartType::SmartType_Map);
+ Formatters::CFormatterJsonBase::jsonValueToObj(json_command, message);
+ const mobile_apis::Result::eType verify_images =
+ MessageHelper::VerifyImageFiles(message, application);
+ result = (mobile_apis::Result::INVALID_DATA != verify_images);
+ } else {
+ LOG4CXX_WARN(logger_, "Invalid json object");
+ }
+ }
+ } else {
+ LOG4CXX_WARN(logger_, "Passed json object is null");
+ }
+ LOG4CXX_DEBUG(logger_, "CheckIcons result " << result);
+ return result;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+Json::Value& ResumeCtrl::GetFromSavedOrAppend(const std::string& mobile_app_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ for (Json::Value::iterator it = GetSavedApplications().begin();
+ it != GetSavedApplications().end(); ++it) {
+ if (mobile_app_id == (*it)[strings::app_id].asString()) {
+ return *it;
+ }
+ }
+
+ return GetSavedApplications().append(Json::Value());
+}
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+bool ResumeCtrl::CheckIgnCycleRestrictions(const Json::Value& json_app) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ bool result = true;
+
+ if (!CheckDelayAfterIgnOn()) {
+ LOG4CXX_INFO(logger_, "Application was connected long after ign on");
+ result = false;
+ }
+
+ if (!DisconnectedJustBeforeIgnOff(json_app)) {
+ LOG4CXX_INFO(logger_, "Application was dissconnected long before ign off");
+ result = false;
+ }
+ return result;
+}
+
+bool ResumeCtrl::DisconnectedInLastIgnCycle(const Json::Value& json_app) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ DCHECK_OR_RETURN(json_app.isMember(strings::suspend_count), false);
+ const uint32_t suspend_count = json_app[strings::suspend_count].asUInt();
+ LOG4CXX_DEBUG(logger_, " suspend_count " << suspend_count);
+ return (1 == suspend_count);
+}
+
+bool ResumeCtrl::DisconnectedJustBeforeIgnOff(const Json::Value& json_app) {
+ using namespace date_time;
+ using namespace profile;
+ LOG4CXX_AUTO_TRACE(logger_);
+ DCHECK_OR_RETURN(json_app.isMember(strings::time_stamp), false);
+
+ const time_t time_stamp =
+ static_cast<time_t>(json_app[strings::time_stamp].asUInt());
+ time_t ign_off_time = GetIgnOffTime();
+ 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 " <<
+ Profile::instance()->resumption_delay_before_ign());
+ return sec_spent_before_ign <=
+ Profile::instance()->resumption_delay_before_ign();
+}
+
+bool ResumeCtrl::CheckDelayAfterIgnOn() {
+ using namespace date_time;
+ using namespace profile;
+ LOG4CXX_AUTO_TRACE(logger_);
+ time_t curr_time = time(NULL);
+ time_t sdl_launch_time = launch_time();
+ const uint32_t seconds_from_sdl_start = labs(curr_time - sdl_launch_time);
+ const uint32_t wait_time =
+ Profile::instance()->resumption_delay_after_ign();
+ LOG4CXX_DEBUG(logger_, "curr_time " << curr_time
+ << "; sdl_launch_time " << sdl_launch_time
+ << "; seconds_from_sdl_start " << seconds_from_sdl_start
+ << "; wait_time " << wait_time);
+ return seconds_from_sdl_start <= wait_time;
+}
+
+bool ResumeCtrl::CheckAppRestrictions(ApplicationSharedPtr application,
+ const Json::Value& json_app) {
+ using namespace mobile_apis;
+ LOG4CXX_AUTO_TRACE(logger_);
+ DCHECK_OR_RETURN(json_app.isMember(strings::hmi_level), false);
+
+ const bool is_media_app = application->is_media_application();
+ const HMILevel::eType hmi_level =
+ static_cast<HMILevel::eType>(json_app[strings::hmi_level].asInt());
+ LOG4CXX_DEBUG(logger_, "is_media_app " << is_media_app
+ << "; hmi_level " << hmi_level);
+
+ if (is_media_app) {
+ if (hmi_level == HMILevel::HMI_FULL ||
+ hmi_level == HMILevel::HMI_LIMITED) {
+ return true;
+ }
+ }
+ return false;
+}
+
+int ResumeCtrl::GetObjectIndex(const std::string& mobile_app_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ sync_primitives::AutoLock lock(resumtion_lock_);
+ const Json::Value& apps = GetSavedApplications();
+ const Json::ArrayIndex size = apps.size();
+ Json::ArrayIndex idx = 0;
+ for (; idx != size; ++idx) {
+ const std::string& saved_app_id = apps[idx][strings::app_id].asString();
+ if (mobile_app_id == saved_app_id) {
+ LOG4CXX_DEBUG(logger_, "Found " << idx);
+ return idx;
+ }
+ }
+ return -1;
+}
+time_t ResumeCtrl::launch_time() const {
+ return launch_time_;
+}
+
+void ResumeCtrl::ResetLaunchTime() {
+ launch_time_ = time(NULL);
+}
+
+void ResumeCtrl::ApplicationResumptiOnTimer() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock auto_lock(queue_lock_);
+ std::vector<uint32_t>::iterator it = waiting_for_timer_.begin();
+
+ for (; it != waiting_for_timer_.end(); ++it) {
+ ApplicationSharedPtr app =
+ ApplicationManagerImpl::instance()->application(*it);
+ if (!app.get()) {
+ LOG4CXX_ERROR(logger_, "Invalid app_id = " << *it);
+ continue;
+ }
+
+ StartAppHmiStateResumption(app);
+ }
+
+ waiting_for_timer_.clear();
+}
+
+void ResumeCtrl::LoadResumeData() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ sync_primitives::AutoLock lock(resumtion_lock_);
+
+ Json::Value& resume_app_list = GetSavedApplications();
+ Json::Value::iterator full_app = resume_app_list.end();
+ time_t time_stamp_full = 0;
+ Json::Value::iterator limited_app = resume_app_list.end();
+ time_t time_stamp_limited = 0;
+
+ Json::Value::iterator it = resume_app_list.begin();
+ for (; it != resume_app_list.end(); ++it) {
+ if ((*it).isMember(strings::ign_off_count) &&
+ (*it).isMember(strings::hmi_level)) {
+
+ // only apps with first IGN should be resumed
+ const int32_t first_ign = 1;
+ if (first_ign == (*it)[strings::ign_off_count].asInt()) {
+
+ const mobile_apis::HMILevel::eType saved_hmi_level =
+ static_cast<mobile_apis::HMILevel::eType>((*it)[strings::hmi_level].asInt());
+
+ const time_t saved_time_stamp =
+ static_cast<time_t>((*it)[strings::time_stamp].asUInt());
+
+ if (mobile_apis::HMILevel::HMI_FULL == saved_hmi_level) {
+ if (time_stamp_full < saved_time_stamp) {
+ time_stamp_full = saved_time_stamp;
+ full_app = it;
+ }
+ }
+
+ if (mobile_apis::HMILevel::HMI_LIMITED == saved_hmi_level) {
+ if (time_stamp_limited < saved_time_stamp) {
+ time_stamp_limited = saved_time_stamp;
+ limited_app = it;
+ }
+ }
+ }
+
+ // set invalid HMI level for all
+ (*it)[strings::hmi_level] =
+ static_cast<int32_t>(mobile_apis::HMILevel::INVALID_ENUM);
+ }
+ }
+
+ if (full_app != resume_app_list.end()) {
+ (*full_app)[strings::hmi_level] =
+ static_cast<int32_t>(mobile_apis::HMILevel::HMI_FULL);
+ }
+
+ if (limited_app != resume_app_list.end()) {
+ (*limited_app)[strings::hmi_level] =
+ static_cast<int32_t>(mobile_apis::HMILevel::HMI_LIMITED);
+ }
+ LOG4CXX_DEBUG(logger_, GetResumptionData().toStyledString());
+}
+
+void ResumeCtrl::SendHMIRequest(
+ const hmi_apis::FunctionID::eType& function_id,
+ const smart_objects::SmartObject* msg_params, bool use_events) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ smart_objects::SmartObjectSPtr 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");
+ }
+}
+
+} // namespce resumption
+
+} // namespace application_manager
diff --git a/src/components/application_manager/src/resumption/resumption_data.cc b/src/components/application_manager/src/resumption/resumption_data.cc
new file mode 100644
index 0000000000..d4b0d92803
--- /dev/null
+++ b/src/components/application_manager/src/resumption/resumption_data.cc
@@ -0,0 +1,320 @@
+/*
+ * Copyright (c) 2015, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "application_manager/resumption/resumption_data.h"
+#include "utils/logger.h"
+
+namespace application_manager {
+namespace resumption {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "ResumptionData")
+
+smart_objects::SmartObject ResumptionData::GetApplicationCommands(
+ ApplicationConstSharedPtr application) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ DCHECK(application.get());
+ smart_objects::SmartObject commands_array = smart_objects::SmartObject(
+ smart_objects::SmartType_Array);
+ if (!application) {
+ LOG4CXX_ERROR(logger_, "NULL Pointer App");
+ return commands_array;
+ }
+ const DataAccessor<CommandsMap> accessor = application->commands_map();
+ const CommandsMap& commands = accessor.GetData();
+ CommandsMap::const_iterator it = commands.begin();
+ for (int i = 0; it != commands.end(); ++it, ++i) {
+ commands_array[i] = *(it->second);
+ }
+ return commands_array;
+}
+
+smart_objects::SmartObject ResumptionData::GetApplicationSubMenus(
+ ApplicationConstSharedPtr application) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ DCHECK(application.get());
+ smart_objects::SmartObject submenues_array = smart_objects::SmartObject(
+ smart_objects::SmartType_Array);
+
+ if (!application) {
+ LOG4CXX_ERROR(logger_, "NULL Pointer App");
+ return submenues_array;
+ }
+ const DataAccessor<SubMenuMap> accessor = application->sub_menu_map();
+ const SubMenuMap& sub_menus = accessor.GetData();
+ SubMenuMap::const_iterator it = sub_menus.begin();
+ for (int i = 0;it != sub_menus.end(); ++it, ++i) {
+ submenues_array[i] = *(it->second);
+ }
+ return submenues_array;
+}
+
+smart_objects::SmartObject ResumptionData::GetApplicationInteractionChoiseSets(
+ ApplicationConstSharedPtr application) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ DCHECK(application.get());
+ smart_objects::SmartObject interaction_choice_set_array =
+ smart_objects::SmartObject(smart_objects::SmartType_Array);
+ if (!application) {
+ LOG4CXX_ERROR(logger_, "NULL Pointer App");
+ return interaction_choice_set_array;
+ }
+ const DataAccessor<ChoiceSetMap> accessor = application->choice_set_map();
+ const ChoiceSetMap& choices = accessor.GetData();
+ ChoiceSetMap::const_iterator it = choices.begin();
+ for (int i = 0; it != choices.end(); ++it, ++i) {
+ interaction_choice_set_array[i] = *(it->second);
+ }
+ return interaction_choice_set_array;
+}
+
+smart_objects::SmartObject ResumptionData::GetApplicationGlobalProperties(
+ ApplicationConstSharedPtr application) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ DCHECK(application.get());
+ smart_objects::SmartObject global_properties =
+ smart_objects::SmartObject(smart_objects::SmartType_Map);
+ if (!application) {
+ LOG4CXX_ERROR(logger_, "NULL Pointer App");
+ return global_properties;
+ }
+
+ global_properties[strings::help_prompt] =
+ PointerToSmartObj(application->help_prompt());
+ global_properties[strings::timeout_prompt] =
+ PointerToSmartObj(application->timeout_prompt());
+ global_properties[strings::vr_help] =
+ PointerToSmartObj(application->vr_help());
+ global_properties[strings::vr_help_title] =
+ PointerToSmartObj(application->vr_help_title());
+ global_properties[strings::vr_synonyms] =
+ PointerToSmartObj(application->vr_synonyms());
+ global_properties[strings::keyboard_properties] =
+ PointerToSmartObj(application->keyboard_props());
+ global_properties[strings::menu_title] =
+ PointerToSmartObj(application->menu_title());
+ global_properties[strings::menu_icon] =
+ PointerToSmartObj(application->menu_icon());
+ return global_properties;
+}
+
+smart_objects::SmartObject ResumptionData::GetApplicationSubscriptions(
+ ApplicationConstSharedPtr application) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ DCHECK(application.get());
+ smart_objects::SmartObject subscriptions =
+ smart_objects::SmartObject(smart_objects::SmartType_Map);
+ if (!application) {
+ LOG4CXX_ERROR(logger_, "NULL Pointer App");
+ return subscriptions;
+ }
+ LOG4CXX_DEBUG(logger_, "app_id:" << application->app_id());
+ LOG4CXX_DEBUG(logger_, "SubscribedButtons:"
+ << application->SubscribedButtons().size());
+ Append(application->SubscribedButtons().begin(),
+ application->SubscribedButtons().end(),
+ strings::application_buttons, subscriptions);
+ LOG4CXX_DEBUG(logger_, "SubscribesIVI:"
+ << application->SubscribesIVI().size());
+ Append(application->SubscribesIVI().begin(),
+ application->SubscribesIVI().end(),
+ strings::application_vehicle_info, subscriptions);
+ return subscriptions;
+}
+
+smart_objects::SmartObject ResumptionData::GetApplicationFiles(
+ ApplicationConstSharedPtr application) {
+ DCHECK(application.get());
+ LOG4CXX_TRACE(logger_, "ENTER app_id:"
+ << application->app_id());
+
+ smart_objects::SmartObject files =
+ smart_objects::SmartObject(smart_objects::SmartType_Array);
+ if (!application) {
+ LOG4CXX_ERROR(logger_, "NULL Pointer App");
+ return files;
+ }
+
+ const AppFilesMap& app_files = application->getAppFiles();
+ int i = 0;
+ for(AppFilesMap::const_iterator file_it = app_files.begin();
+ file_it != app_files.end(); file_it++, ++i) {
+ const AppFile& file = file_it->second;
+ if (file.is_persistent) {
+ smart_objects::SmartObject file_data =
+ smart_objects::SmartObject(smart_objects::SmartType_Map);
+ 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;
+ file_data[strings::file_type] = file.file_type;
+ files[i] = file_data;
+ }
+ }
+ return files;
+}
+
+void ResumptionData::AddFiles(ApplicationSharedPtr application,
+ const smart_objects::SmartObject& saved_app) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ if (saved_app.keyExists(strings::application_files)) {
+ const smart_objects::SmartObject& application_files =
+ saved_app[strings::application_files];
+ for (int i = 0; i < application_files.length(); ++i) {
+ const smart_objects::SmartObject& file_data =
+ appliction_files[i];
+ const bool is_persistent = file_data.keyExists(strings::persistent_file) &&
+ file_data[strings::persistent_file].asBool();
+ if (is_persistent) {
+ AppFile file;
+ file.is_persistent = is_persistent;
+ file.is_download_complete =
+ file_data[strings::is_download_complete].asBool();
+ file.file_name = file_data[strings::sync_file_name].asString();
+ file.file_type = static_cast<mobile_apis::FileType::eType> (
+ file_data[strings::file_type].asInt());
+ application->AddFile(file);
+ }
+ }
+ } else {
+ LOG4CXX_FATAL(logger_, "application_files section is not exists");
+ }
+}
+
+void ResumptionData::AddSubmenues(ApplicationSharedPtr application,
+ const smart_objects::SmartObject& saved_app) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ if (saved_app.keyExists(strings::application_submenus)) {
+ const smart_objects::SmartObject& app_submenus =
+ saved_app[strings::application_submenus];
+ for (int i = 0; i < app_submenus.length(); ++i) {
+ const smart_objects::SmartObject& submenu = app_submenues[i];
+ application->AddSubMenu(submenu[strings::menu_id].asUInt(), submenu);
+ }
+ } else {
+ LOG4CXX_FATAL(logger_, "application_submenus section is not exists");
+ }
+}
+
+void ResumptionData::AddCommands(ApplicationSharedPtr application,
+ const smart_objects::SmartObject& saved_app) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ if (saved_app.keyExists(strings::application_commands)) {
+ const smart_objects::SmartObject& app_commands =
+ saved_app[strings::application_commands];
+ for (int i = 0; i < app_commands.length(); ++i) {
+ const smart_objects::SmartObject& command =
+ app_commands[i];
+ application->AddCommand(command[strings::cmd_id].asUInt(), command);
+ }
+ } else {
+ LOG4CXX_FATAL(logger_, "application_commands section is not exists");
+ }
+}
+
+void ResumptionData::AddChoicesets(ApplicationSharedPtr application,
+ const smart_objects::SmartObject& saved_app) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ if (saved_app.keyExists(strings::application_choice_sets)) {
+ const smart_objects::SmartObject& app_choice_sets =
+ saved_app[strings::application_choice_sets];
+ for (int i = 0; i < app_choice_sets.length(); ++i) {
+ const smart_objects::SmartObject& choice_set =
+ app_choice_sets[i];
+ const int32_t choice_set_id =
+ choice_set[strings::interaction_choice_set_id].asInt();
+ application->AddChoiceSet(choice_set_id, choice_set);
+ }
+ } else {
+ LOG4CXX_FATAL(logger_, "There is no any choicesets");
+ }
+}
+
+void ResumptionData::SetGlobalProperties(ApplicationSharedPtr application,
+ const smart_objects::SmartObject& saved_app) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ if (saved_app.keyExists(strings::application_global_properties)) {
+ const smart_objects::SmartObject& properties_so =
+ saved_app[strings::application_global_properties];
+ application->load_global_properties(properties_so);
+ }
+}
+
+void ResumptionData::AddSubscriptions(ApplicationSharedPtr application,
+ const smart_objects::SmartObject& saved_app) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (saved_app.keyExists(strings::application_subscribtions)) {
+ const smart_objects::SmartObject& subscribtions =
+ saved_app[strings::application_subscribtions];
+
+ if (subscribtions.keyExists(strings::application_buttons)) {
+ const smart_objects::SmartObject& subscribtions_buttons =
+ subscribtions[strings::application_buttons];
+ mobile_apis::ButtonName::eType btn;
+ for (int i = 0; i < subscribtions_buttons.length(); ++i) {
+ btn = static_cast<mobile_apis::ButtonName::eType>(
+ (subscribtions_buttons[i]).asInt());
+ application->SubscribeToButton(btn);
+ }
+ }
+
+ if (subscribtions.keyExists(strings::application_vehicle_info)) {
+ const smart_objects::SmartObject& subscribtions_ivi =
+ subscribtions[strings::application_vehicle_info];
+ VehicleDataType ivi;
+ for (int i = 0; i < subscribtions_ivi.length(); ++i) {
+ ivi = static_cast<VehicleDataType>((subscribtions_ivi[i]).asInt());
+ application->SubscribeToIVI(ivi);
+ }
+ }
+ }
+}
+
+smart_objects::SmartObject ResumptionData::PointerToSmartObj(
+ smart_objects::SmartObject* ptr) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ smart_objects::SmartObject temp;
+ if (ptr) {
+ temp = *ptr;
+ }
+ return temp;
+}
+
+} // namespace resumption
+} // namespace application_manager
diff --git a/src/components/application_manager/src/resumption/resumption_data_db.cc b/src/components/application_manager/src/resumption/resumption_data_db.cc
new file mode 100644
index 0000000000..891d51a3e7
--- /dev/null
+++ b/src/components/application_manager/src/resumption/resumption_data_db.cc
@@ -0,0 +1,345 @@
+/*
+ * Copyright (c) 2015, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "application_manager/resumption/resumption_data_db.h"
+#include "application_manager/resumption/resumption_sql_queries.h"
+#if __QNX__
+# include "qdb_wrapper/sql_database.h"
+# include "qdb_wrapper/sql_query.h"
+#else // __QNX__
+# include "sqlite_wrapper/sql_database.h"
+# include "sqlite_wrapper/sql_query.h"
+#endif // __QNX__
+
+namespace application_manager {
+namespace resumption {
+CREATE_LOGGERPTR_GLOBAL(logger_, "ResumptionDataDB")
+
+int ResumptionDataDB::GetStoredHMILevel(const std::string& m_app_id,
+ const std::string& device_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ int hmi_level;
+ if (SelectHMILevel(m_app_id, device_id, hmi_level)) {
+ LOG4CXX_INFO(logger_, "Application with mobile application id = "<<m_app_id
+ <<" and device id = "<<device_id<<"has hmi level = "<<hmi_level);
+ return hmi_level;
+ }
+ LOG4CXX_FATAL(logger_, "HMI level doesn't exists in saved data");
+ return -1;
+}
+
+bool ResumptionDataDB::IsHMIApplicationIdExist(uint32_t hmi_app_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ return CheckExistenceHMIId(hmi_app_id);
+}
+
+bool ResumptionDataDB::CheckSavedApplication(const std::string& mobile_app_id,
+ const std::string& device_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ if (!CheckExistenceApplication(mobile_app_id, device_id)) {
+ LOG4CXX_INFO(logger_, "Application with mobile_app_id = "<<mobile_app_id
+ <<" and device_id = "<<device_id<<" does not exist");
+ return false;
+ }
+ return true;
+}
+
+uint32_t ResumptionDataDB::GetHMIApplicationID(const std::string& mobile_app_id,
+ const std::string& device_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ uint32_t hmi_app_id = 0;
+ SelectHMIId(mobile_app_id, device_id, hmi_app_id);
+ return hmi_app_id;
+}
+
+void ResumptionDataDB::Suspend() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ utils::dbms::SQLQuery query_delete_applications(db());
+ utils::dbms::SQLQuery query_update_suspend_data(db());
+ utils::dbms::SQLQuery query_update_last_ign_off_time(db());
+
+ if (query_delete_applications.Prepare(kDeleteApplicationsAccordingWithIgnOffCount)) {
+ query_delete_applications.Bind(0, static_cast<int>(kApplicationLifes));
+ if (query_delete_applications.Exec()) {
+ LOG4CXX_INFO(logger_, "Saved application with ign_off_count = "<<kApplicationLifes
+ <<" was deleted");
+ }
+ }
+
+ if (query_update_suspend_data.Prepare(kUpdateSuspendData)) {
+ if (query_update_suspend_data.Exec()) {
+ LOG4CXX_INFO(logger_, "Data ign_off_count and suspend_count was updated");
+ }
+ }
+
+ if (query_update_last_ign_off_time.Prepare(KUpdateLastIgnOffTime)) {
+ query_update_lals_ign_off_time.Bind(0, static_cast<uint32_t>(time(NULL)));
+ if (query_update_last_ign_off_time.Exec()) {
+ LOG4CXX_INFO(logger_, "Data last_ign_off_time was updated");
+ }
+ }
+}
+
+
+bool ResumptionDataDB::GetHashId(const std::string& mobile_app_id,
+ const std::string& device_id,
+ std::string& hash_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ return SelectHashId(mobile_app_id, device_id, hash_id);
+}
+
+void ResumptionDataDB::OnAwake() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ UpdateDataOnAwake();
+}
+
+bool ResumptionDataDB::RemoveApplicationFromSaved(
+ const std::string& mobile_app_id, const std::string& device_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ return DeleteSavedApplication(mobile_app_id, device_id);
+}
+
+uint32_t ResumptionDataDB::GetIgnOffTime() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ return SelectIgnOffTime();
+}
+
+int ResumptionDataDB::IsApplicationSaved(const std::string& mobile_app_id,
+ const std::string& device_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ if (CheckExistenceApplication(mobile_app_id, device_id)) {
+ return 0;
+ }
+ return -1;
+}
+
+void ResumptionDataDB::GetDataForLoadResumeData(smart_objects::SmartObject& saved_data) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ SelectDataForLoadResumeData(saved_data);
+}
+
+void ResumptionDataDB::SetHMILevelForSavedApplication(const std::string& mobile_app_id,
+ const std::string& device_id, int32_t hmi_level) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ UpdateHmiLevel(mobile_app_id, device_id, hmi_level);
+}
+
+bool ResumptionDataDB::SelectHMILevel(const std::string& m_app_id,
+ const std::string& device_id,
+ int& hmi_level) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ utils::dbms::SQLQuery query(db());
+ if (query.Prepare(kSelectHMILevel)) {
+ query.Bind(0, device_id);
+ query.Bind(1, m_app_id);
+ if (query.Exec() && !(query.IsNull(0))) {
+ hmi_level = query.GetInteger(0);
+ return true;
+ }
+ }
+ return false;
+}
+
+bool ResumptionDataDB::CheckExistenceHMIId(const uint32_t hmi_app_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ utils::dbms::SQLQuery query(db());
+ if (query.Prepare(kCheckHMIId)) {
+ query.Bind(0, hmi_app_id);
+ if (query.Exec() && !(query.IsNull(0))) {
+ LOG4CXX_INFO(logger_, "Saved data has HMI appID");
+ return true;
+ }
+ }
+ LOG4CXX_FATAL(logger_, "HMI appID = " <<hmi_app_id
+ <<" doesn't exist in saved data");
+ return false;
+}
+
+void ResumptionDataDB::SelectHMIId(const std::string& mobile_app_id,
+ const std::string& device_id,
+ uint32_t& hmi_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ utils::dbms::SQLQuery query(db());
+ if (query.Prepare(kSelectHMIId)) {
+ query.Bind(0, device_id);
+ query.Bind(1, mobile_app_id);
+ if (query.Exec() && !(query.IsNull(0))) {
+ hmi_id = query.GetInteger(0);
+ LOG4CXX_INFO(logger_, "Saved HMI appID = "<<hmi_id);
+ }
+ }
+ LOG4CXX_FATAL(logger_, "Saved data doesn't have application with "
+ "device id = "<<device_id<<" and mobile appID = "<<mobi_app_id
+ "or hmi id"<<);
+}
+
+bool ResumptionDataDB::SelectHashId(const std::string& mobile_app_id,
+ const std::string& device_id,
+ std::string& hash_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ utils::dbms::SQLQuery query(db());
+ if (query.Prepare(kSelectHashId)) {
+ query.Bind(0, device_id);
+ query.Bind(1, mobile_app_id);
+ if (query.Exec() && !(query.IsNull(0))) {
+ hash_id = query.GetString(0);
+ LOG4CXX_INFO(logger_, "Saved hash ID = "<<hash_id);
+ return true;
+ }
+ }
+ LOG4CXX_FATAL(logger_, "Saved data doesn't have application with "
+ "device id = "<<device_id<<" and mobile appID = "<<mobi_app_id
+ "or hashID");
+ return false;
+}
+
+uint32_t ResumptionDataDB::SelectIgnOffTime() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ uint32_t ignOffTime = 0;
+ utils::dbms::SQLQuery query(db());
+ if (query.Prepare(kSelectIgnOffTime)) {
+ if (query.Exec()) {
+ ignOffTime = query.GetUInteger(0);
+ LOG4CXX_INFO(logger_, "Last ign off time = "<<ignOffTime);
+ }
+ }
+ LOG4CXX_FATAL(logger_, "Problem with prepare query");
+}
+
+bool ResumptionDataDB::CheckExistenceApplication(const std::string& mobile_app_id,
+ const std::string& device_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ utils::dbms::SQLQuery query(db());
+ if (query.Prepare(kCheckApplication)) {
+ query.Bind(0, device_id);
+ query.Bind(1, mobile_app_id);
+ if (query.Exec() && !(query.IsNull(0)) && query.GetInteger(0)) {
+ LOG4CXX_INFO(logger_, "Saved data has application with mobile appID = "
+ <<mobile_app_id<<" and deviceID = "<<device_id);
+ return true;
+ }
+ }
+ LOG4CXX_FATAL(logger_, "Saved data does not contain application");
+ return false;
+}
+
+void ResumptionDataDB::SelectDataForLoadResumeData(
+ smart_objects::SmartObject& saved_data) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ utils::dbms::SQLQuery query(db());
+ if (query.Prepare(kSelectDataForLoadResumeData)) {
+ smart_objects::SmartObject so_array_data(smart_objects::SmartType_Array);
+ int i = 0;
+ while(query.Next()) {
+ smart_objects::SmartObject so_obj(smart_objects::SmartType_Map);
+ so_obj[strings::hmi_level] = query.GetInteger(0);
+ so_obj[strings::ign_off_count] = query.GetInteger(1);
+ so_obj[strings::time_stamp] = query.GetUInteger(2);
+ so_obj[strings::app_id] = query.GetString(3);
+ so_obj[strings::device_id] = query.GetString(4);
+ so_array_data[i++] = so_obj;
+ }
+ saved_data = so_array_data;
+ }
+}
+
+void ResumptionDataDB::UpdateHmiLevel(const std::string& mobile_app_id,
+ const std::string& device_id,
+ int32_t hmi_level) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ utils::dbms::SQLQuery query(db());
+ if (query.Prepare(kUpdateHMILevel)) {
+ query.Bind(0, hmi_level);
+ query.Bind(1, device_id);
+ query.Bind(2, mobile_app_id);
+ if (query.Exec()) {
+ LOG4CXX_INFO(logger_, "Saved data has application with mobile appID = "
+ <<mobile_app_id<<" and deviceID = "<<device_id
+ <<" has new HMI level = "<<hmi_level);
+
+ }
+ }
+}
+
+bool ResumptionDataDB::DeleteSavedApplication(const std::string& mobile_app_id,
+ const std::string& device_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ utils::dbms::SQLQuery query(db());
+ if (query.Prepare(kDeleteApplication)) {
+ query.Bind(0, device_id);
+ query.Bind(1, mobile_app_id);
+ if (query.Exec()) {
+ LOG4CXX_INFO(logger_, "Data of application with mobile appID = "
+ <<mobile_app_id<<" and deviceID = "<<device_id
+ <<" was removed successfully");
+ return true;
+ }
+ }
+ LOG4CXX_INFO(logger_, "Data of application with mobile appID = "
+ <<mobile_app_id<<" and deviceID = "<<device_id
+ <<" was not removed");
+ return false;
+}
+
+void ResumptionDataDB::UpdateDataOnAwake() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ utils::dbms::SQLQuery query(db());
+ if (query.Prepare(kUpdateIgnOffCount)) {
+ if (query.Exec()) {
+ LOG4CXX_INFO(logger_, "Values of ignition off counts were updated successfully");
+ }
+ }
+}
+
+
+
+} // namespace resumption
+} // namespace application_manager
diff --git a/src/components/application_manager/src/resumption/resumption_data_json.cc b/src/components/application_manager/src/resumption/resumption_data_json.cc
new file mode 100644
index 0000000000..8cf8e7d0d9
--- /dev/null
+++ b/src/components/application_manager/src/resumption/resumption_data_json.cc
@@ -0,0 +1,475 @@
+/*
+ * Copyright (c) 2015, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "application_manager/resumption/resumption_data_json.h"
+#include "smart_objects/smart_object.h"
+#include "json/json.h"
+namespace application_manager {
+namespace resumption {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "ResumptionDataJson")
+
+void ResumptionDataJson::SaveApplication(ApplicationConstSharedPtr application) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ DCHECK(application.get());
+
+ if (!application) {
+ LOG4CXX_FATAL(logger_, "Application object is NULL.");
+ return;
+ }
+
+ const std::string& m_app_id = application->mobile_app_id();
+ LOG4CXX_TRACE(logger_, "ENTER app_id : " << application->app_id()
+ << " mobile app_id : " << m_app_id);
+
+ // let's make a copy not to depend on application
+ const std::string hash = application->curHash();
+ const uint32_t grammar_id = application->get_grammar_id();
+ const uint32_t time_stamp = (uint32_t)time(NULL);
+ const std::string device_id =
+ MessageHelper::GetDeviceMacAddressForHandle(application->device());
+
+ const mobile_apis::HMILevel::eType hmi_level = application->hmi_level();
+
+ Json::Value tmp;
+
+ Json::Value& json_app = GetFromSavedOrAppend(m_app_id, device_id);
+
+ json_app[strings::device_id] = device_id;
+
+ json_app[strings::app_id] = m_app_id;
+ json_app[strings::grammar_id] = grammar_id;
+ json_app[strings::connection_key] = application->app_id();
+ json_app[strings::hmi_app_id] = application->hmi_app_id();
+ json_app[strings::is_media_application] = application->IsAudioApplication();
+ json_app[strings::hmi_level] = static_cast<int32_t> (hmi_level);
+ json_app[strings::ign_off_count] = 0;
+ json_app[strings::suspend_count] = 0;
+ json_app[strings::hash_id] = hash;
+ Formatters::CFormatterJsonBase::objToJsonValue(
+ GetApplicationCommands(application), tmp);
+ json_app[strings::application_commands] = tmp;
+ Formatters::CFormatterJsonBase::objToJsonValue(
+ GetApplicationSubMenus(application), tmp);
+ json_app[strings::application_submenus] = tmp;
+ Formatters::CFormatterJsonBase::objToJsonValue(
+ GetApplicationInteractionChoiseSets(application), tmp);
+ json_app[strings::application_choice_sets] = tmp;
+ Formatters::CFormatterJsonBase::objToJsonValue(
+ GetApplicationGlobalProperties(application), tmp);
+ json_app[strings::application_global_properties] = tmp;
+ Formatters::CFormatterJsonBase::objToJsonValue(
+ GetApplicationSubscriptions(application), tmp);
+ json_app[strings::application_subscribtions] = tmp;
+ Formatters::CFormatterJsonBase::objToJsonValue(
+ GetApplicationFiles(application), tmp);
+ json_app[strings::application_files] = tmp;
+ json_app[strings::time_stamp] = time_stamp;
+ LOG4CXX_DEBUG(logger_, "SaveApplication : " << json_app.toStyledString());
+}
+
+int ResumptionDataJson::GetStoredHMILevel(const std::string& m_app_id,
+ const std::string& device_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ int idx = GetObjectIndex(m_app_id, device_id);
+ if (idx != -1) {
+ const Json::Value& json_app = GetSavedApplications()[idx];
+ if (json_app.isMember(strings::hmi_level)) {
+ return json_app[strings::hmi_level].asInt();
+ }
+ }
+ LOG4CXX_FATAL(logger_, "There are some unknown keys among the stored apps");
+ return -1;
+}
+
+bool ResumptionDataJson::RestoreApplicationData(
+ ApplicationSharedPtr application) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ if (!application.valid()) {
+ LOG4CXX_ERROR(logger_, "Application pointer in invalid");
+ return false;
+ }
+
+ LOG4CXX_DEBUG(logger_, "ENTER app_id : " << application->app_id());
+ smart_objects::SmartObject saved_app(smart_objects::SmartType_Map);
+ bool result = GetSavedApplication(application->mobile_app_id(),
+ MessageHelper::GetDeviceMacAddressForHandle(application->device()),
+ saved_app);
+ if (result) {
+ if(saved_app.keyExists(strings::grammar_id)) {
+ const uint32_t app_grammar_id = saved_app[strings::grammar_id].asUInt();
+ application->set_grammar_id(app_grammar_id);
+
+ AddFiles(application, so_saved_app);
+ AddSubmenues(application, so_saved_app);
+ AddCommands(application, so_saved_app);
+ AddChoicesets(application, so_saved_app);
+ SetGlobalProperties(application, so_saved_app);
+ AddSubscriptions(application, so_saved_app);
+ return true;
+ } else {
+ LOG4CXX_WARN(logger_, "Saved data of application does not contain grammar_id");
+ return false;
+ }
+ }
+ LOG4CXX_WARN(logger_, "Application not saved");
+ return false;
+}
+
+bool ResumptionDataJson::IsHMIApplicationIdExist(uint32_t hmi_app_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ for (Json::Value::iterator it = GetSavedApplications().begin();
+ it != GetSavedApplications().end(); ++it) {
+ if ((*it).isMember(strings::hmi_app_id)) {
+ if ((*it)[strings::hmi_app_id].asUInt() == hmi_app_id) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool ResumptionDataJson::CheckSavedApplication(const std::string& mobile_app_id,
+ const std::string& device_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ int index = IsApplicationSaved(mobile_app_id, device_id);
+ if (-1 == index) {
+ return false;
+ }
+
+ if (!IsResumptionDataValid(index)) {
+ LOG4CXX_INFO(logger_, "Resumption data for app_id " << mobile_app_id <<
+ " device id " << device_id <<
+ " is corrupted. Remove application from resumption list");
+ RemoveApplicationFromSaved(mobile_app_id, device_id);
+ return false;
+ }
+ return true;
+}
+
+uint32_t ResumptionDataJson::GetHMIApplicationID(
+ const std::string& mobile_app_id, const std::string& device_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ uint32_t hmi_app_id = 0;
+
+ const int idx = GetObjectIndex(mobile_app_id, device_id);
+ if (-1 == idx) {
+ LOG4CXX_WARN(logger_, "Application not saved");
+ return hmi_app_id;
+ }
+
+ const Json::Value& json_app = GetSavedApplications()[idx];
+ if (json_app.isMember(strings::app_id) &&
+ json_app.isMember(strings::device_id)) {
+ hmi_app_id = json_app[strings::hmi_app_id].asUInt();
+ }
+ LOG4CXX_DEBUG(logger_, "hmi_app_id :" << hmi_app_id);
+ return hmi_app_id;
+}
+
+void ResumptionDataJson::Suspend() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ Json::Value to_save;
+ for (Json::Value::iterator it = GetSavedApplications().begin();
+ it != GetSavedApplications().end(); ++it) {
+ if ((*it).isMember(strings::suspend_count)) {
+ const uint32_t suspend_count = (*it)[strings::suspend_count].asUInt();
+ (*it)[strings::suspend_count] = suspend_count + 1;
+ } else {
+ LOG4CXX_WARN(logger_, "Unknown key among saved applications");
+ (*it)[strings::suspend_count] = 1;
+ }
+ if ((*it).isMember(strings::ign_off_count)) {
+ const uint32_t ign_off_count = (*it)[strings::ign_off_count].asUInt();
+ if (ign_off_count < kApplicationLifes) {
+ (*it)[strings::ign_off_count] = ign_off_count + 1;
+ to_save.append(*it);
+ }
+ } else {
+ LOG4CXX_WARN(logger_, "Unknown key among saved applications");
+ (*it)[strings::ign_off_count] = 1;
+ }
+ }
+ SetSavedApplication(to_save);
+ SetLastIgnOffTime(time(NULL));
+ LOG4CXX_DEBUG(logger_,
+ GetResumptionData().toStyledString());
+ resumption::LastState::instance()->SaveToFileSystem();
+}
+
+void ResumptionDataJson::OnAwake() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ for (Json::Value::iterator it = GetSavedApplications().begin();
+ it != GetSavedApplications().end(); ++it) {
+ if ((*it).isMember(strings::ign_off_count)) {
+ const uint32_t ign_off_count = (*it)[strings::ign_off_count].asUInt();
+ (*it)[strings::ign_off_count] = ign_off_count - 1;
+ } else {
+ LOG4CXX_WARN(logger_, "Unknown key among saved applications");
+ (*it)[strings::ign_off_count] = 0;
+ }
+ }
+}
+
+bool ResumptionDataJson::GetHashId(const std::string& mobile_app_id,
+ const std::string& device_id,
+ std::string& hash_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ const int idx = GetObjectIndex(mobile_app_id, device_id);
+ if (-1 == idx) {
+ LOG4CXX_WARN(logger_, "Application not saved");
+ return false;
+ }
+
+ const Json::Value& json_app = GetSavedApplications()[idx];
+ LOG4CXX_DEBUG(logger_, "Saved_application_data: " << json_app.toStyledString());
+ if (json_app.isMember(strings::hash_id) && json_app.isMember(strings::time_stamp)) {
+ hash_id = json_app[strings::hash_id].asString();
+ return true;
+ }
+ LOG4CXX_WARN(logger_, "There are some unknown keys in the dictionary.");
+ return false;
+}
+
+bool ResumptionDataJson::GetSavedApplication(const std::string& mobile_app_id,
+ const std::string& device_id,
+ smart_objects::SmartObject& saved_app) {
+ const int idx = GetObjectIndex(mobile_app_id, device_id);
+ if (-1 == idx) {
+ return false;
+ }
+ const Json::Value& json_saved_app = GetSavedApplications()[idx];
+ Formatters::CFormatterJsonBase::jsonValueToObj(json_saved_app, saved_app);
+ return true;
+}
+
+bool ResumptionDataJson::RemoveApplicationFromSaved(const std::string& mobile_app_id,
+ const std::string& device_id) {
+ LOG4CXX_TRACE(logger_, "Remove mobile_app_id " << mobile_app_id);
+
+ bool result = false;
+ std::vector<Json::Value> temp;
+ for (Json::Value::iterator it = GetSavedApplications().begin();
+ it != GetSavedApplications().end(); ++it) {
+ if ((*it).isMember(strings::app_id) &&
+ (*it).isMember(strings::device_id)) {
+ const std::string& saved_m_app_id = (*it)[strings::app_id].asString();
+ const std::string& saved_device_id = (*it)[strings::device_id].asString();
+ if (saved_m_app_id != mobile_app_id && saved_device_id != device_id) {
+ temp.push_back((*it));
+ } else {
+ result = true;
+ }
+ }
+ }
+
+ if (false == result) {
+ LOG4CXX_TRACE(logger_, "EXIT result: " << (result ? "true" : "false"));
+ return result;
+ }
+
+ GetSavedApplications().clear();
+ for (std::vector<Json::Value>::iterator it = temp.begin();
+ it != temp.end(); ++it) {
+ GetSavedApplications().append((*it));
+ }
+ LOG4CXX_TRACE(logger_, "EXIT result: " << (result ? "true" : "false"));
+ return result;
+}
+
+uint32_t ResumptionDataJson::GetIgnOffTime() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ Json::Value& resumption = GetResumptionData();
+ if (!resumption.isMember(strings::last_ign_off_time)) {
+ resumption[strings::last_ign_off_time] = 0;
+ LOG4CXX_WARN(logger_, "last_save_time section is missed");
+ }
+ return resumption[strings::last_ign_off_time].asUInt();
+}
+
+int ResumptionDataJson::IsApplicationSaved(const std::string& mobile_app_id,
+ const std::string& device_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ return GetObjectIndex(mobile_app_id, device_id);
+}
+
+Json::Value& ResumptionDataJson::GetFromSavedOrAppend(const std::string& mobile_app_id,
+ const std::string& device_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ for (Json::Value::iterator it = GetSavedApplications().begin();
+ it != GetSavedApplications().end(); ++it) {
+ if (device_id == (*it)[strings::device_id].asString() &&
+ mobile_app_id == (*it)[strings::app_id].asString()) {
+ return *it;
+ }
+ }
+
+ return GetSavedApplications().append(Json::Value());
+}
+
+void ResumptionDataJson::GetDataForLoadResumeData(
+ smart_objects::SmartObject& saved_data) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ smart_objects::SmartObject so_array_data(smart_objects::SmartType_Array);
+ int i = 0;
+ for (Json::Value::iterator it = GetSavedApplications().begin();
+ it != GetSavedApplications().end(); ++it) {
+ if (((*it).isMember(strings::hmi_level)) &&
+ ((*it).isMember(strings::ign_off_count)) &&
+ ((*it).isMember(strings::time_stamp)) &&
+ ((*it).isMember(strings::app_id)) &&
+ ((*it).isMember(strings::device_id))) {
+ smart_objects::SmartObject so(smart_objects::SmartType_Map);
+ so[strings::hmi_level] = (*it)[strings::hmi_level].asInt();
+ so[strings::ign_off_count] = (*it)[strings::ign_off_count].asInt();
+ so[strings::time_stamp] = (*it)[strings::time_stamp].asUInt();
+ so[strings::app_id] = (*it)[strings::app_id].asString();
+ so[strings::device_id] = (*it)[strings::device_id].asString();
+ so_array_data[i++] = so;
+ }
+ }
+ saved_data = so_array_data;
+}
+
+void ResumptionDataJson::SetHMILevelForSavedApplication(const std::string& mobile_app_id,
+ const std::string& device_id,
+ int32_t hmi_level) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ int idx = GetObjIndex(mobile_app_id, device_id);
+ if (-1 == idx) {
+ LOG4CXX_WARN(logger_, "Application isn't saved with mobile_app_id = "
+ <<mobile_app_id<<" device_id = "<<device_id);
+ return;
+ }
+ GetSavedApplications()[idx][strings::hmi_level] = hmi_level;
+}
+
+Json::Value& ResumptionDataJson::GetSavedApplications() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ Json::Value& resumption = GetResumptionData();
+ if (!resumption.isMember(strings::resume_app_list)) {
+ resumption[strings::resume_app_list] = Json::Value(Json::arrayValue);
+ LOG4CXX_WARN(logger_, "app_list section is missed");
+ }
+ Json::Value& resume_app_list = resumption[strings::resume_app_list];
+ if (!resume_app_list.isArray()) {
+ LOG4CXX_ERROR(logger_, "resume_app_list type INVALID rewrite");
+ resume_app_list = Json::Value(Json::arrayValue);
+ }
+ return resume_app_list;
+}
+
+Json::Value& ResumptionDataJson::GetResumptionData() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ Json::Value& last_state = resumption::LastState::instance()->dictionary;
+ if (!last_state.isMember(strings::resumption)) {
+ last_state[strings::resumption] = Json::Value(Json::objectValue);
+ LOG4CXX_WARN(logger_, "resumption section is missed");
+ }
+ Json::Value& resumption = last_state[strings::resumption];
+ if (!resumption.isObject()) {
+ LOG4CXX_ERROR(logger_, "resumption type INVALID rewrite");
+ resumption = Json::Value(Json::objectValue);
+ }
+ return resumption;
+}
+
+int ResumptionDataJson::GetObjectIndex(const std::string& mobile_app_id,
+ const std::string& device_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ const Json::Value& apps = GetSavedApplications();
+ const Json::ArrayIndex size = apps.size();
+ Json::ArrayIndex idx = 0;
+ for (; idx != size; ++idx) {
+ if (apps[idx].isMember(strings::app_id) &&
+ apps[idx].isMember(strings::device_id)) {
+ const std::string& saved_app_id = apps[idx][strings::app_id].asString();
+ const std::string& saved_device_id = apps[idx][strings::device_id].asString();
+ if (device_id == saved_device_id &&
+ mobile_app_id == saved_app_id) {
+ LOG4CXX_DEBUG(logger_, "Found " << idx);
+ return idx;
+ }
+ }
+ }
+ return -1;
+}
+
+bool ResumptionDataJson::IsResumptionDataValid(uint32_t index) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ const Json::Value& json_app = GetSavedApplications()[index];
+ if (!json_app.isMember(strings::app_id) ||
+ !json_app.isMember(strings::ign_off_count) ||
+ !json_app.isMember(strings::hmi_level) ||
+ !json_app.isMember(strings::hmi_app_id) ||
+ !json_app.isMember(strings::time_stamp) ||
+ !json_app.isMember(strings::device_id)) {
+ LOG4CXX_ERROR(logger_, "Wrong resumption data");
+ return false;
+ }
+
+ if (json_app.isMember(strings::hmi_app_id) &&
+ 0 >= json_app[strings::hmi_app_id].asUInt()) {
+ LOG4CXX_ERROR(logger_, "Wrong resumption hmi app ID");
+ return false;
+ }
+
+ return true;
+}
+
+void ResumptionDataJson::SetSavedApplication(Json::Value& apps_json) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ Json::Value& app_list = GetSavedApplications();
+ app_list = apps_json;
+}
+
+void ResumptionDataJson::SetLastIgnOffTime(time_t ign_off_time) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_WARN(logger_, "ign_off_time = " << ign_off_time);
+ Json::Value& resumption = GetResumptionData();
+ resumption[strings::last_ign_off_time] = static_cast<uint32_t>(ign_off_time);
+}
+
+} // resumption
+} // application_manager
diff --git a/src/components/application_manager/src/resumption/resumption_sql_queries.cc b/src/components/application_manager/src/resumption/resumption_sql_queries.cc
new file mode 100644
index 0000000000..3ba34a090e
--- /dev/null
+++ b/src/components/application_manager/src/resumption/resumption_sql_queries.cc
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2015, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "application_manager/resumption/resumption_sql_queries.h"
+
+namespace application_manager {
+namespace resumption {
+
+const std::string kCreateSchema;
+
+const std::string kSelectHMILevel =
+ "SELECT `hmiLevel` FROM `application` "
+ "WHERE `deviceID` = ? AND `AppID` = ?";
+
+const std::string kCheckHMIId =
+ "SELECT `hmiAppID` FROM `application` "
+ "WHERE `hmiAppID` = ?";
+
+const std::string kSelectHMIId =
+ "SELECT `hmiAppID` FROM `application` "
+ "WHERE `deviceID` = ? AND `AppID` = ?";
+
+const std::string kSelectHashId =
+ "SELECT `hashID` FROM `application` "
+ "WHERE `deviceID` = ? AND `AppID` = ?";
+
+const std::string kSelectIgnOffTime =
+ "SELECT `last_ign_off_time` FROM `resumption`";
+
+const std::string kCheckApplication =
+ "SELECT COUNT (`deviceID`) FROM `application` "
+ "WHERE `deviceID` = ? AND `AppID` = ?";
+
+const std::string kSelectDataForLoadResumeData =
+ "SELECT `hmiLevel`, `ign_off_count`, `timeStamp`, `appID`, `deviceID` "
+ "FROM `application`"
+ "WHERE `hmiLevel` IS NOT NULL AND `ign_off_count` IS NOT NULL "
+ "AND `timeStamp` IS NOT NULL AND `appID` IS NOT NULL AND `deviceID` IS NOT NULL";
+
+const std::string kUpdateHMILevel =
+ "UPDATE `application` "
+ "SET `hmiLevel` = ? "
+ "WHERE `deviceID` = ? AND `AppID` = ?";
+
+const std::string kDeleteApplication =
+ "DELETE "
+ "FROM `application` "
+ "WHERE `deviceID` = ? AND `AppID` = ?";
+
+const std::string kUpdateIgnOffCount =
+ "UPDATE `application` "
+ "SET `ign_off_count` = `ign_off_count` - 1"
+ "WHERE `ign_off_count` > 0";
+
+const std::string kDeleteApplicationsAccordingWithIgnOffCount =
+ "DELETE "
+ "FROM `application` "
+ "WHERE `ign_off_count` >= ?";
+
+const std::string kUpdateSuspendData =
+ "UPDATE `application` "
+ "SET `ign_off_count` = `ign_off_count` + 1, "
+ "`suspend_count` = `suspend_count` + 1";
+
+const std::string KUpdateLastIgnOffTime =
+ "UPDATE `resumption` "
+ "SET `last_ign_off_time` = ?";
+
+} // namespace resumption
+} // namespace application_manager
diff --git a/src/components/utils/include/utils/qdb_wrapper/sql_query.h b/src/components/utils/include/utils/qdb_wrapper/sql_query.h
index ad79a00a55..122133f4ea 100644
--- a/src/components/utils/include/utils/qdb_wrapper/sql_query.h
+++ b/src/components/utils/include/utils/qdb_wrapper/sql_query.h
@@ -151,6 +151,13 @@ class SQLQuery {
/**
* Gets value in the result record
* @param pos position of value
+ * @return unsigned integer value
+ */
+ uint32_t SQLQuery::GetUInteger(int pos) const;
+
+ /**
+ * Gets value in the result record
+ * @param pos position of value
* @return double value
*/
double GetDouble(int pos) const;
diff --git a/src/components/utils/include/utils/sqlite_wrapper/sql_query.h b/src/components/utils/include/utils/sqlite_wrapper/sql_query.h
index 0f79370f9c..1240610ca4 100644
--- a/src/components/utils/include/utils/sqlite_wrapper/sql_query.h
+++ b/src/components/utils/include/utils/sqlite_wrapper/sql_query.h
@@ -150,6 +150,13 @@ class SQLQuery {
/**
* Gets value in the result record
* @param pos position of value
+ * @return unsigned integer value
+ */
+ uint32_t GetUInteger(int pos) const;
+
+ /**
+ * Gets value in the result record
+ * @param pos position of value
* @return double value
*/
double GetDouble(int pos) const;
diff --git a/src/components/utils/src/qdb_wrapper/sql_query.cc b/src/components/utils/src/qdb_wrapper/sql_query.cc
index e13cab5ee3..59619bbe4d 100644
--- a/src/components/utils/src/qdb_wrapper/sql_query.cc
+++ b/src/components/utils/src/qdb_wrapper/sql_query.cc
@@ -240,6 +240,15 @@ int SQLQuery::GetInteger(int pos) const {
return 0;
}
+uint32_t SQLQuery::GetUInteger(int pos) const {
+ void* ret = qdb_cell(result_, current_row_, pos);
+ if (rows_ !=0 && ret) {
+ return *static_cast<uint32_t*>(ret);
+ }
+ return 0;
+}
+
+
double SQLQuery::GetDouble(int pos) const {
void* ret = qdb_cell(result_, current_row_, pos);
if (rows_ !=0 && ret) {
diff --git a/src/components/utils/src/sqlite_wrapper/sql_query.cc b/src/components/utils/src/sqlite_wrapper/sql_query.cc
index f548a9f23f..7b8a6ef837 100644
--- a/src/components/utils/src/sqlite_wrapper/sql_query.cc
+++ b/src/components/utils/src/sqlite_wrapper/sql_query.cc
@@ -121,6 +121,11 @@ int SQLQuery::GetInteger(int pos) const {
return sqlite3_column_int(statement_, pos);
}
+uint32_t SQLQuery::GetUInteger(int pos) const {
+ return static_cast<uint32_t>(
+ sqlite3_column_int64(statement_, pos));
+}
+
double SQLQuery::GetDouble(int pos) const {
return sqlite3_column_double(statement_, pos);
}