summaryrefslogtreecommitdiff
path: root/src/components/application_manager/src/application_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/application_manager/src/application_impl.cc')
-rw-r--r--src/components/application_manager/src/application_impl.cc740
1 files changed, 740 insertions, 0 deletions
diff --git a/src/components/application_manager/src/application_impl.cc b/src/components/application_manager/src/application_impl.cc
new file mode 100644
index 0000000000..2812c17ffb
--- /dev/null
+++ b/src/components/application_manager/src/application_impl.cc
@@ -0,0 +1,740 @@
+/**
+ * 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.
+ */
+
+#include <string>
+#include <strings.h>
+#include <stdlib.h>
+#include "application_manager/application_impl.h"
+#include "application_manager/message_helper.h"
+#include "config_profile/profile.h"
+#include "interfaces/MOBILE_API.h"
+#include "utils/file_system.h"
+#include "utils/logger.h"
+
+namespace {
+
+mobile_apis::FileType::eType StringToFileType(const char* str) {
+ if (0 == strcasecmp(str, "json")) {
+ return mobile_apis::FileType::JSON;
+ } else if (0 == strcasecmp(str, "bmp")) {
+ return mobile_apis::FileType::GRAPHIC_BMP;
+ } else if (0 == strcasecmp(str, "jpeg")) {
+ return mobile_apis::FileType::GRAPHIC_JPEG;
+ } else if (0 == strcasecmp(str, "png")) {
+ return mobile_apis::FileType::GRAPHIC_PNG;
+ } else if (0 == strcasecmp(str, "wave")) {
+ return mobile_apis::FileType::AUDIO_WAVE;
+ } else if ((0 == strcasecmp(str, "m4a")) ||
+ (0 == strcasecmp(str, "m4b")) ||
+ (0 == strcasecmp(str, "m4p")) ||
+ (0 == strcasecmp(str, "m4v")) ||
+ (0 == strcasecmp(str, "m4r")) ||
+ (0 == strcasecmp(str, "3gp")) ||
+ (0 == strcasecmp(str, "mp4")) ||
+ (0 == strcasecmp(str, "aac"))) {
+ return mobile_apis::FileType::AUDIO_AAC;
+ } else if (0 == strcasecmp(str, "mp3")) {
+ return mobile_apis::FileType::AUDIO_MP3;
+ } else {
+ return mobile_apis::FileType::BINARY;
+ }
+}
+}
+
+namespace application_manager {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "ApplicationManager")
+
+ApplicationImpl::ApplicationImpl(uint32_t application_id,
+ const std::string& mobile_app_id,
+ const std::string& app_name,
+ utils::SharedPtr<usage_statistics::StatisticsManager> statistics_manager)
+ : grammar_id_(0),
+ app_id_(application_id),
+ active_message_(NULL),
+ is_media_(false),
+ allowed_support_navigation_(false),
+ hmi_supports_navi_video_streaming_(false),
+ hmi_supports_navi_audio_streaming_(false),
+ is_app_allowed_(true),
+ has_been_activated_(false),
+ tts_speak_state_(false),
+ tts_properties_in_none_(false),
+ tts_properties_in_full_(false),
+ hmi_level_(mobile_api::HMILevel::HMI_NONE),
+ put_file_in_none_count_(0),
+ delete_file_in_none_count_(0),
+ list_files_in_none_count_(0),
+ system_context_(mobile_api::SystemContext::SYSCTXT_MAIN),
+ audio_streaming_state_(mobile_api::AudioStreamingState::NOT_AUDIBLE),
+ device_(0),
+ usage_report_(mobile_app_id, statistics_manager),
+ protocol_version_(ProtocolVersion::kV3),
+ is_video_stream_retry_active_(false),
+ is_audio_stream_retry_active_(false),
+ video_stream_retry_number_(0),
+ audio_stream_retry_number_(0) {
+
+ cmd_number_to_time_limits_[mobile_apis::FunctionID::ReadDIDID] =
+ {date_time::DateTime::getCurrentTime(), 0};
+ cmd_number_to_time_limits_[mobile_apis::FunctionID::GetVehicleDataID] =
+ {date_time::DateTime::getCurrentTime(), 0};
+
+
+ set_mobile_app_id(smart_objects::SmartObject(mobile_app_id));
+ set_name(app_name);
+
+ // subscribe application to custom button by default
+ SubscribeToButton(mobile_apis::ButtonName::CUSTOM_BUTTON);
+
+ // load persistent files
+ LoadPersistentFiles();
+}
+
+ApplicationImpl::~ApplicationImpl() {
+ // TODO(AK): check if this is correct assimption
+ if (active_message_) {
+ delete active_message_;
+ active_message_ = NULL;
+ }
+
+ subscribed_buttons_.clear();
+ subscribed_vehicle_info_.clear();
+ if (is_perform_interaction_active()) {
+ set_perform_interaction_active(0);
+ set_perform_interaction_mode(-1);
+ DeletePerformInteractionChoiceSetMap();
+ }
+ CleanupFiles();
+}
+
+void ApplicationImpl::CloseActiveMessage() {
+ delete active_message_;
+ active_message_ = NULL;
+}
+
+bool ApplicationImpl::IsFullscreen() const {
+ return mobile_api::HMILevel::HMI_FULL == hmi_level_;
+}
+
+bool ApplicationImpl::MakeFullscreen() {
+ hmi_level_ = mobile_api::HMILevel::HMI_FULL;
+ if (is_media_ && !tts_speak_state_) {
+ audio_streaming_state_ = mobile_api::AudioStreamingState::AUDIBLE;
+ }
+ system_context_ = mobile_api::SystemContext::SYSCTXT_MAIN;
+ if (!has_been_activated_) {
+ has_been_activated_ = true;
+ }
+ return true;
+}
+
+bool ApplicationImpl::IsAudible() const {
+ return mobile_api::HMILevel::HMI_FULL == hmi_level_
+ || mobile_api::HMILevel::HMI_LIMITED == hmi_level_;
+}
+
+void ApplicationImpl::MakeNotAudible() {
+ hmi_level_ = mobile_api::HMILevel::HMI_BACKGROUND;
+ audio_streaming_state_ = mobile_api::AudioStreamingState::NOT_AUDIBLE;
+}
+
+bool ApplicationImpl::allowed_support_navigation() const {
+ return allowed_support_navigation_;
+}
+
+void ApplicationImpl::set_allowed_support_navigation(bool allow) {
+ allowed_support_navigation_ = allow;
+}
+
+const smart_objects::SmartObject* ApplicationImpl::active_message() const {
+ return active_message_;
+}
+
+const Version& ApplicationImpl::version() const {
+ return version_;
+}
+
+void ApplicationImpl::set_hmi_application_id(uint32_t hmi_app_id) {
+ hmi_app_id_ = hmi_app_id;
+}
+
+const std::string& ApplicationImpl::name() const {
+ return app_name_;
+}
+
+const std::string ApplicationImpl::folder_name() const {
+ return name() + mobile_app_id()->asString();
+}
+
+bool ApplicationImpl::is_media_application() const {
+ return is_media_;
+}
+
+const mobile_api::HMILevel::eType& ApplicationImpl::hmi_level() const {
+ return hmi_level_;
+}
+
+const uint32_t ApplicationImpl::put_file_in_none_count() const {
+ return put_file_in_none_count_;
+}
+
+const uint32_t ApplicationImpl::delete_file_in_none_count() const {
+ return delete_file_in_none_count_;
+}
+
+const uint32_t ApplicationImpl::list_files_in_none_count() const {
+ return list_files_in_none_count_;
+}
+
+const mobile_api::SystemContext::eType&
+ApplicationImpl::system_context() const {
+ return system_context_;
+}
+
+const std::string& ApplicationImpl::app_icon_path() const {
+ return app_icon_path_;
+}
+
+connection_handler::DeviceHandle ApplicationImpl::device() const {
+ return device_;
+}
+
+void ApplicationImpl::set_version(const Version& ver) {
+ version_ = ver;
+}
+
+void ApplicationImpl::set_name(const std::string& name) {
+ app_name_ = name;
+}
+
+void ApplicationImpl::set_is_media_application(bool is_media) {
+ is_media_ = is_media;
+ // Audio streaming state for non-media application can not be different
+ // from NOT_AUDIBLE
+ if (!is_media)
+ set_audio_streaming_state(mobile_api::AudioStreamingState::NOT_AUDIBLE);
+}
+
+void ApplicationImpl::set_tts_speak_state(bool state_tts_speak) {
+ tts_speak_state_ = state_tts_speak;
+}
+
+bool ApplicationImpl::tts_speak_state() {
+ return tts_speak_state_;
+}
+
+void ApplicationImpl::set_tts_properties_in_none(
+ bool active) {
+ tts_properties_in_none_ = active;
+}
+
+bool ApplicationImpl::tts_properties_in_none() {
+ return tts_properties_in_none_;
+}
+
+void ApplicationImpl::set_tts_properties_in_full(
+ bool active) {
+ tts_properties_in_full_ = active;
+}
+
+bool ApplicationImpl::tts_properties_in_full() {
+ return tts_properties_in_full_;
+}
+
+void ApplicationImpl::set_hmi_level(
+ const mobile_api::HMILevel::eType& hmi_level) {
+ if (mobile_api::HMILevel::HMI_NONE != hmi_level_ &&
+ mobile_api::HMILevel::HMI_NONE == hmi_level) {
+ put_file_in_none_count_ = 0;
+ delete_file_in_none_count_ = 0;
+ list_files_in_none_count_ = 0;
+ }
+
+ hmi_level_ = hmi_level;
+ usage_report_.RecordHmiStateChanged(hmi_level);
+}
+
+void ApplicationImpl::set_hmi_supports_navi_video_streaming(bool supports) {
+ hmi_supports_navi_video_streaming_ = supports;
+
+ if ((!supports) && (!video_stream_retry_active())) {
+ std::pair<uint32_t, int32_t> stream_retry =
+ profile::Profile::instance()->start_stream_retry_amount();
+ set_video_stream_retry_active(true);
+ video_stream_retry_number_ = stream_retry.first;
+ video_stream_retry_timer_ =
+ utils::SharedPtr<timer::TimerThread<ApplicationImpl>>(
+ new timer::TimerThread<ApplicationImpl>(
+ "VideoStreamRetry", this, &ApplicationImpl::OnVideoStreamRetry, true));
+ // start separate pthread for timer without delays
+ video_stream_retry_timer_->start(0);
+ }
+}
+
+bool ApplicationImpl::hmi_supports_navi_video_streaming() const {
+ return hmi_supports_navi_video_streaming_;
+}
+
+void ApplicationImpl::set_hmi_supports_navi_audio_streaming(bool supports) {
+ hmi_supports_navi_audio_streaming_ = supports;
+
+ if ((!supports) && (!audio_stream_retry_active())) {
+ std::pair<uint32_t, int32_t> stream_retry =
+ profile::Profile::instance()->start_stream_retry_amount();
+ set_audio_stream_retry_active(true);
+ audio_stream_retry_number_ = stream_retry.first;
+ audio_stream_retry_timer_ =
+ utils::SharedPtr<timer::TimerThread<ApplicationImpl>>(
+ new timer::TimerThread<ApplicationImpl>(
+ "AudioStreamRetry", this, &ApplicationImpl::OnAudioStreamRetry, true));
+ // start separate pthread for timer without delays
+ audio_stream_retry_timer_->start(0);
+ }
+}
+
+bool ApplicationImpl::hmi_supports_navi_audio_streaming() const {
+ return hmi_supports_navi_audio_streaming_;
+}
+
+bool ApplicationImpl::video_stream_retry_active() const {
+ return is_video_stream_retry_active_;
+}
+
+void ApplicationImpl::set_video_stream_retry_active(bool active) {
+ is_video_stream_retry_active_ = active;
+}
+
+bool ApplicationImpl::audio_stream_retry_active() const {
+ return is_audio_stream_retry_active_;
+}
+
+void ApplicationImpl::set_audio_stream_retry_active(bool active) {
+ is_audio_stream_retry_active_ = active;
+}
+
+void ApplicationImpl::OnVideoStreamRetry() {
+ if (video_stream_retry_number_) {
+ LOG4CXX_INFO(logger_, "Send video stream retry "
+ << video_stream_retry_number_);
+
+ application_manager::MessageHelper::SendNaviStartStream(app_id());
+ --video_stream_retry_number_;
+
+ std::pair<uint32_t, int32_t> stream_retry =
+ profile::Profile::instance()->start_stream_retry_amount();
+ int32_t time_out = stream_retry.second;
+ video_stream_retry_timer_->updateTimeOut(time_out);
+ } else {
+ LOG4CXX_INFO(logger_, "Stop video streaming retry");
+ video_stream_retry_timer_.release();
+ set_video_stream_retry_active(false);
+ }
+}
+
+void ApplicationImpl::OnAudioStreamRetry() {
+ if (audio_stream_retry_number_) {
+ LOG4CXX_INFO(logger_, "Send audio streaming retry "
+ << audio_stream_retry_number_);
+
+ application_manager::MessageHelper::SendAudioStartStream(app_id());
+ --audio_stream_retry_number_;
+
+ std::pair<uint32_t, int32_t> stream_retry =
+ profile::Profile::instance()->start_stream_retry_amount();
+ int32_t time_out = stream_retry.second;
+ audio_stream_retry_timer_->updateTimeOut(time_out);
+ } else {
+ LOG4CXX_INFO(logger_, "Stop audio streaming retry");
+ audio_stream_retry_timer_.release();
+ set_audio_stream_retry_active(false);
+ }
+}
+
+void ApplicationImpl::increment_put_file_in_none_count() {
+ ++put_file_in_none_count_;
+}
+
+void ApplicationImpl::increment_delete_file_in_none_count() {
+ ++delete_file_in_none_count_;
+}
+
+void ApplicationImpl::increment_list_files_in_none_count() {
+ ++list_files_in_none_count_;
+}
+
+void ApplicationImpl::set_system_context(
+ const mobile_api::SystemContext::eType& system_context) {
+ system_context_ = system_context;
+}
+
+void ApplicationImpl::set_audio_streaming_state(
+ const mobile_api::AudioStreamingState::eType& state) {
+ if (!is_media_application()
+ && state != mobile_api::AudioStreamingState::NOT_AUDIBLE) {
+ LOG4CXX_WARN(logger_, "Trying to set audio streaming state"
+ " for non-media application to different from NOT_AUDIBLE");
+ return;
+ }
+ audio_streaming_state_ = state;
+}
+
+bool ApplicationImpl::set_app_icon_path(const std::string& path) {
+ if (app_files_.find(path) != app_files_.end()) {
+ app_icon_path_ = path;
+ return true;
+ }
+ return false;
+}
+
+void ApplicationImpl::set_app_allowed(const bool& allowed) {
+ is_app_allowed_ = allowed;
+}
+
+void ApplicationImpl::set_device(connection_handler::DeviceHandle device) {
+ device_ = device;
+}
+
+uint32_t ApplicationImpl::get_grammar_id() const {
+ return grammar_id_;
+}
+
+void ApplicationImpl::set_grammar_id(uint32_t value) {
+ grammar_id_ = value;
+}
+
+bool ApplicationImpl::has_been_activated() const {
+ return has_been_activated_;
+}
+
+void ApplicationImpl::set_protocol_version(
+ const ProtocolVersion& protocol_version) {
+ protocol_version_ = protocol_version;
+}
+
+ProtocolVersion ApplicationImpl::protocol_version() const {
+ return protocol_version_;
+}
+
+bool ApplicationImpl::AddFile(AppFile& file) {
+ if (app_files_.count(file.file_name) == 0) {
+ LOG4CXX_INFO(logger_, "AddFile file " << file.file_name
+ << " File type is " << file.file_type);
+ app_files_[file.file_name] = file;
+ return true;
+ }
+ return false;
+}
+
+bool ApplicationImpl::UpdateFile(AppFile& file) {
+ if (app_files_.count(file.file_name) != 0) {
+ LOG4CXX_INFO(logger_, "UpdateFile file " << file.file_name
+ << " File type is " << file.file_type);
+ app_files_[file.file_name] = file;
+ return true;
+ }
+ return false;
+}
+
+bool ApplicationImpl::DeleteFile(const std::string& file_name) {
+ AppFilesMap::iterator it = app_files_.find(file_name);
+ if (it != app_files_.end()) {
+ LOG4CXX_INFO(logger_, "DeleteFile file " << it->second.file_name
+ << " File type is " << it->second.file_type);
+ app_files_.erase(it);
+ return true;
+ }
+ return false;
+}
+
+const AppFilesMap& ApplicationImpl::getAppFiles() const {
+ return this->app_files_;
+}
+
+const AppFile* ApplicationImpl::GetFile(const std::string& file_name) {
+ if (app_files_.find(file_name) != app_files_.end()) {
+ return &(app_files_[file_name]);
+ }
+ return NULL;
+}
+
+bool ApplicationImpl::SubscribeToButton(mobile_apis::ButtonName::eType btn_name) {
+ size_t old_size = subscribed_buttons_.size();
+ subscribed_buttons_.insert(btn_name);
+ return (subscribed_buttons_.size() == old_size + 1);
+}
+
+bool ApplicationImpl::IsSubscribedToButton(mobile_apis::ButtonName::eType btn_name) {
+ std::set<mobile_apis::ButtonName::eType>::iterator it = subscribed_buttons_.find(btn_name);
+ return (subscribed_buttons_.end() != it);
+}
+
+bool ApplicationImpl::UnsubscribeFromButton(mobile_apis::ButtonName::eType btn_name) {
+ size_t old_size = subscribed_buttons_.size();
+ subscribed_buttons_.erase(btn_name);
+ return (subscribed_buttons_.size() == old_size - 1);
+}
+
+bool ApplicationImpl::SubscribeToIVI(uint32_t vehicle_info_type_) {
+ size_t old_size = subscribed_vehicle_info_.size();
+ subscribed_vehicle_info_.insert(vehicle_info_type_);
+ return (subscribed_vehicle_info_.size() == old_size + 1);
+}
+
+bool ApplicationImpl::IsSubscribedToIVI(uint32_t vehicle_info_type_) {
+ std::set<uint32_t>::iterator it = subscribed_vehicle_info_.find(
+ vehicle_info_type_);
+ return (subscribed_vehicle_info_.end() != it);
+}
+
+bool ApplicationImpl::UnsubscribeFromIVI(uint32_t vehicle_info_type_) {
+ size_t old_size = subscribed_vehicle_info_.size();
+ subscribed_vehicle_info_.erase(vehicle_info_type_);
+ return (subscribed_vehicle_info_.size() == old_size - 1);
+}
+
+UsageStatistics& ApplicationImpl::usage_report() {
+ return usage_report_;
+}
+
+bool ApplicationImpl::IsCommandLimitsExceeded(
+ mobile_apis::FunctionID::eType cmd_id,
+ TLimitSource source) {
+ TimevalStruct current = date_time::DateTime::getCurrentTime();
+ switch (source) {
+ // In case of config file values there is COMMON limitations for number of
+ // commands per certain time in seconds, i.e. 5 requests per 10 seconds with
+ // any interval between them
+ case CONFIG_FILE: {
+ CommandNumberTimeLimit::iterator it =
+ cmd_number_to_time_limits_.find(cmd_id);
+ if (cmd_number_to_time_limits_.end() == it) {
+ LOG4CXX_WARN(logger_, "Limits for command id " << cmd_id
+ << "had not been set.");
+ return true;
+ }
+
+ TimeToNumberLimit& limit = it->second;
+
+ std::pair<uint32_t, int32_t> frequency_restrictions;
+
+ if (mobile_apis::FunctionID::ReadDIDID == cmd_id) {
+ frequency_restrictions =
+ profile::Profile::instance()->read_did_frequency();
+
+ } else if (mobile_apis::FunctionID::GetVehicleDataID == cmd_id) {
+ frequency_restrictions =
+ profile::Profile::instance()->get_vehicle_data_frequency();
+ } else {
+ LOG4CXX_INFO(logger_, "No restrictions for request");
+ return false;
+ }
+
+ LOG4CXX_INFO(logger_, "Time Info: " <<
+ "\n Current: " << current.tv_sec <<
+ "\n Limit: (" << limit.first.tv_sec << "," << limit.second << ")"
+ "\n frequency_restrictions: (" << frequency_restrictions.first << "," << frequency_restrictions.second << ")"
+ );
+ if (current.tv_sec < limit.first.tv_sec + frequency_restrictions.second) {
+ if (limit.second < frequency_restrictions.first) {
+ ++limit.second;
+ return false;
+ }
+ return true;
+ }
+
+ limit.first = current;
+ limit.second = 1;
+
+ return false;
+
+ break;
+ }
+ // In case of policy table values, there is EVEN limitation for number of
+ // commands per minute, e.g. 10 command per minute i.e. 1 command per 6 sec
+ case POLICY_TABLE: {
+ uint32_t cmd_limit = application_manager::MessageHelper::GetAppCommandLimit(
+ mobile_app_id_->asString());
+
+ if (0 == cmd_limit) {
+ return true;
+ }
+
+ const uint32_t dummy_limit = 1;
+ CommandNumberTimeLimit::iterator it =
+ cmd_number_to_time_limits_.find(cmd_id);
+ // If no command with cmd_id had been executed yet, just add to limits
+ if (cmd_number_to_time_limits_.end() == it) {
+ cmd_number_to_time_limits_[cmd_id] = {current, dummy_limit};
+ return false;
+ }
+
+ const uint32_t minute = 60;
+
+ TimeToNumberLimit& limit = it->second;
+
+ // Checking even limitation for command
+ if (static_cast<uint32_t>(current.tv_sec - limit.first.tv_sec) <
+ minute/cmd_limit) {
+ return true;
+ }
+
+ cmd_number_to_time_limits_[cmd_id] = {current, dummy_limit};
+
+ return false;
+ break;
+ }
+ default: {
+ LOG4CXX_WARN(logger_, "Limit source is not implemented.");
+ break;
+ }
+ }
+
+ return true;
+}
+
+const std::set<mobile_apis::ButtonName::eType>& ApplicationImpl::SubscribedButtons() const {
+ return subscribed_buttons_;
+}
+
+const std::set<uint32_t>& ApplicationImpl::SubscribesIVI() const {
+ return subscribed_vehicle_info_;
+}
+
+uint32_t ApplicationImpl::nextHash() {
+ hash_val_ = rand();
+ return hash_val_;
+}
+
+uint32_t ApplicationImpl::curHash() const {
+ return hash_val_;
+}
+
+uint32_t ApplicationImpl::UpdateHash() {
+ uint32_t new_hash= nextHash();
+ MessageHelper::SendHashUpdateNotification(app_id());
+ return new_hash;
+}
+
+void ApplicationImpl::CleanupFiles() {
+ std::string directory_name =
+ profile::Profile::instance()->app_storage_folder();
+ directory_name += "/" + folder_name();
+
+ if (file_system::DirectoryExists(directory_name)) {
+ std::vector<std::string> files = file_system::ListFiles(
+ directory_name);
+ AppFilesMap::const_iterator app_files_it;
+
+ std::vector<std::string>::const_iterator it = files.begin();
+ for (; it != files.end(); ++it) {
+ std::string file_name = directory_name;
+ file_name += "/";
+ file_name += *it;
+ app_files_it = app_files_.find(file_name);
+ if ((app_files_it == app_files_.end()) ||
+ (!app_files_it->second.is_persistent)) {
+ LOG4CXX_INFO(logger_, "DeleteFile file " << file_name);
+ file_system::DeleteFile(file_name);
+ }
+ }
+
+ file_system::RemoveDirectory(directory_name, false);
+ }
+ app_files_.clear();
+}
+
+void ApplicationImpl::LoadPersistentFiles() {
+ std::string directory_name =
+ profile::Profile::instance()->app_storage_folder();
+ directory_name += "/" + folder_name();
+
+ if (file_system::DirectoryExists(directory_name)) {
+ std::vector<std::string> persistent_files =
+ file_system::ListFiles(directory_name);
+
+ std::vector<std::string>::const_iterator it = persistent_files.begin();
+ for (; it != persistent_files.end(); ++it) {
+ AppFile file;
+ file.is_persistent = true;
+ file.is_download_complete = true;
+ file.file_name = directory_name;
+ file.file_name += "/";
+ file.file_name += *it;
+ file.file_type = mobile_apis::FileType::BINARY;
+ // Search file extension and convert it to the type
+ std::size_t index = it->find_last_of('.');
+ if (index != std::string::npos) {
+ std::string file_type = it->substr(++index);
+ file.file_type = StringToFileType(file_type.c_str());
+ }
+
+ LOG4CXX_INFO(logger_, "Loaded persistent file " << file.file_name
+ << " File type is " << file.file_type);
+ AddFile(file);
+ }
+ }
+}
+
+void ApplicationImpl::SubscribeToSoftButtons(int32_t cmd_id,
+ const SoftButtonID& softbuttons_id) {
+ sync_primitives::AutoLock lock(cmd_softbuttonid_lock_);
+ if (static_cast<int32_t>(mobile_apis::FunctionID::ScrollableMessageID) == cmd_id) {
+ CommandSoftButtonID::iterator it = cmd_softbuttonid_.find(cmd_id);
+ if (cmd_softbuttonid_.end() == it) {
+ cmd_softbuttonid_[cmd_id] = softbuttons_id;
+ }
+ } else {
+ cmd_softbuttonid_[cmd_id] = softbuttons_id;
+ }
+}
+
+bool ApplicationImpl::IsSubscribedToSoftButton(const uint32_t softbutton_id) {
+ sync_primitives::AutoLock lock(cmd_softbuttonid_lock_);
+ CommandSoftButtonID::iterator it = cmd_softbuttonid_.begin();
+ for (; it != cmd_softbuttonid_.end(); ++it) {
+ if((it->second).find(softbutton_id) != (it->second).end()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void ApplicationImpl::UnsubscribeFromSoftButtons(int32_t cmd_id) {
+ sync_primitives::AutoLock lock(cmd_softbuttonid_lock_);
+ CommandSoftButtonID::iterator it = cmd_softbuttonid_.find(cmd_id);
+ if(it != cmd_softbuttonid_.end()) {
+ cmd_softbuttonid_.erase(it);
+ }
+}
+
+} // namespace application_manager