APPLINK-6387 Core sends OnAppRegistered notification to HMI without check whether...
[profile/ivi/smartdevicelink.git] / src / components / application_manager / include / application_manager / application_manager_impl.h
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 #ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_H_
34 #define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_H_
35
36 #include <cstdint>
37 #include <vector>
38 #include <map>
39 #include <set>
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"
49
50 #include "media_manager/media_manager_impl.h"
51
52 #include "connection_handler/connection_handler_observer.h"
53 #include "connection_handler/device.h"
54
55 #include "formatters/CSmartFactory.hpp"
56
57 #include "interfaces/HMI_API.h"
58 #include "interfaces/HMI_API_schema.h"
59 #include "interfaces/MOBILE_API_schema.h"
60
61 #include "interfaces/v4_protocol_v1_2_no_extra.h"
62 #include "interfaces/v4_protocol_v1_2_no_extra_schema.h"
63
64 #include "protocol_handler/service_type.h"
65
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"
75
76 namespace NsSmartDeviceLink {
77 namespace NsSmartObjects {
78 class SmartObject;
79 }
80 }
81
82 namespace smart_objects = NsSmartDeviceLink::NsSmartObjects;
83
84 namespace threads {
85 class Thread;
86 }
87 class CommandNotificationImpl;
88
89 namespace application_manager {
90 namespace mobile_api = mobile_apis;
91
92 class ApplicationManagerImpl;
93
94 enum VRTTSSessionChanging {
95   kVRSessionChanging = 0,
96   kTTSSessionChanging = 1
97 };
98
99 namespace impl {
100 using namespace threads;
101
102 /*
103  * These dummy classes are here to locally impose strong typing on different
104  * kinds of messages
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
109  * when we have them.
110  */
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(); }
116 };
117
118 struct MessageToMobile: public utils::SharedPtr<Message> {
119   explicit MessageToMobile(const utils::SharedPtr<Message>& message,
120                            bool final_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
125   bool is_final;
126  };
127
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(); }
133 };
134
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(); }
140 };
141
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;
151 }
152
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;
163   public:
164     ~ApplicationManagerImpl();
165
166     /**
167      * @brief Stop work.
168      *
169      * @return TRUE on success otherwise FALSE.
170      **/
171     virtual bool Stop();
172
173     /////////////////////////////////////////////////////
174
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();
181
182     /////////////////////////////////////////////////////
183
184     HMICapabilities& hmi_capabilities();
185
186     ApplicationSharedPtr RegisterApplication(
187       const utils::SharedPtr<smart_objects::SmartObject>& request_for_registration);
188     /*
189      * @brief Closes application by id
190      *
191      * @param app_id Application id
192      * @param is_resuming describes - is this unregister
193      *        is normal or need to be resumed
194      */
195     void UnregisterApplication(const uint32_t& app_id, bool is_resuming = false);
196
197     /*
198      * @brief Sets unregister reason for closing all registered applications
199      * duringHU switching off
200      *
201      * @param reason Describes the reason for HU switching off
202      */
203     void SetUnregisterAllApplicationsReason(
204         mobile_api::AppInterfaceUnregisteredReason::eType reason);
205
206     /*
207      * @brief Closes all registered applications
208      */
209     void UnregisterAllApplications();
210
211     bool RemoveAppDataFromHMI(ApplicationSharedPtr app);
212     bool LoadAppDataToHMI(ApplicationSharedPtr app);
213     bool ActivateApplication(ApplicationSharedPtr app);
214     /**
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
220      */
221     mobile_api::HMILevel::eType PutApplicationInLimited(ApplicationSharedPtr app);
222
223     /**
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
229      */
230     mobile_api::HMILevel::eType PutApplicationInFull(ApplicationSharedPtr app);
231
232     void DeactivateApplication(ApplicationSharedPtr app);
233     void ConnectToDevice(uint32_t id);
234     void OnHMIStartedCooperation();
235
236     /*
237      * @brief Returns unique correlation ID for HMI request
238      *
239      * @return Unique correlation ID
240      */
241     uint32_t GetNextHMICorrelationID();
242
243     /* @brief Starts audio passthru process
244      *
245      * @return true on success, false if passthru is already in process
246      */
247     bool begin_audio_pass_thru();
248
249     /*
250      * @brief Finishes already started audio passthru process
251      *
252      * @return true on success, false if passthru is not active
253      */
254     bool end_audio_pass_thru();
255
256     /*
257      * @brief Retrieves driver distraction state
258      *
259      * @return Current state of the distraction state
260      */
261     inline bool driver_distraction() const;
262
263     /*
264      * @brief Sets state for driver distraction
265      *
266      * @param state New state to be set
267      */
268     void set_driver_distraction(bool is_distracting);
269
270     /*
271      * @brief Retrieves if VR session has started
272      *
273      * @return Current VR session state (started, stopped)
274      */
275     inline bool vr_session_started() const;
276
277     /*
278      * @brief Sets VR session state
279      *
280      * @param state Current HMI VR session state
281      */
282     void set_vr_session_started(const bool& state);
283
284     /*
285      * @brief Retrieves SDL access to all mobile apps
286      *
287      * @return Currently active state of the access
288      */
289     inline bool all_apps_allowed() const;
290
291     /*
292      * @brief Sets SDL access to all mobile apps
293      *
294      * @param allowed SDL access to all mobile apps
295      */
296     void set_all_apps_allowed(const bool& allowed);
297
298     /*
299      * @brief Starts audio pass thru thread
300      *
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
307      */
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);
311
312     /*
313      * @brief Terminates audio pass thru thread
314      * @param application_key Id of application for which
315      * audio pass thru should be stopped
316      */
317     void StopAudioPassThru(int32_t application_key);
318
319     void SendAudioPassThroughNotification(uint32_t session_key,
320                                           std::vector<uint8_t> binaryData);
321
322     std::string GetDeviceName(connection_handler::DeviceHandle handle);
323
324     /////////////////////////////////////////////////////
325
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);
330
331     ///////////////////////////////////////////////////////
332
333     void StartDevicesDiscovery();
334
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);
346
347     /////////////////////////////////////////////////////////
348     /*
349      * @brief Overriden ProtocolObserver method
350      */
351     virtual void OnMessageReceived(const protocol_handler::
352                                    RawMessagePtr& message);
353
354     /*
355      * @brief Overriden ProtocolObserver method
356      */
357     virtual void OnMobileMessageSent(const protocol_handler::
358                                      RawMessagePtr& message);
359
360     void OnMessageReceived(
361       hmi_message_handler::MessageSharedPointer message);
362     void OnErrorSending(hmi_message_handler::MessageSharedPointer message);
363
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);
371
372     /**
373      * @ Add notification to collection
374      *
375      * @param ptr Reference to shared pointer that point on hmi notification
376      */
377     void addNotification(const CommandSharedPtr& ptr);
378
379     /**
380      * @ Add notification to collection
381      *
382      * @param ptr Reference to shared pointer that point on hmi notification
383      */
384     void removeNotification(const CommandSharedPtr& ptr);
385
386     /**
387      * @ Updates request timeout
388      *
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
392      */
393     void updateRequestTimeout(uint32_t connection_key,
394                               uint32_t mobile_correlation_id,
395                               uint32_t new_timeout_value);
396
397     /*
398      * @brief Retrieves application id associated whith correlation id
399      *
400      * @param correlation_id Correlation ID of the HMI request
401      *
402      * @return application id associated whith correlation id
403      */
404     const uint32_t application_id(const int32_t correlation_id);
405
406     /*
407      * @brief Sets application id correlation id
408      *
409      * @param correlation_id Correlation ID of the HMI request
410      * @param app_id Application ID
411      */
412     void set_application_id(const int32_t correlation_id,
413                             const uint32_t app_id);
414
415     /*
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
422      */
423     void Mute(VRTTSSessionChanging changing_state);
424
425     /*
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
431      */
432     void Unmute(VRTTSSessionChanging changing_state);
433
434     /*
435      * @brief Checks HMI level and returns true if audio streaming is allowed
436      */
437     bool IsAudioStreamingAllowed(uint32_t connection_key) const;
438
439     /*
440      * @brief Checks HMI level and returns true if video streaming is allowed
441      */
442     bool IsVideoStreamingAllowed(uint32_t connection_key) const;
443
444     /**
445       * Getter for resume_controller
446       * @return Resume Controller
447       */
448     ResumeCtrl& resume_controller() { return resume_ctrl_; }
449
450     /*
451      * @brief Save binary data to specified directory
452      *
453      * @param application name
454      * @param binary file name
455      * @param binary data
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 )
458      *
459      * @return SUCCESS if file was saved, other code otherwise
460      */
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);
466
467     /*
468      * @brief returns true if HMI is cooperating
469      */
470     bool IsHMICooperating() const;
471
472   private:
473     ApplicationManagerImpl();
474     bool InitThread(threads::Thread* thread);
475     hmi_apis::HMI_API& hmi_so_factory();
476     mobile_apis::MOBILE_API& mobile_so_factory();
477
478     void CreateHMIMatrix(HMIMatrix* matrix);
479     void CreatePoliciesManager(PoliciesManager* managaer);
480
481     /**
482      * \brief Performs check using PoliciesManager of availability
483      * of the message for the application. If error occured it is sent
484      * as response to initiator of request.
485      * \param message Message received for application
486      * \param application Application that recieved message to be checked by policies
487      * \return bool Indicates whether message is allowed for application
488      */
489     bool CheckPolicies(smart_objects::SmartObject* message,
490                        ApplicationSharedPtr app);
491
492     /**
493      * \brief Using HMIMatrix checks which messages sent to HMI are of higher priority
494      * and acts accordingly (closes message with lower priority,
495      * rejects message in case message with higher priority is operating on HMI).
496      * If error occured it is sent as response to initiator of request.
497      * \param message Message received for application
498      * \return bool Indicates whether message is allowed for application
499      */
500     bool CheckHMIMatrix(smart_objects::SmartObject* message);
501
502     bool ConvertMessageToSO(const Message& message,
503                             smart_objects::SmartObject& output);
504     bool ConvertSOtoMessage(const smart_objects::SmartObject& message,
505                             Message& output);
506     utils::SharedPtr<Message> ConvertRawMsgToMessage(
507       const protocol_handler::RawMessagePtr& message);
508
509     void ProcessMessageFromMobile(const utils::SharedPtr<Message>& message);
510     void ProcessMessageFromHMI(const utils::SharedPtr<Message>& message);
511
512     // threads::MessageLoopThread<*>::Handler implementations
513     /*
514      * @brief Handles for threads pumping different types
515      * of messages. Beware, each is called on different thread!
516      */
517     // CALLED ON messages_from_mobile_ thread!
518     virtual void Handle(const impl::MessageFromMobile& message) OVERRIDE;
519
520     // CALLED ON messages_to_mobile_ thread!
521     virtual void Handle(const impl::MessageToMobile& message) OVERRIDE;
522
523     // CALLED ON messages_from_hmi_ thread!
524     virtual void Handle(const impl::MessageFromHmi& message) OVERRIDE;
525
526     // CALLED ON messages_to_hmi_ thread!
527     virtual void Handle(const impl::MessageToHmi& message) OVERRIDE;
528
529   private:
530
531
532     // members
533     ResumeCtrl resume_ctrl_;
534
535     /**
536      * @brief Resume controler is responcible for save and load information
537      * about persistent application data on disk, and save session ID for resuming
538      * application in case INGITION_OFF or MASTER_RESSET
539      */
540
541     /**
542      * @brief Map of connection keys and associated applications
543      */
544     std::map<int32_t, ApplicationSharedPtr> applications_;
545
546     /**
547      * @brief List of applications
548      */
549     std::set<ApplicationSharedPtr> application_list_;
550
551     /**
552      * @brief Set of HMI notifications with timeout.
553      */
554     std::list<CommandSharedPtr> notification_list_;
555
556     /**
557      * @brief Map of correlation id  and associated application id.
558      */
559     std::map<const int32_t, const uint32_t> appID_list_;
560
561     bool audio_pass_thru_active_;
562     sync_primitives::Lock audio_pass_thru_lock_;
563     bool is_distracting_driver_;
564     bool is_vr_session_strated_;
565     bool hmi_cooperating_;
566     bool is_all_apps_allowed_;
567     media_manager::MediaManager* media_manager_;
568
569     hmi_message_handler::HMIMessageHandler* hmi_handler_;
570     connection_handler::ConnectionHandler*  connection_handler_;
571     protocol_handler::ProtocolHandler*      protocol_handler_;
572     policies::PolicyManager*                policy_manager_;
573     request_controller::RequestController   request_ctrl_;
574     HMICapabilities                         hmi_capabilities_;
575
576     // TODO(YS): Remove old implementation
577     policies_manager::PoliciesManager policies_manager_;
578
579     hmi_apis::HMI_API*                      hmi_so_factory_;
580     mobile_apis::MOBILE_API*                mobile_so_factory_;
581
582     static log4cxx::LoggerPtr logger_;
583
584     static uint32_t corelation_id_;
585     static const uint32_t max_corelation_id_;
586
587     // The reason of HU shutdown
588     mobile_api::AppInterfaceUnregisteredReason::eType unregister_reason_;
589
590     // Construct message threads when everything is already created
591
592     // Thread that pumps messages coming from mobile side.
593     impl::FromMobileQueue messages_from_mobile_;
594     // Thread that pumps messages being passed to mobile side.
595     impl::ToMobileQueue messages_to_mobile_;
596     // Thread that pumps messages coming from HMI.
597     impl::FromHmiQueue messages_from_hmi_;
598     // Thread that pumps messages being passed to HMI.
599     impl::ToHmiQueue messages_to_hmi_;
600
601     // Lock for applications list
602     sync_primitives::Lock applications_list_lock_;
603
604     DISALLOW_COPY_AND_ASSIGN(ApplicationManagerImpl);
605
606     FRIEND_BASE_SINGLETON_CLASS(ApplicationManagerImpl);
607 };
608
609 const std::set<ApplicationSharedPtr>& ApplicationManagerImpl::applications() const {
610   return application_list_;
611 }
612
613 bool ApplicationManagerImpl::vr_session_started() const {
614   return is_vr_session_strated_;
615 }
616
617 bool ApplicationManagerImpl::driver_distraction() const {
618   return is_distracting_driver_;
619 }
620
621 inline bool ApplicationManagerImpl::all_apps_allowed() const {
622   return is_all_apps_allowed_;
623 }
624 }  // namespace application_manager
625
626 #endif  // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_H_