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 "connection_handler/connection_handler_impl.h"
46 #include "formatters/formatter_json_rpc.h"
47 #include "formatters/CFormatterJsonSDLRPCv2.hpp"
48 #include "formatters/CFormatterJsonSDLRPCv1.hpp"
49 #include "config_profile/profile.h"
50 #include "utils/threads/thread.h"
51 #include "utils/file_system.h"
52 #include "policies/policy_manager.h"
53 #include "application_manager/application_impl.h"
55 namespace application_manager {
57 log4cxx::LoggerPtr ApplicationManagerImpl::logger_ = log4cxx::LoggerPtr(
58 log4cxx::Logger::getLogger("ApplicationManager"));
60 uint32_t ApplicationManagerImpl::corelation_id_ = 0;
61 const uint32_t ApplicationManagerImpl::max_corelation_id_ = UINT_MAX;
63 namespace formatters = NsSmartDeviceLink::NsJSONHandler::Formatters;
64 namespace jhs = NsSmartDeviceLink::NsJSONHandler::strings;
66 ApplicationManagerImpl::ApplicationManagerImpl()
67 : audio_pass_thru_active_(false),
68 is_distracting_driver_(false),
69 is_vr_session_strated_(false),
70 hmi_cooperating_(false),
71 is_all_apps_allowed_(true),
73 connection_handler_(NULL),
74 policy_manager_(NULL),
75 hmi_so_factory_(NULL),
76 mobile_so_factory_(NULL),
77 protocol_handler_(NULL),
78 messages_from_mobile_("application_manager::FromMobileThreadImpl", this),
79 messages_to_mobile_("application_manager::ToMobileThreadImpl", this),
80 messages_from_hmi_("application_manager::FromHMHThreadImpl", this),
81 messages_to_hmi_("application_manager::ToHMHThreadImpl", this),
83 hmi_capabilities_(this),
84 unregister_reason_(mobile_api::AppInterfaceUnregisteredReason::MASTER_RESET),
88 LOG4CXX_INFO(logger_, "Creating ApplicationManager");
89 if (!policies_manager_.Init()) {
90 LOG4CXX_ERROR(logger_, "Policies manager initialization failed.");
94 media_manager_ = media_manager::MediaManagerImpl::instance();
97 bool ApplicationManagerImpl::InitThread(threads::Thread* thread) {
99 LOG4CXX_ERROR(logger_, "Failed to allocate memory for thread object");
104 "Starting thread with stack size "
105 << profile::Profile::instance()->thread_min_stack_size());
106 if (!thread->start()) {
108 threads::ThreadOptions(
109 profile::Profile::instance()->thread_min_stack_size()))*/
110 LOG4CXX_ERROR(logger_, "Failed to start thread");
116 ApplicationManagerImpl::~ApplicationManagerImpl() {
117 LOG4CXX_INFO(logger_, "Destructing ApplicationManager.");
119 media_manager_ = NULL;
121 connection_handler_ = NULL;
122 policy_manager_ = NULL;
123 hmi_so_factory_ = NULL;
124 mobile_so_factory_ = NULL;
125 protocol_handler_ = NULL;
126 media_manager_ = NULL;
129 bool ApplicationManagerImpl::Stop() {
130 LOG4CXX_INFO(logger_, "Stop ApplicationManager.");
132 UnregisterAllApplications();
135 LOG4CXX_ERROR(logger_,
136 "An error occured during unregistering applications.");
138 MessageHelper::SendOnSdlCloseNotificationToHMI();
142 ApplicationSharedPtr ApplicationManagerImpl::application(int32_t app_id) const {
143 std::map<int32_t, ApplicationSharedPtr>::const_iterator it =
144 applications_.find(app_id);
145 if (applications_.end() != it) {
148 return ApplicationSharedPtr();
152 ApplicationSharedPtr ApplicationManagerImpl::active_application() const {
153 // TODO(DK) : check driver distraction
154 for (std::set<ApplicationSharedPtr>::iterator it = application_list_.begin();
155 application_list_.end() != it;
157 if ((*it)->IsFullscreen()) {
161 return ApplicationSharedPtr();
164 std::vector<ApplicationSharedPtr> ApplicationManagerImpl::applications_by_button(
166 std::vector<ApplicationSharedPtr> result;
167 for (std::set<ApplicationSharedPtr>::iterator it = application_list_.begin();
168 application_list_.end() != it; ++it) {
169 if ((*it)->IsSubscribedToButton(
170 static_cast<mobile_apis::ButtonName::eType>(button))) {
171 result.push_back(*it);
177 std::vector<ApplicationSharedPtr> ApplicationManagerImpl::applications_by_ivi(
178 uint32_t vehicle_info) {
179 std::vector<ApplicationSharedPtr> result;
180 for (std::set<ApplicationSharedPtr>::iterator it = application_list_.begin();
181 application_list_.end() != it;
183 if ((*it)->IsSubscribedToIVI(vehicle_info)) {
184 result.push_back(*it);
190 std::vector<ApplicationSharedPtr> ApplicationManagerImpl::applications_with_navi() {
191 std::vector<ApplicationSharedPtr> result;
192 for (std::set<ApplicationSharedPtr>::iterator it = application_list_.begin();
193 application_list_.end() != it;
195 if ((*it)->allowed_support_navigation()) {
196 result.push_back(*it);
202 ApplicationSharedPtr ApplicationManagerImpl::RegisterApplication(
203 const utils::SharedPtr<smart_objects::SmartObject>&
204 request_for_registration) {
205 smart_objects::SmartObject& message = *request_for_registration;
206 uint32_t connection_key =
207 message[strings::params][strings::connection_key].asInt();
209 if (false == is_all_apps_allowed_) {
210 LOG4CXX_INFO(logger_,
211 "RegisterApplication: access to app's disabled by user");
212 utils::SharedPtr<smart_objects::SmartObject> response(
213 MessageHelper::CreateNegativeResponse(
214 connection_key, mobile_apis::FunctionID::RegisterAppInterfaceID,
215 message[strings::params][strings::correlation_id].asUInt(),
216 mobile_apis::Result::DISALLOWED));
217 ManageMobileCommand(response);
218 return ApplicationSharedPtr();
221 // app_id is SDL "internal" ID
222 // original app_id can be gotten via ApplicationImpl::mobile_app_id()
224 std::list<int32_t> sessions_list;
225 uint32_t device_id = 0;
227 if (connection_handler_) {
228 connection_handler::ConnectionHandlerImpl* con_handler_impl =
229 static_cast<connection_handler::ConnectionHandlerImpl*>(
230 connection_handler_);
231 if (con_handler_impl->GetDataOnSessionKey(connection_key, &app_id,
232 &sessions_list, &device_id)
234 LOG4CXX_ERROR(logger_,
235 "Failed to create application: no connection info.");
236 utils::SharedPtr<smart_objects::SmartObject> response(
237 MessageHelper::CreateNegativeResponse(
238 connection_key, mobile_apis::FunctionID::RegisterAppInterfaceID,
239 message[strings::params][strings::correlation_id].asUInt(),
240 mobile_apis::Result::GENERIC_ERROR));
241 ManageMobileCommand(response);
242 return ApplicationSharedPtr();
246 ApplicationSharedPtr application(new ApplicationImpl(app_id));
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::OUT_OF_MEMORY));
253 ManageMobileCommand(response);
254 return ApplicationSharedPtr();
257 const std::string& name =
258 message[strings::msg_params][strings::app_name].asString();
260 application->set_name(name);
261 application->set_device(device_id);
263 application->set_language(
264 static_cast<mobile_api::Language::eType>(
265 message[strings::msg_params][strings::language_desired].asInt()));
267 application->set_ui_language(
268 static_cast<mobile_api::Language::eType>(
269 message[strings::msg_params][strings::hmi_display_language_desired]
273 int32_t min_version =
274 message[strings::msg_params][strings::sync_msg_version]
275 [strings::minor_version].asInt();
277 /*if (min_version < APIVersion::kAPIV2) {
278 LOG4CXX_ERROR(logger_, "UNSUPPORTED_VERSION");
279 utils::SharedPtr<smart_objects::SmartObject> response(
280 MessageHelper::CreateNegativeResponse(
281 connection_key, mobile_apis::FunctionID::RegisterAppInterfaceID,
282 message[strings::params][strings::correlation_id],
283 mobile_apis::Result::UNSUPPORTED_VERSION));
284 ManageMobileCommand(response);
288 version.min_supported_api_version = static_cast<APIVersion>(min_version);
290 int32_t max_version =
291 message[strings::msg_params][strings::sync_msg_version]
292 [strings::major_version].asInt();
294 /*if (max_version > APIVersion::kAPIV2) {
295 LOG4CXX_ERROR(logger_, "UNSUPPORTED_VERSION");
296 utils::SharedPtr<smart_objects::SmartObject> response(
297 MessageHelper::CreateNegativeResponse(
298 connection_key, mobile_apis::FunctionID::RegisterAppInterfaceID,
299 message[strings::params][strings::correlation_id],
300 mobile_apis::Result::UNSUPPORTED_VERSION));
301 ManageMobileCommand(response);
305 version.max_supported_api_version = static_cast<APIVersion>(max_version);
306 application->set_version(version);
308 application->set_mobile_app_id(message[strings::msg_params][strings::app_id]);
310 sync_primitives::AutoLock lock(applications_list_lock_);
312 applications_.insert(std::pair<int32_t, ApplicationSharedPtr>(app_id, application));
313 application_list_.insert(application);
315 // TODO(PV): add asking user to allow application
316 // BasicCommunication_AllowApp
317 // application->set_app_allowed(result);
321 bool ApplicationManagerImpl::RemoveAppDataFromHMI(ApplicationSharedPtr app) {
325 bool ApplicationManagerImpl::LoadAppDataToHMI(ApplicationSharedPtr app) {
329 bool ApplicationManagerImpl::ActivateApplication(ApplicationSharedPtr app) {
331 LOG4CXX_ERROR(logger_, "Null-pointer application received.");
336 bool is_new_app_media = app->is_media_application();
338 for (std::set<ApplicationSharedPtr>::iterator it = application_list_.begin();
339 application_list_.end() != it;
341 ApplicationSharedPtr curr_app = *it;
342 if (app->app_id() == curr_app->app_id()) {
343 if (curr_app->IsFullscreen()) {
344 LOG4CXX_WARN(logger_, "Application is already active.");
347 if (mobile_api::HMILevel::eType::HMI_LIMITED !=
348 curr_app->hmi_level()) {
349 if (curr_app->has_been_activated()) {
350 MessageHelper::SendAppDataToHMI(curr_app);
353 if (!curr_app->MakeFullscreen()) {
356 MessageHelper::SendHMIStatusNotification(*curr_app);
358 if (is_new_app_media) {
359 if (curr_app->IsAudible()) {
360 curr_app->MakeNotAudible();
361 MessageHelper::SendHMIStatusNotification(*curr_app);
364 if (curr_app->IsFullscreen()) {
365 MessageHelper::RemoveAppDataFromHMI(curr_app);
372 mobile_apis::HMILevel::eType ApplicationManagerImpl::PutApplicationInLimited(
373 ApplicationSharedPtr app) {
376 bool is_new_app_media = app->is_media_application();
377 mobile_api::HMILevel::eType result = mobile_api::HMILevel::HMI_LIMITED;
379 for (std::set<ApplicationSharedPtr>::iterator it = application_list_.begin();
380 application_list_.end() != it;
382 ApplicationSharedPtr curr_app = *it;
383 if (app->app_id() == curr_app->app_id()) {
387 if (curr_app->hmi_level() == mobile_api::HMILevel::HMI_LIMITED) {
388 result = mobile_api::HMILevel::HMI_BACKGROUND;
391 if (curr_app->hmi_level() == mobile_api::HMILevel::HMI_FULL) {
392 if (curr_app->is_media_application()) {
393 result = mobile_api::HMILevel::HMI_BACKGROUND;
396 result = mobile_api::HMILevel::HMI_LIMITED;
401 app->set_hmi_level(result);
405 mobile_api::HMILevel::eType ApplicationManagerImpl::PutApplicationInFull(
406 ApplicationSharedPtr app) {
409 bool is_new_app_media = app->is_media_application();
410 mobile_api::HMILevel::eType result = mobile_api::HMILevel::HMI_FULL;
412 std::set<ApplicationSharedPtr>::iterator it = application_list_.begin();
413 for (; application_list_.end() != it; ++it) {
414 ApplicationSharedPtr curr_app = *it;
415 if (app->app_id() == curr_app->app_id()) {
419 if (is_new_app_media) {
420 if (curr_app->hmi_level() == mobile_api::HMILevel::HMI_FULL) {
421 if (curr_app->is_media_application()) {
422 result = mobile_api::HMILevel::HMI_BACKGROUND;
425 result = mobile_api::HMILevel::HMI_LIMITED;
428 if (curr_app->hmi_level() == mobile_api::HMILevel::HMI_LIMITED) {
429 result = mobile_api::HMILevel::HMI_BACKGROUND;
433 if (curr_app->hmi_level() == mobile_api::HMILevel::HMI_FULL) {
434 result = mobile_api::HMILevel::HMI_BACKGROUND;
437 if (curr_app->hmi_level() == mobile_api::HMILevel::HMI_LIMITED) {
438 result = mobile_api::HMILevel::HMI_FULL;
443 if ( result == mobile_api::HMILevel::HMI_FULL) {
444 app->set_hmi_level(result);
445 MessageHelper::SendActivateAppToHMI(app->app_id());
450 void ApplicationManagerImpl::DeactivateApplication(ApplicationSharedPtr app) {
451 MessageHelper::SendDeleteCommandRequestToHMI(app);
452 MessageHelper::ResetGlobalproperties(app);
455 void ApplicationManagerImpl::ConnectToDevice(uint32_t id) {
456 // TODO(VS): Call function from ConnectionHandler
457 if (!connection_handler_) {
458 LOG4CXX_WARN(logger_, "Connection handler is not set.");
462 connection_handler_->ConnectToDevice(id);
465 void ApplicationManagerImpl::OnHMIStartedCooperation() {
466 hmi_cooperating_ = true;
467 LOG4CXX_INFO(logger_, "ApplicationManagerImpl::OnHMIStartedCooperation()");
469 if (true == profile::Profile::instance()->launch_hmi()) {
470 utils::SharedPtr<smart_objects::SmartObject> is_vr_ready(
471 MessageHelper::CreateModuleInfoSO(
472 static_cast<uint32_t>(hmi_apis::FunctionID::VR_IsReady)));
473 ManageHMICommand(is_vr_ready);
475 utils::SharedPtr<smart_objects::SmartObject> is_tts_ready(
476 MessageHelper::CreateModuleInfoSO(hmi_apis::FunctionID::TTS_IsReady));
477 ManageHMICommand(is_tts_ready);
479 utils::SharedPtr<smart_objects::SmartObject> is_ui_ready(
480 MessageHelper::CreateModuleInfoSO(hmi_apis::FunctionID::UI_IsReady));
481 ManageHMICommand(is_ui_ready);
483 utils::SharedPtr<smart_objects::SmartObject> is_navi_ready(
484 MessageHelper::CreateModuleInfoSO(
485 hmi_apis::FunctionID::Navigation_IsReady));
486 ManageHMICommand(is_navi_ready);
488 utils::SharedPtr<smart_objects::SmartObject> is_ivi_ready(
489 MessageHelper::CreateModuleInfoSO(
490 hmi_apis::FunctionID::VehicleInfo_IsReady));
491 ManageHMICommand(is_ivi_ready);
493 utils::SharedPtr<smart_objects::SmartObject> button_capabilities(
494 MessageHelper::CreateModuleInfoSO(
495 hmi_apis::FunctionID::Buttons_GetCapabilities));
496 ManageHMICommand(button_capabilities);
499 if (!connection_handler_) {
500 LOG4CXX_WARN(logger_, "Connection handler is not set.");
502 connection_handler_->StartTransportManager();
506 uint32_t ApplicationManagerImpl::GetNextHMICorrelationID() {
507 if (corelation_id_ < max_corelation_id_) {
513 return corelation_id_;
516 bool ApplicationManagerImpl::begin_audio_pass_thru() {
517 sync_primitives::AutoLock lock(audio_pass_thru_lock_);
518 if (audio_pass_thru_active_) {
521 audio_pass_thru_active_ = true;
526 bool ApplicationManagerImpl::end_audio_pass_thru() {
527 sync_primitives::AutoLock lock(audio_pass_thru_lock_);
528 if (audio_pass_thru_active_) {
529 audio_pass_thru_active_ = false;
536 void ApplicationManagerImpl::set_driver_distraction(bool is_distracting) {
537 is_distracting_driver_ = is_distracting;
540 void ApplicationManagerImpl::set_vr_session_started(const bool& state) {
541 is_vr_session_strated_ = state;
544 void ApplicationManagerImpl::set_all_apps_allowed(const bool& allowed) {
545 is_all_apps_allowed_ = allowed;
548 void ApplicationManagerImpl::StartAudioPassThruThread(int32_t session_key,
549 int32_t correlation_id, int32_t max_duration, int32_t sampling_rate,
550 int32_t bits_per_sample, int32_t audio_type) {
551 LOG4CXX_INFO(logger_, "START MICROPHONE RECORDER");
552 if (NULL != media_manager_) {
553 media_manager_->StartMicrophoneRecording(
555 std::string("record.wav"),
560 void ApplicationManagerImpl::SendAudioPassThroughNotification(
561 uint32_t session_key,
562 std::vector<uint8_t> binaryData) {
563 LOG4CXX_TRACE_ENTER(logger_);
566 sync_primitives::AutoLock lock(audio_pass_thru_lock_);
567 if (!audio_pass_thru_active_) {
568 LOG4CXX_ERROR(logger_, "Trying to send PassThroughNotification"
569 " when PassThrough is not active");
575 smart_objects::SmartObject* on_audio_pass = NULL;
576 on_audio_pass = new smart_objects::SmartObject();
578 if (NULL == on_audio_pass) {
579 LOG4CXX_ERROR_EXT(logger_, "OnAudioPassThru NULL pointer");
584 LOG4CXX_INFO_EXT(logger_, "Fill smart object");
586 (*on_audio_pass)[strings::params][strings::message_type] =
587 application_manager::MessageType::kNotification;
589 (*on_audio_pass)[strings::params][strings::connection_key] =
590 static_cast<int32_t>(session_key);
591 (*on_audio_pass)[strings::params][strings::function_id] =
592 mobile_apis::FunctionID::OnAudioPassThruID;
594 LOG4CXX_INFO_EXT(logger_, "Fill binary data");
596 (*on_audio_pass)[strings::params][strings::binary_data] =
597 smart_objects::SmartObject(binaryData);
599 LOG4CXX_INFO_EXT(logger_, "After fill binary data");
601 LOG4CXX_INFO_EXT(logger_, "Send data");
602 CommandSharedPtr command =
603 MobileCommandFactory::CreateCommand(&(*on_audio_pass));
609 void ApplicationManagerImpl::StopAudioPassThru(int32_t application_key) {
610 LOG4CXX_TRACE_ENTER(logger_);
611 if (NULL != media_manager_) {
612 media_manager_->StopMicrophoneRecording(application_key);
616 std::string ApplicationManagerImpl::GetDeviceName(
617 connection_handler::DeviceHandle handle) {
618 DCHECK(connection_handler_ != 0);
620 std::string device_name = "";
621 std::list<uint32_t> applications_list;
622 connection_handler::ConnectionHandlerImpl* con_handler_impl =
623 static_cast<connection_handler::ConnectionHandlerImpl*>(
624 connection_handler_);
625 if (con_handler_impl->GetDataOnDeviceID(handle, &device_name,
626 &applications_list) == -1) {
627 LOG4CXX_ERROR(logger_, "Failed to extract device name for id " << handle);
629 LOG4CXX_INFO(logger_, "\t\t\t\t\tDevice name is " << device_name);
635 void ApplicationManagerImpl::OnMessageReceived(
636 const protocol_handler::RawMessagePtr& message) {
637 LOG4CXX_INFO(logger_, "ApplicationManagerImpl::OnMessageReceived");
640 LOG4CXX_ERROR(logger_, "Null-pointer message received.");
645 utils::SharedPtr<Message> outgoing_message = ConvertRawMsgToMessage(message);
646 if (outgoing_message) {
647 messages_from_mobile_.PostMessage(
648 impl::MessageFromMobile(outgoing_message));
650 LOG4CXX_WARN(logger_, "Incorrect message received");
654 void ApplicationManagerImpl::OnMobileMessageSent(
655 const protocol_handler::RawMessagePtr& message) {
656 LOG4CXX_INFO(logger_, "ApplicationManagerImpl::OnMobileMessageSent");
659 void ApplicationManagerImpl::OnMessageReceived(
660 hmi_message_handler::MessageSharedPointer message) {
661 LOG4CXX_INFO(logger_, "ApplicationManagerImpl::OnMessageReceived");
664 LOG4CXX_ERROR(logger_, "Null-pointer message received.");
669 messages_from_hmi_.PostMessage(impl::MessageFromHmi(message));
672 void ApplicationManagerImpl::OnErrorSending(
673 hmi_message_handler::MessageSharedPointer message) {
677 void ApplicationManagerImpl::OnDeviceListUpdated(
678 const connection_handler::DeviceList& device_list) {
679 LOG4CXX_INFO(logger_, "ApplicationManagerImpl::OnDeviceListUpdated");
681 smart_objects::SmartObject* update_list = new smart_objects::SmartObject;
682 smart_objects::SmartObject& so_to_send = *update_list;
683 so_to_send[jhs::S_PARAMS][jhs::S_FUNCTION_ID] =
684 hmi_apis::FunctionID::BasicCommunication_UpdateDeviceList;
685 so_to_send[jhs::S_PARAMS][jhs::S_MESSAGE_TYPE] =
686 hmi_apis::messageType::request;
687 so_to_send[jhs::S_PARAMS][jhs::S_PROTOCOL_VERSION] = 2;
688 so_to_send[jhs::S_PARAMS][jhs::S_PROTOCOL_TYPE] = 1;
689 so_to_send[jhs::S_PARAMS][jhs::S_CORRELATION_ID] = GetNextHMICorrelationID();
690 smart_objects::SmartObject* msg_params = MessageHelper::CreateDeviceListSO(
693 LOG4CXX_WARN(logger_, "Failed to create sub-smart object.");
697 so_to_send[jhs::S_MSG_PARAMS] = *msg_params;
698 ManageHMICommand(update_list);
701 void ApplicationManagerImpl::RemoveDevice(
702 const connection_handler::DeviceHandle& device_handle) {
706 bool ApplicationManagerImpl::IsAudioStreamingAllowed(uint32_t connection_key) const {
707 ApplicationSharedPtr app = application(connection_key);
710 LOG4CXX_INFO(logger_, "An application is not registered.");
714 const mobile_api::HMILevel::eType& hmi_level = app->hmi_level();
716 if (mobile_api::HMILevel::HMI_FULL == hmi_level ||
717 mobile_api::HMILevel::HMI_LIMITED == hmi_level) {
724 bool ApplicationManagerImpl::IsVideoStreamingAllowed(uint32_t connection_key) const {
725 ApplicationSharedPtr app = application(connection_key);
728 LOG4CXX_INFO(logger_, "An application is not registered.");
732 const mobile_api::HMILevel::eType& hmi_level = app->hmi_level();
734 if (mobile_api::HMILevel::HMI_FULL == hmi_level &&
735 app->hmi_supports_navi_streaming() ) {
742 bool ApplicationManagerImpl::OnServiceStartedCallback(
743 const connection_handler::DeviceHandle& device_handle,
744 const int32_t& session_key,
745 const protocol_handler::ServiceType& type) {
746 LOG4CXX_INFO(logger_,
747 "OnServiceStartedCallback " << type << " in session " << session_key);
749 ApplicationSharedPtr app = application(session_key);
752 case protocol_handler::kRpc: {
753 LOG4CXX_INFO(logger_, "RPC service is about to be started.");
756 case protocol_handler::kMobileNav: {
757 LOG4CXX_INFO(logger_, "Video service is about to be started.");
758 if (media_manager_) {
760 LOG4CXX_ERROR_EXT(logger_, "An application is not registered.");
763 if (app->allowed_support_navigation()) {
764 media_manager_->StartVideoStreaming(session_key);
771 case protocol_handler::kAudio: {
772 LOG4CXX_INFO(logger_, "Audio service is about to be started.");
773 if (media_manager_) {
775 LOG4CXX_ERROR_EXT(logger_, "An application is not registered.");
778 if (app->allowed_support_navigation()) {
779 media_manager_->StartAudioStreaming(session_key);
787 LOG4CXX_WARN(logger_, "Unknown type of service to be started.");
795 void ApplicationManagerImpl::OnServiceEndedCallback(const int32_t& session_key,
796 const protocol_handler::ServiceType& type) {
799 "OnServiceEndedCallback " << type << " in session " << session_key);
801 case protocol_handler::kRpc: {
802 LOG4CXX_INFO(logger_, "Remove application.");
803 UnregisterApplication(session_key, true);
806 case protocol_handler::kMobileNav: {
807 LOG4CXX_INFO(logger_, "Stop video streaming.");
808 if (media_manager_) {
809 media_manager_->StopVideoStreaming(session_key);
813 case protocol_handler::kAudio:{
814 LOG4CXX_INFO(logger_, "Stop audio service.");
815 if (media_manager_) {
816 media_manager_->StopAudioStreaming(session_key);
821 LOG4CXX_WARN(logger_, "Unknown type of service to be ended.");
826 void ApplicationManagerImpl::set_hmi_message_handler(
827 hmi_message_handler::HMIMessageHandler* handler) {
828 hmi_handler_ = handler;
831 void ApplicationManagerImpl::set_connection_handler(
832 connection_handler::ConnectionHandler* handler) {
833 connection_handler_ = handler;
834 resume_ctrl_.LoadApplications();
837 void ApplicationManagerImpl::set_policy_manager(
838 policies::PolicyManager* policy_manager) {
839 policy_manager_ = policy_manager;
842 void ApplicationManagerImpl::set_protocol_handler(
843 protocol_handler::ProtocolHandler* handler) {
844 protocol_handler_ = handler;
847 void ApplicationManagerImpl::StartDevicesDiscovery() {
848 connection_handler::ConnectionHandlerImpl::instance()->
849 StartDevicesDiscovery();
852 void ApplicationManagerImpl::SendMessageToMobile(
853 const utils::SharedPtr<smart_objects::SmartObject>& message,
854 bool final_message) {
855 LOG4CXX_INFO(logger_, "ApplicationManagerImpl::SendMessageToMobile");
858 LOG4CXX_ERROR(logger_, "Null-pointer message received.");
863 if (!protocol_handler_) {
864 LOG4CXX_WARN(logger_, "No Protocol Handler set");
868 mobile_so_factory().attachSchema(*message);
871 "Attached schema to message, result if valid: " << message->isValid());
873 // Messages to mobile are not yet prioritized so use default priority value
874 utils::SharedPtr<Message> message_to_send(new Message(
875 protocol_handler::MessagePriority::kDefault));
876 if (!ConvertSOtoMessage((*message), (*message_to_send))) {
877 LOG4CXX_WARN(logger_, "Can't send msg to Mobile: failed to create string");
881 smart_objects::SmartObject& msg_to_mobile = *message;
882 if (msg_to_mobile[strings::params].keyExists(strings::correlation_id)) {
883 request_ctrl_.terminateRequest(
884 msg_to_mobile[strings::params][strings::correlation_id].asUInt());
887 messages_to_mobile_.PostMessage(impl::MessageToMobile(message_to_send,
891 bool ApplicationManagerImpl::ManageMobileCommand(
892 const utils::SharedPtr<smart_objects::SmartObject>& message) {
893 LOG4CXX_INFO(logger_, "ApplicationManagerImpl::ManageMobileCommand");
896 LOG4CXX_WARN(logger_, "Null-pointer message received.");
902 MessageHelper::PrintSmartObject(*message);
905 LOG4CXX_INFO(logger_, "Trying to create message in mobile factory.");
906 CommandSharedPtr command = MobileCommandFactory::CreateCommand(message);
909 LOG4CXX_WARN(logger_, "Failed to create mobile command from smart object");
913 mobile_apis::FunctionID::eType function_id =
914 static_cast<mobile_apis::FunctionID::eType>(
915 (*message)[strings::params][strings::function_id].asInt());
917 // Notifications from HMI have no such parameter
918 uint32_t correlation_id =
919 (*message)[strings::params].keyExists(strings::correlation_id)
920 ? (*message)[strings::params][strings::correlation_id].asUInt()
923 uint32_t connection_key =
924 (*message)[strings::params][strings::connection_key].asUInt();
926 uint32_t protocol_type =
927 (*message)[strings::params][strings::protocol_type].asUInt();
929 ApplicationSharedPtr app;
931 if (((mobile_apis::FunctionID::RegisterAppInterfaceID != function_id) &&
932 (protocol_type == commands::CommandImpl::mobile_protocol_type_)) &&
933 (mobile_apis::FunctionID::UnregisterAppInterfaceID != function_id)) {
934 app = ApplicationManagerImpl::instance()->application(connection_key);
936 LOG4CXX_ERROR_EXT(logger_, "APPLICATION_NOT_REGISTERED");
937 smart_objects::SmartObject* response =
938 MessageHelper::CreateNegativeResponse(
940 static_cast<int32_t>(function_id),
942 static_cast<int32_t>(mobile_apis::Result::APPLICATION_NOT_REGISTERED));
944 ApplicationManagerImpl::instance()->SendMessageToMobile(response);
948 // Message for "CheckPermission" must be with attached schema
949 mobile_so_factory().attachSchema(*message);
951 policies::CheckPermissionResult result =
952 policy_manager_->CheckPermission(app->app_id(),
956 if (policies::PermissionResult::PERMISSION_ALLOWED != result.result) {
959 "Request blocked by policies. " << "FunctionID: "
960 << static_cast<int32_t>(function_id) << " Application HMI status: "
961 << static_cast<int32_t>(app->hmi_level()));
963 smart_objects::SmartObject* response =
964 MessageHelper::CreateBlockedByPoliciesResponse(function_id,
965 mobile_apis::Result::REJECTED, correlation_id, connection_key);
967 ApplicationManagerImpl::instance()->SendMessageToMobile(response);
972 if (command->Init()) {
973 if ((*message)[strings::params][strings::message_type].asInt() ==
974 mobile_apis::messageType::request) {
975 // get application hmi level
976 mobile_api::HMILevel::eType app_hmi_level =
977 mobile_api::HMILevel::INVALID_ENUM;
979 app_hmi_level = app->hmi_level();
982 request_controller::RequestController::TResult result =
983 request_ctrl_.addRequest(command, app_hmi_level);
985 if (result == request_controller::RequestController::SUCCESS) {
986 LOG4CXX_INFO(logger_, "Perform request");
988 request_controller::RequestController::
989 TOO_MANY_PENDING_REQUESTS) {
990 LOG4CXX_ERROR_EXT(logger_, "Unable to perform request: " <<
991 "TOO_MANY_PENDING_REQUESTS");
993 smart_objects::SmartObject* response =
994 MessageHelper::CreateNegativeResponse(
996 static_cast<int32_t>(function_id),
998 static_cast<int32_t>(mobile_apis::Result::TOO_MANY_PENDING_REQUESTS));
1000 ApplicationManagerImpl::instance()->SendMessageToMobile(response);
1002 } else if (result ==
1003 request_controller::RequestController::TOO_MANY_REQUESTS) {
1004 LOG4CXX_ERROR_EXT(logger_, "Unable to perform request: " <<
1005 "TOO_MANY_REQUESTS");
1007 MessageHelper::SendOnAppInterfaceUnregisteredNotificationToMobile(
1009 mobile_api::AppInterfaceUnregisteredReason::TOO_MANY_REQUESTS);
1011 UnregisterApplication(connection_key, true);
1013 } else if (result ==
1014 request_controller::RequestController::
1015 NONE_HMI_LEVEL_MANY_REQUESTS) {
1016 LOG4CXX_ERROR_EXT(logger_, "Unable to perform request: " <<
1017 "REQUEST_WHILE_IN_NONE_HMI_LEVEL");
1019 MessageHelper::SendOnAppInterfaceUnregisteredNotificationToMobile(
1020 connection_key, mobile_api::AppInterfaceUnregisteredReason::
1021 REQUEST_WHILE_IN_NONE_HMI_LEVEL);
1023 UnregisterApplication(connection_key, true);
1026 LOG4CXX_ERROR_EXT(logger_, "Unable to perform request: Unknown case");
1037 void ApplicationManagerImpl::SendMessageToHMI(
1038 const utils::SharedPtr<smart_objects::SmartObject>& message) {
1039 LOG4CXX_INFO(logger_, "ApplicationManagerImpl::SendMessageToHMI");
1042 LOG4CXX_WARN(logger_, "Null-pointer message received.");
1047 if (!hmi_handler_) {
1048 LOG4CXX_WARN(logger_, "No HMI Handler set");
1052 // SmartObject |message| has no way to declare priority for now
1053 utils::SharedPtr<Message> message_to_send(
1054 new Message(protocol_handler::MessagePriority::kDefault));
1055 if (!message_to_send) {
1056 LOG4CXX_ERROR(logger_, "Null pointer");
1060 hmi_so_factory().attachSchema(*message);
1063 "Attached schema to message, result if valid: " << message->isValid());
1066 if (!ConvertSOtoMessage(*message, *message_to_send)) {
1067 LOG4CXX_WARN(logger_,
1068 "Cannot send message to HMI: failed to create string");
1074 message_to_send->set_smart_object(*message);
1077 messages_to_hmi_.PostMessage(impl::MessageToHmi(message_to_send));
1080 bool ApplicationManagerImpl::ManageHMICommand(
1081 const utils::SharedPtr<smart_objects::SmartObject>& message) {
1082 LOG4CXX_INFO(logger_, "ApplicationManagerImpl::ManageHMICommand");
1085 LOG4CXX_WARN(logger_, "Null-pointer message received.");
1091 MessageHelper::PrintSmartObject(*message);
1094 CommandSharedPtr command = HMICommandFactory::CreateCommand(message);
1097 LOG4CXX_WARN(logger_, "Failed to create command from smart object");
1101 if (command->Init()) {
1103 if (command->CleanUp()) {
1110 void ApplicationManagerImpl::CreateHMIMatrix(HMIMatrix* matrix) {
1113 void ApplicationManagerImpl::CreatePoliciesManager(PoliciesManager* managaer) {
1116 bool ApplicationManagerImpl::CheckPolicies(smart_objects::SmartObject* message,
1117 ApplicationSharedPtr app) {
1121 bool ApplicationManagerImpl::CheckHMIMatrix(
1122 smart_objects::SmartObject* message) {
1126 bool ApplicationManagerImpl::ConvertMessageToSO(
1127 const Message& message, smart_objects::SmartObject& output) {
1130 "\t\t\tMessage to convert: protocol " << message.protocol_version()
1131 << "; json " << message.json_message());
1133 switch (message.protocol_version()) {
1134 case ProtocolVersion::kV2: {
1136 if (!formatters::CFormatterJsonSDLRPCv2::fromString(
1137 message.json_message(),
1139 message.function_id(),
1141 message.correlation_id())
1142 || !mobile_so_factory().attachSchema(output)
1143 || ((output.validate() != smart_objects::Errors::OK)
1144 && (output.validate() !=
1145 smart_objects::Errors::UNEXPECTED_PARAMETER))) {
1146 LOG4CXX_WARN(logger_, "Failed to parse string to smart object");
1147 utils::SharedPtr<smart_objects::SmartObject> response(
1148 MessageHelper::CreateNegativeResponse(
1149 message.connection_key(), message.function_id(),
1150 message.correlation_id(), mobile_apis::Result::INVALID_DATA));
1151 ManageMobileCommand(response);
1156 "Convertion result for sdl object is true" << " function_id "
1157 << output[jhs::S_PARAMS][jhs::S_FUNCTION_ID].asInt());
1158 output[strings::params][strings::connection_key] =
1159 message.connection_key();
1160 if (message.binary_data()) {
1161 output[strings::params][strings::binary_data] =
1162 *(message.binary_data());
1166 case ProtocolVersion::kHMI: {
1167 int32_t result = formatters::FormatterJsonRpc::FromString <
1168 hmi_apis::FunctionID::eType, hmi_apis::messageType::eType > (
1169 message.json_message(), output);
1172 "Convertion result: " << result << " function id "
1173 << output[jhs::S_PARAMS][jhs::S_FUNCTION_ID].asInt());
1174 if (!hmi_so_factory().attachSchema(output)) {
1175 LOG4CXX_WARN(logger_, "Failed to attach schema to object.");
1178 if (output.validate() != smart_objects::Errors::OK &&
1179 output.validate() != smart_objects::Errors::UNEXPECTED_PARAMETER) {
1182 "Incorrect parameter from HMI");
1183 output.erase(strings::msg_params);
1184 output[strings::params][hmi_response::code] =
1185 hmi_apis::Common_Result::INVALID_DATA;
1186 output[strings::msg_params][strings::info] =
1187 std::string("Received invalid data on HMI response");
1191 case ProtocolVersion::kV1: {
1192 static NsSmartDeviceLinkRPC::V1::v4_protocol_v1_2_no_extra v1_shema;
1194 if (message.function_id() == 0 || message.type() == kUnknownType) {
1195 LOG4CXX_ERROR(logger_, "Message received: UNSUPPORTED_VERSION");
1197 int32_t conversation_result =
1198 formatters::CFormatterJsonSDLRPCv1::fromString <
1199 NsSmartDeviceLinkRPC::V1::FunctionID::eType,
1200 NsSmartDeviceLinkRPC::V1::messageType::eType > (
1201 message.json_message(), output);
1203 if (formatters::CFormatterJsonSDLRPCv1::kSuccess
1204 == conversation_result) {
1206 smart_objects::SmartObject params = smart_objects::SmartObject(smart_objects::SmartType::SmartType_Map);
1208 output[strings::params][strings::message_type] =
1209 NsSmartDeviceLinkRPC::V1::messageType::response;
1210 output[strings::params][strings::connection_key] = message.connection_key();
1212 output[strings::msg_params] =
1213 smart_objects::SmartObject(smart_objects::SmartType::SmartType_Map);
1214 output[strings::msg_params][strings::success] = false;
1215 output[strings::msg_params][strings::result_code] =
1216 NsSmartDeviceLinkRPC::V1::Result::UNSUPPORTED_VERSION;
1218 smart_objects::SmartObject* msg_to_send = new smart_objects::SmartObject(output);
1219 v1_shema.attachSchema(*msg_to_send);
1220 SendMessageToMobile(msg_to_send);
1229 // removed NOTREACHED() because some app can still have vesion 1.
1232 "Application used unsupported protocol :" << message.protocol_version()
1237 LOG4CXX_INFO(logger_, "Successfully parsed message into smart object");
1241 bool ApplicationManagerImpl::ConvertSOtoMessage(
1242 const smart_objects::SmartObject& message, Message& output) {
1243 LOG4CXX_INFO(logger_, "Message to convert");
1245 if (smart_objects::SmartType_Null == message.getType()
1246 || smart_objects::SmartType_Invalid == message.getType()) {
1247 LOG4CXX_WARN(logger_, "Invalid smart object received.");
1253 "Message with protocol: "
1254 << message.getElement(jhs::S_PARAMS).getElement(jhs::S_PROTOCOL_TYPE)
1257 std::string output_string;
1258 switch (message.getElement(jhs::S_PARAMS).getElement(jhs::S_PROTOCOL_TYPE)
1262 if (message.getElement(jhs::S_PARAMS).getElement(jhs::S_PROTOCOL_VERSION).asInt() == 1) {
1263 if (!formatters::CFormatterJsonSDLRPCv1::toString(message,
1265 LOG4CXX_WARN(logger_, "Failed to serialize smart object");
1268 output.set_protocol_version(application_manager::kV1);
1270 if (!formatters::CFormatterJsonSDLRPCv2::toString(message,
1272 LOG4CXX_WARN(logger_, "Failed to serialize smart object");
1275 output.set_protocol_version(application_manager::kV2);
1281 if (!formatters::FormatterJsonRpc::ToString(message, output_string)) {
1282 LOG4CXX_WARN(logger_, "Failed to serialize smart object");
1285 output.set_protocol_version(application_manager::kHMI);
1293 LOG4CXX_INFO(logger_, "Convertion result: " << output_string);
1295 output.set_connection_key(
1296 message.getElement(jhs::S_PARAMS).getElement(strings::connection_key)
1299 output.set_function_id(
1300 message.getElement(jhs::S_PARAMS).getElement(jhs::S_FUNCTION_ID).asInt());
1302 output.set_correlation_id(
1303 message.getElement(jhs::S_PARAMS).getElement(jhs::S_CORRELATION_ID)
1305 output.set_message_type(
1306 static_cast<MessageType>(message.getElement(jhs::S_PARAMS).getElement(
1307 jhs::S_MESSAGE_TYPE).asInt()));
1309 // Currently formatter creates JSON = 3 bytes for empty SmartObject.
1310 // workaround for notification. JSON must be empty
1311 if (mobile_apis::FunctionID::OnAudioPassThruID
1312 != message.getElement(jhs::S_PARAMS).getElement(strings::function_id)
1314 output.set_json_message(output_string);
1317 if (message.getElement(jhs::S_PARAMS).keyExists(strings::binary_data)) {
1318 application_manager::BinaryData* binaryData =
1319 new application_manager::BinaryData(
1320 message.getElement(jhs::S_PARAMS).getElement(strings::binary_data)
1323 if (NULL == binaryData) {
1324 LOG4CXX_ERROR(logger_, "Null pointer");
1327 output.set_binary_data(binaryData);
1330 LOG4CXX_INFO(logger_, "Successfully parsed smart object into message");
1334 utils::SharedPtr<Message> ApplicationManagerImpl::ConvertRawMsgToMessage(
1335 const protocol_handler::RawMessagePtr& message) {
1337 utils::SharedPtr<Message> outgoing_message;
1339 if (message->service_type() != protocol_handler::kRpc
1341 message->service_type() != protocol_handler::kBulk) {
1342 // skip this message, not under handling of ApplicationManager
1343 LOG4CXX_INFO(logger_, "Skipping message; not the under AM handling.");
1344 return outgoing_message;
1347 Message* convertion_result = NULL;
1348 if (message->protocol_version() == 1) {
1350 MobileMessageHandler::HandleIncomingMessageProtocolV1(message);
1351 } else if (message->protocol_version() == 2) {
1353 MobileMessageHandler::HandleIncomingMessageProtocolV2(message);
1355 LOG4CXX_WARN(logger_, "Unknown protocol version.");
1356 return outgoing_message;
1359 if (convertion_result) {
1360 outgoing_message = convertion_result;
1362 LOG4CXX_ERROR(logger_, "Received invalid message");
1364 return outgoing_message;
1367 void ApplicationManagerImpl::ProcessMessageFromMobile(
1368 const utils::SharedPtr<Message>& message) {
1369 LOG4CXX_INFO(logger_, "ApplicationManagerImpl::ProcessMessageFromMobile()");
1371 utils::SharedPtr<smart_objects::SmartObject> so_from_mobile(
1372 new smart_objects::SmartObject);
1374 if (!so_from_mobile) {
1375 LOG4CXX_ERROR(logger_, "Null pointer");
1379 if (!ConvertMessageToSO(*message, *so_from_mobile)) {
1380 LOG4CXX_ERROR(logger_, "Cannot create smart object from message");
1384 if (!ManageMobileCommand(so_from_mobile)) {
1385 LOG4CXX_ERROR(logger_, "Received command didn't run successfully");
1389 void ApplicationManagerImpl::ProcessMessageFromHMI(
1390 const utils::SharedPtr<Message>& message) {
1391 LOG4CXX_INFO(logger_, "ApplicationManagerImpl::ProcessMessageFromHMI()");
1392 utils::SharedPtr<smart_objects::SmartObject> smart_object(
1393 new smart_objects::SmartObject);
1395 if (!smart_object) {
1396 LOG4CXX_ERROR(logger_, "Null pointer");
1401 if (!ConvertMessageToSO(*message, *smart_object)) {
1402 LOG4CXX_ERROR(logger_, "Cannot create smart object from message");
1408 *smart_object = message->smart_object();
1411 LOG4CXX_INFO(logger_, "Converted message, trying to create hmi command");
1412 if (!ManageHMICommand(smart_object)) {
1413 LOG4CXX_ERROR(logger_, "Received command didn't run successfully");
1417 hmi_apis::HMI_API& ApplicationManagerImpl::hmi_so_factory() {
1418 if (!hmi_so_factory_) {
1419 hmi_so_factory_ = new hmi_apis::HMI_API;
1420 if (!hmi_so_factory_) {
1421 LOG4CXX_ERROR(logger_, "Out of memory");
1425 return *hmi_so_factory_;
1428 mobile_apis::MOBILE_API& ApplicationManagerImpl::mobile_so_factory() {
1429 if (!mobile_so_factory_) {
1430 mobile_so_factory_ = new mobile_apis::MOBILE_API;
1431 if (!mobile_so_factory_) {
1432 LOG4CXX_ERROR(logger_, "Out of memory.");
1436 return *mobile_so_factory_;
1439 HMICapabilities& ApplicationManagerImpl::hmi_capabilities() {
1440 return hmi_capabilities_;
1443 void ApplicationManagerImpl::addNotification(const CommandSharedPtr& ptr) {
1444 notification_list_.push_back(ptr);
1447 void ApplicationManagerImpl::removeNotification(const CommandSharedPtr& ptr) {
1448 std::list<CommandSharedPtr>::iterator it = notification_list_.begin();
1449 for (; notification_list_.end() != it; ++it) {
1451 notification_list_.erase(it);
1457 void ApplicationManagerImpl::updateRequestTimeout(uint32_t connection_key,
1458 uint32_t mobile_correlation_id,
1459 uint32_t new_timeout_value) {
1460 request_ctrl_.updateRequestTimeout(connection_key, mobile_correlation_id,
1464 const uint32_t ApplicationManagerImpl::application_id
1465 (const int32_t correlation_id) {
1466 // ykazakov: there is no erase for const iterator for QNX
1467 std::map<const int32_t, const uint32_t>::iterator it =
1468 appID_list_.find(correlation_id);
1469 if (appID_list_.end() != it) {
1470 const uint32_t app_id = it->second;
1471 appID_list_.erase(it);
1478 void ApplicationManagerImpl::set_application_id(const int32_t correlation_id,
1479 const uint32_t app_id) {
1480 appID_list_.insert(std::pair<const int32_t, const uint32_t>
1481 (correlation_id, app_id));
1484 void ApplicationManagerImpl::SetUnregisterAllApplicationsReason(
1485 mobile_api::AppInterfaceUnregisteredReason::eType reason) {
1486 unregister_reason_ = reason;
1489 void ApplicationManagerImpl::UnregisterAllApplications() {
1490 LOG4CXX_INFO(logger_, "ApplicationManagerImpl::UnregisterAllApplications " <<
1491 unregister_reason_);
1493 hmi_cooperating_ = false;
1495 std::set<ApplicationSharedPtr>::iterator it = application_list_.begin();
1496 while (it != application_list_.end()) {
1497 MessageHelper::SendOnAppInterfaceUnregisteredNotificationToMobile(
1498 (*it)->app_id(), unregister_reason_);
1500 UnregisterApplication((*it)->app_id(), true);
1501 it = application_list_.begin();
1503 resume_ctrl_.IgnitionOff();
1506 void ApplicationManagerImpl::UnregisterApplication(const uint32_t& app_id, bool is_resuming) {
1507 LOG4CXX_INFO(logger_,
1508 "ApplicationManagerImpl::UnregisterApplication " << app_id);
1510 sync_primitives::AutoLock lock(applications_list_lock_);
1512 std::map<int32_t, ApplicationSharedPtr>::iterator it = applications_.find(app_id);
1513 if (applications_.end() == it) {
1514 LOG4CXX_INFO(logger_, "Application is already unregistered.");
1517 ApplicationSharedPtr app_to_remove = it->second;
1519 resume_ctrl_.SaveApplication(app_to_remove);
1521 if (audio_pass_thru_active_) {
1522 // May be better to put this code in MessageHelper?
1523 end_audio_pass_thru();
1524 StopAudioPassThru(app_id);
1525 MessageHelper::SendStopAudioPathThru();
1527 MessageHelper::RemoveAppDataFromHMI(it->second);
1528 MessageHelper::SendOnAppUnregNotificationToHMI(it->second);
1529 applications_.erase(it);
1530 application_list_.erase(app_to_remove);
1531 request_ctrl_.terminateAppRequests(app_id);
1536 void ApplicationManagerImpl::Handle(const impl::MessageFromMobile& message) {
1537 LOG4CXX_INFO(logger_, "Received message from Mobile side");
1540 LOG4CXX_ERROR(logger_, "Null-pointer message received.");
1543 ProcessMessageFromMobile(message);
1546 void ApplicationManagerImpl::Handle(const impl::MessageToMobile& message) {
1547 protocol_handler::RawMessage* rawMessage = 0;
1548 if (message->protocol_version() == application_manager::kV1) {
1549 rawMessage = MobileMessageHandler::HandleOutgoingMessageProtocolV1(
1551 } else if (message->protocol_version() == application_manager::kV2) {
1552 rawMessage = MobileMessageHandler::HandleOutgoingMessageProtocolV2(
1558 LOG4CXX_ERROR(logger_, "Failed to create raw message.");
1562 if (!protocol_handler_) {
1563 LOG4CXX_WARN(logger_,
1564 "Protocol Handler is not set; cannot send message to mobile.");
1568 protocol_handler_->SendMessageToMobileApp(rawMessage, message.is_final);
1570 LOG4CXX_INFO(logger_, "Message for mobile given away.");
1573 void ApplicationManagerImpl::Handle(const impl::MessageFromHmi& message) {
1574 LOG4CXX_INFO(logger_, "Received message from hmi");
1577 LOG4CXX_ERROR(logger_, "Null-pointer message received.");
1581 ProcessMessageFromHMI(message);
1584 void ApplicationManagerImpl::Handle(const impl::MessageToHmi& message) {
1585 LOG4CXX_INFO(logger_, "Received message to hmi");
1586 if (!hmi_handler_) {
1587 LOG4CXX_ERROR(logger_, "Observer is not set for HMIMessageHandler");
1591 hmi_handler_->SendMessageToHMI(message);
1592 LOG4CXX_INFO(logger_, "Message from hmi given away.");
1596 void ApplicationManagerImpl::Mute(VRTTSSessionChanging changing_state) {
1597 mobile_apis::AudioStreamingState::eType state =
1598 hmi_capabilities_.attenuated_supported()
1599 ? mobile_apis::AudioStreamingState::ATTENUATED
1600 : mobile_apis::AudioStreamingState::NOT_AUDIBLE;
1602 std::set<ApplicationSharedPtr>::const_iterator it = application_list_.begin();
1603 std::set<ApplicationSharedPtr>::const_iterator itEnd = application_list_.end();
1604 for (; it != itEnd; ++it) {
1605 if ((*it)->is_media_application()) {
1606 if (kTTSSessionChanging == changing_state) {
1607 (*it)->set_tts_speak_state(true);
1609 if ((*it)->audio_streaming_state() != state) {
1610 (*it)->set_audio_streaming_state(state);
1611 MessageHelper::SendHMIStatusNotification(*(*it));
1617 void ApplicationManagerImpl::Unmute(VRTTSSessionChanging changing_state) {
1618 std::set<ApplicationSharedPtr>::const_iterator it = application_list_.begin();
1619 std::set<ApplicationSharedPtr>::const_iterator itEnd = application_list_.end();
1620 for (; it != itEnd; ++it) {
1621 if ((*it)->is_media_application()) {
1622 if (kTTSSessionChanging == changing_state) {
1623 (*it)->set_tts_speak_state(false);
1625 if ((!(vr_session_started())) &&
1626 ((*it)->audio_streaming_state() !=
1627 mobile_apis::AudioStreamingState::AUDIBLE)) {
1628 (*it)->set_audio_streaming_state(
1629 mobile_apis::AudioStreamingState::AUDIBLE);
1630 MessageHelper::SendHMIStatusNotification(*(*it));
1636 mobile_apis::Result::eType ApplicationManagerImpl::SaveBinary(
1637 const std::string& app_name, const std::vector<uint8_t>& binary_data,
1638 const std::string& save_path, const uint32_t offset) {
1639 if (binary_data.size() > file_system::GetAvailableSpaceForApp(app_name)) {
1640 return mobile_apis::Result::OUT_OF_MEMORY;
1643 LOG4CXX_INFO(logger_, "SaveBinaryWithOffset binary_size = "
1644 << binary_data.size() << " offset = " << offset);
1646 uint32_t file_size = file_system::FileSize(file_system::FullPath(save_path));
1647 std::ofstream* file_stream;
1649 if (file_size != offset) {
1650 LOG4CXX_INFO(logger_, "ApplicationManagerImpl::SaveBinaryWithOffset offset does'n match existing filesize");
1651 return mobile_apis::Result::INVALID_DATA;
1653 file_stream = file_system::Open(file_system::FullPath(save_path),
1654 std::ios_base::app);
1656 LOG4CXX_INFO(logger_, "ApplicationManagerImpl::SaveBinaryWithOffset offset is 0, rewrite");
1657 // if offset == 0: rewrite file
1658 file_stream = file_system::Open(file_system::FullPath(save_path),
1659 std::ios_base::out);
1662 if (!file_system::Write(file_stream,binary_data.data(), binary_data.size())) {
1663 file_system::Close(file_stream);
1664 return mobile_apis::Result::GENERIC_ERROR;
1666 file_system::Close(file_stream);
1667 LOG4CXX_INFO(logger_, "Successfully write data to file");
1668 return mobile_apis::Result::SUCCESS;
1671 } // namespace application_manager