2 * Copyright (c) 2013, Ford Motor Company
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
8 * Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following
13 * disclaimer in the documentation and/or other materials provided with the
16 * Neither the name of the Ford Motor Company nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
33 #include "application_manager/application_manager_impl.h"
39 #include "application_manager/application_manager_impl.h"
40 #include "application_manager/mobile_command_factory.h"
41 #include "application_manager/commands/command_impl.h"
42 #include "application_manager/commands/command_notification_impl.h"
43 #include "application_manager/message_helper.h"
44 #include "application_manager/mobile_message_handler.h"
45 #include "application_manager/policies/policy_handler.h"
46 #include "connection_handler/connection_handler_impl.h"
47 #include "formatters/formatter_json_rpc.h"
48 #include "formatters/CFormatterJsonSDLRPCv2.hpp"
49 #include "formatters/CFormatterJsonSDLRPCv1.hpp"
50 #include "config_profile/profile.h"
51 #include "utils/threads/thread.h"
52 #include "utils/file_system.h"
53 #include "application_manager/application_impl.h"
54 #include "usage_statistics/counter.h"
56 namespace application_manager {
59 log4cxx::LoggerPtr ApplicationManagerImpl::logger_ = log4cxx::LoggerPtr(
60 log4cxx::Logger::getLogger("ApplicationManager"));
63 uint32_t ApplicationManagerImpl::corelation_id_ = 0;
64 const uint32_t ApplicationManagerImpl::max_corelation_id_ = UINT_MAX;
66 namespace formatters = NsSmartDeviceLink::NsJSONHandler::Formatters;
67 namespace jhs = NsSmartDeviceLink::NsJSONHandler::strings;
69 ApplicationManagerImpl::ApplicationManagerImpl()
70 : audio_pass_thru_active_(false),
71 is_distracting_driver_(false),
72 is_vr_session_strated_(false),
73 hmi_cooperating_(false),
74 is_all_apps_allowed_(true),
76 connection_handler_(NULL),
77 policy_manager_(NULL),
78 hmi_so_factory_(NULL),
79 mobile_so_factory_(NULL),
80 protocol_handler_(NULL),
81 messages_from_mobile_("application_manager::FromMobileThreadImpl", this),
82 messages_to_mobile_("application_manager::ToMobileThreadImpl", this),
83 messages_from_hmi_("application_manager::FromHMHThreadImpl", this),
84 messages_to_hmi_("application_manager::ToHMHThreadImpl", this),
86 hmi_capabilities_(this),
87 unregister_reason_(mobile_api::AppInterfaceUnregisteredReason::IGNITION_OFF),
90 LOG4CXX_INFO(logger_, "Creating ApplicationManager");
91 media_manager_ = media_manager::MediaManagerImpl::instance();
92 CreatePoliciesManager();
95 bool ApplicationManagerImpl::InitThread(threads::Thread* thread) {
97 LOG4CXX_ERROR(logger_, "Failed to allocate memory for thread object");
102 "Starting thread with stack size "
103 << profile::Profile::instance()->thread_min_stack_size());
104 if (!thread->start()) {
106 threads::ThreadOptions(
107 profile::Profile::instance()->thread_min_stack_size()))*/
108 LOG4CXX_ERROR(logger_, "Failed to start thread");
114 ApplicationManagerImpl::~ApplicationManagerImpl() {
115 LOG4CXX_INFO(logger_, "Destructing ApplicationManager.");
117 if (policy_manager_) {
118 LOG4CXX_INFO(logger_, "Unloading policy library.");
119 policy::PolicyHandler::instance()->UnloadPolicyLibrary();
121 policy_manager_ = NULL;
122 media_manager_ = NULL;
124 connection_handler_ = NULL;
125 hmi_so_factory_ = NULL;
126 mobile_so_factory_ = NULL;
127 protocol_handler_ = NULL;
128 media_manager_ = NULL;
131 bool ApplicationManagerImpl::Stop() {
132 LOG4CXX_INFO(logger_, "Stop ApplicationManager.");
134 UnregisterAllApplications();
136 LOG4CXX_ERROR(logger_,
137 "An error occured during unregistering applications.");
139 MessageHelper::SendOnSdlCloseNotificationToHMI();
143 ApplicationSharedPtr ApplicationManagerImpl::application(int32_t app_id) const {
144 sync_primitives::AutoLock lock(applications_list_lock_);
146 std::map<int32_t, ApplicationSharedPtr>::const_iterator it =
147 applications_.find(app_id);
148 if (applications_.end() != it) {
151 return ApplicationSharedPtr();
155 ApplicationSharedPtr ApplicationManagerImpl::active_application() const {
156 // TODO(DK) : check driver distraction
157 for (std::set<ApplicationSharedPtr>::iterator it = application_list_.begin();
158 application_list_.end() != it;
160 if ((*it)->IsFullscreen()) {
164 return ApplicationSharedPtr();
167 std::vector<ApplicationSharedPtr> ApplicationManagerImpl::applications_by_button(
169 std::vector<ApplicationSharedPtr> result;
170 for (std::set<ApplicationSharedPtr>::iterator it = application_list_.begin();
171 application_list_.end() != it; ++it) {
172 if ((*it)->IsSubscribedToButton(
173 static_cast<mobile_apis::ButtonName::eType>(button))) {
174 result.push_back(*it);
180 std::vector<utils::SharedPtr<Application>> ApplicationManagerImpl::IviInfoUpdated(
181 VehicleDataType vehicle_info, int value) {
182 // Notify Policy Manager if available about info it's interested in,
184 switch (vehicle_info) {
186 policy::PolicyHandler::instance()->KmsChanged(value);
192 std::vector<utils::SharedPtr<application_manager::Application>> result;
193 for (std::set<utils::SharedPtr<application_manager::Application>>::iterator it = application_list_.begin();
194 application_list_.end() != it; ++it) {
195 if ((*it)->IsSubscribedToIVI(static_cast<uint32_t>(vehicle_info))) {
196 result.push_back(*it);
202 std::vector<ApplicationSharedPtr> ApplicationManagerImpl::applications_with_navi() {
203 std::vector<ApplicationSharedPtr> result;
204 for (std::set<ApplicationSharedPtr>::iterator it = application_list_.begin();
205 application_list_.end() != it;
207 if ((*it)->allowed_support_navigation()) {
208 result.push_back(*it);
214 ApplicationSharedPtr ApplicationManagerImpl::RegisterApplication(
215 const utils::SharedPtr<smart_objects::SmartObject>&
216 request_for_registration) {
217 smart_objects::SmartObject& message = *request_for_registration;
218 uint32_t connection_key =
219 message[strings::params][strings::connection_key].asInt();
221 if (false == is_all_apps_allowed_) {
222 LOG4CXX_INFO(logger_,
223 "RegisterApplication: access to app's disabled by user");
224 utils::SharedPtr<smart_objects::SmartObject> response(
225 MessageHelper::CreateNegativeResponse(
226 connection_key, mobile_apis::FunctionID::RegisterAppInterfaceID,
227 message[strings::params][strings::correlation_id].asUInt(),
228 mobile_apis::Result::DISALLOWED));
229 ManageMobileCommand(response);
230 return ApplicationSharedPtr();
233 // app_id is SDL "internal" ID
234 // original app_id can be gotten via ApplicationImpl::mobile_app_id()
236 std::list<int32_t> sessions_list;
237 uint32_t device_id = 0;
239 if (connection_handler_) {
240 connection_handler::ConnectionHandlerImpl* con_handler_impl =
241 static_cast<connection_handler::ConnectionHandlerImpl*>(
242 connection_handler_);
243 if (con_handler_impl->GetDataOnSessionKey(connection_key, &app_id,
244 &sessions_list, &device_id)
246 LOG4CXX_ERROR(logger_,
247 "Failed to create application: no connection info.");
248 utils::SharedPtr<smart_objects::SmartObject> response(
249 MessageHelper::CreateNegativeResponse(
250 connection_key, mobile_apis::FunctionID::RegisterAppInterfaceID,
251 message[strings::params][strings::correlation_id].asUInt(),
252 mobile_apis::Result::GENERIC_ERROR));
253 ManageMobileCommand(response);
254 return ApplicationSharedPtr();
258 smart_objects::SmartObject& params = message[strings::msg_params];
260 const std::string mobile_app_id = params[strings::app_id].asString();
261 ApplicationSharedPtr application(
262 new ApplicationImpl(app_id, mobile_app_id, policy_manager_));
264 usage_statistics::AppCounter count_of_rejections_sync_out_of_memory(
265 policy_manager_, mobile_app_id,
266 usage_statistics::REJECTIONS_SYNC_OUT_OF_MEMORY);
267 ++count_of_rejections_sync_out_of_memory;
269 utils::SharedPtr<smart_objects::SmartObject> response(
270 MessageHelper::CreateNegativeResponse(
271 connection_key, mobile_apis::FunctionID::RegisterAppInterfaceID,
272 message[strings::params][strings::correlation_id].asUInt(),
273 mobile_apis::Result::OUT_OF_MEMORY));
274 ManageMobileCommand(response);
275 return ApplicationSharedPtr();
278 const std::string& name =
279 message[strings::msg_params][strings::app_name].asString();
281 application->set_name(name);
282 application->set_device(device_id);
284 mobile_api::Language::eType launguage_desired =
285 static_cast<mobile_api::Language::eType>(params[strings::language_desired]
287 application->set_language(launguage_desired);
288 application->usage_report().RecordAppRegistrationVuiLanguage(
291 mobile_api::Language::eType hmi_display_language_desired =
292 static_cast<mobile_api::Language::eType>(params[strings::hmi_display_language_desired]
294 application->set_ui_language(hmi_display_language_desired);
295 application->usage_report().RecordAppRegistrationGuiLanguage(
296 hmi_display_language_desired);
299 int32_t min_version =
300 message[strings::msg_params][strings::sync_msg_version]
301 [strings::minor_version].asInt();
303 /*if (min_version < APIVersion::kAPIV2) {
304 LOG4CXX_ERROR(logger_, "UNSUPPORTED_VERSION");
305 utils::SharedPtr<smart_objects::SmartObject> response(
306 MessageHelper::CreateNegativeResponse(
307 connection_key, mobile_apis::FunctionID::RegisterAppInterfaceID,
308 message[strings::params][strings::correlation_id],
309 mobile_apis::Result::UNSUPPORTED_VERSION));
310 ManageMobileCommand(response);
314 version.min_supported_api_version = static_cast<APIVersion>(min_version);
316 int32_t max_version =
317 message[strings::msg_params][strings::sync_msg_version]
318 [strings::major_version].asInt();
320 /*if (max_version > APIVersion::kAPIV2) {
321 LOG4CXX_ERROR(logger_, "UNSUPPORTED_VERSION");
322 utils::SharedPtr<smart_objects::SmartObject> response(
323 MessageHelper::CreateNegativeResponse(
324 connection_key, mobile_apis::FunctionID::RegisterAppInterfaceID,
325 message[strings::params][strings::correlation_id],
326 mobile_apis::Result::UNSUPPORTED_VERSION));
327 ManageMobileCommand(response);
331 version.max_supported_api_version = static_cast<APIVersion>(max_version);
332 application->set_version(version);
334 application->set_mobile_app_id(message[strings::msg_params][strings::app_id]);
336 sync_primitives::AutoLock lock(applications_list_lock_);
338 applications_.insert(std::pair<int32_t, ApplicationSharedPtr>(app_id, application));
339 application_list_.insert(application);
341 // TODO(PV): add asking user to allow application
342 // BasicCommunication_AllowApp
343 // application->set_app_allowed(result);
347 bool ApplicationManagerImpl::RemoveAppDataFromHMI(ApplicationSharedPtr app) {
351 bool ApplicationManagerImpl::LoadAppDataToHMI(ApplicationSharedPtr app) {
355 bool ApplicationManagerImpl::ActivateApplication(ApplicationSharedPtr app) {
357 LOG4CXX_ERROR(logger_, "Null-pointer application received.");
362 bool is_new_app_media = app->is_media_application();
364 for (std::set<ApplicationSharedPtr>::iterator it = application_list_.begin();
365 application_list_.end() != it;
367 ApplicationSharedPtr curr_app = *it;
368 if (app->app_id() == curr_app->app_id()) {
369 if (curr_app->IsFullscreen()) {
370 LOG4CXX_WARN(logger_, "Application is already active.");
373 if (mobile_api::HMILevel::eType::HMI_LIMITED !=
374 curr_app->hmi_level()) {
375 if (curr_app->has_been_activated()) {
376 MessageHelper::SendAppDataToHMI(curr_app);
379 if (!curr_app->MakeFullscreen()) {
382 MessageHelper::SendHMIStatusNotification(*curr_app);
384 if (is_new_app_media) {
385 if (curr_app->IsAudible()) {
386 curr_app->MakeNotAudible();
387 MessageHelper::SendHMIStatusNotification(*curr_app);
390 if (curr_app->IsFullscreen()) {
391 MessageHelper::RemoveAppDataFromHMI(curr_app);
398 mobile_apis::HMILevel::eType ApplicationManagerImpl::PutApplicationInLimited(
399 ApplicationSharedPtr app) {
402 bool is_new_app_media = app->is_media_application();
403 mobile_api::HMILevel::eType result = mobile_api::HMILevel::HMI_LIMITED;
405 for (std::set<ApplicationSharedPtr>::iterator it = application_list_.begin();
406 application_list_.end() != it;
408 ApplicationSharedPtr curr_app = *it;
409 if (app->app_id() == curr_app->app_id()) {
413 if (curr_app->hmi_level() == mobile_api::HMILevel::HMI_LIMITED) {
414 result = mobile_api::HMILevel::HMI_BACKGROUND;
417 if (curr_app->hmi_level() == mobile_api::HMILevel::HMI_FULL) {
418 if (curr_app->is_media_application()) {
419 result = mobile_api::HMILevel::HMI_BACKGROUND;
422 result = mobile_api::HMILevel::HMI_LIMITED;
427 app->set_hmi_level(result);
431 mobile_api::HMILevel::eType ApplicationManagerImpl::PutApplicationInFull(
432 ApplicationSharedPtr app) {
435 bool is_new_app_media = app->is_media_application();
436 mobile_api::HMILevel::eType result = mobile_api::HMILevel::HMI_FULL;
438 std::set<ApplicationSharedPtr>::iterator it = application_list_.begin();
439 for (; application_list_.end() != it; ++it) {
440 ApplicationSharedPtr curr_app = *it;
441 if (app->app_id() == curr_app->app_id()) {
445 if (is_new_app_media) {
446 if (curr_app->hmi_level() == mobile_api::HMILevel::HMI_FULL) {
447 if (curr_app->is_media_application()) {
448 result = mobile_api::HMILevel::HMI_BACKGROUND;
451 result = mobile_api::HMILevel::HMI_LIMITED;
454 if (curr_app->hmi_level() == mobile_api::HMILevel::HMI_LIMITED) {
455 result = mobile_api::HMILevel::HMI_BACKGROUND;
459 if (curr_app->hmi_level() == mobile_api::HMILevel::HMI_FULL) {
460 result = mobile_api::HMILevel::HMI_BACKGROUND;
463 if (curr_app->hmi_level() == mobile_api::HMILevel::HMI_LIMITED) {
464 result = mobile_api::HMILevel::HMI_FULL;
469 if (result == mobile_api::HMILevel::HMI_FULL) {
470 app->set_hmi_level(result);
471 MessageHelper::SendActivateAppToHMI(app->app_id());
476 void ApplicationManagerImpl::DeactivateApplication(ApplicationSharedPtr app) {
477 MessageHelper::SendDeleteCommandRequestToHMI(app);
478 MessageHelper::ResetGlobalproperties(app);
481 void ApplicationManagerImpl::ConnectToDevice(uint32_t id) {
482 // TODO(VS): Call function from ConnectionHandler
483 if (!connection_handler_) {
484 LOG4CXX_WARN(logger_, "Connection handler is not set.");
488 connection_handler_->ConnectToDevice(id);
491 void ApplicationManagerImpl::OnHMIStartedCooperation() {
492 hmi_cooperating_ = true;
493 LOG4CXX_INFO(logger_, "ApplicationManagerImpl::OnHMIStartedCooperation()");
495 if (true == profile::Profile::instance()->launch_hmi()) {
496 utils::SharedPtr<smart_objects::SmartObject> is_vr_ready(
497 MessageHelper::CreateModuleInfoSO(
498 static_cast<uint32_t>(hmi_apis::FunctionID::VR_IsReady)));
499 ManageHMICommand(is_vr_ready);
501 utils::SharedPtr<smart_objects::SmartObject> is_tts_ready(
502 MessageHelper::CreateModuleInfoSO(hmi_apis::FunctionID::TTS_IsReady));
503 ManageHMICommand(is_tts_ready);
505 utils::SharedPtr<smart_objects::SmartObject> is_ui_ready(
506 MessageHelper::CreateModuleInfoSO(hmi_apis::FunctionID::UI_IsReady));
507 ManageHMICommand(is_ui_ready);
509 utils::SharedPtr<smart_objects::SmartObject> is_navi_ready(
510 MessageHelper::CreateModuleInfoSO(
511 hmi_apis::FunctionID::Navigation_IsReady));
512 ManageHMICommand(is_navi_ready);
514 utils::SharedPtr<smart_objects::SmartObject> is_ivi_ready(
515 MessageHelper::CreateModuleInfoSO(
516 hmi_apis::FunctionID::VehicleInfo_IsReady));
517 ManageHMICommand(is_ivi_ready);
519 utils::SharedPtr<smart_objects::SmartObject> button_capabilities(
520 MessageHelper::CreateModuleInfoSO(
521 hmi_apis::FunctionID::Buttons_GetCapabilities));
522 ManageHMICommand(button_capabilities);
525 if (!connection_handler_) {
526 LOG4CXX_WARN(logger_, "Connection handler is not set.");
528 connection_handler_->StartTransportManager();
532 uint32_t ApplicationManagerImpl::GetNextHMICorrelationID() {
533 if (corelation_id_ < max_corelation_id_) {
539 return corelation_id_;
542 bool ApplicationManagerImpl::begin_audio_pass_thru() {
543 sync_primitives::AutoLock lock(audio_pass_thru_lock_);
544 if (audio_pass_thru_active_) {
547 audio_pass_thru_active_ = true;
552 bool ApplicationManagerImpl::end_audio_pass_thru() {
553 sync_primitives::AutoLock lock(audio_pass_thru_lock_);
554 if (audio_pass_thru_active_) {
555 audio_pass_thru_active_ = false;
562 void ApplicationManagerImpl::set_driver_distraction(bool is_distracting) {
563 is_distracting_driver_ = is_distracting;
566 void ApplicationManagerImpl::set_vr_session_started(const bool& state) {
567 is_vr_session_strated_ = state;
570 void ApplicationManagerImpl::set_all_apps_allowed(const bool& allowed) {
571 is_all_apps_allowed_ = allowed;
574 void ApplicationManagerImpl::StartAudioPassThruThread(int32_t session_key,
575 int32_t correlation_id, int32_t max_duration, int32_t sampling_rate,
576 int32_t bits_per_sample, int32_t audio_type) {
577 LOG4CXX_INFO(logger_, "START MICROPHONE RECORDER");
578 if (NULL != media_manager_) {
579 media_manager_->StartMicrophoneRecording(
581 std::string("record.wav"),
586 void ApplicationManagerImpl::SendAudioPassThroughNotification(
587 uint32_t session_key,
588 std::vector<uint8_t> binaryData) {
589 LOG4CXX_TRACE_ENTER(logger_);
592 sync_primitives::AutoLock lock(audio_pass_thru_lock_);
593 if (!audio_pass_thru_active_) {
594 LOG4CXX_ERROR(logger_, "Trying to send PassThroughNotification"
595 " when PassThrough is not active");
601 smart_objects::SmartObject* on_audio_pass = NULL;
602 on_audio_pass = new smart_objects::SmartObject();
604 if (NULL == on_audio_pass) {
605 LOG4CXX_ERROR_EXT(logger_, "OnAudioPassThru NULL pointer");
610 LOG4CXX_INFO_EXT(logger_, "Fill smart object");
612 (*on_audio_pass)[strings::params][strings::message_type] =
613 application_manager::MessageType::kNotification;
615 (*on_audio_pass)[strings::params][strings::connection_key] =
616 static_cast<int32_t>(session_key);
617 (*on_audio_pass)[strings::params][strings::function_id] =
618 mobile_apis::FunctionID::OnAudioPassThruID;
620 LOG4CXX_INFO_EXT(logger_, "Fill binary data");
622 (*on_audio_pass)[strings::params][strings::binary_data] =
623 smart_objects::SmartObject(binaryData);
625 LOG4CXX_INFO_EXT(logger_, "After fill binary data");
627 LOG4CXX_INFO_EXT(logger_, "Send data");
628 CommandSharedPtr command =
629 MobileCommandFactory::CreateCommand(&(*on_audio_pass));
635 void ApplicationManagerImpl::StopAudioPassThru(int32_t application_key) {
636 LOG4CXX_TRACE_ENTER(logger_);
637 if (NULL != media_manager_) {
638 media_manager_->StopMicrophoneRecording(application_key);
642 std::string ApplicationManagerImpl::GetDeviceName(
643 connection_handler::DeviceHandle handle) {
644 DCHECK(connection_handler_ != 0);
646 std::string device_name = "";
647 std::list<uint32_t> applications_list;
648 connection_handler::ConnectionHandlerImpl* con_handler_impl =
649 static_cast<connection_handler::ConnectionHandlerImpl*>(
650 connection_handler_);
651 if (con_handler_impl->GetDataOnDeviceID(handle, &device_name,
652 &applications_list) == -1) {
653 LOG4CXX_ERROR(logger_, "Failed to extract device name for id " << handle);
655 LOG4CXX_INFO(logger_, "\t\t\t\t\tDevice name is " << device_name);
661 void ApplicationManagerImpl::OnMessageReceived(
662 const protocol_handler::RawMessagePtr& message) {
663 LOG4CXX_INFO(logger_, "ApplicationManagerImpl::OnMessageReceived");
666 LOG4CXX_ERROR(logger_, "Null-pointer message received.");
671 utils::SharedPtr<Message> outgoing_message = ConvertRawMsgToMessage(message);
672 if (outgoing_message) {
673 messages_from_mobile_.PostMessage(
674 impl::MessageFromMobile(outgoing_message));
676 LOG4CXX_WARN(logger_, "Incorrect message received");
680 void ApplicationManagerImpl::OnMobileMessageSent(
681 const protocol_handler::RawMessagePtr& message) {
682 LOG4CXX_INFO(logger_, "ApplicationManagerImpl::OnMobileMessageSent");
685 void ApplicationManagerImpl::OnMessageReceived(
686 hmi_message_handler::MessageSharedPointer message) {
687 LOG4CXX_INFO(logger_, "ApplicationManagerImpl::OnMessageReceived");
690 LOG4CXX_ERROR(logger_, "Null-pointer message received.");
695 messages_from_hmi_.PostMessage(impl::MessageFromHmi(message));
698 void ApplicationManagerImpl::OnErrorSending(
699 hmi_message_handler::MessageSharedPointer message) {
703 void ApplicationManagerImpl::OnDeviceListUpdated(
704 const connection_handler::DeviceList& device_list) {
705 LOG4CXX_INFO(logger_, "ApplicationManagerImpl::OnDeviceListUpdated");
707 smart_objects::SmartObject* update_list = new smart_objects::SmartObject;
708 smart_objects::SmartObject& so_to_send = *update_list;
709 so_to_send[jhs::S_PARAMS][jhs::S_FUNCTION_ID] =
710 hmi_apis::FunctionID::BasicCommunication_UpdateDeviceList;
711 so_to_send[jhs::S_PARAMS][jhs::S_MESSAGE_TYPE] =
712 hmi_apis::messageType::request;
713 so_to_send[jhs::S_PARAMS][jhs::S_PROTOCOL_VERSION] = 2;
714 so_to_send[jhs::S_PARAMS][jhs::S_PROTOCOL_TYPE] = 1;
715 so_to_send[jhs::S_PARAMS][jhs::S_CORRELATION_ID] = GetNextHMICorrelationID();
716 smart_objects::SmartObject* msg_params = MessageHelper::CreateDeviceListSO(
719 LOG4CXX_WARN(logger_, "Failed to create sub-smart object.");
723 so_to_send[jhs::S_MSG_PARAMS] = *msg_params;
724 ManageHMICommand(update_list);
727 void ApplicationManagerImpl::RemoveDevice(
728 const connection_handler::DeviceHandle& device_handle) {
732 bool ApplicationManagerImpl::IsAudioStreamingAllowed(uint32_t connection_key) const {
733 ApplicationSharedPtr app = application(connection_key);
736 LOG4CXX_INFO(logger_, "An application is not registered.");
740 const mobile_api::HMILevel::eType& hmi_level = app->hmi_level();
742 if (mobile_api::HMILevel::HMI_FULL == hmi_level ||
743 mobile_api::HMILevel::HMI_LIMITED == hmi_level) {
750 bool ApplicationManagerImpl::IsVideoStreamingAllowed(uint32_t connection_key) const {
751 ApplicationSharedPtr app = application(connection_key);
754 LOG4CXX_INFO(logger_, "An application is not registered.");
758 const mobile_api::HMILevel::eType& hmi_level = app->hmi_level();
760 if (mobile_api::HMILevel::HMI_FULL == hmi_level &&
761 app->hmi_supports_navi_streaming()) {
768 bool ApplicationManagerImpl::OnServiceStartedCallback(
769 const connection_handler::DeviceHandle& device_handle,
770 const int32_t& session_key,
771 const protocol_handler::ServiceType& type) {
772 LOG4CXX_INFO(logger_,
773 "OnServiceStartedCallback " << type << " in session " << session_key);
775 ApplicationSharedPtr app = application(session_key);
778 case protocol_handler::kRpc: {
779 LOG4CXX_INFO(logger_, "RPC service is about to be started.");
782 case protocol_handler::kMobileNav: {
783 LOG4CXX_INFO(logger_, "Video service is about to be started.");
784 if (media_manager_) {
786 LOG4CXX_ERROR_EXT(logger_, "An application is not registered.");
789 if (app->allowed_support_navigation()) {
790 media_manager_->StartVideoStreaming(session_key);
797 case protocol_handler::kAudio: {
798 LOG4CXX_INFO(logger_, "Audio service is about to be started.");
799 if (media_manager_) {
801 LOG4CXX_ERROR_EXT(logger_, "An application is not registered.");
804 if (app->allowed_support_navigation()) {
805 media_manager_->StartAudioStreaming(session_key);
813 LOG4CXX_WARN(logger_, "Unknown type of service to be started.");
821 void ApplicationManagerImpl::OnServiceEndedCallback(const int32_t& session_key,
822 const protocol_handler::ServiceType& type) {
825 "OnServiceEndedCallback " << type << " in session " << session_key);
827 case protocol_handler::kRpc: {
828 LOG4CXX_INFO(logger_, "Remove application.");
829 UnregisterApplication(session_key, mobile_apis::Result::INVALID_ENUM,
833 case protocol_handler::kMobileNav: {
834 LOG4CXX_INFO(logger_, "Stop video streaming.");
835 if (media_manager_) {
836 media_manager_->StopVideoStreaming(session_key);
840 case protocol_handler::kAudio: {
841 LOG4CXX_INFO(logger_, "Stop audio service.");
842 if (media_manager_) {
843 media_manager_->StopAudioStreaming(session_key);
848 LOG4CXX_WARN(logger_, "Unknown type of service to be ended.");
853 void ApplicationManagerImpl::set_hmi_message_handler(
854 hmi_message_handler::HMIMessageHandler* handler) {
855 hmi_handler_ = handler;
858 void ApplicationManagerImpl::set_connection_handler(
859 connection_handler::ConnectionHandler* handler) {
860 connection_handler_ = handler;
863 void ApplicationManagerImpl::set_protocol_handler(
864 protocol_handler::ProtocolHandler* handler) {
865 protocol_handler_ = handler;
868 void ApplicationManagerImpl::StartDevicesDiscovery() {
869 connection_handler::ConnectionHandlerImpl::instance()->
870 StartDevicesDiscovery();
873 void ApplicationManagerImpl::SendMessageToMobile(
874 const utils::SharedPtr<smart_objects::SmartObject>& message,
875 bool final_message) {
876 LOG4CXX_INFO(logger_, "ApplicationManagerImpl::SendMessageToMobile");
879 LOG4CXX_ERROR(logger_, "Null-pointer message received.");
884 if (!protocol_handler_) {
885 LOG4CXX_WARN(logger_, "No Protocol Handler set");
889 mobile_so_factory().attachSchema(*message);
892 "Attached schema to message, result if valid: " << message->isValid());
894 // Messages to mobile are not yet prioritized so use default priority value
895 utils::SharedPtr<Message> message_to_send(new Message(
896 protocol_handler::MessagePriority::kDefault));
897 if (!ConvertSOtoMessage((*message), (*message_to_send))) {
898 LOG4CXX_WARN(logger_, "Can't send msg to Mobile: failed to create string");
902 smart_objects::SmartObject& msg_to_mobile = *message;
903 if (msg_to_mobile[strings::params].keyExists(strings::correlation_id)) {
904 request_ctrl_.terminateRequest(
905 msg_to_mobile[strings::params][strings::correlation_id].asUInt());
908 messages_to_mobile_.PostMessage(impl::MessageToMobile(message_to_send,
912 bool ApplicationManagerImpl::ManageMobileCommand(
913 const utils::SharedPtr<smart_objects::SmartObject>& message) {
914 LOG4CXX_INFO(logger_, "ApplicationManagerImpl::ManageMobileCommand");
917 LOG4CXX_WARN(logger_, "Null-pointer message received.");
923 MessageHelper::PrintSmartObject(*message);
926 LOG4CXX_INFO(logger_, "Trying to create message in mobile factory.");
927 CommandSharedPtr command = MobileCommandFactory::CreateCommand(message);
930 LOG4CXX_WARN(logger_, "Failed to create mobile command from smart object");
934 mobile_apis::FunctionID::eType function_id =
935 static_cast<mobile_apis::FunctionID::eType>(
936 (*message)[strings::params][strings::function_id].asInt());
938 // Notifications from HMI have no such parameter
939 uint32_t correlation_id =
940 (*message)[strings::params].keyExists(strings::correlation_id)
941 ? (*message)[strings::params][strings::correlation_id].asUInt()
944 uint32_t connection_key =
945 (*message)[strings::params][strings::connection_key].asUInt();
947 uint32_t protocol_type =
948 (*message)[strings::params][strings::protocol_type].asUInt();
950 ApplicationSharedPtr app;
952 if (((mobile_apis::FunctionID::RegisterAppInterfaceID != function_id) &&
953 (protocol_type == commands::CommandImpl::mobile_protocol_type_)) &&
954 (mobile_apis::FunctionID::UnregisterAppInterfaceID != function_id)) {
955 app = ApplicationManagerImpl::instance()->application(connection_key);
957 LOG4CXX_ERROR_EXT(logger_, "APPLICATION_NOT_REGISTERED");
958 smart_objects::SmartObject* response =
959 MessageHelper::CreateNegativeResponse(
961 static_cast<int32_t>(function_id),
963 static_cast<int32_t>(mobile_apis::Result::APPLICATION_NOT_REGISTERED));
965 ApplicationManagerImpl::instance()->SendMessageToMobile(response);
969 // Message for "CheckPermission" must be with attached schema
970 mobile_so_factory().attachSchema(*message);
972 if (policy_manager_) {
975 "Checking permissions for " << app->mobile_app_id()->asString() << " in " << MessageHelper::StringifiedHMILevel(app->hmi_level()) << " rpc " << MessageHelper::StringifiedFunctionID(function_id));
976 policy::CheckPermissionResult result = policy_manager_->CheckPermissions(
977 app->mobile_app_id()->asString(),
978 MessageHelper::StringifiedHMILevel(app->hmi_level()),
979 MessageHelper::StringifiedFunctionID(function_id));
981 if (app->hmi_level() == mobile_apis::HMILevel::HMI_NONE
982 && function_id != mobile_apis::FunctionID::UnregisterAppInterfaceID) {
983 app->usage_report().RecordRpcSentInHMINone();
986 if (!result.hmi_level_permitted) {
989 "Request blocked by policies. " << "FunctionID: " << static_cast<int32_t>(function_id) << " Application HMI status: " << static_cast<int32_t>(app->hmi_level()));
991 app->usage_report().RecordPolicyRejectedRpcCall();
993 smart_objects::SmartObject* response =
994 MessageHelper::CreateBlockedByPoliciesResponse(function_id,
995 mobile_apis::Result::REJECTED, correlation_id, connection_key);
997 ApplicationManagerImpl::instance()->SendMessageToMobile(response);
1003 if (command->Init()) {
1004 if ((*message)[strings::params][strings::message_type].asInt() ==
1005 mobile_apis::messageType::request) {
1006 // get application hmi level
1007 mobile_api::HMILevel::eType app_hmi_level =
1008 mobile_api::HMILevel::INVALID_ENUM;
1010 app_hmi_level = app->hmi_level();
1013 request_controller::RequestController::TResult result =
1014 request_ctrl_.addRequest(command, app_hmi_level);
1016 if (result == request_controller::RequestController::SUCCESS) {
1017 LOG4CXX_INFO(logger_, "Perform request");
1018 } else if (result ==
1019 request_controller::RequestController::
1020 TOO_MANY_PENDING_REQUESTS) {
1021 LOG4CXX_ERROR_EXT(logger_, "Unable to perform request: " <<
1022 "TOO_MANY_PENDING_REQUESTS");
1024 smart_objects::SmartObject* response =
1025 MessageHelper::CreateNegativeResponse(
1027 static_cast<int32_t>(function_id),
1029 static_cast<int32_t>(mobile_apis::Result::TOO_MANY_PENDING_REQUESTS));
1031 ApplicationManagerImpl::instance()->SendMessageToMobile(response);
1033 } else if (result ==
1034 request_controller::RequestController::TOO_MANY_REQUESTS) {
1035 LOG4CXX_ERROR_EXT(logger_, "Unable to perform request: " <<
1036 "TOO_MANY_REQUESTS");
1038 MessageHelper::SendOnAppInterfaceUnregisteredNotificationToMobile(
1040 mobile_api::AppInterfaceUnregisteredReason::TOO_MANY_REQUESTS);
1042 UnregisterApplication(connection_key,
1043 mobile_apis::Result::TOO_MANY_PENDING_REQUESTS,
1046 } else if (result ==
1047 request_controller::RequestController::
1048 NONE_HMI_LEVEL_MANY_REQUESTS) {
1049 LOG4CXX_ERROR_EXT(logger_, "Unable to perform request: " <<
1050 "REQUEST_WHILE_IN_NONE_HMI_LEVEL");
1052 MessageHelper::SendOnAppInterfaceUnregisteredNotificationToMobile(
1053 connection_key, mobile_api::AppInterfaceUnregisteredReason::
1054 REQUEST_WHILE_IN_NONE_HMI_LEVEL);
1056 UnregisterApplication(connection_key, mobile_apis::Result::INVALID_ENUM,
1060 LOG4CXX_ERROR_EXT(logger_, "Unable to perform request: Unknown case");
1071 void ApplicationManagerImpl::SendMessageToHMI(
1072 const utils::SharedPtr<smart_objects::SmartObject>& message) {
1073 LOG4CXX_INFO(logger_, "ApplicationManagerImpl::SendMessageToHMI");
1076 LOG4CXX_WARN(logger_, "Null-pointer message received.");
1081 if (!hmi_handler_) {
1082 LOG4CXX_WARN(logger_, "No HMI Handler set");
1086 // SmartObject |message| has no way to declare priority for now
1087 utils::SharedPtr<Message> message_to_send(
1088 new Message(protocol_handler::MessagePriority::kDefault));
1089 if (!message_to_send) {
1090 LOG4CXX_ERROR(logger_, "Null pointer");
1094 hmi_so_factory().attachSchema(*message);
1097 "Attached schema to message, result if valid: " << message->isValid());
1100 if (!ConvertSOtoMessage(*message, *message_to_send)) {
1101 LOG4CXX_WARN(logger_,
1102 "Cannot send message to HMI: failed to create string");
1105 #endif // HMI_JSON_API
1108 message_to_send->set_smart_object(*message);
1109 #endif // HMI_DBUS_API
1111 messages_to_hmi_.PostMessage(impl::MessageToHmi(message_to_send));
1114 bool ApplicationManagerImpl::ManageHMICommand(
1115 const utils::SharedPtr<smart_objects::SmartObject>& message) {
1116 LOG4CXX_INFO(logger_, "ApplicationManagerImpl::ManageHMICommand");
1119 LOG4CXX_WARN(logger_, "Null-pointer message received.");
1125 MessageHelper::PrintSmartObject(*message);
1128 CommandSharedPtr command = HMICommandFactory::CreateCommand(message);
1131 LOG4CXX_WARN(logger_, "Failed to create command from smart object");
1135 if (command->Init()) {
1137 if (command->CleanUp()) {
1144 void ApplicationManagerImpl::CreateHMIMatrix(HMIMatrix* matrix) {
1147 void ApplicationManagerImpl::CreatePoliciesManager() {
1148 LOG4CXX_INFO(logger_, "CreatePoliciesManager");
1149 policy_manager_ = policy::PolicyHandler::instance()->LoadPolicyLibrary();
1150 if (policy_manager_) {
1151 LOG4CXX_INFO(logger_, "Policy library is loaded, now initing PT");
1152 policy::PolicyHandler::instance()->InitPolicyTable();
1156 bool ApplicationManagerImpl::CheckPolicies(smart_objects::SmartObject* message,
1157 ApplicationSharedPtr app) {
1161 bool ApplicationManagerImpl::CheckHMIMatrix(
1162 smart_objects::SmartObject* message) {
1166 bool ApplicationManagerImpl::ConvertMessageToSO(
1167 const Message& message, smart_objects::SmartObject& output) {
1170 "\t\t\tMessage to convert: protocol " << message.protocol_version()
1171 << "; json " << message.json_message());
1173 switch (message.protocol_version()) {
1174 case ProtocolVersion::kV2: {
1176 if (!formatters::CFormatterJsonSDLRPCv2::fromString(
1177 message.json_message(),
1179 message.function_id(),
1181 message.correlation_id())
1182 || !mobile_so_factory().attachSchema(output)
1183 || ((output.validate() != smart_objects::Errors::OK)
1184 && (output.validate() !=
1185 smart_objects::Errors::UNEXPECTED_PARAMETER))) {
1186 LOG4CXX_WARN(logger_, "Failed to parse string to smart object");
1187 utils::SharedPtr<smart_objects::SmartObject> response(
1188 MessageHelper::CreateNegativeResponse(
1189 message.connection_key(), message.function_id(),
1190 message.correlation_id(), mobile_apis::Result::INVALID_DATA));
1191 ManageMobileCommand(response);
1196 "Convertion result for sdl object is true" << " function_id "
1197 << output[jhs::S_PARAMS][jhs::S_FUNCTION_ID].asInt());
1198 output[strings::params][strings::connection_key] =
1199 message.connection_key();
1200 if (message.binary_data()) {
1201 output[strings::params][strings::binary_data] =
1202 *(message.binary_data());
1206 case ProtocolVersion::kHMI: {
1207 int32_t result = formatters::FormatterJsonRpc::FromString <
1208 hmi_apis::FunctionID::eType, hmi_apis::messageType::eType > (
1209 message.json_message(), output);
1212 "Convertion result: " << result << " function id "
1213 << output[jhs::S_PARAMS][jhs::S_FUNCTION_ID].asInt());
1214 if (!hmi_so_factory().attachSchema(output)) {
1215 LOG4CXX_WARN(logger_, "Failed to attach schema to object.");
1218 if (output.validate() != smart_objects::Errors::OK &&
1219 output.validate() != smart_objects::Errors::UNEXPECTED_PARAMETER) {
1222 "Incorrect parameter from HMI");
1223 output.erase(strings::msg_params);
1224 output[strings::params][hmi_response::code] =
1225 hmi_apis::Common_Result::INVALID_DATA;
1226 output[strings::msg_params][strings::info] =
1227 std::string("Received invalid data on HMI response");
1231 case ProtocolVersion::kV1: {
1232 static NsSmartDeviceLinkRPC::V1::v4_protocol_v1_2_no_extra v1_shema;
1234 if (message.function_id() == 0 || message.type() == kUnknownType) {
1235 LOG4CXX_ERROR(logger_, "Message received: UNSUPPORTED_VERSION");
1237 int32_t conversation_result =
1238 formatters::CFormatterJsonSDLRPCv1::fromString <
1239 NsSmartDeviceLinkRPC::V1::FunctionID::eType,
1240 NsSmartDeviceLinkRPC::V1::messageType::eType > (
1241 message.json_message(), output);
1243 if (formatters::CFormatterJsonSDLRPCv1::kSuccess
1244 == conversation_result) {
1246 smart_objects::SmartObject params = smart_objects::SmartObject(smart_objects::SmartType::SmartType_Map);
1248 output[strings::params][strings::message_type] =
1249 NsSmartDeviceLinkRPC::V1::messageType::response;
1250 output[strings::params][strings::connection_key] = message.connection_key();
1252 output[strings::msg_params] =
1253 smart_objects::SmartObject(smart_objects::SmartType::SmartType_Map);
1254 output[strings::msg_params][strings::success] = false;
1255 output[strings::msg_params][strings::result_code] =
1256 NsSmartDeviceLinkRPC::V1::Result::UNSUPPORTED_VERSION;
1258 smart_objects::SmartObject* msg_to_send = new smart_objects::SmartObject(output);
1259 v1_shema.attachSchema(*msg_to_send);
1260 SendMessageToMobile(msg_to_send);
1269 // removed NOTREACHED() because some app can still have vesion 1.
1272 "Application used unsupported protocol :" << message.protocol_version()
1277 LOG4CXX_INFO(logger_, "Successfully parsed message into smart object");
1281 bool ApplicationManagerImpl::ConvertSOtoMessage(
1282 const smart_objects::SmartObject& message, Message& output) {
1283 LOG4CXX_INFO(logger_, "Message to convert");
1285 if (smart_objects::SmartType_Null == message.getType()
1286 || smart_objects::SmartType_Invalid == message.getType()) {
1287 LOG4CXX_WARN(logger_, "Invalid smart object received.");
1293 "Message with protocol: "
1294 << message.getElement(jhs::S_PARAMS).getElement(jhs::S_PROTOCOL_TYPE)
1297 std::string output_string;
1298 switch (message.getElement(jhs::S_PARAMS).getElement(jhs::S_PROTOCOL_TYPE)
1301 if (message.getElement(jhs::S_PARAMS).getElement(jhs::S_PROTOCOL_VERSION).asInt() == 1) {
1302 if (!formatters::CFormatterJsonSDLRPCv1::toString(message,
1304 LOG4CXX_WARN(logger_, "Failed to serialize smart object");
1307 output.set_protocol_version(application_manager::kV1);
1309 if (!formatters::CFormatterJsonSDLRPCv2::toString(message,
1311 LOG4CXX_WARN(logger_, "Failed to serialize smart object");
1314 output.set_protocol_version(application_manager::kV2);
1320 if (!formatters::FormatterJsonRpc::ToString(message, output_string)) {
1321 LOG4CXX_WARN(logger_, "Failed to serialize smart object");
1324 output.set_protocol_version(application_manager::kHMI);
1332 LOG4CXX_INFO(logger_, "Convertion result: " << output_string);
1334 output.set_connection_key(
1335 message.getElement(jhs::S_PARAMS).getElement(strings::connection_key)
1338 output.set_function_id(
1339 message.getElement(jhs::S_PARAMS).getElement(jhs::S_FUNCTION_ID).asInt());
1341 output.set_correlation_id(
1342 message.getElement(jhs::S_PARAMS).getElement(jhs::S_CORRELATION_ID)
1344 output.set_message_type(
1345 static_cast<MessageType>(message.getElement(jhs::S_PARAMS).getElement(
1346 jhs::S_MESSAGE_TYPE).asInt()));
1348 // Currently formatter creates JSON = 3 bytes for empty SmartObject.
1349 // workaround for notification. JSON must be empty
1350 if (mobile_apis::FunctionID::OnAudioPassThruID
1351 != message.getElement(jhs::S_PARAMS).getElement(strings::function_id)
1353 output.set_json_message(output_string);
1356 if (message.getElement(jhs::S_PARAMS).keyExists(strings::binary_data)) {
1357 application_manager::BinaryData* binaryData =
1358 new application_manager::BinaryData(
1359 message.getElement(jhs::S_PARAMS).getElement(strings::binary_data)
1362 if (NULL == binaryData) {
1363 LOG4CXX_ERROR(logger_, "Null pointer");
1366 output.set_binary_data(binaryData);
1369 LOG4CXX_INFO(logger_, "Successfully parsed smart object into message");
1373 utils::SharedPtr<Message> ApplicationManagerImpl::ConvertRawMsgToMessage(
1374 const protocol_handler::RawMessagePtr& message) {
1376 utils::SharedPtr<Message> outgoing_message;
1378 if (message->service_type() != protocol_handler::kRpc
1380 message->service_type() != protocol_handler::kBulk) {
1381 // skip this message, not under handling of ApplicationManager
1382 LOG4CXX_INFO(logger_, "Skipping message; not the under AM handling.");
1383 return outgoing_message;
1386 Message* convertion_result = NULL;
1387 if (message->protocol_version() == 1) {
1389 MobileMessageHandler::HandleIncomingMessageProtocolV1(message);
1390 } else if (message->protocol_version() == 2) {
1392 MobileMessageHandler::HandleIncomingMessageProtocolV2(message);
1394 LOG4CXX_WARN(logger_, "Unknown protocol version.");
1395 return outgoing_message;
1398 if (convertion_result) {
1399 outgoing_message = convertion_result;
1401 LOG4CXX_ERROR(logger_, "Received invalid message");
1403 return outgoing_message;
1406 void ApplicationManagerImpl::ProcessMessageFromMobile(
1407 const utils::SharedPtr<Message>& message) {
1408 LOG4CXX_INFO(logger_, "ApplicationManagerImpl::ProcessMessageFromMobile()");
1410 utils::SharedPtr<smart_objects::SmartObject> so_from_mobile(
1411 new smart_objects::SmartObject);
1413 if (!so_from_mobile) {
1414 LOG4CXX_ERROR(logger_, "Null pointer");
1418 if (!ConvertMessageToSO(*message, *so_from_mobile)) {
1419 LOG4CXX_ERROR(logger_, "Cannot create smart object from message");
1423 if (!ManageMobileCommand(so_from_mobile)) {
1424 LOG4CXX_ERROR(logger_, "Received command didn't run successfully");
1428 void ApplicationManagerImpl::ProcessMessageFromHMI(
1429 const utils::SharedPtr<Message>& message) {
1430 LOG4CXX_INFO(logger_, "ApplicationManagerImpl::ProcessMessageFromHMI()");
1431 utils::SharedPtr<smart_objects::SmartObject> smart_object(
1432 new smart_objects::SmartObject);
1434 if (!smart_object) {
1435 LOG4CXX_ERROR(logger_, "Null pointer");
1440 if (!ConvertMessageToSO(*message, *smart_object)) {
1441 LOG4CXX_ERROR(logger_, "Cannot create smart object from message");
1444 #endif // HMI_JSON_API
1447 *smart_object = message->smart_object();
1448 #endif // HMI_DBUS_API
1450 LOG4CXX_INFO(logger_, "Converted message, trying to create hmi command");
1451 if (!ManageHMICommand(smart_object)) {
1452 LOG4CXX_ERROR(logger_, "Received command didn't run successfully");
1456 hmi_apis::HMI_API& ApplicationManagerImpl::hmi_so_factory() {
1457 if (!hmi_so_factory_) {
1458 hmi_so_factory_ = new hmi_apis::HMI_API;
1459 if (!hmi_so_factory_) {
1460 LOG4CXX_ERROR(logger_, "Out of memory");
1464 return *hmi_so_factory_;
1467 mobile_apis::MOBILE_API& ApplicationManagerImpl::mobile_so_factory() {
1468 if (!mobile_so_factory_) {
1469 mobile_so_factory_ = new mobile_apis::MOBILE_API;
1470 if (!mobile_so_factory_) {
1471 LOG4CXX_ERROR(logger_, "Out of memory.");
1475 return *mobile_so_factory_;
1478 HMICapabilities& ApplicationManagerImpl::hmi_capabilities() {
1479 return hmi_capabilities_;
1482 void ApplicationManagerImpl::addNotification(const CommandSharedPtr& ptr) {
1483 notification_list_.push_back(ptr);
1486 void ApplicationManagerImpl::removeNotification(const CommandSharedPtr& ptr) {
1487 std::list<CommandSharedPtr>::iterator it = notification_list_.begin();
1488 for (; notification_list_.end() != it; ++it) {
1490 notification_list_.erase(it);
1496 void ApplicationManagerImpl::updateRequestTimeout(uint32_t connection_key,
1497 uint32_t mobile_correlation_id,
1498 uint32_t new_timeout_value) {
1499 request_ctrl_.updateRequestTimeout(connection_key, mobile_correlation_id,
1503 const uint32_t ApplicationManagerImpl::application_id
1504 (const int32_t correlation_id) {
1505 // ykazakov: there is no erase for const iterator for QNX
1506 std::map<const int32_t, const uint32_t>::iterator it =
1507 appID_list_.find(correlation_id);
1508 if (appID_list_.end() != it) {
1509 const uint32_t app_id = it->second;
1510 appID_list_.erase(it);
1517 void ApplicationManagerImpl::set_application_id(const int32_t correlation_id,
1518 const uint32_t app_id) {
1519 appID_list_.insert(std::pair<const int32_t, const uint32_t>
1520 (correlation_id, app_id));
1523 void ApplicationManagerImpl::SetUnregisterAllApplicationsReason(
1524 mobile_api::AppInterfaceUnregisteredReason::eType reason) {
1525 unregister_reason_ = reason;
1528 void ApplicationManagerImpl::HeadUnitReset(
1529 mobile_api::AppInterfaceUnregisteredReason::eType reason) {
1531 case mobile_api::AppInterfaceUnregisteredReason::MASTER_RESET:
1532 policy::PolicyHandler::instance()->InitPolicyTable();
1534 case mobile_api::AppInterfaceUnregisteredReason::FACTORY_DEFAULTS:
1535 policy::PolicyHandler::instance()->RevertPolicyTable();
1540 void ApplicationManagerImpl::UnregisterAllApplications() {
1541 LOG4CXX_INFO(logger_, "ApplicationManagerImpl::UnregisterAllApplications " <<
1542 unregister_reason_);
1544 hmi_cooperating_ = false;
1546 std::set<ApplicationSharedPtr>::iterator it = application_list_.begin();
1547 while (it != application_list_.end()) {
1548 MessageHelper::SendOnAppInterfaceUnregisteredNotificationToMobile(
1549 (*it)->app_id(), unregister_reason_);
1551 UnregisterApplication((*it)->app_id(), mobile_apis::Result::INVALID_ENUM,
1553 it = application_list_.begin();
1555 resume_controller().IgnitionOff();
1558 void ApplicationManagerImpl::UnregisterApplication(
1559 const uint32_t& app_id, mobile_apis::Result::eType reason,
1561 LOG4CXX_INFO(logger_,
1562 "ApplicationManagerImpl::UnregisterApplication " << app_id);
1565 case mobile_apis::Result::DISALLOWED:
1566 case mobile_apis::Result::USER_DISALLOWED:
1567 case mobile_apis::Result::INVALID_CERT:
1568 case mobile_apis::Result::EXPIRED_CERT:
1569 case mobile_apis::Result::TOO_MANY_PENDING_REQUESTS: {
1570 application(app_id)->usage_report().RecordRemovalsForBadBehavior();
1575 sync_primitives::AutoLock lock(applications_list_lock_);
1577 std::map<int32_t, ApplicationSharedPtr>::iterator it = applications_.find(app_id);
1578 if (applications_.end() == it) {
1579 LOG4CXX_INFO(logger_, "Application is already unregistered.");
1582 ApplicationSharedPtr app_to_remove = it->second;
1584 resume_ctrl_.SaveApplication(app_to_remove);
1586 if (audio_pass_thru_active_) {
1587 // May be better to put this code in MessageHelper?
1588 end_audio_pass_thru();
1589 StopAudioPassThru(app_id);
1590 MessageHelper::SendStopAudioPathThru();
1592 MessageHelper::RemoveAppDataFromHMI(it->second);
1593 MessageHelper::SendOnAppUnregNotificationToHMI(it->second);
1594 applications_.erase(it);
1595 application_list_.erase(app_to_remove);
1596 request_ctrl_.terminateAppRequests(app_id);
1601 void ApplicationManagerImpl::Handle(const impl::MessageFromMobile& message) {
1602 LOG4CXX_INFO(logger_, "Received message from Mobile side");
1605 LOG4CXX_ERROR(logger_, "Null-pointer message received.");
1608 ProcessMessageFromMobile(message);
1611 void ApplicationManagerImpl::Handle(const impl::MessageToMobile& message) {
1612 protocol_handler::RawMessage* rawMessage = 0;
1613 if (message->protocol_version() == application_manager::kV1) {
1614 rawMessage = MobileMessageHandler::HandleOutgoingMessageProtocolV1(message);
1615 } else if (message->protocol_version() == application_manager::kV2) {
1616 rawMessage = MobileMessageHandler::HandleOutgoingMessageProtocolV2(message);
1621 LOG4CXX_ERROR(logger_, "Failed to create raw message.");
1625 if (!protocol_handler_) {
1626 LOG4CXX_WARN(logger_,
1627 "Protocol Handler is not set; cannot send message to mobile.");
1631 protocol_handler_->SendMessageToMobileApp(rawMessage, message.is_final);
1633 LOG4CXX_INFO(logger_, "Message for mobile given away.");
1636 void ApplicationManagerImpl::Handle(const impl::MessageFromHmi& message) {
1637 LOG4CXX_INFO(logger_, "Received message from hmi");
1640 LOG4CXX_ERROR(logger_, "Null-pointer message received.");
1644 ProcessMessageFromHMI(message);
1647 void ApplicationManagerImpl::Handle(const impl::MessageToHmi& message) {
1648 LOG4CXX_INFO(logger_, "Received message to hmi");
1649 if (!hmi_handler_) {
1650 LOG4CXX_ERROR(logger_, "Observer is not set for HMIMessageHandler");
1654 hmi_handler_->SendMessageToHMI(message);
1655 LOG4CXX_INFO(logger_, "Message from hmi given away.");
1659 void ApplicationManagerImpl::Mute(VRTTSSessionChanging changing_state) {
1660 mobile_apis::AudioStreamingState::eType state =
1661 hmi_capabilities_.attenuated_supported()
1662 ? mobile_apis::AudioStreamingState::ATTENUATED
1663 : mobile_apis::AudioStreamingState::NOT_AUDIBLE;
1665 std::set<ApplicationSharedPtr>::const_iterator it = application_list_.begin();
1666 std::set<ApplicationSharedPtr>::const_iterator itEnd = application_list_.end();
1667 for (; it != itEnd; ++it) {
1668 if ((*it)->is_media_application()) {
1669 if (kTTSSessionChanging == changing_state) {
1670 (*it)->set_tts_speak_state(true);
1672 if ((*it)->audio_streaming_state() != state) {
1673 (*it)->set_audio_streaming_state(state);
1674 MessageHelper::SendHMIStatusNotification(*(*it));
1680 void ApplicationManagerImpl::Unmute(VRTTSSessionChanging changing_state) {
1681 std::set<ApplicationSharedPtr>::const_iterator it = application_list_.begin();
1682 std::set<ApplicationSharedPtr>::const_iterator itEnd = application_list_.end();
1683 for (; it != itEnd; ++it) {
1684 if ((*it)->is_media_application()) {
1685 if (kTTSSessionChanging == changing_state) {
1686 (*it)->set_tts_speak_state(false);
1688 if ((!(vr_session_started())) &&
1689 ((*it)->audio_streaming_state() !=
1690 mobile_apis::AudioStreamingState::AUDIBLE)) {
1691 (*it)->set_audio_streaming_state(
1692 mobile_apis::AudioStreamingState::AUDIBLE);
1693 MessageHelper::SendHMIStatusNotification(*(*it));
1699 mobile_apis::Result::eType ApplicationManagerImpl::SaveBinary(
1700 const std::vector<uint8_t>& binary_data, const std::string& file_path,
1701 const uint32_t offset) {
1704 "SaveBinaryWithOffset binary_size = " << binary_data.size()
1705 << " offset = " << offset);
1707 if (binary_data.size() > file_system::GetAvailableDiskSpace()) {
1708 LOG4CXX_ERROR(logger_, "Out of free disc space.");
1709 return mobile_apis::Result::OUT_OF_MEMORY;
1712 uint32_t file_size = file_system::FileSize(file_path);
1713 std::ofstream* file_stream;
1715 if (file_size != offset) {
1718 "ApplicationManagerImpl::SaveBinaryWithOffset offset does'n match existing filesize");
1719 return mobile_apis::Result::INVALID_DATA;
1721 file_stream = file_system::Open(file_path, std::ios_base::app);
1725 "ApplicationManagerImpl::SaveBinaryWithOffset offset is 0, rewrite");
1726 // if offset == 0: rewrite file
1727 file_stream = file_system::Open(file_path, std::ios_base::out);
1730 if (!file_system::Write(file_stream, binary_data.data(),
1731 binary_data.size())) {
1732 file_system::Close(file_stream);
1733 return mobile_apis::Result::GENERIC_ERROR;
1735 file_system::Close(file_stream);
1736 LOG4CXX_INFO(logger_, "Successfully write data to file");
1737 return mobile_apis::Result::SUCCESS;
1740 bool ApplicationManagerImpl::IsHMICooperating() const {
1741 return hmi_cooperating_;
1744 } // namespace application_manager