57b9a25b57702fa1f449158ba9b3e15454616a25
[profile/ivi/smartdevicelink.git] / src / components / application_manager / src / application_manager_impl.cc
1 /**
2  * Copyright (c) 2013, Ford Motor Company
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * Redistributions of source code must retain the above copyright notice, this
9  * list of conditions and the following disclaimer.
10  *
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
14  * distribution.
15  *
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.
19  *
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.
31  */
32
33 #include "application_manager/application_manager_impl.h"
34
35 #include <climits>
36 #include <string>
37 #include <fstream>
38
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"
54
55 namespace application_manager {
56
57 log4cxx::LoggerPtr ApplicationManagerImpl::logger_ = log4cxx::LoggerPtr(
58       log4cxx::Logger::getLogger("ApplicationManager"));
59
60 uint32_t ApplicationManagerImpl::corelation_id_ = 0;
61 const uint32_t ApplicationManagerImpl::max_corelation_id_ = UINT_MAX;
62
63 namespace formatters = NsSmartDeviceLink::NsJSONHandler::Formatters;
64 namespace jhs = NsSmartDeviceLink::NsJSONHandler::strings;
65
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),
72     hmi_handler_(NULL),
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),
82     request_ctrl_(),
83     hmi_capabilities_(this),
84     unregister_reason_(mobile_api::AppInterfaceUnregisteredReason::MASTER_RESET),
85     media_manager_(NULL),
86     resume_ctrl_(this)
87 {
88   LOG4CXX_INFO(logger_, "Creating ApplicationManager");
89   if (!policies_manager_.Init()) {
90     LOG4CXX_ERROR(logger_, "Policies manager initialization failed.");
91     return;
92   }
93
94   media_manager_ = media_manager::MediaManagerImpl::instance();
95 }
96
97 bool ApplicationManagerImpl::InitThread(threads::Thread* thread) {
98   if (!thread) {
99     LOG4CXX_ERROR(logger_, "Failed to allocate memory for thread object");
100     return false;
101   }
102   LOG4CXX_INFO(
103     logger_,
104     "Starting thread with stack size "
105     << profile::Profile::instance()->thread_min_stack_size());
106   if (!thread->start()) {
107     /*startWithOptions(
108      threads::ThreadOptions(
109      profile::Profile::instance()->thread_min_stack_size()))*/
110     LOG4CXX_ERROR(logger_, "Failed to start thread");
111     return false;
112   }
113   return true;
114 }
115
116 ApplicationManagerImpl::~ApplicationManagerImpl() {
117   LOG4CXX_INFO(logger_, "Destructing ApplicationManager.");
118
119   media_manager_ = NULL;
120   hmi_handler_ = 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;
127 }
128
129 bool ApplicationManagerImpl::Stop() {
130   LOG4CXX_INFO(logger_, "Stop ApplicationManager.");
131   try {
132     UnregisterAllApplications();
133   }
134   catch(...) {
135     LOG4CXX_ERROR(logger_,
136                   "An error occured during unregistering applications.");
137   }
138   MessageHelper::SendOnSdlCloseNotificationToHMI();
139   return true;
140 }
141
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) {
146     return it->second;
147   } else {
148     return ApplicationSharedPtr();
149   }
150 }
151
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;
156        ++it) {
157     if ((*it)->IsFullscreen()) {
158       return *it;
159     }
160   }
161   return ApplicationSharedPtr();
162 }
163
164 std::vector<ApplicationSharedPtr> ApplicationManagerImpl::applications_by_button(
165   uint32_t 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);
172     }
173   }
174   return result;
175 }
176
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;
182        ++it) {
183     if ((*it)->IsSubscribedToIVI(vehicle_info)) {
184       result.push_back(*it);
185     }
186   }
187   return result;
188 }
189
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;
194        ++it) {
195     if ((*it)->allowed_support_navigation()) {
196       result.push_back(*it);
197     }
198   }
199   return result;
200 }
201
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();
208
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();
219   }
220
221   // app_id is SDL "internal" ID
222   // original app_id can be gotten via ApplicationImpl::mobile_app_id()
223   uint32_t app_id = 0;
224   std::list<int32_t> sessions_list;
225   uint32_t device_id = 0;
226
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)
233         == -1) {
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();
243     }
244   }
245
246   ApplicationSharedPtr application(new ApplicationImpl(app_id));
247   if (!application) {
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();
255   }
256
257   const std::string& name =
258     message[strings::msg_params][strings::app_name].asString();
259
260   application->set_name(name);
261   application->set_device(device_id);
262
263   application->set_language(
264     static_cast<mobile_api::Language::eType>(
265       message[strings::msg_params][strings::language_desired].asInt()));
266
267   application->set_ui_language(
268     static_cast<mobile_api::Language::eType>(
269       message[strings::msg_params][strings::hmi_display_language_desired]
270       .asInt()));
271
272   Version version;
273   int32_t min_version =
274     message[strings::msg_params][strings::sync_msg_version]
275     [strings::minor_version].asInt();
276
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);
285     delete application;
286     return NULL;
287   }*/
288   version.min_supported_api_version = static_cast<APIVersion>(min_version);
289
290   int32_t max_version =
291     message[strings::msg_params][strings::sync_msg_version]
292     [strings::major_version].asInt();
293
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);
302     delete application;
303     return NULL;
304   }*/
305   version.max_supported_api_version = static_cast<APIVersion>(max_version);
306   application->set_version(version);
307
308   application->set_mobile_app_id(message[strings::msg_params][strings::app_id]);
309
310   sync_primitives::AutoLock lock(applications_list_lock_);
311
312   applications_.insert(std::pair<int32_t, ApplicationSharedPtr>(app_id, application));
313   application_list_.insert(application);
314
315   // TODO(PV): add asking user to allow application
316   // BasicCommunication_AllowApp
317   // application->set_app_allowed(result);
318   return application;
319 }
320
321 bool ApplicationManagerImpl::RemoveAppDataFromHMI(ApplicationSharedPtr app) {
322   return true;
323 }
324
325 bool ApplicationManagerImpl::LoadAppDataToHMI(ApplicationSharedPtr app) {
326   return true;
327 }
328
329 bool ApplicationManagerImpl::ActivateApplication(ApplicationSharedPtr app) {
330   if (!app) {
331     LOG4CXX_ERROR(logger_, "Null-pointer application received.");
332     NOTREACHED();
333     return false;
334   }
335
336   bool is_new_app_media = app->is_media_application();
337
338   for (std::set<ApplicationSharedPtr>::iterator it = application_list_.begin();
339        application_list_.end() != it;
340        ++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.");
345         return false;
346       }
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);
351         }
352       }
353       if (!curr_app->MakeFullscreen()) {
354         return false;
355       }
356       MessageHelper::SendHMIStatusNotification(*curr_app);
357     } else {
358       if (is_new_app_media) {
359         if (curr_app->IsAudible()) {
360           curr_app->MakeNotAudible();
361           MessageHelper::SendHMIStatusNotification(*curr_app);
362         }
363       }
364       if (curr_app->IsFullscreen()) {
365         MessageHelper::RemoveAppDataFromHMI(curr_app);
366       }
367     }
368   }
369   return true;
370 }
371
372 mobile_apis::HMILevel::eType ApplicationManagerImpl::PutApplicationInLimited(
373     ApplicationSharedPtr app) {
374   DCHECK(app.get())
375
376   bool is_new_app_media = app->is_media_application();
377   mobile_api::HMILevel::eType result = mobile_api::HMILevel::HMI_LIMITED;
378
379   for (std::set<ApplicationSharedPtr>::iterator it = application_list_.begin();
380        application_list_.end() != it;
381        ++it) {
382     ApplicationSharedPtr curr_app = *it;
383     if (app->app_id() == curr_app->app_id()) {
384       continue;
385     }
386
387     if (curr_app->hmi_level() == mobile_api::HMILevel::HMI_LIMITED) {
388       result = mobile_api::HMILevel::HMI_BACKGROUND;
389       break;
390     }
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;
394         break;
395       } else {
396         result = mobile_api::HMILevel::HMI_LIMITED;
397       }
398     }
399
400   }
401   app->set_hmi_level(result);
402   return result;
403 }
404
405 mobile_api::HMILevel::eType ApplicationManagerImpl::PutApplicationInFull(
406     ApplicationSharedPtr app) {
407   DCHECK(app.get())
408
409   bool is_new_app_media = app->is_media_application();
410   mobile_api::HMILevel::eType result = mobile_api::HMILevel::HMI_FULL;
411
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()) {
416       continue;
417     }
418
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;
423           break;
424         } else {
425           result = mobile_api::HMILevel::HMI_LIMITED;
426         }
427       }
428       if (curr_app->hmi_level() == mobile_api::HMILevel::HMI_LIMITED) {
429         result = mobile_api::HMILevel::HMI_BACKGROUND;
430         break;
431       }
432     } else {
433       if (curr_app->hmi_level() == mobile_api::HMILevel::HMI_FULL) {
434         result = mobile_api::HMILevel::HMI_BACKGROUND;
435         break;
436       }
437       if (curr_app->hmi_level() == mobile_api::HMILevel::HMI_LIMITED) {
438         result = mobile_api::HMILevel::HMI_FULL;
439       }
440     }
441   }
442
443   if ( result == mobile_api::HMILevel::HMI_FULL) {
444     app->set_hmi_level(result);
445     MessageHelper::SendActivateAppToHMI(app->app_id());
446   }
447   return result;
448 }
449
450 void ApplicationManagerImpl::DeactivateApplication(ApplicationSharedPtr app) {
451   MessageHelper::SendDeleteCommandRequestToHMI(app);
452   MessageHelper::ResetGlobalproperties(app);
453 }
454
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.");
459     return;
460   }
461
462   connection_handler_->ConnectToDevice(id);
463 }
464
465 void ApplicationManagerImpl::OnHMIStartedCooperation() {
466   hmi_cooperating_ = true;
467   LOG4CXX_INFO(logger_, "ApplicationManagerImpl::OnHMIStartedCooperation()");
468
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);
474
475     utils::SharedPtr<smart_objects::SmartObject> is_tts_ready(
476       MessageHelper::CreateModuleInfoSO(hmi_apis::FunctionID::TTS_IsReady));
477     ManageHMICommand(is_tts_ready);
478
479     utils::SharedPtr<smart_objects::SmartObject> is_ui_ready(
480       MessageHelper::CreateModuleInfoSO(hmi_apis::FunctionID::UI_IsReady));
481     ManageHMICommand(is_ui_ready);
482
483     utils::SharedPtr<smart_objects::SmartObject> is_navi_ready(
484       MessageHelper::CreateModuleInfoSO(
485         hmi_apis::FunctionID::Navigation_IsReady));
486     ManageHMICommand(is_navi_ready);
487
488     utils::SharedPtr<smart_objects::SmartObject> is_ivi_ready(
489       MessageHelper::CreateModuleInfoSO(
490         hmi_apis::FunctionID::VehicleInfo_IsReady));
491     ManageHMICommand(is_ivi_ready);
492
493     utils::SharedPtr<smart_objects::SmartObject> button_capabilities(
494       MessageHelper::CreateModuleInfoSO(
495         hmi_apis::FunctionID::Buttons_GetCapabilities));
496     ManageHMICommand(button_capabilities);
497   }
498
499   if (!connection_handler_) {
500     LOG4CXX_WARN(logger_, "Connection handler is not set.");
501   } else {
502     connection_handler_->StartTransportManager();
503   }
504 }
505
506 uint32_t ApplicationManagerImpl::GetNextHMICorrelationID() {
507   if (corelation_id_ < max_corelation_id_) {
508     corelation_id_++;
509   } else {
510     corelation_id_ = 0;
511   }
512
513   return corelation_id_;
514 }
515
516 bool ApplicationManagerImpl::begin_audio_pass_thru() {
517   sync_primitives::AutoLock lock(audio_pass_thru_lock_);
518   if (audio_pass_thru_active_) {
519     return false;
520   } else {
521     audio_pass_thru_active_ = true;
522     return true;
523   }
524 }
525
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;
530     return true;
531   } else {
532     return false;
533   }
534 }
535
536 void ApplicationManagerImpl::set_driver_distraction(bool is_distracting) {
537   is_distracting_driver_ = is_distracting;
538 }
539
540 void ApplicationManagerImpl::set_vr_session_started(const bool& state) {
541   is_vr_session_strated_ = state;
542 }
543
544 void ApplicationManagerImpl::set_all_apps_allowed(const bool& allowed) {
545   is_all_apps_allowed_ = allowed;
546 }
547
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(
554       session_key,
555       std::string("record.wav"),
556       max_duration);
557   }
558 }
559
560 void ApplicationManagerImpl::SendAudioPassThroughNotification(
561   uint32_t session_key,
562   std::vector<uint8_t> binaryData) {
563   LOG4CXX_TRACE_ENTER(logger_);
564
565   {
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");
570
571       return;
572     }
573   }
574
575   smart_objects::SmartObject* on_audio_pass = NULL;
576   on_audio_pass = new smart_objects::SmartObject();
577
578   if (NULL == on_audio_pass) {
579     LOG4CXX_ERROR_EXT(logger_, "OnAudioPassThru NULL pointer");
580
581     return;
582   }
583
584   LOG4CXX_INFO_EXT(logger_, "Fill smart object");
585
586   (*on_audio_pass)[strings::params][strings::message_type] =
587     application_manager::MessageType::kNotification;
588
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;
593
594   LOG4CXX_INFO_EXT(logger_, "Fill binary data");
595   // binary data
596   (*on_audio_pass)[strings::params][strings::binary_data] =
597     smart_objects::SmartObject(binaryData);
598
599   LOG4CXX_INFO_EXT(logger_, "After fill binary data");
600
601   LOG4CXX_INFO_EXT(logger_, "Send data");
602   CommandSharedPtr command =
603     MobileCommandFactory::CreateCommand(&(*on_audio_pass));
604   command->Init();
605   command->Run();
606   command->CleanUp();
607 }
608
609 void ApplicationManagerImpl::StopAudioPassThru(int32_t application_key) {
610   LOG4CXX_TRACE_ENTER(logger_);
611   if (NULL != media_manager_) {
612     media_manager_->StopMicrophoneRecording(application_key);
613   }
614 }
615
616 std::string ApplicationManagerImpl::GetDeviceName(
617   connection_handler::DeviceHandle handle) {
618   DCHECK(connection_handler_ != 0);
619
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);
628   } else {
629     LOG4CXX_INFO(logger_, "\t\t\t\t\tDevice name is " << device_name);
630   }
631
632   return device_name;
633 }
634
635 void ApplicationManagerImpl::OnMessageReceived(
636   const protocol_handler::RawMessagePtr& message) {
637   LOG4CXX_INFO(logger_, "ApplicationManagerImpl::OnMessageReceived");
638
639   if (!message) {
640     LOG4CXX_ERROR(logger_, "Null-pointer message received.");
641     NOTREACHED();
642     return;
643   }
644
645   utils::SharedPtr<Message> outgoing_message = ConvertRawMsgToMessage(message);
646   if (outgoing_message) {
647     messages_from_mobile_.PostMessage(
648         impl::MessageFromMobile(outgoing_message));
649   } else {
650     LOG4CXX_WARN(logger_, "Incorrect message received");
651   }
652 }
653
654 void ApplicationManagerImpl::OnMobileMessageSent(
655   const protocol_handler::RawMessagePtr& message) {
656   LOG4CXX_INFO(logger_, "ApplicationManagerImpl::OnMobileMessageSent");
657 }
658
659 void ApplicationManagerImpl::OnMessageReceived(
660   hmi_message_handler::MessageSharedPointer message) {
661   LOG4CXX_INFO(logger_, "ApplicationManagerImpl::OnMessageReceived");
662
663   if (!message) {
664     LOG4CXX_ERROR(logger_, "Null-pointer message received.");
665     NOTREACHED();
666     return;
667   }
668
669   messages_from_hmi_.PostMessage(impl::MessageFromHmi(message));
670 }
671
672 void ApplicationManagerImpl::OnErrorSending(
673   hmi_message_handler::MessageSharedPointer message) {
674   return;
675 }
676
677 void ApplicationManagerImpl::OnDeviceListUpdated(
678   const connection_handler::DeviceList& device_list) {
679   LOG4CXX_INFO(logger_, "ApplicationManagerImpl::OnDeviceListUpdated");
680
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(
691         device_list);
692   if (!msg_params) {
693     LOG4CXX_WARN(logger_, "Failed to create sub-smart object.");
694     delete update_list;
695     return;
696   }
697   so_to_send[jhs::S_MSG_PARAMS] = *msg_params;
698   ManageHMICommand(update_list);
699 }
700
701 void ApplicationManagerImpl::RemoveDevice(
702   const connection_handler::DeviceHandle& device_handle) {
703 }
704
705
706 bool ApplicationManagerImpl::IsAudioStreamingAllowed(uint32_t connection_key) const {
707   ApplicationSharedPtr app = application(connection_key);
708
709   if (!app) {
710     LOG4CXX_INFO(logger_, "An application is not registered.");
711     return false;
712   }
713
714   const mobile_api::HMILevel::eType& hmi_level = app->hmi_level();
715
716   if (mobile_api::HMILevel::HMI_FULL == hmi_level ||
717       mobile_api::HMILevel::HMI_LIMITED == hmi_level) {
718     return true;
719   }
720
721   return false;
722 }
723
724 bool ApplicationManagerImpl::IsVideoStreamingAllowed(uint32_t connection_key) const {
725   ApplicationSharedPtr app = application(connection_key);
726
727   if (!app) {
728     LOG4CXX_INFO(logger_, "An application is not registered.");
729     return false;
730   }
731
732   const mobile_api::HMILevel::eType& hmi_level = app->hmi_level();
733
734   if (mobile_api::HMILevel::HMI_FULL == hmi_level &&
735       app->hmi_supports_navi_streaming() ) {
736     return true;
737   }
738
739   return false;
740 }
741
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);
748
749   ApplicationSharedPtr app = application(session_key);
750
751   switch (type) {
752     case protocol_handler::kRpc: {
753       LOG4CXX_INFO(logger_, "RPC service is about to be started.");
754       break;
755     }
756     case protocol_handler::kMobileNav: {
757       LOG4CXX_INFO(logger_, "Video service is about to be started.");
758       if (media_manager_) {
759         if (!app) {
760             LOG4CXX_ERROR_EXT(logger_, "An application is not registered.");
761             return false;
762         }
763         if (app->allowed_support_navigation()) {
764           media_manager_->StartVideoStreaming(session_key);
765         } else {
766           return false;
767         }
768       }
769       break;
770     }
771     case protocol_handler::kAudio: {
772       LOG4CXX_INFO(logger_, "Audio service is about to be started.");
773       if (media_manager_) {
774         if (!app) {
775           LOG4CXX_ERROR_EXT(logger_, "An application is not registered.");
776           return false;
777         }
778         if (app->allowed_support_navigation()) {
779           media_manager_->StartAudioStreaming(session_key);
780         } else {
781           return false;
782         }
783       }
784       break;
785     }
786     default: {
787       LOG4CXX_WARN(logger_, "Unknown type of service to be started.");
788       break;
789     }
790   }
791
792   return true;
793 }
794
795 void ApplicationManagerImpl::OnServiceEndedCallback(const int32_t& session_key,
796   const protocol_handler::ServiceType& type) {
797   LOG4CXX_INFO_EXT(
798     logger_,
799     "OnServiceEndedCallback " << type  << " in session " << session_key);
800   switch (type) {
801     case protocol_handler::kRpc: {
802       LOG4CXX_INFO(logger_, "Remove application.");
803       UnregisterApplication(session_key, true);
804       break;
805     }
806     case protocol_handler::kMobileNav: {
807       LOG4CXX_INFO(logger_, "Stop video streaming.");
808       if (media_manager_) {
809         media_manager_->StopVideoStreaming(session_key);
810       }
811       break;
812     }
813     case protocol_handler::kAudio:{
814       LOG4CXX_INFO(logger_, "Stop audio service.");
815       if (media_manager_) {
816         media_manager_->StopAudioStreaming(session_key);
817       }
818       break;
819     }
820     default:
821       LOG4CXX_WARN(logger_, "Unknown type of service to be ended.");
822       break;
823   }
824 }
825
826 void ApplicationManagerImpl::set_hmi_message_handler(
827   hmi_message_handler::HMIMessageHandler* handler) {
828   hmi_handler_ = handler;
829 }
830
831 void ApplicationManagerImpl::set_connection_handler(
832   connection_handler::ConnectionHandler* handler) {
833   connection_handler_ = handler;
834   resume_ctrl_.LoadApplications();
835 }
836
837 void ApplicationManagerImpl::set_policy_manager(
838   policies::PolicyManager* policy_manager) {
839   policy_manager_ = policy_manager;
840 }
841
842 void ApplicationManagerImpl::set_protocol_handler(
843   protocol_handler::ProtocolHandler* handler) {
844   protocol_handler_ = handler;
845 }
846
847 void ApplicationManagerImpl::StartDevicesDiscovery() {
848   connection_handler::ConnectionHandlerImpl::instance()->
849   StartDevicesDiscovery();
850 }
851
852 void ApplicationManagerImpl::SendMessageToMobile(
853   const utils::SharedPtr<smart_objects::SmartObject>& message,
854   bool final_message) {
855   LOG4CXX_INFO(logger_, "ApplicationManagerImpl::SendMessageToMobile");
856
857   if (!message) {
858     LOG4CXX_ERROR(logger_, "Null-pointer message received.");
859     NOTREACHED();
860     return;
861   }
862
863   if (!protocol_handler_) {
864     LOG4CXX_WARN(logger_, "No Protocol Handler set");
865     return;
866   }
867
868   mobile_so_factory().attachSchema(*message);
869   LOG4CXX_INFO(
870     logger_,
871     "Attached schema to message, result if valid: " << message->isValid());
872
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");
878     return;
879   }
880
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());
885   }
886
887   messages_to_mobile_.PostMessage(impl::MessageToMobile(message_to_send,
888                                                         final_message));
889 }
890
891 bool ApplicationManagerImpl::ManageMobileCommand(
892   const utils::SharedPtr<smart_objects::SmartObject>& message) {
893   LOG4CXX_INFO(logger_, "ApplicationManagerImpl::ManageMobileCommand");
894
895   if (!message) {
896     LOG4CXX_WARN(logger_, "Null-pointer message received.");
897     NOTREACHED()
898     return false;
899   }
900
901 #ifdef DEBUG
902   MessageHelper::PrintSmartObject(*message);
903 #endif
904
905   LOG4CXX_INFO(logger_, "Trying to create message in mobile factory.");
906   CommandSharedPtr command = MobileCommandFactory::CreateCommand(message);
907
908   if (!command) {
909     LOG4CXX_WARN(logger_, "Failed to create mobile command from smart object");
910     return false;
911   }
912
913   mobile_apis::FunctionID::eType function_id =
914     static_cast<mobile_apis::FunctionID::eType>(
915       (*message)[strings::params][strings::function_id].asInt());
916
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()
921       : 0;
922
923   uint32_t connection_key =
924     (*message)[strings::params][strings::connection_key].asUInt();
925
926   uint32_t protocol_type =
927     (*message)[strings::params][strings::protocol_type].asUInt();
928
929   ApplicationSharedPtr app;
930
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);
935     if (!app) {
936       LOG4CXX_ERROR_EXT(logger_, "APPLICATION_NOT_REGISTERED");
937       smart_objects::SmartObject* response =
938         MessageHelper::CreateNegativeResponse(
939             connection_key,
940             static_cast<int32_t>(function_id),
941             correlation_id,
942             static_cast<int32_t>(mobile_apis::Result::APPLICATION_NOT_REGISTERED));
943
944       ApplicationManagerImpl::instance()->SendMessageToMobile(response);
945       return false;
946     }
947
948     // Message for "CheckPermission" must be with attached schema
949     mobile_so_factory().attachSchema(*message);
950
951     policies::CheckPermissionResult result =
952       policy_manager_->CheckPermission(app->app_id(),
953                                        *message,
954                                        app->hmi_level());
955
956     if (policies::PermissionResult::PERMISSION_ALLOWED != result.result) {
957       LOG4CXX_WARN(
958         logger_,
959         "Request blocked by policies. " << "FunctionID: "
960         << static_cast<int32_t>(function_id) << " Application HMI status: "
961         << static_cast<int32_t>(app->hmi_level()));
962
963       smart_objects::SmartObject* response =
964         MessageHelper::CreateBlockedByPoliciesResponse(function_id,
965             mobile_apis::Result::REJECTED, correlation_id, connection_key);
966
967       ApplicationManagerImpl::instance()->SendMessageToMobile(response);
968       return true;
969     }
970   }
971
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;
978       if (app) {
979         app_hmi_level = app->hmi_level();
980       }
981
982       request_controller::RequestController::TResult result =
983         request_ctrl_.addRequest(command, app_hmi_level);
984
985       if (result == request_controller::RequestController::SUCCESS) {
986         LOG4CXX_INFO(logger_, "Perform request");
987       } else if (result ==
988                  request_controller::RequestController::
989                  TOO_MANY_PENDING_REQUESTS) {
990         LOG4CXX_ERROR_EXT(logger_, "Unable to perform request: " <<
991                           "TOO_MANY_PENDING_REQUESTS");
992
993         smart_objects::SmartObject* response =
994           MessageHelper::CreateNegativeResponse(
995               connection_key,
996               static_cast<int32_t>(function_id),
997               correlation_id,
998               static_cast<int32_t>(mobile_apis::Result::TOO_MANY_PENDING_REQUESTS));
999
1000         ApplicationManagerImpl::instance()->SendMessageToMobile(response);
1001         return false;
1002       } else if (result ==
1003                  request_controller::RequestController::TOO_MANY_REQUESTS) {
1004         LOG4CXX_ERROR_EXT(logger_, "Unable to perform request: " <<
1005                           "TOO_MANY_REQUESTS");
1006
1007         MessageHelper::SendOnAppInterfaceUnregisteredNotificationToMobile(
1008           connection_key,
1009           mobile_api::AppInterfaceUnregisteredReason::TOO_MANY_REQUESTS);
1010
1011         UnregisterApplication(connection_key, true);
1012         return false;
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");
1018
1019         MessageHelper::SendOnAppInterfaceUnregisteredNotificationToMobile(
1020           connection_key, mobile_api::AppInterfaceUnregisteredReason::
1021           REQUEST_WHILE_IN_NONE_HMI_LEVEL);
1022
1023         UnregisterApplication(connection_key, true);
1024         return false;
1025       } else {
1026         LOG4CXX_ERROR_EXT(logger_, "Unable to perform request: Unknown case");
1027         return false;
1028       }
1029     }
1030
1031     command->Run();
1032   }
1033
1034   return true;
1035 }
1036
1037 void ApplicationManagerImpl::SendMessageToHMI(
1038   const utils::SharedPtr<smart_objects::SmartObject>& message) {
1039   LOG4CXX_INFO(logger_, "ApplicationManagerImpl::SendMessageToHMI");
1040
1041   if (!message) {
1042     LOG4CXX_WARN(logger_, "Null-pointer message received.");
1043     NOTREACHED();
1044     return;
1045   }
1046
1047   if (!hmi_handler_) {
1048     LOG4CXX_WARN(logger_, "No HMI Handler set");
1049     return;
1050   }
1051
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");
1057     return;
1058   }
1059
1060   hmi_so_factory().attachSchema(*message);
1061   LOG4CXX_INFO(
1062     logger_,
1063     "Attached schema to message, result if valid: " << message->isValid());
1064
1065 #ifdef WEB_HMI
1066   if (!ConvertSOtoMessage(*message, *message_to_send)) {
1067     LOG4CXX_WARN(logger_,
1068                  "Cannot send message to HMI: failed to create string");
1069     return;
1070   }
1071 #endif  // WEB_HMI
1072
1073 #ifdef QT_HMI
1074   message_to_send->set_smart_object(*message);
1075 #endif  // QT_HMI
1076
1077   messages_to_hmi_.PostMessage(impl::MessageToHmi(message_to_send));
1078 }
1079
1080 bool ApplicationManagerImpl::ManageHMICommand(
1081   const utils::SharedPtr<smart_objects::SmartObject>& message) {
1082   LOG4CXX_INFO(logger_, "ApplicationManagerImpl::ManageHMICommand");
1083
1084   if (!message) {
1085     LOG4CXX_WARN(logger_, "Null-pointer message received.");
1086     NOTREACHED();
1087     return false;
1088   }
1089
1090 #ifdef DEBUG
1091   MessageHelper::PrintSmartObject(*message);
1092 #endif
1093
1094   CommandSharedPtr command = HMICommandFactory::CreateCommand(message);
1095
1096   if (!command) {
1097     LOG4CXX_WARN(logger_, "Failed to create command from smart object");
1098     return false;
1099   }
1100
1101   if (command->Init()) {
1102     command->Run();
1103     if (command->CleanUp()) {
1104       return true;
1105     }
1106   }
1107   return false;
1108 }
1109
1110 void ApplicationManagerImpl::CreateHMIMatrix(HMIMatrix* matrix) {
1111 }
1112
1113 void ApplicationManagerImpl::CreatePoliciesManager(PoliciesManager* managaer) {
1114 }
1115
1116 bool ApplicationManagerImpl::CheckPolicies(smart_objects::SmartObject* message,
1117     ApplicationSharedPtr app) {
1118   return true;
1119 }
1120
1121 bool ApplicationManagerImpl::CheckHMIMatrix(
1122   smart_objects::SmartObject* message) {
1123   return true;
1124 }
1125
1126 bool ApplicationManagerImpl::ConvertMessageToSO(
1127   const Message& message, smart_objects::SmartObject& output) {
1128   LOG4CXX_INFO(
1129     logger_,
1130     "\t\t\tMessage to convert: protocol " << message.protocol_version()
1131     << "; json " << message.json_message());
1132
1133   switch (message.protocol_version()) {
1134     case ProtocolVersion::kV2: {
1135
1136       if (!formatters::CFormatterJsonSDLRPCv2::fromString(
1137             message.json_message(),
1138             output,
1139             message.function_id(),
1140             message.type(),
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);
1152         return false;
1153       }
1154       LOG4CXX_INFO(
1155         logger_,
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());
1163       }
1164       break;
1165     }
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);
1170       LOG4CXX_INFO(
1171         logger_,
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.");
1176         return false;
1177       }
1178       if (output.validate() != smart_objects::Errors::OK &&
1179           output.validate() != smart_objects::Errors::UNEXPECTED_PARAMETER) {
1180         LOG4CXX_WARN(
1181           logger_,
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");
1188       }
1189       break;
1190     }
1191     case ProtocolVersion::kV1: {
1192         static NsSmartDeviceLinkRPC::V1::v4_protocol_v1_2_no_extra v1_shema;
1193
1194         if (message.function_id() == 0 || message.type() == kUnknownType) {
1195           LOG4CXX_ERROR(logger_, "Message received: UNSUPPORTED_VERSION");
1196
1197           int32_t conversation_result =
1198             formatters::CFormatterJsonSDLRPCv1::fromString <
1199             NsSmartDeviceLinkRPC::V1::FunctionID::eType,
1200             NsSmartDeviceLinkRPC::V1::messageType::eType > (
1201               message.json_message(), output);
1202
1203           if (formatters::CFormatterJsonSDLRPCv1::kSuccess
1204               == conversation_result) {
1205
1206             smart_objects::SmartObject params = smart_objects::SmartObject(smart_objects::SmartType::SmartType_Map);
1207
1208             output[strings::params][strings::message_type] =
1209                 NsSmartDeviceLinkRPC::V1::messageType::response;
1210             output[strings::params][strings::connection_key] = message.connection_key();
1211
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;
1217
1218             smart_objects::SmartObject* msg_to_send = new smart_objects::SmartObject(output);
1219             v1_shema.attachSchema(*msg_to_send);
1220             SendMessageToMobile(msg_to_send);
1221             return false;
1222           }
1223         }
1224
1225         break;
1226     }
1227     default:
1228       // TODO(PV):
1229       //  removed NOTREACHED() because some app can still have vesion 1.
1230       LOG4CXX_WARN(
1231         logger_,
1232         "Application used unsupported protocol :" << message.protocol_version()
1233         << ".");
1234       return false;
1235   }
1236
1237   LOG4CXX_INFO(logger_, "Successfully parsed message into smart object");
1238   return true;
1239 }
1240
1241 bool ApplicationManagerImpl::ConvertSOtoMessage(
1242   const smart_objects::SmartObject& message, Message& output) {
1243   LOG4CXX_INFO(logger_, "Message to convert");
1244
1245   if (smart_objects::SmartType_Null == message.getType()
1246       || smart_objects::SmartType_Invalid == message.getType()) {
1247     LOG4CXX_WARN(logger_, "Invalid smart object received.");
1248     return false;
1249   }
1250
1251   LOG4CXX_INFO(
1252     logger_,
1253     "Message with protocol: "
1254     << message.getElement(jhs::S_PARAMS).getElement(jhs::S_PROTOCOL_TYPE)
1255     .asInt());
1256
1257   std::string output_string;
1258   switch (message.getElement(jhs::S_PARAMS).getElement(jhs::S_PROTOCOL_TYPE)
1259           .asInt()) {
1260     case 0:
1261       {
1262         if (message.getElement(jhs::S_PARAMS).getElement(jhs::S_PROTOCOL_VERSION).asInt() == 1) {
1263           if (!formatters::CFormatterJsonSDLRPCv1::toString(message,
1264               output_string)) {
1265             LOG4CXX_WARN(logger_, "Failed to serialize smart object");
1266             return false;
1267           }
1268           output.set_protocol_version(application_manager::kV1);
1269         } else {
1270           if (!formatters::CFormatterJsonSDLRPCv2::toString(message,
1271               output_string)) {
1272             LOG4CXX_WARN(logger_, "Failed to serialize smart object");
1273             return false;
1274           }
1275           output.set_protocol_version(application_manager::kV2);
1276         }
1277
1278       break;
1279     }
1280     case 1: {
1281       if (!formatters::FormatterJsonRpc::ToString(message, output_string)) {
1282         LOG4CXX_WARN(logger_, "Failed to serialize smart object");
1283         return false;
1284       }
1285       output.set_protocol_version(application_manager::kHMI);
1286       break;
1287     }
1288     default:
1289       NOTREACHED();
1290       return false;
1291   }
1292
1293   LOG4CXX_INFO(logger_, "Convertion result: " << output_string);
1294
1295   output.set_connection_key(
1296     message.getElement(jhs::S_PARAMS).getElement(strings::connection_key)
1297     .asInt());
1298
1299   output.set_function_id(
1300     message.getElement(jhs::S_PARAMS).getElement(jhs::S_FUNCTION_ID).asInt());
1301
1302   output.set_correlation_id(
1303     message.getElement(jhs::S_PARAMS).getElement(jhs::S_CORRELATION_ID)
1304     .asInt());
1305   output.set_message_type(
1306     static_cast<MessageType>(message.getElement(jhs::S_PARAMS).getElement(
1307                                jhs::S_MESSAGE_TYPE).asInt()));
1308
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)
1313       .asInt()) {
1314     output.set_json_message(output_string);
1315   }
1316
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)
1321       .asBinary());
1322
1323     if (NULL == binaryData) {
1324       LOG4CXX_ERROR(logger_, "Null pointer");
1325       return false;
1326     }
1327     output.set_binary_data(binaryData);
1328   }
1329
1330   LOG4CXX_INFO(logger_, "Successfully parsed smart object into message");
1331   return true;
1332 }
1333
1334 utils::SharedPtr<Message> ApplicationManagerImpl::ConvertRawMsgToMessage(
1335   const protocol_handler::RawMessagePtr& message) {
1336   DCHECK(message);
1337   utils::SharedPtr<Message> outgoing_message;
1338
1339   if (message->service_type() != protocol_handler::kRpc
1340       &&
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;
1345   }
1346
1347   Message* convertion_result = NULL;
1348   if (message->protocol_version() == 1) {
1349     convertion_result =
1350       MobileMessageHandler::HandleIncomingMessageProtocolV1(message);
1351   } else if (message->protocol_version() == 2) {
1352     convertion_result =
1353       MobileMessageHandler::HandleIncomingMessageProtocolV2(message);
1354   } else {
1355     LOG4CXX_WARN(logger_, "Unknown protocol version.");
1356     return outgoing_message;
1357   }
1358
1359   if (convertion_result) {
1360     outgoing_message = convertion_result;
1361   } else {
1362     LOG4CXX_ERROR(logger_, "Received invalid message");
1363   }
1364   return outgoing_message;
1365 }
1366
1367 void ApplicationManagerImpl::ProcessMessageFromMobile(
1368   const utils::SharedPtr<Message>& message) {
1369   LOG4CXX_INFO(logger_, "ApplicationManagerImpl::ProcessMessageFromMobile()");
1370
1371   utils::SharedPtr<smart_objects::SmartObject> so_from_mobile(
1372     new smart_objects::SmartObject);
1373
1374   if (!so_from_mobile) {
1375     LOG4CXX_ERROR(logger_, "Null pointer");
1376     return;
1377   }
1378
1379   if (!ConvertMessageToSO(*message, *so_from_mobile)) {
1380     LOG4CXX_ERROR(logger_, "Cannot create smart object from message");
1381     return;
1382   }
1383
1384   if (!ManageMobileCommand(so_from_mobile)) {
1385     LOG4CXX_ERROR(logger_, "Received command didn't run successfully");
1386   }
1387 }
1388
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);
1394
1395   if (!smart_object) {
1396     LOG4CXX_ERROR(logger_, "Null pointer");
1397     return;
1398   }
1399
1400 #ifdef WEB_HMI
1401   if (!ConvertMessageToSO(*message, *smart_object)) {
1402     LOG4CXX_ERROR(logger_, "Cannot create smart object from message");
1403     return;
1404   }
1405 #endif  // WEB_HMI
1406
1407 #ifdef QT_HMI
1408   *smart_object = message->smart_object();
1409 #endif  // QT_HMI
1410
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");
1414   }
1415 }
1416
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");
1422       NOTREACHED();
1423     }
1424   }
1425   return *hmi_so_factory_;
1426 }
1427
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.");
1433       NOTREACHED();
1434     }
1435   }
1436   return *mobile_so_factory_;
1437 }
1438
1439 HMICapabilities& ApplicationManagerImpl::hmi_capabilities() {
1440   return hmi_capabilities_;
1441 }
1442
1443 void ApplicationManagerImpl::addNotification(const CommandSharedPtr& ptr) {
1444   notification_list_.push_back(ptr);
1445 }
1446
1447 void ApplicationManagerImpl::removeNotification(const CommandSharedPtr& ptr) {
1448   std::list<CommandSharedPtr>::iterator it = notification_list_.begin();
1449   for (; notification_list_.end() != it; ++it) {
1450     if (*it == ptr) {
1451       notification_list_.erase(it);
1452       break;
1453     }
1454   }
1455 }
1456
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,
1461                                      new_timeout_value);
1462 }
1463
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);
1472     return app_id;
1473   } else {
1474     return 0;
1475   }
1476 }
1477
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));
1482 }
1483
1484 void ApplicationManagerImpl::SetUnregisterAllApplicationsReason(
1485   mobile_api::AppInterfaceUnregisteredReason::eType reason) {
1486   unregister_reason_ = reason;
1487 }
1488
1489 void ApplicationManagerImpl::UnregisterAllApplications() {
1490   LOG4CXX_INFO(logger_, "ApplicationManagerImpl::UnregisterAllApplications "  <<
1491                unregister_reason_);
1492
1493   hmi_cooperating_ = false;
1494
1495   std::set<ApplicationSharedPtr>::iterator it = application_list_.begin();
1496   while (it != application_list_.end()) {
1497     MessageHelper::SendOnAppInterfaceUnregisteredNotificationToMobile(
1498       (*it)->app_id(), unregister_reason_);
1499
1500     UnregisterApplication((*it)->app_id(), true);
1501     it = application_list_.begin();
1502   }
1503   resume_ctrl_.IgnitionOff();
1504 }
1505
1506 void ApplicationManagerImpl::UnregisterApplication(const uint32_t& app_id, bool is_resuming) {
1507   LOG4CXX_INFO(logger_,
1508                "ApplicationManagerImpl::UnregisterApplication " << app_id);
1509
1510   sync_primitives::AutoLock lock(applications_list_lock_);
1511
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.");
1515     return;
1516   }
1517   ApplicationSharedPtr app_to_remove = it->second;
1518   if (is_resuming) {
1519     resume_ctrl_.SaveApplication(app_to_remove);
1520   }
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();
1526   }
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);
1532
1533   return;
1534 }
1535
1536 void ApplicationManagerImpl::Handle(const impl::MessageFromMobile& message) {
1537   LOG4CXX_INFO(logger_, "Received message from Mobile side");
1538
1539   if (!message) {
1540     LOG4CXX_ERROR(logger_, "Null-pointer message received.");
1541     return;
1542   }
1543   ProcessMessageFromMobile(message);
1544 }
1545
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(
1550                    message);
1551   } else if (message->protocol_version() == application_manager::kV2) {
1552     rawMessage = MobileMessageHandler::HandleOutgoingMessageProtocolV2(
1553                    message);
1554   } else {
1555     return;
1556   }
1557   if (!rawMessage) {
1558     LOG4CXX_ERROR(logger_, "Failed to create raw message.");
1559     return;
1560   }
1561
1562   if (!protocol_handler_) {
1563     LOG4CXX_WARN(logger_,
1564                  "Protocol Handler is not set; cannot send message to mobile.");
1565     return;
1566   }
1567
1568   protocol_handler_->SendMessageToMobileApp(rawMessage, message.is_final);
1569
1570   LOG4CXX_INFO(logger_, "Message for mobile given away.");
1571 }
1572
1573 void ApplicationManagerImpl::Handle(const impl::MessageFromHmi& message) {
1574   LOG4CXX_INFO(logger_, "Received message from hmi");
1575
1576   if (!message) {
1577     LOG4CXX_ERROR(logger_, "Null-pointer message received.");
1578     return;
1579   }
1580
1581   ProcessMessageFromHMI(message);
1582 }
1583
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");
1588     return;
1589   }
1590
1591   hmi_handler_->SendMessageToHMI(message);
1592   LOG4CXX_INFO(logger_, "Message from hmi given away.");
1593 }
1594
1595
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;
1601
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);
1608       }
1609       if ((*it)->audio_streaming_state() != state) {
1610         (*it)->set_audio_streaming_state(state);
1611         MessageHelper::SendHMIStatusNotification(*(*it));
1612       }
1613     }
1614   }
1615 }
1616
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);
1624       }
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));
1631       }
1632     }
1633   }
1634 }
1635
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;
1641   }
1642
1643   LOG4CXX_INFO(logger_, "SaveBinaryWithOffset  binary_size = "
1644                << binary_data.size() << " offset = " << offset);
1645
1646   uint32_t file_size = file_system::FileSize(file_system::FullPath(save_path));
1647   std::ofstream* file_stream;
1648   if (offset != 0) {
1649     if (file_size != offset) {
1650       LOG4CXX_INFO(logger_, "ApplicationManagerImpl::SaveBinaryWithOffset offset does'n match existing filesize");
1651       return mobile_apis::Result::INVALID_DATA;
1652     }
1653     file_stream = file_system::Open(file_system::FullPath(save_path),
1654                                     std::ios_base::app);
1655   } else {
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);
1660   }
1661
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;
1665   }
1666   file_system::Close(file_stream);
1667   LOG4CXX_INFO(logger_, "Successfully write data to file");
1668   return mobile_apis::Result::SUCCESS;
1669 }
1670
1671 }  // namespace application_manager