summaryrefslogtreecommitdiff
path: root/src/components/application_manager/src/application_manager_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/application_manager/src/application_manager_impl.cc')
-rw-r--r--src/components/application_manager/src/application_manager_impl.cc1506
1 files changed, 981 insertions, 525 deletions
diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc
index 6d7fdeec6..1c4a924c0 100644
--- a/src/components/application_manager/src/application_manager_impl.cc
+++ b/src/components/application_manager/src/application_manager_impl.cc
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (c) 2014, Ford Motor Company
* All rights reserved.
*
@@ -35,6 +35,7 @@
#include <climits>
#include <string>
#include <fstream>
+#include <utility>
#include "application_manager/application_manager_impl.h"
#include "application_manager/mobile_command_factory.h"
@@ -51,10 +52,19 @@
#include "config_profile/profile.h"
#include "utils/threads/thread.h"
#include "utils/file_system.h"
+#include "utils/helpers.h"
+#include "smart_objects/enum_schema_item.h"
+#include "interfaces/HMI_API_schema.h"
#include "application_manager/application_impl.h"
#include "usage_statistics/counter.h"
#include <time.h>
+namespace {
+ int get_rand_from_range(uint32_t from = 0, int to = RAND_MAX) {
+ return std::rand() % to + from;
+ }
+}
+
namespace application_manager {
CREATE_LOGGERPTR_GLOBAL(logger_, "ApplicationManager")
@@ -65,6 +75,8 @@ const uint32_t ApplicationManagerImpl::max_corelation_id_ = UINT_MAX;
namespace formatters = NsSmartDeviceLink::NsJSONHandler::Formatters;
namespace jhs = NsSmartDeviceLink::NsJSONHandler::strings;
+using namespace NsSmartDeviceLink::NsSmartObjects;
+
ApplicationManagerImpl::ApplicationManagerImpl()
: applications_list_lock_(true),
audio_pass_thru_active_(false),
@@ -83,9 +95,12 @@ ApplicationManagerImpl::ApplicationManagerImpl()
messages_to_mobile_("AM ToMobile", this),
messages_from_hmi_("AM FromHMI", this),
messages_to_hmi_("AM ToHMI", this),
+ audio_pass_thru_messages_("AudioPassThru", this),
hmi_capabilities_(this),
- unregister_reason_(mobile_api::AppInterfaceUnregisteredReason::IGNITION_OFF),
+ unregister_reason_(mobile_api::AppInterfaceUnregisteredReason::INVALID_ENUM),
resume_ctrl_(this),
+ end_services_timer("EndServiceTimer", this, &ApplicationManagerImpl::EndNaviServices),
+ wait_end_service_timeout_(profile::Profile::instance()->stop_streaming_timeout()),
#ifdef TIME_TESTER
metric_observer_(NULL),
#endif // TIME_TESTER
@@ -93,8 +108,10 @@ ApplicationManagerImpl::ApplicationManagerImpl()
tts_global_properties_timer_("TTSGLPRTimer",
this,
&ApplicationManagerImpl::OnTimerSendTTSGlobalProperties,
- true) {
+ true),
+ is_low_voltage_(false) {
std::srand(std::time(0));
+ AddPolicyObserver(this);
}
ApplicationManagerImpl::~ApplicationManagerImpl() {
@@ -104,17 +121,18 @@ ApplicationManagerImpl::~ApplicationManagerImpl() {
media_manager_ = NULL;
hmi_handler_ = NULL;
connection_handler_ = NULL;
- if (hmi_so_factory_) {
+ if(hmi_so_factory_) {
delete hmi_so_factory_;
+ hmi_so_factory_ = NULL;
}
- hmi_so_factory_ = NULL;
- if (mobile_so_factory_) {
+ if(mobile_so_factory_) {
delete mobile_so_factory_;
+ mobile_so_factory_ = NULL;
}
- mobile_so_factory_ = NULL;
protocol_handler_ = NULL;
media_manager_ = NULL;
LOG4CXX_INFO(logger_, "Destroying Policy Handler");
+ RemovePolicyObserver(this);
policy::PolicyHandler::destroy();
}
@@ -129,7 +147,7 @@ bool ApplicationManagerImpl::Stop() {
}
- // for PASA customer policy backup should happen OnExitAllApp(SUSPEND)
+ // for PASA customer policy backup should happen :AllApp(SUSPEND)
LOG4CXX_INFO(logger_, "Unloading policy library.");
policy::PolicyHandler::instance()->UnloadPolicyLibrary();
@@ -137,103 +155,123 @@ bool ApplicationManagerImpl::Stop() {
}
ApplicationSharedPtr ApplicationManagerImpl::application(uint32_t app_id) const {
- sync_primitives::AutoLock lock(applications_list_lock_);
-
- std::set<ApplicationSharedPtr>::const_iterator it =
- application_list_.begin();
- for (; it != application_list_.end(); ++it) {
- if ((*it)->app_id() == app_id) {
- return (*it);
- }
- }
- return ApplicationSharedPtr();
+ AppIdPredicate finder(app_id);
+ ApplicationListAccessor accessor;
+ ApplicationSharedPtr app = accessor.Find(finder);
+ LOG4CXX_DEBUG(logger_, " app_id << " << app_id << "Found = " << app);
+ return app;
}
ApplicationSharedPtr ApplicationManagerImpl::application_by_hmi_app(
uint32_t hmi_app_id) const {
- sync_primitives::AutoLock lock(applications_list_lock_);
-
- std::set<ApplicationSharedPtr>::const_iterator it =
- application_list_.begin();
- for (; it != application_list_.end(); ++it) {
- if ((*it)->hmi_app_id() == hmi_app_id) {
- return (*it);
- }
- }
- return ApplicationSharedPtr();
+ HmiAppIdPredicate finder(hmi_app_id);
+ ApplicationListAccessor accessor;
+ ApplicationSharedPtr app = accessor.Find(finder);
+ LOG4CXX_DEBUG(logger_, " hmi_app_id << " << hmi_app_id << "Found = " << app);
+ return app;
}
ApplicationSharedPtr ApplicationManagerImpl::application_by_policy_id(
const std::string& policy_app_id) const {
- sync_primitives::AutoLock lock(applications_list_lock_);
+ MobileAppIdPredicate finder(policy_app_id);
+ ApplicationListAccessor accessor;
+ ApplicationSharedPtr app = accessor.Find(finder);
+ LOG4CXX_DEBUG(logger_, " policy_app_id << " << policy_app_id << "Found = " << app);
+ return app;
+}
- std::vector<ApplicationSharedPtr> result;
- for (std::set<ApplicationSharedPtr>::iterator it = application_list_.begin();
- application_list_.end() != it;
- ++it) {
- if (policy_app_id.compare((*it)->mobile_app_id()->asString()) == 0) {
- return *it;
- }
- }
- return ApplicationSharedPtr();
+bool ActiveAppPredicate (const ApplicationSharedPtr app) {
+ return app ? app->IsFullscreen() : false;
}
ApplicationSharedPtr ApplicationManagerImpl::active_application() const {
// TODO(DK) : check driver distraction
- for (std::set<ApplicationSharedPtr>::iterator it = application_list_.begin();
- application_list_.end() != it;
- ++it) {
- if ((*it)->IsFullscreen()) {
- return *it;
- }
- }
- return ApplicationSharedPtr();
+ ApplicationListAccessor accessor;
+ ApplicationSharedPtr app = accessor.Find(ActiveAppPredicate);
+ LOG4CXX_DEBUG(logger_, " Found = " << app);
+ return app;
}
+bool LimitedAppPredicate (const ApplicationSharedPtr app) {
+ return app ? app->hmi_level() == mobile_api::HMILevel::HMI_LIMITED :
+ false;
+}
ApplicationSharedPtr
ApplicationManagerImpl::get_limited_media_application() const {
- sync_primitives::AutoLock lock(applications_list_lock_);
-
- for (TAppListIt it = application_list_.begin();
- application_list_.end() != it; ++it) {
- if ((*it)->is_media_application() &&
- (mobile_api::HMILevel::HMI_LIMITED == (*it)->hmi_level())) {
- return *it;
- }
- }
+ ApplicationListAccessor accessor;
+ ApplicationSharedPtr app = accessor.Find(LimitedAppPredicate);
+ LOG4CXX_DEBUG(logger_, " Found = " << app);
+ return app;
+}
- return ApplicationSharedPtr();
+bool LimitedNaviAppPredicate (const ApplicationSharedPtr app) {
+ return app ? (app->is_navi() &&
+ app->hmi_level() == mobile_api::HMILevel::HMI_LIMITED) :
+ false;
}
ApplicationSharedPtr
ApplicationManagerImpl::get_limited_navi_application() const {
- sync_primitives::AutoLock lock(applications_list_lock_);
-
- for (TAppListIt it = application_list_.begin();
- application_list_.end() != it; ++it) {
- if ((*it)->allowed_support_navigation() &&
- (mobile_api::HMILevel::HMI_LIMITED == (*it)->hmi_level())) {
- return *it;
- }
- }
+ ApplicationListAccessor accessor;
+ ApplicationSharedPtr app = accessor.Find(LimitedNaviAppPredicate);
+ LOG4CXX_DEBUG(logger_, " Found = " << app);
+ return app;
+}
- return ApplicationSharedPtr();
+bool LimitedVoiceAppPredicate (const ApplicationSharedPtr app) {
+ return app ? (app->is_voice_communication_supported() &&
+ app->hmi_level() == mobile_api::HMILevel::HMI_LIMITED) :
+ false;
}
ApplicationSharedPtr
ApplicationManagerImpl::get_limited_voice_application() const {
- sync_primitives::AutoLock lock(applications_list_lock_);
+ ApplicationListAccessor accessor;
+ ApplicationSharedPtr app = accessor.Find(LimitedVoiceAppPredicate);
+ LOG4CXX_DEBUG(logger_, " Found = " << app);
+ return app;
+}
- for (TAppListIt it = application_list_.begin();
- application_list_.end() != it; ++it) {
- if ((*it)->is_voice_communication_supported() &&
- (mobile_api::HMILevel::HMI_LIMITED == (*it)->hmi_level())) {
- return *it;
- }
+bool NaviAppPredicate (const ApplicationSharedPtr app) {
+ return app ? app->is_navi() : false;
+}
+
+std::vector<ApplicationSharedPtr> ApplicationManagerImpl::applications_with_navi() {
+ ApplicationListAccessor accessor;
+ std::vector<ApplicationSharedPtr> apps = accessor.FindAll(NaviAppPredicate);
+ LOG4CXX_DEBUG(logger_, " Found count: " << apps.size());
+ return apps;
+}
+std::vector<ApplicationSharedPtr> ApplicationManagerImpl::applications_by_button(
+ uint32_t button) {
+ SubscribedToButtonPredicate finder(
+ static_cast<mobile_apis::ButtonName::eType>(button));
+ ApplicationListAccessor accessor;
+ std::vector<ApplicationSharedPtr> apps = accessor.FindAll(finder);
+ LOG4CXX_DEBUG(logger_, " Found count: " << apps.size());
+ return apps;
+}
+
+std::vector<ApplicationSharedPtr> ApplicationManagerImpl::IviInfoUpdated(
+ VehicleDataType vehicle_info, int value) {
+
+ // Notify Policy Manager if available about info it's interested in,
+ // i.e. odometer etc
+ switch (vehicle_info) {
+ case ODOMETER:
+ policy::PolicyHandler::instance()->KmsChanged(value);
+ break;
+ default:
+ break;
}
- return ApplicationSharedPtr();
+ SubscribedToIVIPredicate finder(
+ static_cast<int32_t>(vehicle_info));
+ ApplicationListAccessor accessor;
+ std::vector<ApplicationSharedPtr> apps = accessor.FindAll(NaviAppPredicate);
+ LOG4CXX_DEBUG(logger_, " vehicle_info << " << vehicle_info << "Found count: " << apps.size());
+ return apps;
}
bool ApplicationManagerImpl::DoesAudioAppWithSameHMITypeExistInFullOrLimited(
@@ -288,58 +326,13 @@ bool ApplicationManagerImpl::DoesAudioAppWithSameHMITypeExistInFullOrLimited(
return false;
}
-std::vector<ApplicationSharedPtr> ApplicationManagerImpl::applications_by_button(
- uint32_t button) {
- std::vector<ApplicationSharedPtr> result;
- for (std::set<ApplicationSharedPtr>::iterator it = application_list_.begin();
- application_list_.end() != it; ++it) {
- if ((*it)->IsSubscribedToButton(
- static_cast<mobile_apis::ButtonName::eType>(button))) {
- result.push_back(*it);
- }
- }
- return result;
-}
-
-std::vector<utils::SharedPtr<Application>> ApplicationManagerImpl::IviInfoUpdated(
-VehicleDataType vehicle_info, int value) {
- // Notify Policy Manager if available about info it's interested in,
- // i.e. odometer etc
- switch (vehicle_info) {
- case ODOMETER:
- policy::PolicyHandler::instance()->KmsChanged(value);
- break;
- default:
- break;
- }
-
- std::vector<utils::SharedPtr<application_manager::Application>> result;
- for (std::set<utils::SharedPtr<application_manager::Application>>::iterator it = application_list_.begin();
- application_list_.end() != it; ++it) {
- if ((*it)->IsSubscribedToIVI(static_cast<uint32_t>(vehicle_info))) {
- result.push_back(*it);
- }
- }
- return result;
-}
-
-std::vector<ApplicationSharedPtr> ApplicationManagerImpl::applications_with_navi() {
- std::vector<ApplicationSharedPtr> result;
- for (std::set<ApplicationSharedPtr>::iterator it = application_list_.begin();
- application_list_.end() != it;
- ++it) {
- if ((*it)->allowed_support_navigation()) {
- result.push_back(*it);
- }
- }
- return result;
-}
ApplicationSharedPtr ApplicationManagerImpl::RegisterApplication(
const utils::SharedPtr<smart_objects::SmartObject>&
request_for_registration) {
LOG4CXX_DEBUG(logger_, "Restarting application list update timer");
+ policy::PolicyHandler::instance()->OnAppsSearchStarted();
uint32_t timeout = profile::Profile::instance()->application_list_update_timeout();
application_list_update_timer_->start(timeout);
@@ -409,6 +402,7 @@ ApplicationSharedPtr ApplicationManagerImpl::RegisterApplication(
ManageMobileCommand(response);
return ApplicationSharedPtr();
}
+
application->set_device(device_id);
application->set_grammar_id(GenerateGrammarID());
mobile_api::Language::eType launguage_desired =
@@ -429,35 +423,11 @@ ApplicationSharedPtr ApplicationManagerImpl::RegisterApplication(
int32_t min_version =
message[strings::msg_params][strings::sync_msg_version]
[strings::minor_version].asInt();
-
- /*if (min_version < APIVersion::kAPIV2) {
- LOG4CXX_ERROR(logger_, "UNSUPPORTED_VERSION");
- utils::SharedPtr<smart_objects::SmartObject> response(
- MessageHelper::CreateNegativeResponse(
- connection_key, mobile_apis::FunctionID::RegisterAppInterfaceID,
- message[strings::params][strings::correlation_id],
- mobile_apis::Result::UNSUPPORTED_VERSION));
- ManageMobileCommand(response);
- delete application;
- return NULL;
- }*/
version.min_supported_api_version = static_cast<APIVersion>(min_version);
int32_t max_version =
message[strings::msg_params][strings::sync_msg_version]
[strings::major_version].asInt();
-
- /*if (max_version > APIVersion::kAPIV2) {
- LOG4CXX_ERROR(logger_, "UNSUPPORTED_VERSION");
- utils::SharedPtr<smart_objects::SmartObject> response(
- MessageHelper::CreateNegativeResponse(
- connection_key, mobile_apis::FunctionID::RegisterAppInterfaceID,
- message[strings::params][strings::correlation_id],
- mobile_apis::Result::UNSUPPORTED_VERSION));
- ManageMobileCommand(response);
- delete application;
- return NULL;
- }*/
version.max_supported_api_version = static_cast<APIVersion>(max_version);
application->set_version(version);
@@ -470,14 +440,18 @@ ApplicationSharedPtr ApplicationManagerImpl::RegisterApplication(
connection_handler_->BindProtocolVersionWithSession(
connection_key, static_cast<uint8_t>(protocol_version));
}
- if (ProtocolVersion::kV3 == protocol_version) {
+ if (protocol_version >= ProtocolVersion::kV3 &&
+ profile::Profile::instance()->heart_beat_timeout() > 0) {
connection_handler_->StartSessionHeartBeat(connection_key);
}
}
- sync_primitives::AutoLock lock(applications_list_lock_);
-
- application_list_.insert(application);
+ apps_to_register_list_lock_.Acquire();
+ apps_to_register_.erase(application);
+ apps_to_register_list_lock_.Release();
+ ApplicationListAccessor app_list_accesor;
+ application->MarkRegistered();
+ app_list_accesor.Insert(application);
return application;
}
@@ -491,6 +465,7 @@ bool ApplicationManagerImpl::LoadAppDataToHMI(ApplicationSharedPtr app) {
}
bool ApplicationManagerImpl::ActivateApplication(ApplicationSharedPtr app) {
+ LOG4CXX_AUTO_TRACE(logger_);
if (!app) {
LOG4CXX_ERROR(logger_, "Null-pointer application received.");
NOTREACHED();
@@ -502,57 +477,52 @@ bool ApplicationManagerImpl::ActivateApplication(ApplicationSharedPtr app) {
return false;
}
+ using namespace mobile_api::HMILevel;
+
bool is_new_app_media = app->is_media_application();
ApplicationSharedPtr current_active_app = active_application();
- if (mobile_api::HMILevel::eType::HMI_LIMITED != app->hmi_level()) {
+ if (HMI_LIMITED != app->hmi_level()) {
if (app->has_been_activated()) {
MessageHelper::SendAppDataToHMI(app);
}
}
- if (current_active_app.valid()) {
+ if (current_active_app) {
if (is_new_app_media && current_active_app->is_media_application()) {
- current_active_app->MakeNotAudible();
- } else if (!(current_active_app->IsAudioApplication())) {
- current_active_app->set_hmi_level(mobile_api::HMILevel::HMI_BACKGROUND);
+ MakeAppNotAudible(current_active_app->app_id());
} else {
- current_active_app->set_hmi_level(mobile_api::HMILevel::HMI_LIMITED);
+ ChangeAppsHMILevel(current_active_app->app_id(),
+ current_active_app->IsAudioApplication() ? HMI_LIMITED :
+ HMI_BACKGROUND);
}
MessageHelper::SendHMIStatusNotification(*current_active_app);
}
- app->MakeFullscreen();
+ MakeAppFullScreen(app->app_id());
if (is_new_app_media) {
ApplicationSharedPtr limited_app = get_limited_media_application();
- if (limited_app.valid()) {
- limited_app->MakeNotAudible();
- MessageHelper::SendHMIStatusNotification(*limited_app);
- }
- }
-
- if (app->is_voice_communication_supported()) {
- ApplicationSharedPtr limited_app = get_limited_voice_application();
- if (limited_app.valid()) {
- if (limited_app->is_media_application()) {
- limited_app->set_audio_streaming_state(
- mobile_api::AudioStreamingState::NOT_AUDIBLE);
+ if (limited_app ) {
+ if (!limited_app->is_navi()) {
+ MakeAppNotAudible(limited_app->app_id());
+ MessageHelper::SendHMIStatusNotification(*limited_app);
+ } else {
+ app->set_audio_streaming_state(mobile_apis::AudioStreamingState::ATTENUATED);
+ MessageHelper::SendHMIStatusNotification(*app);
}
- limited_app->set_hmi_level(mobile_api::HMILevel::HMI_BACKGROUND);
- MessageHelper::SendHMIStatusNotification(*limited_app);
}
}
- if (app->allowed_support_navigation()) {
- ApplicationSharedPtr limited_app = get_limited_navi_application();
+ if (app->is_voice_communication_supported() || app->is_navi()) {
+ ApplicationSharedPtr limited_app = get_limited_voice_application();
if (limited_app.valid()) {
if (limited_app->is_media_application()) {
limited_app->set_audio_streaming_state(
mobile_api::AudioStreamingState::NOT_AUDIBLE);
}
- limited_app->set_hmi_level(mobile_api::HMILevel::HMI_BACKGROUND);
+ ChangeAppsHMILevel(app->app_id(), HMI_BACKGROUND);
MessageHelper::SendHMIStatusNotification(*limited_app);
}
}
@@ -560,30 +530,33 @@ bool ApplicationManagerImpl::ActivateApplication(ApplicationSharedPtr app) {
return true;
}
-mobile_api::HMILevel::eType ApplicationManagerImpl::PutApplicationInFull(
+mobile_api::HMILevel::eType ApplicationManagerImpl::IsHmiLevelFullAllowed(
ApplicationSharedPtr app) {
- DCHECK(app.get())
-
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (!app) {
+ LOG4CXX_ERROR(logger_, "Application pointer invalid");
+ NOTREACHED();
+ return mobile_api::HMILevel::INVALID_ENUM;
+ }
bool is_audio_app = app->IsAudioApplication();
bool does_audio_app_with_same_type_exist =
DoesAudioAppWithSameHMITypeExistInFullOrLimited(app);
+ bool is_active_app_exist = active_application().valid();
- mobile_api::HMILevel::eType result = mobile_api::HMILevel::HMI_FULL;
- bool is_active_app_exist = active_application().valid();
+ mobile_api::HMILevel::eType result = mobile_api::HMILevel::HMI_FULL;
if (is_audio_app && does_audio_app_with_same_type_exist) {
- result = mobile_apis::HMILevel::HMI_BACKGROUND;
+ result = GetDefaultHmiLevel(app);
} else if (is_active_app_exist && is_audio_app) {
result = mobile_apis::HMILevel::HMI_LIMITED;
} else if (is_active_app_exist && (!is_audio_app)) {
- result = mobile_apis::HMILevel::HMI_BACKGROUND;
- }
-
- if (mobile_api::HMILevel::HMI_FULL == result) {
- app->set_hmi_level(result);
- MessageHelper::SendActivateAppToHMI(app->app_id());
+ result = GetDefaultHmiLevel(app);
}
+ LOG4CXX_ERROR(logger_, "is_audio_app : " << is_audio_app
+ << "; does_audio_app_with_same_type_exist : " << does_audio_app_with_same_type_exist
+ << "; is_active_app_exist : " << is_active_app_exist
+ << "; result : " << result);
return result;
}
@@ -633,6 +606,7 @@ void ApplicationManagerImpl::OnHMIStartedCooperation() {
MessageHelper::CreateModuleInfoSO(
hmi_apis::FunctionID::BasicCommunication_MixingAudioSupported));
ManageHMICommand(mixing_audio_supported_request);
+ resume_controller().ResetLaunchTime();
}
uint32_t ApplicationManagerImpl::GetNextHMICorrelationID() {
@@ -691,50 +665,23 @@ void ApplicationManagerImpl::StartAudioPassThruThread(int32_t session_key,
void ApplicationManagerImpl::SendAudioPassThroughNotification(
uint32_t session_key,
- std::vector<uint8_t> binaryData) {
- LOG4CXX_TRACE_ENTER(logger_);
+ std::vector<uint8_t>& binary_data) {
+ LOG4CXX_AUTO_TRACE(logger_);
if (!audio_pass_thru_active_) {
LOG4CXX_ERROR(logger_, "Trying to send PassThroughNotification"
" when PassThrough is not active");
return;
}
- smart_objects::SmartObject* on_audio_pass = NULL;
- on_audio_pass = new smart_objects::SmartObject();
- if (NULL == on_audio_pass) {
- LOG4CXX_ERROR_EXT(logger_, "OnAudioPassThru NULL pointer");
-
- return;
- }
-
- LOG4CXX_INFO_EXT(logger_, "Fill smart object");
-
- (*on_audio_pass)[strings::params][strings::message_type] =
- application_manager::MessageType::kNotification;
-
- (*on_audio_pass)[strings::params][strings::connection_key] =
- static_cast<int32_t>(session_key);
- (*on_audio_pass)[strings::params][strings::function_id] =
- mobile_apis::FunctionID::OnAudioPassThruID;
-
- LOG4CXX_INFO_EXT(logger_, "Fill binary data");
- // binary data
- (*on_audio_pass)[strings::params][strings::binary_data] =
- smart_objects::SmartObject(binaryData);
-
- LOG4CXX_INFO_EXT(logger_, "After fill binary data");
-
- LOG4CXX_INFO_EXT(logger_, "Send data");
- CommandSharedPtr command (
- MobileCommandFactory::CreateCommand(&(*on_audio_pass)));
- command->Init();
- command->Run();
- command->CleanUp();
+ impl::AudioData data;
+ data.session_key = session_key;
+ data.binary_data = binary_data;
+ audio_pass_thru_messages_.PostMessage(data);
}
void ApplicationManagerImpl::StopAudioPassThru(int32_t application_key) {
- LOG4CXX_TRACE_ENTER(logger_);
+ LOG4CXX_AUTO_TRACE(logger_);
sync_primitives::AutoLock lock(audio_pass_thru_lock_);
if (NULL != media_manager_) {
media_manager_->StopMicrophoneRecording(application_key);
@@ -761,7 +708,7 @@ std::string ApplicationManagerImpl::GetDeviceName(
void ApplicationManagerImpl::OnMessageReceived(
const ::protocol_handler::RawMessagePtr message) {
- LOG4CXX_INFO(logger_, "ApplicationManagerImpl::OnMessageReceived");
+ LOG4CXX_AUTO_TRACE(logger_);
if (!message) {
LOG4CXX_ERROR(logger_, "Null-pointer message received.");
@@ -779,12 +726,12 @@ void ApplicationManagerImpl::OnMessageReceived(
void ApplicationManagerImpl::OnMobileMessageSent(
const ::protocol_handler::RawMessagePtr message) {
- LOG4CXX_INFO(logger_, "ApplicationManagerImpl::OnMobileMessageSent");
+ LOG4CXX_AUTO_TRACE(logger_);
}
void ApplicationManagerImpl::OnMessageReceived(
hmi_message_handler::MessageSharedPointer message) {
- LOG4CXX_INFO(logger_, "ApplicationManagerImpl::OnMessageReceived");
+ LOG4CXX_AUTO_TRACE(logger_);
if (!message) {
LOG4CXX_ERROR(logger_, "Null-pointer message received.");
@@ -802,9 +749,15 @@ void ApplicationManagerImpl::OnErrorSending(
void ApplicationManagerImpl::OnDeviceListUpdated(
const connection_handler::DeviceMap& device_list) {
- LOG4CXX_INFO(logger_, "ApplicationManagerImpl::OnDeviceListUpdated");
+ LOG4CXX_AUTO_TRACE(logger_);
+ smart_objects::SmartObjectSPtr msg_params = MessageHelper::CreateDeviceListSO(
+ device_list);
+ if (!msg_params) {
+ LOG4CXX_WARN(logger_, "Failed to create sub-smart object.");
+ return;
+ }
- smart_objects::SmartObject* update_list = new smart_objects::SmartObject;
+ smart_objects::SmartObjectSPtr update_list = new smart_objects::SmartObject;
smart_objects::SmartObject& so_to_send = *update_list;
so_to_send[jhs::S_PARAMS][jhs::S_FUNCTION_ID] =
hmi_apis::FunctionID::BasicCommunication_UpdateDeviceList;
@@ -813,13 +766,6 @@ void ApplicationManagerImpl::OnDeviceListUpdated(
so_to_send[jhs::S_PARAMS][jhs::S_PROTOCOL_VERSION] = 3;
so_to_send[jhs::S_PARAMS][jhs::S_PROTOCOL_TYPE] = 1;
so_to_send[jhs::S_PARAMS][jhs::S_CORRELATION_ID] = GetNextHMICorrelationID();
- smart_objects::SmartObject* msg_params = MessageHelper::CreateDeviceListSO(
- device_list);
- if (!msg_params) {
- LOG4CXX_WARN(logger_, "Failed to create sub-smart object.");
- delete update_list;
- return;
- }
so_to_send[jhs::S_MSG_PARAMS] = *msg_params;
ManageHMICommand(update_list);
}
@@ -829,41 +775,25 @@ void ApplicationManagerImpl::OnFindNewApplicationsRequest() {
LOG4CXX_DEBUG(logger_, "Starting application list update timer");
uint32_t timeout = profile::Profile::instance()->application_list_update_timeout();
application_list_update_timer_->start(timeout);
+ policy::PolicyHandler::instance()->OnAppsSearchStarted();
}
-void ApplicationManagerImpl::SendUpdateAppList(const std::list<uint32_t>& applications_ids) {
- LOG4CXX_TRACE(logger_, "SendUpdateAppList");
+void ApplicationManagerImpl::SendUpdateAppList() {
+ LOG4CXX_AUTO_TRACE(logger_);
- LOG4CXX_DEBUG(logger_, applications_ids.size() << " applications.");
+ using namespace smart_objects;
+ using namespace hmi_apis;
- smart_objects::SmartObject* request = MessageHelper::CreateModuleInfoSO(
- hmi_apis::FunctionID::BasicCommunication_UpdateAppList);
- (*request)[strings::msg_params][strings::applications] =
- smart_objects::SmartObject(smart_objects::SmartType_Array);
+ SmartObjectSPtr request = MessageHelper::CreateModuleInfoSO(
+ FunctionID::BasicCommunication_UpdateAppList);
- smart_objects::SmartObject& applications =
- (*request)[strings::msg_params][strings::applications];
+ (*request)[strings::msg_params][strings::applications] = SmartObject(SmartType_Array);
- uint32_t app_count = 0;
- for (std::list<uint32_t>::const_iterator it = applications_ids.begin();
- it != applications_ids.end(); ++it) {
- ApplicationSharedPtr app = application(*it);
+ SmartObject& applications = (*request)[strings::msg_params][strings::applications];
- if (!app.valid()) {
- LOG4CXX_ERROR(logger_, "Application not found , id = " << *it);
- continue;
- }
+ PrepareApplicationListSO(applications_, applications);
+ PrepareApplicationListSO(apps_to_register_, applications);
- smart_objects::SmartObject hmi_application(smart_objects::SmartType_Map);;
- if (!MessageHelper::CreateHMIApplicationStruct(app, hmi_application)) {
- LOG4CXX_ERROR(logger_, "Can't CreateHMIApplicationStruct ', id = " << *it);
- continue;
- }
- applications[app_count++] = hmi_application;
- }
- if (app_count <= 0) {
- LOG4CXX_WARN(logger_, "Empty applications list");
- }
ManageHMICommand(request);
}
@@ -875,37 +805,59 @@ void ApplicationManagerImpl::RemoveDevice(
bool ApplicationManagerImpl::IsAudioStreamingAllowed(uint32_t application_key) const {
ApplicationSharedPtr app = application(application_key);
+ using namespace mobile_apis::HMILevel;
+ using namespace helpers;
if (!app) {
LOG4CXX_WARN(logger_, "An application is not registered.");
return false;
}
- const mobile_api::HMILevel::eType& hmi_level = app->hmi_level();
-
- if (mobile_api::HMILevel::HMI_FULL == hmi_level ||
- mobile_api::HMILevel::HMI_LIMITED == hmi_level) {
- return true;
- }
-
- return false;
+ return Compare<eType, EQ, ONE>(
+ app->hmi_level(), HMI_FULL, HMI_LIMITED);
}
bool ApplicationManagerImpl::IsVideoStreamingAllowed(uint32_t application_key) const {
ApplicationSharedPtr app = application(application_key);
+ using namespace mobile_apis::HMILevel;
+ using namespace helpers;
if (!app) {
LOG4CXX_WARN(logger_, "An application is not registered.");
return false;
}
- const mobile_api::HMILevel::eType& hmi_level = app->hmi_level();
+ LOG4CXX_DEBUG(logger_, "HMILevel: " << app->hmi_level());
+ return Compare<eType, EQ, ONE>(app->hmi_level(), HMI_FULL, HMI_LIMITED);
+}
- if (mobile_api::HMILevel::HMI_FULL == hmi_level &&
- app->hmi_supports_navi_video_streaming()) {
- return true;
- }
+mobile_apis::HMILevel::eType ApplicationManagerImpl::GetDefaultHmiLevel(
+ ApplicationSharedPtr application) const {
+ using namespace mobile_apis;
+ LOG4CXX_AUTO_TRACE(logger_);
+ HMILevel::eType default_hmi = HMILevel::HMI_NONE;
- return false;
+ if (policy::PolicyHandler::instance()->PolicyEnabled()) {
+ const std::string policy_app_id = application->mobile_app_id();
+ std::string default_hmi_string = "";
+ if (policy::PolicyHandler::instance()->GetDefaultHmi(
+ policy_app_id, &default_hmi_string)) {
+ if ("BACKGROUND" == default_hmi_string) {
+ default_hmi = HMILevel::HMI_BACKGROUND;
+ } else if ("FULL" == default_hmi_string) {
+ default_hmi = HMILevel::HMI_FULL;
+ } else if ("LIMITED" == default_hmi_string) {
+ default_hmi = HMILevel::HMI_LIMITED;
+ } else if ("NONE" == default_hmi_string) {
+ default_hmi = HMILevel::HMI_NONE;
+ } else {
+ LOG4CXX_ERROR(logger_, "Unable to convert " + default_hmi_string + " to HMILevel");
+ }
+ } else {
+ LOG4CXX_ERROR(logger_, "Unable to get default hmi_level for "
+ << policy_app_id);
+ }
+ }
+ return default_hmi;
}
uint32_t ApplicationManagerImpl::GenerateGrammarID() {
@@ -913,19 +865,23 @@ uint32_t ApplicationManagerImpl::GenerateGrammarID() {
}
uint32_t ApplicationManagerImpl::GenerateNewHMIAppID() {
- uint32_t hmi_app_id = rand();
+ LOG4CXX_TRACE(logger_, "ENTER");
+ uint32_t hmi_app_id = get_rand_from_range(1);
+ LOG4CXX_DEBUG(logger_, "GenerateNewHMIAppID value is: " << hmi_app_id);
while (resume_ctrl_.IsHMIApplicationIdExist(hmi_app_id)) {
- hmi_app_id = rand();
+ LOG4CXX_DEBUG(logger_, "HMI appID " << hmi_app_id << " is exists.");
+ hmi_app_id = get_rand_from_range(1);
+ LOG4CXX_DEBUG(logger_, "Trying new value: " << hmi_app_id);
}
+ LOG4CXX_TRACE(logger_, "EXIT");
return hmi_app_id;
}
void ApplicationManagerImpl::ReplaceMobileByHMIAppId(
smart_objects::SmartObject& message) {
MessageHelper::PrintSmartObject(message);
- flush(std::cout);
if (message.keyExists(strings::app_id)) {
ApplicationSharedPtr application =
ApplicationManagerImpl::instance()->application(
@@ -998,96 +954,133 @@ void ApplicationManagerImpl::ReplaceHMIByMobileAppId(
}
}
-bool ApplicationManagerImpl::OnServiceStartedCallback(
- const connection_handler::DeviceHandle& device_handle,
- const int32_t& session_key,
- const protocol_handler::ServiceType& type) {
- LOG4CXX_INFO(logger_,
- "OnServiceStartedCallback " << type << " in session " << session_key);
- ApplicationSharedPtr app = application(session_key);
+bool ApplicationManagerImpl::ProcessNaviService(protocol_handler::ServiceType type,
+ uint32_t connection_key) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ if (!media_manager_) {
+ LOG4CXX_DEBUG(logger_, "The media manager is not initialized.");
+ return false;
+ }
+ bool result = false;
switch (type) {
- case protocol_handler::kRpc: {
- LOG4CXX_INFO(logger_, "RPC service is about to be started.");
- break;
- }
- case protocol_handler::kMobileNav: {
- LOG4CXX_INFO(logger_, "Video service is about to be started.");
- if (media_manager_) {
- if (!app) {
- LOG4CXX_ERROR_EXT(logger_, "An application is not registered.");
- return false;
- }
- if (app->allowed_support_navigation()) {
- media_manager_->StartVideoStreaming(session_key);
- } else {
- return false;
- }
+ case protocol_handler::kMobileNav:
+ LOG4CXX_DEBUG(logger_, "Video service is about to be started.");
+ if (IsVideoStreamingAllowed(connection_key)) {
+ media_manager_->StartVideoStreaming(connection_key);
+ result = true;
}
break;
- }
- case protocol_handler::kAudio: {
- LOG4CXX_INFO(logger_, "Audio service is about to be started.");
- if (media_manager_) {
- if (!app) {
- LOG4CXX_ERROR_EXT(logger_, "An application is not registered.");
- return false;
- }
- if (app->allowed_support_navigation()) {
- media_manager_->StartAudioStreaming(session_key);
- } else {
- return false;
- }
+ case protocol_handler::kAudio:
+ LOG4CXX_DEBUG(logger_, "Audio service is about to be started.");
+ if (IsAudioStreamingAllowed(connection_key)) {
+ media_manager_->StartAudioStreaming(connection_key);
+ result = true;
}
break;
- }
- default: {
- LOG4CXX_WARN(logger_, "Unknown type of service to be started.");
+ default:
+ LOG4CXX_DEBUG(logger_, "Unknown type of service to be started.");
break;
- }
}
- return true;
+ service_status_[type] = std::make_pair(result, false);
+ return result;
+}
+
+bool ApplicationManagerImpl::OnServiceStartedCallback(
+ const connection_handler::DeviceHandle& device_handle,
+ const int32_t& session_key,
+ const protocol_handler::ServiceType& type) {
+ using namespace protocol_handler;
+ using namespace helpers;
+
+ LOG4CXX_INFO(logger_,
+ "OnServiceStartedCallback " << type << " in session " << session_key);
+ if (type == kRpc) {
+ LOG4CXX_INFO(logger_, "RPC service is about to be started.");
+ return true;
+ }
+ ApplicationSharedPtr app = application(session_key);
+ if (!app) {
+ LOG4CXX_DEBUG(logger_, "The application with id:" << session_key <<
+ " doesn't exists.");
+ return false;
+ }
+ bool result = false;
+ if (Compare<ServiceType, EQ, ONE>(type, kMobileNav, kAudio)) {
+ if (app->is_navi()) {
+ result = ProcessNaviService(type, session_key);
+ app->set_streaming_allowed(result);
+ }
+ }
+ return result;
}
void ApplicationManagerImpl::OnServiceEndedCallback(const int32_t& session_key,
const protocol_handler::ServiceType& type) {
+ using namespace protocol_handler;
LOG4CXX_INFO_EXT(
logger_,
"OnServiceEndedCallback " << type << " in session " << session_key);
- switch (type) {
- case protocol_handler::kRpc: {
- LOG4CXX_INFO(logger_, "Remove application.");
- /* in case it was unexpected disconnect application will be removed
- and we will notify HMI that it was unexpected disconnect,
- but in case it was closed by mobile we will be unable to find it in the list
- */
- UnregisterApplication(session_key, mobile_apis::Result::INVALID_ENUM,
- true, true);
- break;
- }
- case protocol_handler::kMobileNav: {
- LOG4CXX_INFO(logger_, "Stop video streaming.");
- if (media_manager_) {
+ if (type == kRpc) {
+ LOG4CXX_INFO(logger_, "Remove application.");
+ /* in case it was unexpected disconnect application will be removed
+ and we will notify HMI that it was unexpected disconnect,
+ but in case it was closed by mobile we will be unable to find it in the list
+ */
+ UnregisterApplication(session_key, mobile_apis::Result::INVALID_ENUM,
+ true, true);
+ return;
+ }
+
+ if (media_manager_) {
+ switch (type) {
+ case protocol_handler::kMobileNav: {
+ LOG4CXX_INFO(logger_, "Stop video streaming.");
media_manager_->StopVideoStreaming(session_key);
+ break;
}
- break;
- }
- case protocol_handler::kAudio: {
- LOG4CXX_INFO(logger_, "Stop audio service.");
- if (media_manager_) {
+ case protocol_handler::kAudio: {
+ LOG4CXX_INFO(logger_, "Stop audio service.");
media_manager_->StopAudioStreaming(session_key);
+ break;
}
- break;
+ default:
+ LOG4CXX_WARN(logger_, "Unknown type of service to be ended." << type);
+ break;
}
- default:
- LOG4CXX_WARN(logger_, "Unknown type of service to be ended." <<
- type);
- break;
+ service_status_[type].second = true;
+ LOG4CXX_DEBUG(logger_, "Ack status: " << service_status_[type].first <<" : "
+ << service_status_[type].second);
}
}
+void ApplicationManagerImpl::OnApplicationFloodCallBack(const uint32_t &connection_key) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_, "Unregister flooding application " << connection_key);
+
+ MessageHelper::SendOnAppInterfaceUnregisteredNotificationToMobile(
+ connection_key,
+ mobile_apis::AppInterfaceUnregisteredReason::TOO_MANY_REQUESTS);
+
+ const bool resuming = true;
+ const bool unexpected_disconnect = false;
+ UnregisterApplication(connection_key, mobile_apis::Result::TOO_MANY_PENDING_REQUESTS,
+ resuming, unexpected_disconnect);
+ // TODO(EZamakhov): increment "removals_for_bad_behaviour" field in policy table
+}
+
+void ApplicationManagerImpl::OnMalformedMessageCallback(const uint32_t &connection_key) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_, "Unregister malformed messaging application " << connection_key);
+
+ MessageHelper::SendOnAppInterfaceUnregisteredNotificationToMobile(
+ connection_key,
+ mobile_apis::AppInterfaceUnregisteredReason::PROTOCOL_VIOLATION);
+}
+
void ApplicationManagerImpl::set_hmi_message_handler(
hmi_message_handler::HMIMessageHandler* handler) {
hmi_handler_ = handler;
@@ -1113,9 +1106,8 @@ void ApplicationManagerImpl::StartDevicesDiscovery() {
}
void ApplicationManagerImpl::SendMessageToMobile(
- const utils::SharedPtr<smart_objects::SmartObject> message,
- bool final_message) {
- LOG4CXX_INFO(logger_, "ApplicationManagerImpl::SendMessageToMobile");
+ const commands::MessageSharedPtr message, bool final_message) {
+ LOG4CXX_AUTO_TRACE(logger_);
if (!message) {
LOG4CXX_ERROR(logger_, "Null-pointer message received.");
@@ -1141,7 +1133,7 @@ void ApplicationManagerImpl::SendMessageToMobile(
ProtocolVersion::kV1;
} else {
(*message)[strings::params][strings::protocol_version] =
- ProtocolVersion::kV3;
+ SupportedSDLVersion();
}
} else {
(*message)[strings::params][strings::protocol_version] =
@@ -1166,7 +1158,8 @@ void ApplicationManagerImpl::SendMessageToMobile(
// checked against policy permissions
if (msg_to_mobile[strings::params].keyExists(strings::correlation_id)) {
request_ctrl_.terminateMobileRequest(
- msg_to_mobile[strings::params][strings::correlation_id].asInt());
+ msg_to_mobile[strings::params][strings::correlation_id].asInt(),
+ msg_to_mobile[strings::params][strings::connection_key].asInt());
} else if (app) {
mobile_apis::FunctionID::eType function_id =
static_cast<mobile_apis::FunctionID::eType>(
@@ -1179,11 +1172,14 @@ void ApplicationManagerImpl::SendMessageToMobile(
smart_objects::SmartMap::iterator iter_end = s_map.map_end();
for (; iter != iter_end; ++iter) {
- params.push_back(iter->first);
+ if (true == iter->second.asBool()) {
+ LOG4CXX_INFO(logger_, "Request's param: " << iter->first);
+ params.push_back(iter->first);
+ }
}
}
const mobile_apis::Result::eType check_result =
- CheckPolicyPermissions( app->mobile_app_id()->asString(),
+ CheckPolicyPermissions( app->mobile_app_id(),
app->hmi_level(), function_id, params);
if (mobile_apis::Result::SUCCESS != check_result) {
const std::string string_functionID =
@@ -1194,7 +1190,13 @@ void ApplicationManagerImpl::SendMessageToMobile(
}
if (function_id == mobile_apis::FunctionID::OnSystemRequestID) {
- policy::PolicyHandler::instance()->OnUpdateRequestSentToMobile();
+ mobile_apis::RequestType::eType request_type =
+ static_cast<mobile_apis::RequestType::eType>(
+ (*message)[strings::msg_params][strings::request_type].asUInt());
+ if (mobile_apis::RequestType::PROPRIETARY == request_type ||
+ mobile_apis::RequestType::HTTP == request_type) {
+ policy::PolicyHandler::instance()->OnUpdateRequestSentToMobile();
+ }
}
}
@@ -1203,21 +1205,26 @@ void ApplicationManagerImpl::SendMessageToMobile(
}
bool ApplicationManagerImpl::ManageMobileCommand(
- const utils::SharedPtr<smart_objects::SmartObject> message) {
- LOG4CXX_INFO(logger_, "ApplicationManagerImpl::ManageMobileCommand");
+ const commands::MessageSharedPtr message,
+ commands::Command::CommandOrigin origin) {
+ LOG4CXX_AUTO_TRACE(logger_);
if (!message) {
LOG4CXX_WARN(logger_, "RET Null-pointer message received.");
- NOTREACHED()
return false;
}
+ if (IsLowVoltage()) {
+ LOG4CXX_WARN(logger_, "Low Voltage is active");
+ return false;
+ }
#ifdef DEBUG
MessageHelper::PrintSmartObject(*message);
#endif
LOG4CXX_INFO(logger_, "Trying to create message in mobile factory.");
- commands::Command* command = MobileCommandFactory::CreateCommand(message);
+ utils::SharedPtr<commands::Command> command(
+ MobileCommandFactory::CreateCommand(message, origin));
if (!command) {
LOG4CXX_WARN(logger_, "RET Failed to create mobile command from smart object");
@@ -1249,12 +1256,11 @@ bool ApplicationManagerImpl::ManageMobileCommand(
app = ApplicationManagerImpl::instance()->application(connection_key);
if (!app) {
LOG4CXX_ERROR_EXT(logger_, "RET APPLICATION_NOT_REGISTERED");
- smart_objects::SmartObject* response =
- MessageHelper::CreateNegativeResponse(
- connection_key,
- static_cast<int32_t>(function_id),
- correlation_id,
- static_cast<int32_t>(mobile_apis::Result::APPLICATION_NOT_REGISTERED));
+ smart_objects::SmartObjectSPtr response =
+ MessageHelper::CreateNegativeResponse(connection_key,
+ static_cast<int32_t>(function_id),
+ correlation_id,
+ static_cast<int32_t>(mobile_apis::Result::APPLICATION_NOT_REGISTERED));
SendMessageToMobile(response);
return false;
@@ -1270,18 +1276,15 @@ bool ApplicationManagerImpl::ManageMobileCommand(
command->Run();
command->CleanUp();
}
- delete command;
return true;
}
if (message_type ==
mobile_apis::messageType::notification) {
- commands::CommandNotificationImpl* command_notify =
- static_cast<commands::CommandNotificationImpl*>(command);
- request_ctrl_.addNotification(command_notify);
- if (command_notify->Init()) {
- command_notify->Run();
- if (command_notify->CleanUp()) {
- request_ctrl_.removeNotification(command_notify);
+ request_ctrl_.addNotification(command);
+ if (command->Init()) {
+ command->Run();
+ if (command->CleanUp()) {
+ request_ctrl_.removeNotification(command.get());
}
// If CleanUp returned false notification should remove it self.
}
@@ -1291,8 +1294,6 @@ bool ApplicationManagerImpl::ManageMobileCommand(
if (message_type ==
mobile_apis::messageType::request) {
- commands::CommandRequestImpl* command_request =
- static_cast<commands::CommandRequestImpl*>(command);
// commands will be launched from requesr_ctrl
mobile_apis::HMILevel::eType app_hmi_level = mobile_apis::HMILevel::INVALID_ENUM;
if (app) {
@@ -1301,8 +1302,8 @@ bool ApplicationManagerImpl::ManageMobileCommand(
// commands will be launched from request_ctrl
- request_controller::RequestController::TResult result =
- request_ctrl_.addMobileRequest(command_request, app_hmi_level);
+ const request_controller::RequestController::TResult result =
+ request_ctrl_.addMobileRequest(command, app_hmi_level);
if (result == request_controller::RequestController::SUCCESS) {
LOG4CXX_INFO(logger_, "Perform request");
@@ -1312,12 +1313,11 @@ bool ApplicationManagerImpl::ManageMobileCommand(
LOG4CXX_ERROR_EXT(logger_, "RET Unable top perform request: " <<
"TOO_MANY_PENDING_REQUESTS");
- smart_objects::SmartObject* response =
- MessageHelper::CreateNegativeResponse(
- connection_key,
- static_cast<int32_t>(function_id),
- correlation_id,
- static_cast<int32_t>(mobile_apis::Result::TOO_MANY_PENDING_REQUESTS));
+ smart_objects::SmartObjectSPtr response =
+ MessageHelper::CreateNegativeResponse(connection_key,
+ static_cast<int32_t>(function_id),
+ correlation_id,
+ static_cast<int32_t>(mobile_apis::Result::TOO_MANY_PENDING_REQUESTS));
SendMessageToMobile(response);
return false;
@@ -1344,7 +1344,10 @@ bool ApplicationManagerImpl::ManageMobileCommand(
connection_key, mobile_api::AppInterfaceUnregisteredReason::
REQUEST_WHILE_IN_NONE_HMI_LEVEL);
- application(connection_key)->usage_report().RecordRemovalsForBadBehavior();
+ ApplicationSharedPtr app_ptr = application(connection_key);
+ if(app_ptr) {
+ app_ptr->usage_report().RecordRemovalsForBadBehavior();
+ }
UnregisterApplication(connection_key, mobile_apis::Result::INVALID_ENUM,
false);
return false;
@@ -1360,8 +1363,8 @@ bool ApplicationManagerImpl::ManageMobileCommand(
}
void ApplicationManagerImpl::SendMessageToHMI(
- const utils::SharedPtr<smart_objects::SmartObject> message) {
- LOG4CXX_INFO(logger_, "ApplicationManagerImpl::SendMessageToHMI");
+ const commands::MessageSharedPtr message) {
+ LOG4CXX_AUTO_TRACE(logger_);
if (!message) {
LOG4CXX_WARN(logger_, "Null-pointer message received.");
@@ -1387,7 +1390,6 @@ void ApplicationManagerImpl::SendMessageToHMI(
logger_,
"Attached schema to message, result if valid: " << message->isValid());
-
#ifdef HMI_DBUS_API
message_to_send->set_smart_object(*message);
#else
@@ -1402,15 +1404,18 @@ void ApplicationManagerImpl::SendMessageToHMI(
}
bool ApplicationManagerImpl::ManageHMICommand(
- const utils::SharedPtr<smart_objects::SmartObject> message) {
- LOG4CXX_INFO(logger_, "ApplicationManagerImpl::ManageHMICommand");
+ const commands::MessageSharedPtr message) {
+ LOG4CXX_AUTO_TRACE(logger_);
if (!message) {
LOG4CXX_WARN(logger_, "Null-pointer message received.");
- NOTREACHED();
return false;
}
+ if (IsLowVoltage()) {
+ LOG4CXX_WARN(logger_, "Low Voltage is active");
+ return false;
+ }
MessageHelper::PrintSmartObject(*message);
@@ -1440,19 +1445,6 @@ bool ApplicationManagerImpl::ManageHMICommand(
bool ApplicationManagerImpl::Init() {
LOG4CXX_TRACE(logger_, "Init application manager");
- if (policy::PolicyHandler::instance()->PolicyEnabled()) {
- if(!policy::PolicyHandler::instance()->LoadPolicyLibrary()) {
- LOG4CXX_ERROR(logger_, "Policy library is not loaded. Check LD_LIBRARY_PATH");
- return false;
- }
- LOG4CXX_INFO(logger_, "Policy library is loaded, now initing PT");
- if (!policy::PolicyHandler::instance()->InitPolicyTable()) {
- LOG4CXX_ERROR(logger_, "Policy table is not initialized.");
- return false;
- }
- } else {
- LOG4CXX_WARN(logger_, "System is configured to work without policy functionality.");
- }
const std::string app_storage_folder =
profile::Profile::instance()->app_storage_folder();
if (!file_system::DirectoryExists(app_storage_folder)) {
@@ -1488,6 +1480,19 @@ bool ApplicationManagerImpl::Init() {
"System directory doesn't have read/write permissions");
return false;
}
+ if (policy::PolicyHandler::instance()->PolicyEnabled()) {
+ if(!policy::PolicyHandler::instance()->LoadPolicyLibrary()) {
+ LOG4CXX_ERROR(logger_, "Policy library is not loaded. Check LD_LIBRARY_PATH");
+ return false;
+ }
+ LOG4CXX_INFO(logger_, "Policy library is loaded, now initing PT");
+ if (!policy::PolicyHandler::instance()->InitPolicyTable()) {
+ LOG4CXX_ERROR(logger_, "Policy table is not initialized.");
+ return false;
+ }
+ } else {
+ LOG4CXX_WARN(logger_, "System is configured to work without policy functionality.");
+ }
media_manager_ = media_manager::MediaManagerImpl::instance();
return true;
}
@@ -1500,6 +1505,7 @@ bool ApplicationManagerImpl::ConvertMessageToSO(
<< "; json " << message.json_message());
switch (message.protocol_version()) {
+ case ProtocolVersion::kV4:
case ProtocolVersion::kV3:
case ProtocolVersion::kV2: {
const bool conversion_result =
@@ -1559,7 +1565,20 @@ bool ApplicationManagerImpl::ConvertMessageToSO(
return false;
}
if (output.validate() != smart_objects::Errors::OK) {
- LOG4CXX_WARN(logger_, "Incorrect parameter from HMI");
+ LOG4CXX_ERROR(logger_, "Incorrect parameter from HMI");
+
+ if (application_manager::MessageType::kNotification ==
+ output[strings::params][strings::message_type].asInt()) {
+ LOG4CXX_ERROR(logger_, "Ignore wrong HMI notification");
+ return false;
+ }
+
+ if (application_manager::MessageType::kRequest ==
+ output[strings::params][strings::message_type].asInt()) {
+ LOG4CXX_ERROR(logger_, "Ignore wrong HMI request");
+ return false;
+ }
+
output.erase(strings::msg_params);
output[strings::params][hmi_response::code] =
hmi_apis::Common_Result::INVALID_DATA;
@@ -1595,7 +1614,7 @@ bool ApplicationManagerImpl::ConvertMessageToSO(
output[strings::msg_params][strings::result_code] =
NsSmartDeviceLinkRPC::V1::Result::UNSUPPORTED_VERSION;
- smart_objects::SmartObject* msg_to_send = new smart_objects::SmartObject(output);
+ smart_objects::SmartObjectSPtr msg_to_send = new smart_objects::SmartObject(output);
v1_shema.attachSchema(*msg_to_send);
SendMessageToMobile(msg_to_send);
return false;
@@ -1728,18 +1747,7 @@ utils::SharedPtr<Message> ApplicationManagerImpl::ConvertRawMsgToMessage(
return outgoing_message;
}
- Message* convertion_result = NULL;
- if (message->protocol_version() == 1) {
- convertion_result =
- MobileMessageHandler::HandleIncomingMessageProtocolV1(message);
- } else if ((message->protocol_version() == 2) ||
- (message->protocol_version() == 3)) {
- convertion_result =
- MobileMessageHandler::HandleIncomingMessageProtocolV2(message);
- } else {
- LOG4CXX_WARN(logger_, "Unknown protocol version.");
- return outgoing_message;
- }
+ Message* convertion_result = MobileMessageHandler::HandleIncomingMessageProtocol(message);
if (convertion_result) {
outgoing_message = convertion_result;
@@ -1756,8 +1764,7 @@ void ApplicationManagerImpl::ProcessMessageFromMobile(
AMMetricObserver::MessageMetricSharedPtr metric(new AMMetricObserver::MessageMetric());
metric->begin = date_time::DateTime::getCurrentTime();
#endif // TIME_TESTER
- utils::SharedPtr<smart_objects::SmartObject> so_from_mobile(
- new smart_objects::SmartObject);
+ smart_objects::SmartObjectSPtr so_from_mobile(new smart_objects::SmartObject);
if (!so_from_mobile) {
LOG4CXX_ERROR(logger_, "Null pointer");
@@ -1772,7 +1779,8 @@ void ApplicationManagerImpl::ProcessMessageFromMobile(
metric->message = so_from_mobile;
#endif // TIME_TESTER
- if (!ManageMobileCommand(so_from_mobile)) {
+ if (!ManageMobileCommand(so_from_mobile,
+ commands::Command::ORIGIN_MOBILE)) {
LOG4CXX_ERROR(logger_, "Received command didn't run successfully");
}
#ifdef TIME_TESTER
@@ -1786,8 +1794,7 @@ void ApplicationManagerImpl::ProcessMessageFromMobile(
void ApplicationManagerImpl::ProcessMessageFromHMI(
const utils::SharedPtr<Message> message) {
LOG4CXX_INFO(logger_, "ApplicationManagerImpl::ProcessMessageFromHMI()");
- utils::SharedPtr<smart_objects::SmartObject> smart_object(
- new smart_objects::SmartObject);
+ smart_objects::SmartObjectSPtr smart_object(new smart_objects::SmartObject);
if (!smart_object) {
LOG4CXX_ERROR(logger_, "Null pointer");
@@ -1835,6 +1842,63 @@ HMICapabilities& ApplicationManagerImpl::hmi_capabilities() {
return hmi_capabilities_;
}
+void ApplicationManagerImpl::CreateApplications(SmartArray& obj_array) {
+
+ using namespace policy;
+
+ const std::size_t arr_size(obj_array.size());
+ for (std::size_t idx = 0; idx < arr_size; ++idx) {
+
+ const SmartObject& app_data = obj_array[idx];
+ if (app_data.isValid()) {
+ const std::string url_schema(app_data[strings::urlSchema].asString());
+ const std::string package_name(app_data[strings::packageName].asString());
+ const std::string mobile_app_id(app_data[strings::app_id].asString());
+ const std::string appName(app_data[strings::app_name].asString());
+
+ const uint32_t hmi_app_id(GenerateNewHMIAppID());
+
+ ApplicationSharedPtr app(
+ new ApplicationImpl(0,
+ mobile_app_id,
+ appName,
+ PolicyHandler::instance()->GetStatisticManager()));
+ if (app) {
+ app->SetShemaUrl(url_schema);
+ app->SetPackageName(package_name);
+ app->set_hmi_application_id(hmi_app_id);
+
+ sync_primitives::AutoLock lock(apps_to_register_list_lock_);
+ apps_to_register_.insert(app);
+ }
+ }
+ }
+}
+
+void ApplicationManagerImpl::ProcessQueryApp(
+ const smart_objects::SmartObject& sm_object) {
+ using namespace policy;
+ using namespace profile;
+
+ if (sm_object.keyExists(strings::application)) {
+ SmartArray* obj_array = sm_object[strings::application].asArray();
+ if (NULL != obj_array) {
+ const std::string app_icon_dir(Profile::instance()->app_icons_folder());
+ CreateApplications(*obj_array);
+ SendUpdateAppList();
+
+ AppsWaitRegistrationSet::const_iterator it = apps_to_register_.begin();
+ for (; it != apps_to_register_.end(); ++it) {
+
+ const std::string full_icon_path(app_icon_dir + "/" + (*it)->mobile_app_id());
+ if (file_system::FileExists(full_icon_path)) {
+ MessageHelper::SendSetAppIcon((*it)->hmi_app_id(), full_icon_path);
+ }
+ }
+ }
+ }
+}
+
#ifdef TIME_TESTER
void ApplicationManagerImpl::SetTimeMetricObserver(AMMetricObserver* observer) {
metric_observer_ = observer;
@@ -1852,6 +1916,7 @@ void ApplicationManagerImpl::removeNotification(const commands::Command* notific
void ApplicationManagerImpl::updateRequestTimeout(uint32_t connection_key,
uint32_t mobile_correlation_id,
uint32_t new_timeout_value) {
+ LOG4CXX_AUTO_TRACE(logger_);
request_ctrl_.updateRequestTimeout(connection_key, mobile_correlation_id,
new_timeout_value);
}
@@ -1876,8 +1941,17 @@ void ApplicationManagerImpl::set_application_id(const int32_t correlation_id,
(correlation_id, app_id));
}
+void ApplicationManagerImpl::AddPolicyObserver( policy::PolicyHandlerObserver* listener) {
+ policy::PolicyHandler::instance()->add_listener(listener);
+}
+
+void ApplicationManagerImpl::RemovePolicyObserver(policy::PolicyHandlerObserver* listener) {
+ policy::PolicyHandler::instance()->remove_listener(listener);
+}
+
void ApplicationManagerImpl::SetUnregisterAllApplicationsReason(
mobile_api::AppInterfaceUnregisteredReason::eType reason) {
+ LOG4CXX_TRACE(logger_, "reason = " << reason);
unregister_reason_ = reason;
}
@@ -1885,9 +1959,12 @@ void ApplicationManagerImpl::HeadUnitReset(
mobile_api::AppInterfaceUnregisteredReason::eType reason) {
switch (reason) {
case mobile_api::AppInterfaceUnregisteredReason::MASTER_RESET: {
- file_system::remove_directory_content(profile::Profile::instance()->app_storage_folder());
- resume_controller().ClearResumptionInfo();
+ UnregisterAllApplications();
policy::PolicyHandler::instance()->ResetPolicyTable();
+ policy::PolicyHandler::instance()->UnloadPolicyLibrary();
+
+ resume_controller().StopSavePersistentDataTimer();
+ file_system::remove_directory_content(profile::Profile::instance()->app_storage_folder());
break;
}
case mobile_api::AppInterfaceUnregisteredReason::FACTORY_DEFAULTS: {
@@ -1901,15 +1978,12 @@ void ApplicationManagerImpl::HeadUnitReset(
}
}
-void ApplicationManagerImpl::HeadUnitSuspend() {
- LOG4CXX_INFO(logger_, "ApplicationManagerImpl::HeadUnitSuspend");
-}
void ApplicationManagerImpl::SendOnSDLClose() {
- LOG4CXX_INFO(logger_, "ApplicationManagerImpl::SendOnSDLClose");
+ LOG4CXX_AUTO_TRACE(logger_);
// must be sent to PASA HMI on shutdown synchronously
- smart_objects::SmartObject* msg = new smart_objects::SmartObject(
+ smart_objects::SmartObjectSPtr msg = new smart_objects::SmartObject(
smart_objects::SmartType_Map);
(*msg)[strings::params][strings::function_id] =
@@ -1952,39 +2026,38 @@ void ApplicationManagerImpl::SendOnSDLClose() {
return;
}
- delete msg;
hmi_handler_->SendMessageToHMI(message_to_send);
}
-void ApplicationManagerImpl::UnregisterAllApplications(bool generated_by_hmi) {
- LOG4CXX_INFO(logger_, "ApplicationManagerImpl::UnregisterAllApplications " <<
- unregister_reason_);
- hmi_cooperating_ = false;
-
- bool is_ignition_off =
- unregister_reason_ ==
- mobile_api::AppInterfaceUnregisteredReason::IGNITION_OFF ? true : false;
-
- bool is_unexpected_disconnect = (generated_by_hmi != true);
-
- sync_primitives::AutoLock lock(applications_list_lock_);
+void ApplicationManagerImpl::UnregisterAllApplications() {
+ LOG4CXX_DEBUG(logger_, "Unregister reason " << unregister_reason_);
- std::set<ApplicationSharedPtr>::iterator it = application_list_.begin();
- while (it != application_list_.end()) {
+ hmi_cooperating_ = false;
+ bool is_ignition_off = false;
+ using namespace mobile_api::AppInterfaceUnregisteredReason;
+ using namespace helpers;
+
+ is_ignition_off =
+ Compare<eType, EQ, ONE>(unregister_reason_, IGNITION_OFF, INVALID_ENUM);
+
+ bool is_unexpected_disconnect =
+ Compare<eType, NEQ, ALL>(unregister_reason_,
+ IGNITION_OFF, MASTER_RESET, FACTORY_DEFAULTS);
+ ApplicationListAccessor accessor;
+ ApplictionSetConstIt it = accessor.begin();
+ while (it != accessor.end()) {
ApplicationSharedPtr app_to_remove = *it;
- MessageHelper::SendOnAppInterfaceUnregisteredNotificationToMobile(
- app_to_remove->app_id(), unregister_reason_);
+
UnregisterApplication(app_to_remove->app_id(),
mobile_apis::Result::INVALID_ENUM, is_ignition_off,
is_unexpected_disconnect);
-
- connection_handler_->CloseSession(app_to_remove->app_id());
- it = application_list_.begin();
+ connection_handler_->CloseSession(app_to_remove->app_id(),
+ connection_handler::kCommon);
+ it = accessor.begin();
}
-
if (is_ignition_off) {
- resume_controller().IgnitionOff();
+ resume_controller().Suspend();
}
request_ctrl_.terminateAllHMIRequests();
}
@@ -1992,12 +2065,15 @@ void ApplicationManagerImpl::UnregisterAllApplications(bool generated_by_hmi) {
void ApplicationManagerImpl::UnregisterApplication(
const uint32_t& app_id, mobile_apis::Result::eType reason,
bool is_resuming, bool is_unexpected_disconnect) {
- LOG4CXX_INFO(logger_,
- "ApplicationManagerImpl::UnregisterApplication " << app_id);
+ LOG4CXX_INFO(logger_, "app_id = " << app_id
+ << "; reason = " << reason
+ << "; is_resuming = " << is_resuming
+ << "; is_unexpected_disconnect = " << is_unexpected_disconnect);
//remove appID from tts_global_properties_app_list_
- RemoveAppFromTTSGlobalPropertiesList(app_id);
+ MessageHelper::SendOnAppInterfaceUnregisteredNotificationToMobile(
+ app_id, unregister_reason_);
- sync_primitives::AutoLock lock(applications_list_lock_);
+ RemoveAppFromTTSGlobalPropertiesList(app_id);
switch (reason) {
case mobile_apis::Result::SUCCESS:break;
@@ -2006,7 +2082,10 @@ void ApplicationManagerImpl::UnregisterApplication(
case mobile_apis::Result::INVALID_CERT: break;
case mobile_apis::Result::EXPIRED_CERT: break;
case mobile_apis::Result::TOO_MANY_PENDING_REQUESTS: {
- application(app_id)->usage_report().RecordRemovalsForBadBehavior();
+ ApplicationSharedPtr app_ptr = application(app_id);
+ if(app_ptr) {
+ app_ptr->usage_report().RecordRemovalsForBadBehavior();
+ }
break;
}
default: {
@@ -2016,21 +2095,25 @@ void ApplicationManagerImpl::UnregisterApplication(
}
ApplicationSharedPtr app_to_remove;
- std::set<ApplicationSharedPtr>::const_iterator it = application_list_.begin();
- for (; it != application_list_.end(); ++it) {
- if ((*it)->app_id() == app_id) {
- app_to_remove = *it;
- break;
+ {
+ ApplicationListAccessor accessor;
+ ApplictionSetConstIt it = accessor.begin();
+ for (; it != accessor.end(); ++it) {
+ if ((*it)->app_id() == app_id) {
+ app_to_remove = *it;
+ break;
+ }
}
+ if (!app_to_remove) {
+ LOG4CXX_ERROR(logger_, "Cant find application with app_id = " << app_id);
+ return;
+ }
+ accessor.Erase(app_to_remove);
}
- if (!app_to_remove) {
- LOG4CXX_ERROR(logger_, "Cant find application with app_id = " << app_id);
- return;
- }
- application_list_.erase(app_to_remove);
-
if (is_resuming) {
- resume_ctrl_.SaveApplication(app_to_remove);
+ resume_ctrl_.SaveApplication(app_to_remove);
+ } else {
+ resume_ctrl_.RemoveApplicationFromSaved(app_to_remove->mobile_app_id());
}
if (audio_pass_thru_active_) {
@@ -2047,15 +2130,8 @@ void ApplicationManagerImpl::UnregisterApplication(
}
-void ApplicationManagerImpl::UnregisterRevokedApplication(
- const uint32_t& app_id, mobile_apis::Result::eType reason) {
- UnregisterApplication(app_id, reason);
-
- connection_handler_->CloseSession(app_id);
-
- if (application_list_.empty()) {
- connection_handler_->CloseRevokedConnection(app_id);
- }
+void ApplicationManagerImpl::OnAppUnauthorized(const uint32_t& app_id) {
+ connection_handler_->CloseSession(app_id, connection_handler::kCommon);
}
void ApplicationManagerImpl::Handle(const impl::MessageFromMobile message) {
@@ -2069,26 +2145,19 @@ void ApplicationManagerImpl::Handle(const impl::MessageFromMobile message) {
}
void ApplicationManagerImpl::Handle(const impl::MessageToMobile message) {
- protocol_handler::RawMessage* rawMessage = 0;
- if (message->protocol_version() == application_manager::kV1) {
- rawMessage = MobileMessageHandler::HandleOutgoingMessageProtocolV1(message);
- } else if ((message->protocol_version() == application_manager::kV2) ||
- (message->protocol_version() == application_manager::kV3)) {
- rawMessage = MobileMessageHandler::HandleOutgoingMessageProtocolV2(message);
- } else {
- return;
- }
- if (!rawMessage) {
- LOG4CXX_ERROR(logger_, "Failed to create raw message.");
- return;
- }
-
if (!protocol_handler_) {
LOG4CXX_WARN(logger_,
"Protocol Handler is not set; cannot send message to mobile.");
return;
}
+ utils::SharedPtr<protocol_handler::RawMessage> rawMessage =
+ MobileMessageHandler::HandleOutgoingMessageProtocol(message);
+
+ if (!rawMessage) {
+ LOG4CXX_ERROR(logger_, "Failed to create raw message.");
+ return;
+ }
bool is_final = message.is_final;
bool close_session = false;
@@ -2103,7 +2172,8 @@ void ApplicationManagerImpl::Handle(const impl::MessageToMobile message) {
LOG4CXX_INFO(logger_, "Message for mobile given away");
if (close_session) {
- connection_handler_->CloseSession(message->connection_key());
+ connection_handler_->CloseSession(message->connection_key(),
+ connection_handler::kCommon);
}
}
@@ -2129,6 +2199,41 @@ void ApplicationManagerImpl::Handle(const impl::MessageToHmi message) {
LOG4CXX_INFO(logger_, "Message to hmi given away.");
}
+void ApplicationManagerImpl::Handle(const impl::AudioData message) {
+ LOG4CXX_INFO(logger_, "Send AudioPassThru notification");
+ smart_objects::SmartObjectSPtr on_audio_pass = new smart_objects::SmartObject();
+
+ if (!on_audio_pass) {
+ LOG4CXX_ERROR_EXT(logger_, "OnAudioPassThru NULL pointer");
+ return;
+ }
+
+ LOG4CXX_INFO_EXT(logger_, "Fill smart object");
+
+ (*on_audio_pass)[strings::params][strings::message_type] =
+ application_manager::MessageType::kNotification;
+
+ (*on_audio_pass)[strings::params][strings::connection_key] =
+ static_cast<int32_t>(message.session_key);
+ (*on_audio_pass)[strings::params][strings::function_id] =
+ mobile_apis::FunctionID::OnAudioPassThruID;
+
+ LOG4CXX_INFO_EXT(logger_, "Fill binary data");
+ // binary data
+ (*on_audio_pass)[strings::params][strings::binary_data] =
+ smart_objects::SmartObject(message.binary_data);
+
+ LOG4CXX_INFO_EXT(logger_, "After fill binary data");
+
+ LOG4CXX_INFO_EXT(logger_, "Send data");
+ CommandSharedPtr command (
+ MobileCommandFactory::CreateCommand(on_audio_pass,
+ commands::Command::ORIGIN_SDL));
+ command->Init();
+ command->Run();
+ command->CleanUp();
+}
+
mobile_apis::Result::eType ApplicationManagerImpl::CheckPolicyPermissions(
const std::string& policy_app_id,
mobile_apis::HMILevel::eType hmi_level,
@@ -2200,16 +2305,185 @@ mobile_apis::Result::eType ApplicationManagerImpl::CheckPolicyPermissions(
return mobile_api::Result::SUCCESS;
}
+
+void ApplicationManagerImpl::OnLowVoltage() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ is_low_voltage_ = true;
+ request_ctrl_.OnLowVoltage();
+}
+
+bool ApplicationManagerImpl::IsLowVoltage() {
+ LOG4CXX_TRACE(logger_, "result: " << is_low_voltage_);
+ return is_low_voltage_;
+}
+
+void ApplicationManagerImpl::NaviAppStreamStatus(bool stream_active) {
+ ApplicationSharedPtr active_app = active_application();
+ using namespace mobile_apis;
+ if(active_app && active_app->is_media_application()) {
+ LOG4CXX_DEBUG(logger_, "Stream status: " << active_app->app_id());
+
+ active_app->set_audio_streaming_state(stream_active ?
+ AudioStreamingState::ATTENUATED :
+ AudioStreamingState::AUDIBLE);
+ MessageHelper::SendHMIStatusNotification(*active_app);
+ }
+}
+
+void ApplicationManagerImpl::ForbidStreaming(uint32_t app_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ using namespace protocol_handler;
+ ApplicationSharedPtr app = application(app_id);
+ if (!(app && app->is_navi())) {
+ LOG4CXX_DEBUG(logger_, " There is no application with id: " << app_id);
+ return;
+ }
+
+ if (connection_handler_) {
+ const bool send_end_service = true;
+ const bool ack_received = false;
+ if (app->hmi_supports_navi_video_streaming()) {
+ LOG4CXX_DEBUG(logger_, "Going to end video service");
+ connection_handler_->SendEndService(navi_app_to_stop_, kMobileNav);
+ service_status_[kMobileNav] = std::make_pair(send_end_service, ack_received);
+ }
+ if (app->hmi_supports_navi_audio_streaming()) {
+ LOG4CXX_DEBUG(logger_, "Going to end audio service");
+ connection_handler_->SendEndService(navi_app_to_stop_, kAudio);
+ service_status_[kAudio] = std::make_pair(send_end_service, ack_received);
+ }
+ }
+ // this timer will check if appropriate acks from mobile were received.
+ // in case no acks, the application will be unregistered.
+ end_services_timer.start(wait_end_service_timeout_, this, &ApplicationManagerImpl::CloseNaviApp);
+ bool const allow_streaming = false;
+ ChangeStreamStatus(app_id, allow_streaming);
+}
+
+bool ApplicationManagerImpl::CanAppStream(uint32_t app_id) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ ApplicationSharedPtr app = application(app_id);
+ if (!(app && app->is_navi())) {
+ LOG4CXX_DEBUG(logger_, " There is no application with id: " << app_id);
+ return false;
+ }
+
+ return app->is_streaming_allowed();
+}
+
+void ApplicationManagerImpl::ChangeStreamStatus(uint32_t app_id, bool can_stream) {
+ ApplicationSharedPtr app = application(app_id);
+ if (!app) {
+ LOG4CXX_DEBUG(logger_, " There is no application with id: " << app_id);
+ return;
+ }
+
+ // Change streaming status only in case incoming value is different.
+ if (can_stream != app->streaming()) {
+ NaviAppStreamStatus(can_stream);
+ app->set_streaming(can_stream);
+ }
+}
+
+void ApplicationManagerImpl::StreamingEnded(uint32_t app_id) {
+ LOG4CXX_DEBUG(logger_, "Streaming has been stoped.");
+ ChangeStreamStatus(app_id, false);
+}
+
+void ApplicationManagerImpl::OnHMILevelChanged(uint32_t app_id,
+ mobile_apis::HMILevel::eType from,
+ mobile_apis::HMILevel::eType to) {
+ using namespace mobile_apis::HMILevel;
+ using namespace helpers;
+
+ ApplicationSharedPtr app = application(app_id);
+ if (!(app && app->is_navi())) {
+ return;
+ }
+
+ if (Compare<eType, EQ, ONE>(from, HMI_FULL, HMI_LIMITED)) {
+ navi_app_to_stop_ = app_id;
+ NaviAppChangeLevel(to);
+ } else if (Compare<eType, EQ, ONE>(to, HMI_FULL, HMI_LIMITED)) {
+ LOG4CXX_DEBUG(logger_, "Restore streaming ability");
+ app->set_streaming_allowed(true);
+ }
+}
+
+void ApplicationManagerImpl::EndNaviServices() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ ApplicationSharedPtr app = application(navi_app_to_stop_);
+ if (!app) {
+ LOG4CXX_DEBUG(logger_, "The application doesn't exists anymore.");
+ return;
+ }
+ app->set_streaming_allowed(false);
+}
+
+void ApplicationManagerImpl::CloseNaviApp() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ using namespace mobile_apis::AppInterfaceUnregisteredReason;
+ using namespace mobile_apis::Result;
+ using namespace protocol_handler;
+ const bool is_ack_received = AckReceived(kAudio) && AckReceived(kMobileNav);
+ if (!is_ack_received) {
+ SetUnregisterAllApplicationsReason(PROTOCOL_VIOLATION);
+ UnregisterApplication(navi_app_to_stop_, ABORTED);
+ }
+}
+
+bool ApplicationManagerImpl::AckReceived(protocol_handler::ServiceType type) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ using namespace protocol_handler;
+
+ const bool sent = service_status_[type].first;
+ const bool received = service_status_[type].second;
+
+ LOG4CXX_DEBUG(logger_, "Ack for services type " << type
+ << " is send: " << sent
+ << " is received: " << received);
+
+ return sent == received;
+}
+
+void ApplicationManagerImpl::NaviAppChangeLevel(mobile_apis::HMILevel::eType new_level) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ using namespace mobile_apis;
+ if (new_level == HMILevel::HMI_BACKGROUND) {
+ end_services_timer.start(wait_end_service_timeout_, this, &ApplicationManagerImpl::EndNaviServices);
+ } else if (new_level == HMILevel::HMI_NONE) {
+ EndNaviServices();
+ LOG4CXX_DEBUG(logger_, "Send end services start close app timer");
+ end_services_timer.start(wait_end_service_timeout_, this, &ApplicationManagerImpl::CloseNaviApp);
+ } else {
+ LOG4CXX_DEBUG(logger_, "There is no defined behavior for hmi " <<
+ "levels that are differen from NONE or BACKGROUND");
+ }
+}
+
+void ApplicationManagerImpl::OnWakeUp() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ is_low_voltage_ = false;
+ request_ctrl_.OnWakeUp();
+}
+
void ApplicationManagerImpl::Mute(VRTTSSessionChanging changing_state) {
mobile_apis::AudioStreamingState::eType state =
- hmi_capabilities_.attenuated_supported()
- ? mobile_apis::AudioStreamingState::ATTENUATED
- : mobile_apis::AudioStreamingState::NOT_AUDIBLE;
+ mobile_apis::AudioStreamingState::NOT_AUDIBLE;
+
+ // ATTENUATED state applicable only for TTS
+ if ((kTTSSessionChanging == changing_state) &&
+ hmi_capabilities_.attenuated_supported()) {
+ state = mobile_apis::AudioStreamingState::ATTENUATED;
+ }
+
ApplicationManagerImpl::ApplicationListAccessor accessor;
- ApplicationManagerImpl::TAppList local_app_list = accessor.applications();
- ApplicationManagerImpl::TAppListConstIt it = local_app_list.begin();
- ApplicationManagerImpl::TAppListConstIt itEnd = local_app_list.end();
+ ApplicationManagerImpl::ApplictionSetConstIt it =
+ accessor.begin();
+ ApplicationManagerImpl::ApplictionSetConstIt
+ itEnd = accessor.end();
for (; it != itEnd; ++it) {
if ((*it).valid()) {
if ((*it)->is_media_application()) {
@@ -2230,9 +2504,8 @@ void ApplicationManagerImpl::Mute(VRTTSSessionChanging changing_state) {
void ApplicationManagerImpl::Unmute(VRTTSSessionChanging changing_state) {
ApplicationManagerImpl::ApplicationListAccessor accessor;
- ApplicationManagerImpl::TAppList local_app_list = application_list_;
- ApplicationManagerImpl::TAppListConstIt it = local_app_list.begin();
- ApplicationManagerImpl::TAppListConstIt itEnd = local_app_list.end();
+ ApplicationManagerImpl::ApplictionSetConstIt it = accessor.begin();
+ ApplicationManagerImpl::ApplictionSetConstIt itEnd = accessor.end();
for (; it != itEnd; ++it) {
if ((*it).valid()) {
@@ -2332,19 +2605,8 @@ bool ApplicationManagerImpl::IsHMICooperating() const {
void ApplicationManagerImpl::OnApplicationListUpdateTimer() {
LOG4CXX_DEBUG(logger_, "Application list update timer finished");
-
- std::list <uint32_t> applications_ids;
-
- applications_list_lock_.Acquire();
- for (std::set<ApplicationSharedPtr>::const_iterator i = application_list_.begin();
- i != application_list_.end(); ++i) {
- ApplicationSharedPtr application = *i;
- uint32_t app_id = application->app_id();
- applications_ids.push_back(app_id);
- }
- applications_list_lock_.Release();
-
- SendUpdateAppList(applications_ids);
+ SendUpdateAppList();
+ policy::PolicyHandler::instance()->OnAppsSearchCompleted();
}
void ApplicationManagerImpl::OnTimerSendTTSGlobalProperties() {
@@ -2375,11 +2637,12 @@ void ApplicationManagerImpl::OnTimerSendTTSGlobalProperties() {
void ApplicationManagerImpl::AddAppToTTSGlobalPropertiesList(
const uint32_t app_id) {
- LOG4CXX_INFO(logger_, "ApplicationManagerImpl::AddAppToTTSGlobalPropertiesList");
+ LOG4CXX_AUTO_TRACE(logger_);
uint16_t timeout = profile::Profile::instance()->tts_global_properties_timeout();
TimevalStruct current_time = date_time::DateTime::getCurrentTime();
current_time.tv_sec += timeout;
- sync_primitives::AutoLock lock(tts_global_properties_app_list_lock_);
+ // please avoid AutoLock usage to avoid deadlock
+ tts_global_properties_app_list_lock_.Acquire();
if (tts_global_properties_app_list_.end() ==
tts_global_properties_app_list_.find(app_id)) {
tts_global_properties_app_list_[app_id] = current_time;
@@ -2387,38 +2650,45 @@ void ApplicationManagerImpl::AddAppToTTSGlobalPropertiesList(
//if add first item need to start timer on one second
if (1 == tts_global_properties_app_list_.size()) {
LOG4CXX_INFO(logger_, "Start tts_global_properties_timer_");
+ tts_global_properties_app_list_lock_.Release();
tts_global_properties_timer_.start(1);
+ return;
}
+ tts_global_properties_app_list_lock_.Release();
}
void ApplicationManagerImpl::RemoveAppFromTTSGlobalPropertiesList(
const uint32_t app_id) {
- LOG4CXX_INFO(logger_, "ApplicationManagerImpl::RemoveAppFromTTSGlobalPropertiesList");
- sync_primitives::AutoLock lock(tts_global_properties_app_list_lock_);
+ LOG4CXX_AUTO_TRACE(logger_);
+ // please avoid AutoLock usage to avoid deadlock
+ tts_global_properties_app_list_lock_.Acquire();
std::map<uint32_t, TimevalStruct>::iterator it =
tts_global_properties_app_list_.find(app_id);
if (tts_global_properties_app_list_.end() != it) {
tts_global_properties_app_list_.erase(it);
- if (!(tts_global_properties_app_list_.size())) {
+ if (tts_global_properties_app_list_.empty()) {
LOG4CXX_INFO(logger_, "Stop tts_global_properties_timer_");
- //if container is empty need to stop timer
- tts_global_properties_timer_.stop();
+ // if container is empty need to stop timer
+ tts_global_properties_app_list_lock_.Release();
+ tts_global_properties_timer_.pause();
+ return;
}
}
+ tts_global_properties_app_list_lock_.Release();
}
void ApplicationManagerImpl::CreatePhoneCallAppList() {
- LOG4CXX_TRACE_ENTER(logger_);
+ LOG4CXX_AUTO_TRACE(logger_);
ApplicationManagerImpl::ApplicationListAccessor accessor;
- ApplicationManagerImpl::TAppList local_app_list = accessor.applications();
- ApplicationManagerImpl::TAppListIt it = local_app_list.begin();
- ApplicationManagerImpl::TAppListIt itEnd = local_app_list.end();
+ ApplicationManagerImpl::ApplictionSetIt it = accessor.begin();
+ ApplicationManagerImpl::ApplictionSetIt itEnd = accessor.end();
+ using namespace mobile_apis::HMILevel;
+ using namespace helpers;
for (; it != itEnd; ++it) {
- if (mobile_api::HMILevel::HMI_FULL == (*it)->hmi_level() ||
- mobile_api::HMILevel::HMI_LIMITED == (*it)->hmi_level()) {
+ if (Compare<eType, EQ, ONE>((*it)->hmi_level(), HMI_FULL, HMI_LIMITED)) {
// back up app state
on_phone_call_app_list_.insert(std::pair<uint32_t, AppState>(
@@ -2426,8 +2696,9 @@ void ApplicationManagerImpl::CreatePhoneCallAppList() {
(*it)->audio_streaming_state(),
(*it)->system_context())));
+ ChangeAppsHMILevel((*it)->app_id() , (*it)->is_navi() ? HMI_LIMITED : HMI_BACKGROUND);
+
// app state during phone call
- (*it)->set_hmi_level(mobile_api::HMILevel::HMI_BACKGROUND);
(*it)->set_audio_streaming_state(mobile_api::AudioStreamingState::NOT_AUDIBLE);
(*it)->set_system_context(mobile_api::SystemContext::SYSCTXT_MAIN);
MessageHelper::SendHMIStatusNotification(*(*it));
@@ -2436,10 +2707,7 @@ void ApplicationManagerImpl::CreatePhoneCallAppList() {
}
void ApplicationManagerImpl::ResetPhoneCallAppList() {
- LOG4CXX_TRACE_ENTER(logger_);
-
- ApplicationManagerImpl::ApplicationListAccessor accessor;
- ApplicationManagerImpl::TAppList local_app_list = accessor.applications();
+ LOG4CXX_AUTO_TRACE(logger_);
std::map<uint32_t, AppState>::iterator it =
on_phone_call_app_list_.begin();
@@ -2448,7 +2716,8 @@ void ApplicationManagerImpl::ResetPhoneCallAppList() {
for (; it != it_end; ++it) {
ApplicationSharedPtr app = application(it->first);
if (app) {
- app->set_hmi_level(it->second.hmi_level);
+ ChangeAppsHMILevel(app->app_id(), it->second.hmi_level);
+
app->set_audio_streaming_state(it->second.audio_streaming_state);
app->set_system_context(it->second.system_context);
MessageHelper::SendHMIStatusNotification(*app);
@@ -2458,4 +2727,191 @@ void ApplicationManagerImpl::ResetPhoneCallAppList() {
on_phone_call_app_list_.clear();
}
+void ApplicationManagerImpl::ChangeAppsHMILevel(uint32_t app_id,
+ mobile_apis::HMILevel::eType level) {
+ using namespace mobile_apis::HMILevel;
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_, "AppID to change: " << app_id << " -> "
+ << level);
+ ApplicationSharedPtr app = application(app_id);
+ if (!app) {
+ LOG4CXX_DEBUG(logger_, "There is no app with id: " << app_id);
+ return;
+ }
+ eType old_level = app->hmi_level();
+ if (old_level != level) {
+ app->set_hmi_level(level);
+ OnHMILevelChanged(app_id, old_level, level);
+ } else {
+ LOG4CXX_WARN(logger_, "Redudant changing HMI level : " << level);
+ }
+
+}
+
+void ApplicationManagerImpl::MakeAppNotAudible(uint32_t app_id) {
+ using namespace mobile_apis;
+ ApplicationSharedPtr app = application(app_id);
+ if (!app) {
+ LOG4CXX_DEBUG(logger_, "There is no app with id: " << app_id);
+ return;
+ }
+ ChangeAppsHMILevel(app_id, HMILevel::HMI_BACKGROUND);
+ app->set_audio_streaming_state(AudioStreamingState::NOT_AUDIBLE);
+}
+
+bool ApplicationManagerImpl::MakeAppFullScreen(uint32_t app_id) {
+ using namespace mobile_apis;
+ ApplicationSharedPtr app = application(app_id);
+ if (!app) {
+ LOG4CXX_DEBUG(logger_, "There is no app with id: " << app_id);
+ return false;
+ }
+
+ ChangeAppsHMILevel(app_id, HMILevel::HMI_FULL);
+ if (app->is_media_application() || app->is_navi()) {
+ app->set_audio_streaming_state(AudioStreamingState::AUDIBLE);
+ }
+ app->set_system_context(SystemContext::SYSCTXT_MAIN);
+
+ if(!app->has_been_activated()) {
+ app->set_activated(true);
+ }
+
+ return true;
+}
+
+
+mobile_apis::AppHMIType::eType ApplicationManagerImpl::StringToAppHMIType(std::string str) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if ("DEFAULT" == str) {
+ return mobile_apis::AppHMIType::DEFAULT;
+ } else if ("COMMUNICATION" == str) {
+ return mobile_apis::AppHMIType::COMMUNICATION;
+ } else if ("MEDIA" == str) {
+ return mobile_apis::AppHMIType::MEDIA;
+ } else if ("MESSAGING" == str) {
+ return mobile_apis::AppHMIType::MESSAGING;
+ } else if ("NAVIGATION" == str) {
+ return mobile_apis::AppHMIType::NAVIGATION;
+ } else if ("INFORMATION" == str) {
+ return mobile_apis::AppHMIType::INFORMATION;
+ } else if ("SOCIAL" == str) {
+ return mobile_apis::AppHMIType::SOCIAL;
+ } else if ("BACKGROUND_PROCESS" == str) {
+ return mobile_apis::AppHMIType::BACKGROUND_PROCESS;
+ } else if ("TESTING" == str) {
+ return mobile_apis::AppHMIType::TESTING;
+ } else if ("SYSTEM" == str) {
+ return mobile_apis::AppHMIType::SYSTEM;
+ } else {
+ return mobile_apis::AppHMIType::INVALID_ENUM;
+ }
+}
+
+bool ApplicationManagerImpl::CompareAppHMIType (const smart_objects::SmartObject& from_policy,
+ const smart_objects::SmartObject& from_application) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ bool equal = false;
+ uint32_t lenght_policy_app_types = from_policy.length();
+ uint32_t lenght_application_app_types = from_application.length();
+
+ for(uint32_t i = 0; i < lenght_application_app_types; ++i) {
+ for(uint32_t k = 0; k < lenght_policy_app_types; ++k) {
+ if (from_application[i] == from_policy[k]) {
+ equal = true;
+ break;
+ }
+ }
+ if(!equal) {
+ return false;
+ }
+ equal = false;
+ }
+ return true;
+}
+
+void ApplicationManagerImpl::OnUpdateHMIAppType(
+ std::map<std::string, std::vector<std::string> > app_hmi_types) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ std::map<std::string, std::vector<std::string> >::iterator it_app_hmi_types_from_policy;
+ std::vector<std::string> hmi_types_from_policy;
+ smart_objects::SmartObject transform_app_hmi_types(smart_objects::SmartType_Array);
+ bool flag_diffirence_app_hmi_type = false;
+ ApplicationListAccessor accessor;
+ for (ApplictionSetIt it = accessor.begin();
+ it != accessor.end(); ++it) {
+
+ it_app_hmi_types_from_policy =
+ app_hmi_types.find(((*it)->mobile_app_id()));
+
+ if (it_app_hmi_types_from_policy != app_hmi_types.end() &&
+ ((it_app_hmi_types_from_policy->second).size())) {
+ flag_diffirence_app_hmi_type = false;
+ hmi_types_from_policy = (it_app_hmi_types_from_policy->second);
+
+ if(transform_app_hmi_types.length()) {
+ transform_app_hmi_types =
+ smart_objects::SmartObject(smart_objects::SmartType_Array);
+ }
+
+ for(uint32_t i = 0; i < hmi_types_from_policy.size(); ++i) {
+ transform_app_hmi_types[i] = StringToAppHMIType(hmi_types_from_policy[i]);
+ }
+
+ ApplicationConstSharedPtr app = *it;
+ const smart_objects::SmartObject* save_application_hmi_type = app->app_types();
+
+ if (save_application_hmi_type == NULL ||
+ ((*save_application_hmi_type).length() != transform_app_hmi_types.length())) {
+ flag_diffirence_app_hmi_type = true;
+ } else {
+ flag_diffirence_app_hmi_type = !(CompareAppHMIType(transform_app_hmi_types,
+ *save_application_hmi_type));
+ }
+
+ if (flag_diffirence_app_hmi_type) {
+ (*it)->set_app_types(transform_app_hmi_types);
+ (*it)->ChangeSupportingAppHMIType();
+ if ((*it)->hmi_level() == mobile_api::HMILevel::HMI_BACKGROUND) {
+
+ MessageHelper::SendUIChangeRegistrationRequestToHMI(*it);
+ } else if (((*it)->hmi_level() == mobile_api::HMILevel::HMI_FULL) ||
+ ((*it)->hmi_level() == mobile_api::HMILevel::HMI_LIMITED)) {
+
+ MessageHelper::SendActivateAppToHMI((*it)->app_id(),
+ hmi_apis::Common_HMILevel::BACKGROUND,
+ false);
+ MessageHelper::SendUIChangeRegistrationRequestToHMI(*it);
+ ChangeAppsHMILevel((*it)->app_id(), mobile_api::HMILevel::HMI_BACKGROUND);
+ MessageHelper::SendHMIStatusNotification(*(*it));
+ }
+ }
+ }
+ }
+}
+
+ProtocolVersion ApplicationManagerImpl::SupportedSDLVersion() const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ bool heart_beat_support =
+ profile::Profile::instance()->heart_beat_timeout();
+ bool sdl4_support = profile::Profile::instance()->enable_protocol_4();
+
+ if (sdl4_support) {
+ LOG4CXX_DEBUG(logger_, "SDL Supported protocol version "<<ProtocolVersion::kV4);
+ return ProtocolVersion::kV4;
+ }
+ if (heart_beat_support) {
+ LOG4CXX_DEBUG(logger_, "SDL Supported protocol version "<<ProtocolVersion::kV3);
+ return ProtocolVersion::kV3;
+ }
+
+ LOG4CXX_DEBUG(logger_, "SDL Supported protocol version "<<ProtocolVersion::kV2);
+ return ProtocolVersion::kV2;
+}
+
+
+ApplicationManagerImpl::ApplicationListAccessor::~ApplicationListAccessor() {
+}
+
} // namespace application_manager