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 #ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_H_
34 #define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_H_
40 #include "application_manager/hmi_command_factory.h"
41 #include "application_manager/application_manager.h"
42 #include "application_manager/hmi_capabilities.h"
43 #include "application_manager/message.h"
44 #include "application_manager/policies_manager/policies_manager.h"
45 #include "application_manager/request_controller.h"
46 #include "application_manager/resume_ctrl.h"
47 #include "protocol_handler/protocol_observer.h"
48 #include "hmi_message_handler/hmi_message_observer.h"
50 #include "media_manager/media_manager_impl.h"
52 #include "connection_handler/connection_handler_observer.h"
53 #include "connection_handler/device.h"
55 #include "formatters/CSmartFactory.hpp"
57 #include "interfaces/HMI_API.h"
58 #include "interfaces/HMI_API_schema.h"
59 #include "interfaces/MOBILE_API_schema.h"
61 #include "interfaces/v4_protocol_v1_2_no_extra.h"
62 #include "interfaces/v4_protocol_v1_2_no_extra_schema.h"
64 #include "protocol_handler/service_type.h"
66 #include "utils/macro.h"
67 #include "utils/logger.h"
68 #include "utils/shared_ptr.h"
69 #include "utils/message_queue.h"
70 #include "utils/prioritized_queue.h"
71 #include "utils/threads/thread.h"
72 #include "utils/threads/message_loop_thread.h"
73 #include "utils/lock.h"
74 #include "utils/singleton.h"
76 namespace NsSmartDeviceLink {
77 namespace NsSmartObjects {
82 namespace smart_objects = NsSmartDeviceLink::NsSmartObjects;
87 class CommandNotificationImpl;
89 namespace application_manager {
90 namespace mobile_api = mobile_apis;
92 class ApplicationManagerImpl;
94 enum VRTTSSessionChanging {
95 kVRSessionChanging = 0,
96 kTTSSessionChanging = 1
100 using namespace threads;
103 * These dummy classes are here to locally impose strong typing on different
105 * Currently there is no type difference between incoming and outgoing messages
106 * And due to ApplicationManagerImpl works as message router it has to distinguish
107 * messages passed from it's different connection points
108 * TODO(ik): replace these with globally defined message types
111 struct MessageFromMobile: public utils::SharedPtr<Message> {
112 explicit MessageFromMobile(const utils::SharedPtr<Message>& message):
113 utils::SharedPtr<Message>(message) {}
114 // PrioritizedQueue requres this method to decide which priority to assign
115 size_t PriorityOrder() const { return (*this)->Priority().OrderingValue(); }
118 struct MessageToMobile: public utils::SharedPtr<Message> {
119 explicit MessageToMobile(const utils::SharedPtr<Message>& message,
121 utils::SharedPtr<Message>(message), is_final(final_message) {}
122 // PrioritizedQueue requres this method to decide which priority to assign
123 size_t PriorityOrder() const { return (*this)->Priority().OrderingValue(); }
124 // Signals if connection to mobile must be closed after sending this message
128 struct MessageFromHmi: public utils::SharedPtr<Message> {
129 explicit MessageFromHmi(const utils::SharedPtr<Message>& message):
130 utils::SharedPtr<Message>(message) {}
131 // PrioritizedQueue requres this method to decide which priority to assign
132 size_t PriorityOrder() const { return (*this)->Priority().OrderingValue(); }
135 struct MessageToHmi: public utils::SharedPtr<Message> {
136 explicit MessageToHmi(const utils::SharedPtr<Message>& message):
137 utils::SharedPtr<Message>(message) {}
138 // PrioritizedQueue requres this method to decide which priority to assign
139 size_t PriorityOrder() const { return (*this)->Priority().OrderingValue(); }
142 // Short type names for proiritized message queues
143 typedef threads::MessageLoopThread<
144 utils::PrioritizedQueue<MessageFromMobile> > FromMobileQueue;
145 typedef threads::MessageLoopThread<
146 utils::PrioritizedQueue<MessageToMobile> > ToMobileQueue;
147 typedef threads::MessageLoopThread<
148 utils::PrioritizedQueue<MessageFromHmi> > FromHmiQueue;
149 typedef threads::MessageLoopThread<
150 utils::PrioritizedQueue<MessageToHmi> > ToHmiQueue;
153 class ApplicationManagerImpl : public ApplicationManager,
154 public hmi_message_handler::HMIMessageObserver,
155 public protocol_handler::ProtocolObserver,
156 public connection_handler::ConnectionHandlerObserver,
157 public impl::FromMobileQueue::Handler,
158 public impl::ToMobileQueue::Handler,
159 public impl::FromHmiQueue::Handler,
160 public impl::ToHmiQueue::Handler,
161 public utils::Singleton<ApplicationManagerImpl> {
162 friend class ResumeCtrl;
164 ~ApplicationManagerImpl();
169 * @return TRUE on success otherwise FALSE.
173 /////////////////////////////////////////////////////
175 ApplicationSharedPtr application(int32_t app_id) const;
176 inline const std::set<ApplicationSharedPtr>& applications() const;
177 ApplicationSharedPtr active_application() const;
178 std::vector<ApplicationSharedPtr> applications_by_button(uint32_t button);
179 std::vector<ApplicationSharedPtr> applications_by_ivi(uint32_t vehicle_info);
180 std::vector<ApplicationSharedPtr> applications_with_navi();
182 /////////////////////////////////////////////////////
184 HMICapabilities& hmi_capabilities();
186 ApplicationSharedPtr RegisterApplication(
187 const utils::SharedPtr<smart_objects::SmartObject>& request_for_registration);
189 * @brief Closes application by id
191 * @param app_id Application id
192 * @param is_resuming describes - is this unregister
193 * is normal or need to be resumed
195 void UnregisterApplication(const uint32_t& app_id, bool is_resuming = false);
198 * @brief Sets unregister reason for closing all registered applications
199 * duringHU switching off
201 * @param reason Describes the reason for HU switching off
203 void SetUnregisterAllApplicationsReason(
204 mobile_api::AppInterfaceUnregisteredReason::eType reason);
207 * @brief Closes all registered applications
209 void UnregisterAllApplications();
211 bool RemoveAppDataFromHMI(ApplicationSharedPtr app);
212 bool LoadAppDataToHMI(ApplicationSharedPtr app);
213 bool ActivateApplication(ApplicationSharedPtr app);
215 * @brief Put application in Limited HMI Level if possible,
216 * otherwise put applicatuion other HMI level.
217 * do not send any notifications to mobile
218 * @param app, application, that need to be puted in Limeted
219 * @return seted HMI Level
221 mobile_api::HMILevel::eType PutApplicationInLimited(ApplicationSharedPtr app);
224 * @brief Put application in FULL HMI Level if possible,
225 * otherwise put applicatuion other HMI level.
226 * do not send any notifications to mobile
227 * @param app, application, that need to be puted in FULL
228 * @return seted HMI Level
230 mobile_api::HMILevel::eType PutApplicationInFull(ApplicationSharedPtr app);
232 void DeactivateApplication(ApplicationSharedPtr app);
233 void ConnectToDevice(uint32_t id);
234 void OnHMIStartedCooperation();
237 * @brief Returns unique correlation ID for HMI request
239 * @return Unique correlation ID
241 uint32_t GetNextHMICorrelationID();
243 /* @brief Starts audio passthru process
245 * @return true on success, false if passthru is already in process
247 bool begin_audio_pass_thru();
250 * @brief Finishes already started audio passthru process
252 * @return true on success, false if passthru is not active
254 bool end_audio_pass_thru();
257 * @brief Retrieves driver distraction state
259 * @return Current state of the distraction state
261 inline bool driver_distraction() const;
264 * @brief Sets state for driver distraction
266 * @param state New state to be set
268 void set_driver_distraction(bool is_distracting);
271 * @brief Retrieves if VR session has started
273 * @return Current VR session state (started, stopped)
275 inline bool vr_session_started() const;
278 * @brief Sets VR session state
280 * @param state Current HMI VR session state
282 void set_vr_session_started(const bool& state);
285 * @brief Retrieves SDL access to all mobile apps
287 * @return Currently active state of the access
289 inline bool all_apps_allowed() const;
292 * @brief Sets SDL access to all mobile apps
294 * @param allowed SDL access to all mobile apps
296 void set_all_apps_allowed(const bool& allowed);
299 * @brief Starts audio pass thru thread
301 * @param session_key Session key of connection for Mobile side
302 * @param correlation_id Correlation id for response for Mobile side
303 * @param max_duration Max duration of audio recording in milliseconds
304 * @param sampling_rate Value for rate(8, 16, 22, 44 kHz)
305 * @param bits_per_sample The quality the audio is recorded.
306 * @param audio_type Type of audio data
308 void StartAudioPassThruThread(int32_t session_key, int32_t correlation_id,
309 int32_t max_duration, int32_t sampling_rate,
310 int32_t bits_per_sample, int32_t audio_type);
313 * @brief Terminates audio pass thru thread
314 * @param application_key Id of application for which
315 * audio pass thru should be stopped
317 void StopAudioPassThru(int32_t application_key);
319 void SendAudioPassThroughNotification(uint32_t session_key,
320 std::vector<uint8_t> binaryData);
322 std::string GetDeviceName(connection_handler::DeviceHandle handle);
324 /////////////////////////////////////////////////////
326 void set_hmi_message_handler(hmi_message_handler::HMIMessageHandler* handler);
327 void set_connection_handler(connection_handler::ConnectionHandler* handler);
328 virtual void set_policy_manager(policies::PolicyManager* policy_manager);
329 void set_protocol_handler(protocol_handler::ProtocolHandler* handler);
331 ///////////////////////////////////////////////////////
333 void StartDevicesDiscovery();
335 // Put message to the queue to be sent to mobile.
336 // if |final_message| parameter is set connection to mobile will be closed
337 // after processing this message
338 void SendMessageToMobile(
339 const utils::SharedPtr<smart_objects::SmartObject>& message, bool final_message = false);
340 bool ManageMobileCommand(
341 const utils::SharedPtr<smart_objects::SmartObject>& message);
342 void SendMessageToHMI(
343 const utils::SharedPtr<smart_objects::SmartObject>& message);
344 bool ManageHMICommand(
345 const utils::SharedPtr<smart_objects::SmartObject>& message);
347 /////////////////////////////////////////////////////////
349 * @brief Overriden ProtocolObserver method
351 virtual void OnMessageReceived(const protocol_handler::
352 RawMessagePtr& message);
355 * @brief Overriden ProtocolObserver method
357 virtual void OnMobileMessageSent(const protocol_handler::
358 RawMessagePtr& message);
360 void OnMessageReceived(
361 hmi_message_handler::MessageSharedPointer message);
362 void OnErrorSending(hmi_message_handler::MessageSharedPointer message);
364 void OnDeviceListUpdated(const connection_handler::DeviceList& device_list);
365 void RemoveDevice(const connection_handler::DeviceHandle& device_handle);
366 bool OnServiceStartedCallback(const connection_handler::DeviceHandle& device_handle,
367 const int32_t& session_key,
368 const protocol_handler::ServiceType& type);
369 void OnServiceEndedCallback(const int32_t& session_key,
370 const protocol_handler::ServiceType& type);
373 * @ Add notification to collection
375 * @param ptr Reference to shared pointer that point on hmi notification
377 void addNotification(const CommandSharedPtr& ptr);
380 * @ Add notification to collection
382 * @param ptr Reference to shared pointer that point on hmi notification
384 void removeNotification(const CommandSharedPtr& ptr);
387 * @ Updates request timeout
389 * @param connection_key Connection key of application
390 * @param mobile_correlation_id Correlation ID of the mobile request
391 * @param new_timeout_value New timeout to be set
393 void updateRequestTimeout(uint32_t connection_key,
394 uint32_t mobile_correlation_id,
395 uint32_t new_timeout_value);
398 * @brief Retrieves application id associated whith correlation id
400 * @param correlation_id Correlation ID of the HMI request
402 * @return application id associated whith correlation id
404 const uint32_t application_id(const int32_t correlation_id);
407 * @brief Sets application id correlation id
409 * @param correlation_id Correlation ID of the HMI request
410 * @param app_id Application ID
412 void set_application_id(const int32_t correlation_id,
413 const uint32_t app_id);
416 * @brief Change AudioStreamingState for all application according to
417 * system audio-mixing capabilities (NOT_AUDIBLE/ATTENUATED) and
418 * send notification for this changes
419 * @param If changing_state == kVRSessionChanging function is used by
420 * on_vr_started_notification, if changing_state == kTTSSessionChanging
421 * function is used by on_tts_started_notification
423 void Mute(VRTTSSessionChanging changing_state);
426 * @brief Change AudioStreamingState for all application to AUDIBLE and
427 * send notification for this changes
428 * @param If changing_state == kVRSessionChanging function is used by
429 * on_vr_stopped_notification, if changing_state == kTTSSessionChanging
430 * function is used by on_tts_stopped_notification
432 void Unmute(VRTTSSessionChanging changing_state);
435 * @brief Checks HMI level and returns true if audio streaming is allowed
437 bool IsAudioStreamingAllowed(uint32_t connection_key) const;
440 * @brief Checks HMI level and returns true if video streaming is allowed
442 bool IsVideoStreamingAllowed(uint32_t connection_key) const;
445 * Getter for resume_controller
446 * @return Resume Controller
448 ResumeCtrl& resume_controller() { return resume_ctrl_; }
451 * @brief Save binary data to specified directory
453 * @param application name
454 * @param binary file name
456 * @param path for saving data
457 * @param offset for saving data to existing file with offset. If offset is 0 - create new file ( overrite existing )
459 * @return SUCCESS if file was saved, other code otherwise
461 mobile_apis::Result::eType SaveBinary(
462 const std::string& app_name,
463 const std::vector<uint8_t>& binary_data,
464 const std::string& save_path,
465 const uint32_t offset = 0);
468 ApplicationManagerImpl();
469 bool InitThread(threads::Thread* thread);
470 hmi_apis::HMI_API& hmi_so_factory();
471 mobile_apis::MOBILE_API& mobile_so_factory();
473 void CreateHMIMatrix(HMIMatrix* matrix);
474 void CreatePoliciesManager(PoliciesManager* managaer);
477 * \brief Performs check using PoliciesManager of availability
478 * of the message for the application. If error occured it is sent
479 * as response to initiator of request.
480 * \param message Message received for application
481 * \param application Application that recieved message to be checked by policies
482 * \return bool Indicates whether message is allowed for application
484 bool CheckPolicies(smart_objects::SmartObject* message,
485 ApplicationSharedPtr app);
488 * \brief Using HMIMatrix checks which messages sent to HMI are of higher priority
489 * and acts accordingly (closes message with lower priority,
490 * rejects message in case message with higher priority is operating on HMI).
491 * If error occured it is sent as response to initiator of request.
492 * \param message Message received for application
493 * \return bool Indicates whether message is allowed for application
495 bool CheckHMIMatrix(smart_objects::SmartObject* message);
497 bool ConvertMessageToSO(const Message& message,
498 smart_objects::SmartObject& output);
499 bool ConvertSOtoMessage(const smart_objects::SmartObject& message,
501 utils::SharedPtr<Message> ConvertRawMsgToMessage(
502 const protocol_handler::RawMessagePtr& message);
504 void ProcessMessageFromMobile(const utils::SharedPtr<Message>& message);
505 void ProcessMessageFromHMI(const utils::SharedPtr<Message>& message);
507 // threads::MessageLoopThread<*>::Handler implementations
509 * @brief Handles for threads pumping different types
510 * of messages. Beware, each is called on different thread!
512 // CALLED ON messages_from_mobile_ thread!
513 virtual void Handle(const impl::MessageFromMobile& message) OVERRIDE;
515 // CALLED ON messages_to_mobile_ thread!
516 virtual void Handle(const impl::MessageToMobile& message) OVERRIDE;
518 // CALLED ON messages_from_hmi_ thread!
519 virtual void Handle(const impl::MessageFromHmi& message) OVERRIDE;
521 // CALLED ON messages_to_hmi_ thread!
522 virtual void Handle(const impl::MessageToHmi& message) OVERRIDE;
528 ResumeCtrl resume_ctrl_;
531 * @brief Resume controler is responcible for save and load information
532 * about persistent application data on disk, and save session ID for resuming
533 * application in case INGITION_OFF or MASTER_RESSET
537 * @brief Map of connection keys and associated applications
539 std::map<int32_t, ApplicationSharedPtr> applications_;
542 * @brief List of applications
544 std::set<ApplicationSharedPtr> application_list_;
547 * @brief Set of HMI notifications with timeout.
549 std::list<CommandSharedPtr> notification_list_;
552 * @brief Map of correlation id and associated application id.
554 std::map<const int32_t, const uint32_t> appID_list_;
556 bool audio_pass_thru_active_;
557 sync_primitives::Lock audio_pass_thru_lock_;
558 bool is_distracting_driver_;
559 bool is_vr_session_strated_;
560 bool hmi_cooperating_;
561 bool is_all_apps_allowed_;
562 media_manager::MediaManager* media_manager_;
564 hmi_message_handler::HMIMessageHandler* hmi_handler_;
565 connection_handler::ConnectionHandler* connection_handler_;
566 protocol_handler::ProtocolHandler* protocol_handler_;
567 policies::PolicyManager* policy_manager_;
568 request_controller::RequestController request_ctrl_;
569 HMICapabilities hmi_capabilities_;
571 // TODO(YS): Remove old implementation
572 policies_manager::PoliciesManager policies_manager_;
574 hmi_apis::HMI_API* hmi_so_factory_;
575 mobile_apis::MOBILE_API* mobile_so_factory_;
577 static log4cxx::LoggerPtr logger_;
579 static uint32_t corelation_id_;
580 static const uint32_t max_corelation_id_;
582 // The reason of HU shutdown
583 mobile_api::AppInterfaceUnregisteredReason::eType unregister_reason_;
585 // Construct message threads when everything is already created
587 // Thread that pumps messages coming from mobile side.
588 impl::FromMobileQueue messages_from_mobile_;
589 // Thread that pumps messages being passed to mobile side.
590 impl::ToMobileQueue messages_to_mobile_;
591 // Thread that pumps messages coming from HMI.
592 impl::FromHmiQueue messages_from_hmi_;
593 // Thread that pumps messages being passed to HMI.
594 impl::ToHmiQueue messages_to_hmi_;
596 // Lock for applications list
597 sync_primitives::Lock applications_list_lock_;
599 DISALLOW_COPY_AND_ASSIGN(ApplicationManagerImpl);
601 FRIEND_BASE_SINGLETON_CLASS(ApplicationManagerImpl);
604 const std::set<ApplicationSharedPtr>& ApplicationManagerImpl::applications() const {
605 return application_list_;
608 bool ApplicationManagerImpl::vr_session_started() const {
609 return is_vr_session_strated_;
612 bool ApplicationManagerImpl::driver_distraction() const {
613 return is_distracting_driver_;
616 inline bool ApplicationManagerImpl::all_apps_allowed() const {
617 return is_all_apps_allowed_;
619 } // namespace application_manager
621 #endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_H_