diff options
Diffstat (limited to 'src/components/application_manager/include/application_manager/application_manager_impl.h')
-rw-r--r-- | src/components/application_manager/include/application_manager/application_manager_impl.h | 497 |
1 files changed, 431 insertions, 66 deletions
diff --git a/src/components/application_manager/include/application_manager/application_manager_impl.h b/src/components/application_manager/include/application_manager/application_manager_impl.h index dacac9e010..3a951cfbb6 100644 --- a/src/components/application_manager/include/application_manager/application_manager_impl.h +++ b/src/components/application_manager/include/application_manager/application_manager_impl.h @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2014, Ford Motor Company * All rights reserved. * @@ -37,22 +37,23 @@ #include <vector> #include <map> #include <set> +#include <algorithm> + #include "application_manager/hmi_command_factory.h" #include "application_manager/application_manager.h" #include "application_manager/hmi_capabilities.h" #include "application_manager/message.h" +#include "application_manager/message_helper.h" #include "application_manager/request_controller.h" #include "application_manager/resume_ctrl.h" #include "application_manager/vehicle_info_data.h" #include "protocol_handler/protocol_observer.h" #include "hmi_message_handler/hmi_message_observer.h" #include "hmi_message_handler/hmi_message_sender.h" - +#include "application_manager/policies/policy_handler_observer.h" #include "media_manager/media_manager_impl.h" - #include "connection_handler/connection_handler_observer.h" #include "connection_handler/device.h" - #include "formatters/CSmartFactory.hpp" #include "interfaces/HMI_API.h" @@ -73,10 +74,9 @@ #include "utils/threads/message_loop_thread.h" #include "utils/lock.h" #include "utils/singleton.h" +#include "utils/data_accessor.h" + -namespace policy { -class PolicyManager; -} namespace NsSmartDeviceLink { namespace NsSmartObjects { @@ -163,15 +163,26 @@ typedef threads::MessageLoopThread<utils::PrioritizedQueue<MessageFromMobile> > typedef threads::MessageLoopThread<utils::PrioritizedQueue<MessageToMobile> > ToMobileQueue; typedef threads::MessageLoopThread<utils::PrioritizedQueue<MessageFromHmi> > FromHmiQueue; typedef threads::MessageLoopThread<utils::PrioritizedQueue<MessageToHmi> > ToHmiQueue; + +// AudioPassThru +typedef struct { +std::vector<uint8_t> binary_data; +int32_t session_key; +} AudioData; +typedef std::queue<AudioData> RawAudioDataQueue; +typedef threads::MessageLoopThread<RawAudioDataQueue> AudioPassThruQueue; } + typedef std::vector<std::string> RPCParams; class ApplicationManagerImpl : public ApplicationManager, public hmi_message_handler::HMIMessageObserver, public protocol_handler::ProtocolObserver, public connection_handler::ConnectionHandlerObserver, + public policy::PolicyHandlerObserver, public impl::FromMobileQueue::Handler, public impl::ToMobileQueue::Handler, public impl::FromHmiQueue::Handler, public impl::ToHmiQueue::Handler, + public impl::AudioPassThruQueue::Handler, public utils::Singleton<ApplicationManagerImpl> { friend class ResumeCtrl; @@ -244,13 +255,21 @@ class ApplicationManagerImpl : public ApplicationManager, * @param vehicle_info Enum value of type of vehicle data * @param new value (for integer values currently) of vehicle data */ - std::vector<utils::SharedPtr<Application>> IviInfoUpdated( + std::vector<ApplicationSharedPtr> IviInfoUpdated( VehicleDataType vehicle_info, int value); ///////////////////////////////////////////////////// HMICapabilities& hmi_capabilities(); + /** + * @brief ProcessQueryApp executes logic related to QUERY_APP system request. + * + * @param sm_object smart object wich is actually parsed json obtained within + * system request. + */ + void ProcessQueryApp(const smart_objects::SmartObject& sm_object); + #ifdef TIME_TESTER /** * @brief Setup observer for time metric. @@ -278,12 +297,10 @@ class ApplicationManagerImpl : public ApplicationManager, bool is_unexpected_disconnect = false); /** - * @brief Unregister application revoked by Policy + * @brief Handle sequence for unauthorized application * @param app_id Application id - * @param reason Reason of unregistering application */ - void UnregisterRevokedApplication(const uint32_t& app_id, - mobile_apis::Result::eType reason); + void OnAppUnauthorized(const uint32_t& app_id); /* * @brief Sets unregister reason for closing all registered applications @@ -303,15 +320,9 @@ class ApplicationManagerImpl : public ApplicationManager, mobile_api::AppInterfaceUnregisteredReason::eType reason); /* - * @brief Called by HMI on SUSPEND. - * SDL must save all persistence data(Resume, Policy) - */ - void HeadUnitSuspend(); - - /* * @brief Closes all registered applications */ - void UnregisterAllApplications(bool generated_by_hmi = false); + void UnregisterAllApplications(); bool RemoveAppDataFromHMI(ApplicationSharedPtr app); bool LoadAppDataToHMI(ApplicationSharedPtr app); @@ -324,7 +335,7 @@ class ApplicationManagerImpl : public ApplicationManager, * @param app, application, that need to be puted in FULL * @return seted HMI Level */ - mobile_api::HMILevel::eType PutApplicationInFull(ApplicationSharedPtr app); + mobile_api::HMILevel::eType IsHmiLevelFullAllowed(ApplicationSharedPtr app); void ConnectToDevice(uint32_t id); void OnHMIStartedCooperation(); @@ -391,6 +402,20 @@ class ApplicationManagerImpl : public ApplicationManager, */ void set_all_apps_allowed(const bool& allowed); + + /** + * @brief Notification from PolicyHandler about PTU. + * Compares AppHMIType between saved in app and received from PTU. If they are different method sends: + * UI_ChangeRegistration with list new AppHMIType; + * ActivateApp with HMI level BACKGROUND; + * OnHMIStatus notification; + * for app with HMI level FULL or LIMITED. + * method sends: + * UI_ChangeRegistration with list new AppHMIType + * for app with HMI level BACKGROUND. + */ + virtual void OnUpdateHMIAppType(std::map<std::string, std::vector<std::string> > app_hmi_types); + /* * @brief Starts audio pass thru thread * @@ -412,8 +437,17 @@ class ApplicationManagerImpl : public ApplicationManager, */ void StopAudioPassThru(int32_t application_key); + /* + * @brief Creates AudioPassThru data chunk and inserts it + * to audio_pass_thru_messages_ + * + * @param session_key Id of application for which + * audio pass thru should be sent + * + * @param binary_data AudioPassThru data chunk + */ void SendAudioPassThroughNotification(uint32_t session_key, - std::vector<uint8_t> binaryData); + std::vector<uint8_t>& binary_data); std::string GetDeviceName(connection_handler::DeviceHandle handle); @@ -430,42 +464,39 @@ class ApplicationManagerImpl : public ApplicationManager, // Put message to the queue to be sent to mobile. // if |final_message| parameter is set connection to mobile will be closed // after processing this message - void SendMessageToMobile( - const utils::SharedPtr<smart_objects::SmartObject> message, - bool final_message = false); + void SendMessageToMobile(const commands::MessageSharedPtr message, + bool final_message = false); + bool ManageMobileCommand( - const utils::SharedPtr<smart_objects::SmartObject> message); - void SendMessageToHMI( - const utils::SharedPtr<smart_objects::SmartObject> message); - bool ManageHMICommand( - const utils::SharedPtr<smart_objects::SmartObject> message); + const commands::MessageSharedPtr message, + commands::Command::CommandOrigin origin = + commands::Command::ORIGIN_SDL); + void SendMessageToHMI(const commands::MessageSharedPtr message); + bool ManageHMICommand(const commands::MessageSharedPtr message); ///////////////////////////////////////////////////////// - /* - * @brief Overriden ProtocolObserver method - */ + // Overriden ProtocolObserver method virtual void OnMessageReceived( - const ::protocol_handler::RawMessagePtr message); - - /* - * @brief Overriden ProtocolObserver method - */ + const ::protocol_handler::RawMessagePtr message) OVERRIDE; virtual void OnMobileMessageSent( - const ::protocol_handler::RawMessagePtr message); + const ::protocol_handler::RawMessagePtr message) OVERRIDE; - void OnMessageReceived(hmi_message_handler::MessageSharedPointer message); - void OnErrorSending(hmi_message_handler::MessageSharedPointer message); + // Overriden HMIMessageObserver method + void OnMessageReceived(hmi_message_handler::MessageSharedPointer message) OVERRIDE; + void OnErrorSending(hmi_message_handler::MessageSharedPointer message) OVERRIDE; - void OnDeviceListUpdated(const connection_handler::DeviceMap& device_list); + // Overriden ConnectionHandlerObserver method + void OnDeviceListUpdated(const connection_handler::DeviceMap& device_list) OVERRIDE; //TODO (EZamakhov): fix all indentations in this file - virtual void OnFindNewApplicationsRequest(); - void RemoveDevice(const connection_handler::DeviceHandle& device_handle); + void OnFindNewApplicationsRequest() OVERRIDE; + void RemoveDevice(const connection_handler::DeviceHandle& device_handle) OVERRIDE; bool OnServiceStartedCallback( - const connection_handler::DeviceHandle& device_handle, - const int32_t& session_key, const protocol_handler::ServiceType& type); + const connection_handler::DeviceHandle& device_handle, + const int32_t& session_key, const protocol_handler::ServiceType& type) OVERRIDE; void OnServiceEndedCallback(const int32_t& session_key, - const protocol_handler::ServiceType& type); - + const protocol_handler::ServiceType& type) OVERRIDE; + void OnApplicationFloodCallBack(const uint32_t& connection_key) OVERRIDE; + void OnMalformedMessageCallback(const uint32_t& connection_key) OVERRIDE; /** * @ Add notification to collection * @@ -508,6 +539,21 @@ class ApplicationManagerImpl : public ApplicationManager, */ void set_application_id(const int32_t correlation_id, const uint32_t app_id); + /** + * @brief AddPolicyObserver allows to subscribe needed component to events + * from policy. + * + * @param listener the component to subscribe. + */ + void AddPolicyObserver(PolicyHandlerObserver* listener); + + /** + * @brief RemovePolicyObserver allows to remove observer from collection. + * + * @param listener observer to remove. + */ + void RemovePolicyObserver(PolicyHandlerObserver* listener); + /* * @brief Change AudioStreamingState for all application according to * system audio-mixing capabilities (NOT_AUDIBLE/ATTENUATED) and @@ -538,6 +584,36 @@ class ApplicationManagerImpl : public ApplicationManager, bool IsVideoStreamingAllowed(uint32_t connection_key) const; /** + * @brief CanAppStream allows to check whether application is permited for + * data streaming. + * + * In case streaming for app is disallowed the method will send EndService to mobile. + * + * @param app_id the application id which should be checked. + * + * @return true in case streaming is allowed, false otherwise. + */ + bool CanAppStream(uint32_t app_id) const; + + /** + * @brief StreamingEnded Callback called from MediaManager when it decide that + * streaming has been ended + * + * @param app_id the id of application that stops stream. + */ + void StreamingEnded(uint32_t app_id); + + /** + * @brief ForbidStreaming forbid the stream over the certain application. + * + * @param app_id the application's id which should stop streaming. + */ + void ForbidStreaming(uint32_t app_id); + + mobile_api::HMILevel::eType GetDefaultHmiLevel( + ApplicationSharedPtr application) const; + + /** * Getter for resume_controller * @return Resume Controller */ @@ -642,6 +718,33 @@ class ApplicationManagerImpl : public ApplicationManager, void ResetPhoneCallAppList(); /** + * @brief ChangeAppsHMILevel the function that will change application's + * hmi level. + * + * @param app_id id of the application whose hmi level should be changed. + * + * @param level new hmi level for certain application. + */ + void ChangeAppsHMILevel(uint32_t app_id, mobile_apis::HMILevel::eType level); + + /** + * @brief MakeAppNotAudible allows to make certain application not audible. + * + * @param app_id applicatin's id whose audible state should be changed. + */ + void MakeAppNotAudible(uint32_t app_id); + + /** + * @brief MakeAppFullScreen allows ti change application's properties + * in order to make it full screen. + * + * @param app_id the id of application which should be in full screen mode. + * + * @return true if operation was success, false otherwise. + */ + bool MakeAppFullScreen(uint32_t app_id); + + /** * Function used only by HMI request/response/notification base classes * to change HMI app id to Mobile app id and vice versa. * Dot use it inside Core @@ -667,45 +770,107 @@ class ApplicationManagerImpl : public ApplicationManager, mobile_apis::FunctionID::eType function_id, const RPCParams& rpc_params, CommandParametersPermissions* params_permissions = NULL); + /* + * @brief Function Should be called when Low Voltage is occured + */ + void OnLowVoltage(); + + /* + * @brief Function Should be called when WakeUp occures after Low Voltage + */ + void OnWakeUp(); + + struct ApplicationsAppIdSorter { + bool operator() (const ApplicationSharedPtr lhs, + const ApplicationSharedPtr rhs) { + return lhs->app_id() < rhs->app_id(); + } + }; + + struct ApplicationsMobileAppIdSorter { + bool operator() (const ApplicationSharedPtr lhs, + const ApplicationSharedPtr rhs) { + return lhs->mobile_app_id() < rhs->mobile_app_id(); + } + }; // typedef for Applications list - typedef const std::set<ApplicationSharedPtr> TAppList; + typedef std::set<ApplicationSharedPtr, + ApplicationsAppIdSorter> ApplictionSet; + + typedef std::set<ApplicationSharedPtr, + ApplicationsMobileAppIdSorter> AppsWaitRegistrationSet; // typedef for Applications list iterator - typedef std::set<ApplicationSharedPtr>::iterator TAppListIt; + typedef ApplictionSet::iterator ApplictionSetIt; // typedef for Applications list const iterator - typedef std::set<ApplicationSharedPtr>::const_iterator TAppListConstIt; + typedef ApplictionSet::const_iterator ApplictionSetConstIt; + /** * Class for thread-safe access to applications list */ - class ApplicationListAccessor { + class ApplicationListAccessor: public DataAccessor<ApplictionSet> { public: /** * @brief ApplicationListAccessor class constructor */ - ApplicationListAccessor() { - ApplicationManagerImpl::instance()->applications_list_lock_.Acquire(); + ApplicationListAccessor() : + DataAccessor<ApplictionSet>(ApplicationManagerImpl::instance()->applications_, + ApplicationManagerImpl::instance()->applications_list_lock_) { } - /** - * @brief ApplicationListAccessor class destructor - */ - ~ApplicationListAccessor() { - ApplicationManagerImpl::instance()->applications_list_lock_.Release(); - } + ~ApplicationListAccessor(); - // TODO(VS): Now we have return application list by value, because we have - // situations, when our process is killed without Stop method called. - // This problem must be discussed and fixed. /** * @brief thread-safe getter for applications * @return applications list */ - TAppList applications() { - return ApplicationManagerImpl::instance()->application_list_; + const ApplictionSet& applications() const { + return GetData(); + } + + ApplictionSetConstIt begin() { + return applications().begin(); + } + + ApplictionSetConstIt end() { + return applications().end(); + } + + template<class UnaryPredicate> + ApplicationSharedPtr Find(UnaryPredicate finder) { + ApplicationSharedPtr result; + ApplictionSetConstIt it = std::find_if(begin(), end(), finder); + if (it != end()) { + result = *it; + } + return result; + } + + template<class UnaryPredicate> + std::vector<ApplicationSharedPtr> FindAll(UnaryPredicate finder) { + std::vector<ApplicationSharedPtr> result; + ApplictionSetConstIt it = std::find_if(begin(), end(), finder); + while (it != end()) { + result.push_back(*it); + it = std::find_if(++it, end(), finder); + } + return result; + } + + void Erase(ApplicationSharedPtr app_to_remove) { + ApplicationManagerImpl::instance()->applications_.erase(app_to_remove); + } + + void Insert(ApplicationSharedPtr app_to_insert) { + ApplicationManagerImpl::instance()->applications_.insert(app_to_insert); + } + + bool Empty() { + return ApplicationManagerImpl::instance()->applications_.empty(); } private: @@ -714,9 +879,68 @@ class ApplicationManagerImpl : public ApplicationManager, friend class ApplicationListAccessor; + struct AppIdPredicate { + uint32_t app_id_; + AppIdPredicate(uint32_t app_id): app_id_(app_id) {} + bool operator () (const ApplicationSharedPtr app) const { + return app ? app_id_ == app->app_id() : false; + } + }; + + struct HmiAppIdPredicate { + uint32_t hmi_app_id_; + HmiAppIdPredicate(uint32_t hmi_app_id): hmi_app_id_(hmi_app_id) {} + bool operator () (const ApplicationSharedPtr app) const { + return app ? hmi_app_id_ == app->hmi_app_id() : false; + } + }; + + struct MobileAppIdPredicate { + std::string policy_app_id_; + MobileAppIdPredicate(const std::string& policy_app_id): + policy_app_id_(policy_app_id) {} + bool operator () (const ApplicationSharedPtr app) const { + return app ? policy_app_id_ == app->mobile_app_id() : false; + } + }; + + struct SubscribedToButtonPredicate { + mobile_apis::ButtonName::eType button_; + SubscribedToButtonPredicate(mobile_apis::ButtonName::eType button) + : button_(button) {} + bool operator () (const ApplicationSharedPtr app) const { + return app ? app->IsSubscribedToButton(button_) : false; + } + }; + + struct SubscribedToIVIPredicate { + int32_t vehicle_info_; + SubscribedToIVIPredicate(int32_t vehicle_info) + : vehicle_info_(vehicle_info) {} + bool operator () (const ApplicationSharedPtr app) const { + return app ? app->IsSubscribedToIVI(vehicle_info_) : false; + } + }; + private: ApplicationManagerImpl(); + /** + * @brief Method transforms string to AppHMIType + * @param str contains string AppHMIType + * @return enum AppHMIType + */ + mobile_apis::AppHMIType::eType StringToAppHMIType(std::string str); + + /** + * @brief Method compares arrays of app HMI type + * @param from_policy contains app HMI type from policy + * @param from_application contains app HMI type from application + * @return return TRUE if arrays of appHMIType equal, otherwise return FALSE + */ + bool CompareAppHMIType (const smart_objects::SmartObject& from_policy, + const smart_objects::SmartObject& from_application); + hmi_apis::HMI_API& hmi_so_factory(); mobile_apis::MOBILE_API& mobile_so_factory(); @@ -747,26 +971,154 @@ class ApplicationManagerImpl : public ApplicationManager, // CALLED ON messages_to_hmi_ thread! virtual void Handle(const impl::MessageToHmi message) OVERRIDE; - void SendUpdateAppList(const std::list<uint32_t>& applications_ids); + // CALLED ON audio_pass_thru_messages_ thread! + virtual void Handle(const impl::AudioData message) OVERRIDE; + + void SendUpdateAppList(); + + template<typename ApplicationList> + void PrepareApplicationListSO(ApplicationList app_list, + smart_objects::SmartObject& applications) { + CREATE_LOGGERPTR_LOCAL(logger_, "ApplicatinManagerImpl"); + + uint32_t app_count = 0; + typename ApplicationList::const_iterator it; + for (it = app_list.begin(); it != app_list.end(); ++it) { + if (!it->valid()) { + LOG4CXX_ERROR(logger_, "Application not found "); + continue; + } + + smart_objects::SmartObject hmi_application(smart_objects::SmartType_Map);; + if (MessageHelper::CreateHMIApplicationStruct(*it, hmi_application)) { + applications[app_count++] = hmi_application; + } else { + LOG4CXX_DEBUG(logger_, "Can't CreateHMIApplicationStruct "); + } + } + + if (0 == app_count) { + LOG4CXX_WARN(logger_, "Empty applications list"); + } + } + void OnApplicationListUpdateTimer(); + /** + * @brief CreateApplications creates aplpication adds it to application list + * and prepare data for sending AppIcon request. + * + * @param obj_array applications array. + * + * @param app_icon_dir application icons directory + * + * @param apps_with_icon container which store application and it's icon path. + */ + void CreateApplications(smart_objects::SmartArray& obj_array); + /* * @brief Function is called on IGN_OFF, Master_reset or Factory_defaults * to notify HMI that SDL is shutting down. */ void SendOnSDLClose(); + /* + * @brief returns true if low voltage state is active + */ + bool IsLowVoltage(); + private: + /** + * @brief OnHMILevelChanged the callback that allows SDL to react when + * application's HMILeval has been changed. + * + * @param app_id application identifier for which HMILevel has been chaned. + * + * @param from previous HMILevel. + * @param to current HMILevel. + */ + void OnHMILevelChanged(uint32_t app_id, + mobile_apis::HMILevel::eType from, + mobile_apis::HMILevel::eType to); + + /** + * @brief EndNaviServices either send EndService to mobile or proceed + * unregister application procedure. + */ + void EndNaviServices(); + + /** + * @brief CloseNaviApp allows to unregister application in case the EndServiceEndedAck + * didn't come for at least one of services(audio or video). + */ + void CloseNaviApp(); + + /** + * @brief AckReceived allows to distinguish if ack for appropriate service + * has been received (means EndServiceAck). + * + * @param type service type. + * + * @return in case EndService has been sent and appropriate ack has been + * received it returns true. In case no EndService for appropriate serevice type + * has been sent and no ack has been received it returns true as well. + * Otherwise it will return false. + * + */ + bool AckReceived(protocol_handler::ServiceType type); + + /** + * @brief NaviAppChangeLevel the callback which reacts on case when applications + * hmi level has been changed. + */ + void NaviAppChangeLevel(mobile_apis::HMILevel::eType new_level); + + /** + * @brief ChangeStreamStatus allows to process streaming state. + * + * @param app_id id of application whose stream state has been changed. + * + * @param can_stream streaming state if true - streaming active, if false + * streaming is not active. + */ + void ChangeStreamStatus(uint32_t app_id, bool can_stream); + + /** + * @brief ProcessNaviService allows to start navi service + * + * @param type service type. + * + * @param connection_key the application id. + */ + bool ProcessNaviService(protocol_handler::ServiceType type, uint32_t connection_key); + + /** + * @brief NaviAppStreamStatus allows to handle case when navi streaming state + * has ben changed from streaming to non streaming and vise versa. + * + * @param stream_active the stream's state - is it streams or not. + */ + void NaviAppStreamStatus(bool stream_active); + + + /** + * @brief Function returns supported SDL Protocol Version + * @return protocol version depends on parameters from smartDeviceLink.ini. + */ + ProtocolVersion SupportedSDLVersion() const; + // members /** * @brief List of applications */ - std::set<ApplicationSharedPtr> application_list_; + ApplictionSet applications_; + AppsWaitRegistrationSet apps_to_register_; // Lock for applications list mutable sync_primitives::Lock applications_list_lock_; + mutable sync_primitives::Lock apps_to_register_list_lock_; /** * @brief Map of correlation id and associated application id. @@ -831,6 +1183,8 @@ class ApplicationManagerImpl : public ApplicationManager, impl::FromHmiQueue messages_from_hmi_; // Thread that pumps messages being passed to HMI. impl::ToHmiQueue messages_to_hmi_; + // Thread that pumps messages audio pass thru to mobile. + impl::AudioPassThruQueue audio_pass_thru_messages_; HMICapabilities hmi_capabilities_; @@ -844,6 +1198,16 @@ class ApplicationManagerImpl : public ApplicationManager, */ ResumeCtrl resume_ctrl_; + // The map contains service type as a key and pair as a value. + // The pair meaning is: first item shows if EndService has been sent and + // the second one shows if appropriate ACK has been received. + std::map<protocol_handler::ServiceType, std::pair<bool, bool> > service_status_; + + timer::TimerThread<ApplicationManagerImpl> end_services_timer; + uint32_t wait_end_service_timeout_; + uint32_t navi_app_to_stop_; + + #ifdef TIME_TESTER AMMetricObserver* metric_observer_; #endif // TIME_TESTER @@ -860,6 +1224,7 @@ class ApplicationManagerImpl : public ApplicationManager, timer::TimerThread<ApplicationManagerImpl> tts_global_properties_timer_; + bool is_low_voltage_; DISALLOW_COPY_AND_ASSIGN(ApplicationManagerImpl); FRIEND_BASE_SINGLETON_CLASS(ApplicationManagerImpl); |