diff options
author | Andrey Oleynik (GitHub) <aoleynik@luxoft.com> | 2017-09-19 16:51:35 +0300 |
---|---|---|
committer | Andriy Byzhynar <AByzhynar@luxoft.com> | 2018-01-18 11:26:30 +0200 |
commit | a6791129fb1cfcd5dad96e4987b1c2664aafb61e (patch) | |
tree | 82d991edadfd29485946fd07c0f31174c97b0e17 /src | |
parent | e8911d03dde016a29b01fe80533bc6ac56531678 (diff) | |
download | sdl_core-a6791129fb1cfcd5dad96e4987b1c2664aafb61e.tar.gz |
Adds main logic and related bugfixes for transport switching
Diffstat (limited to 'src')
44 files changed, 1213 insertions, 417 deletions
diff --git a/src/appMain/smartDeviceLink.ini b/src/appMain/smartDeviceLink.ini index 4557944048..6cc7c92bb1 100644 --- a/src/appMain/smartDeviceLink.ini +++ b/src/appMain/smartDeviceLink.ini @@ -91,6 +91,12 @@ ReadDIDRequest = 5, 1 GetVehicleDataRequest = 5, 1 PluginFolder = plugins +; The time used during switch transport procedure +AppTransportChangeTimer = 500 + +; The time used as addition for AppTransportChangeTimer +AppTransportChangeTimerAddition = 0 + [MEDIA MANAGER] ; where 3 is a number of retries and 1000 is a timeout in milliseconds for request frequency StartStreamRetry = 3, 1000 diff --git a/src/components/application_manager/include/application_manager/application.h b/src/components/application_manager/include/application_manager/application.h index b753ba0e7f..63b8589b59 100644 --- a/src/components/application_manager/include/application_manager/application.h +++ b/src/components/application_manager/include/application_manager/application.h @@ -561,7 +561,6 @@ class Application : public virtual InitialApplicationData, virtual void increment_list_files_in_none_count() = 0; virtual bool set_app_icon_path(const std::string& file_name) = 0; virtual void set_app_allowed(const bool allowed) = 0; - virtual void set_device(connection_handler::DeviceHandle device) = 0; virtual uint32_t get_grammar_id() const = 0; virtual void set_grammar_id(uint32_t value) = 0; @@ -618,6 +617,13 @@ class Application : public virtual InitialApplicationData, virtual UsageStatistics& usage_report() = 0; /** + * @brief SetInitialState sets initial HMI state for application on + * registration + * @param state Hmi state value + */ + virtual void SetInitialState(HmiStatePtr state) = 0; + + /** * @brief SetRegularState set permanent state of application * * @param state state to setup @@ -764,16 +770,6 @@ class Application : public virtual InitialApplicationData, } /** - * @brief GetDeviceId allows to obtain device id which posseses - * by this application. - * - * @return device the device id. - */ - std::string GetDeviceId() const { - return device_id_; - } - - /** * @brief Returns is application should be greyed out on HMI */ bool is_greyed_out() const { @@ -861,7 +857,6 @@ class Application : public virtual InitialApplicationData, ApplicationState state_; std::string url_; std::string package_name_; - std::string device_id_; ssize_t connection_id_; bool is_greyed_out_; }; diff --git a/src/components/application_manager/include/application_manager/application_impl.h b/src/components/application_manager/include/application_manager/application_impl.h index 01963e24e7..3c5353dfa2 100644 --- a/src/components/application_manager/include/application_manager/application_impl.h +++ b/src/components/application_manager/include/application_manager/application_impl.h @@ -65,6 +65,17 @@ using namespace timer; namespace mobile_api = mobile_apis; namespace custom_str = custom_string; +/** + * @brief SwitchApplicationParameters updates application internal parameters + * on transport switch. Must be used only for switching flow. + * @param app Pointer to switched application + * @param app_id New application id (connection key) + * @param device_id New device id + */ +void SwitchApplicationParameters(ApplicationSharedPtr app, + const uint32_t app_id, + const uint32_t device_id); + class ApplicationImpl : public virtual Application, public virtual InitialApplicationDataImpl, public virtual DynamicApplicationDataImpl { @@ -73,6 +84,7 @@ class ApplicationImpl : public virtual Application, uint32_t application_id, const std::string& policy_app_id, const std::string& mac_address, + const connection_handler::DeviceHandle device_id, const custom_str::CustomString& app_name, utils::SharedPtr<usage_statistics::StatisticsManager> statistics_manager, ApplicationManager& application_manager); @@ -161,7 +173,6 @@ class ApplicationImpl : public virtual Application, void increment_list_files_in_none_count(); bool set_app_icon_path(const std::string& path); void set_app_allowed(const bool allowed); - void set_device(connection_handler::DeviceHandle device); virtual uint32_t get_grammar_id() const; virtual void set_grammar_id(uint32_t value); bool is_audio() const OVERRIDE; @@ -250,6 +261,13 @@ class ApplicationImpl : public virtual Application, virtual bool IsAudioApplication() const; /** + * @brief SetInitialState sets initial HMI state for application on + * registration + * @param state Hmi state value + */ + void SetInitialState(HmiStatePtr state) FINAL; + + /** * @brief SetRegularState set permanent state of application * * @param state state to setup @@ -442,6 +460,7 @@ class ApplicationImpl : public virtual Application, std::string app_icon_path_; connection_handler::DeviceHandle device_; const std::string mac_address_; + connection_handler::DeviceHandle device_id_; std::string bundle_id_; AppFilesMap app_files_; std::set<mobile_apis::ButtonName::eType> subscribed_buttons_; @@ -486,6 +505,11 @@ class ApplicationImpl : public virtual Application, sync_primitives::Lock button_lock_; std::string folder_name_; ApplicationManager& application_manager_; + + friend void SwitchApplicationParameters(ApplicationSharedPtr app, + const uint32_t app_id, + const uint32_t device_id); + DISALLOW_COPY_AND_ASSIGN(ApplicationImpl); }; 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 a0b8d45de2..0e676f5f55 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 @@ -53,6 +53,7 @@ #include "application_manager/application_manager_settings.h" #include "application_manager/event_engine/event_dispatcher_impl.h" #include "application_manager/hmi_interfaces_impl.h" +#include "application_manager/command_holder.h" #include "protocol_handler/protocol_observer.h" #include "protocol_handler/protocol_handler.h" @@ -500,7 +501,22 @@ class ApplicationManagerImpl */ void SetAllAppsAllowed(const bool allowed) OVERRIDE; + /** + * @brief CreateRegularState create regular HMI state for application + * @param app Application + * @param hmi_level of returned state + * @param audio_state of returned state + * @param system_context of returned state + * @return new regular HMI state + */ + HmiStatePtr CreateRegularState( + utils::SharedPtr<Application> app, + mobile_apis::HMILevel::eType hmi_level, + mobile_apis::AudioStreamingState::eType audio_state, + mobile_apis::SystemContext::eType system_context) const OVERRIDE; + /** + * DEPRECATED * @brief CreateRegularState create regular HMI state for application * @param app_id * @param hmi_level of returned state @@ -508,7 +524,7 @@ class ApplicationManagerImpl * @param system_context of returned state * @return new regular HMI state */ - HmiStatePtr CreateRegularState( + DEPRECATED HmiStatePtr CreateRegularState( uint32_t app_id, mobile_apis::HMILevel::eType hmi_level, mobile_apis::AudioStreamingState::eType audio_state, @@ -837,6 +853,10 @@ class ApplicationManagerImpl void OnFindNewApplicationsRequest() OVERRIDE; void RemoveDevice( const connection_handler::DeviceHandle& device_handle) OVERRIDE; + void OnDeviceSwitchingStart(const std::string& device_uid) FINAL; + + void OnDeviceSwitchFinish(const std::string& device_uid) FINAL; + DEPRECATED bool OnServiceStartedCallback( const connection_handler::DeviceHandle& device_handle, const int32_t& session_key, @@ -1212,11 +1232,25 @@ class ApplicationManagerImpl bool IsAppsQueriedFrom( const connection_handler::DeviceHandle handle) const OVERRIDE; + bool IsAppInReconnectMode(const std::string& policy_app_id) const FINAL; + bool IsStopping() const OVERRIDE { return is_stopping_; } /** + * @brief ProcessReconnection handles reconnection flow for application on + * transport switch + * @param application Pointer to switched application, must be validated + * before passing + * @param connection_key Connection key from registration request of + * switched + * application + */ + void ProcessReconnection(ApplicationSharedPtr application, + const uint32_t connection_key) FINAL; + + /** * @brief Clears all applications' persistent data */ void ClearAppsPersistentData(); @@ -1401,7 +1435,7 @@ class ApplicationManagerImpl * @return True on success, false on fail */ DEPRECATED bool StartNaviService(uint32_t app_id, - protocol_handler::ServiceType service_type); + protocol_handler::ServiceType service_type); /** * @brief Starts specified navi service for application @@ -1485,6 +1519,26 @@ class ApplicationManagerImpl void ClearTTSGlobalPropertiesList(); /** + * @brief EraseAppFromReconnectionList drops application from reconnection + * list on transport switch success + * @param app Pointer to application + */ + void EraseAppFromReconnectionList(const ApplicationSharedPtr& app); + + /** + * @brief SwitchApplication updates parameters of switched application and + * internal applications list + * @param app Pointer to switched application, must be validated before + * passing in + * @param connection_key Connection key of switched application from its + * registration request + * @param device_id Device id of switched application + */ + void SwitchApplication(ApplicationSharedPtr app, + const uint32_t connection_key, + const uint32_t device_id); + + /** * @brief Converts BSON object containing video parameters to * smart object's map object * @param output the smart object to add video parameters @@ -1617,6 +1671,11 @@ class ApplicationManagerImpl std::auto_ptr<app_launch::AppLaunchData> app_launch_dto_; std::auto_ptr<app_launch::AppLaunchCtrl> app_launch_ctrl_; + typedef std::vector<ApplicationSharedPtr> ReregisterWaitList; + ReregisterWaitList reregister_wait_list_; + + mutable sync_primitives::Lock reregister_wait_list_lock_; + #ifdef TELEMETRY_MONITOR AMTelemetryObserver* metric_observer_; #endif // TELEMETRY_MONITOR diff --git a/src/components/application_manager/include/application_manager/commands/command_impl.h b/src/components/application_manager/include/application_manager/commands/command_impl.h index 66456dfdb1..7cab97d423 100644 --- a/src/components/application_manager/include/application_manager/commands/command_impl.h +++ b/src/components/application_manager/include/application_manager/commands/command_impl.h @@ -146,14 +146,14 @@ class CommandImpl : public Command { * * @param message Smartobject to be parsed */ - void ReplaceMobileByHMIAppId(smart_objects::SmartObject& message); + bool ReplaceMobileByHMIAppId(smart_objects::SmartObject& message); /** * @brief Parse smartObject and replace HMI app ID by mobile app Id * * @param message Smartobject to be parsed */ - void ReplaceHMIByMobileAppId(smart_objects::SmartObject& message); + bool ReplaceHMIByMobileAppId(smart_objects::SmartObject& message); MessageSharedPtr message_; uint32_t default_timeout_; diff --git a/src/components/application_manager/include/application_manager/commands/hmi/on_app_unregistered_notification.h b/src/components/application_manager/include/application_manager/commands/hmi/on_app_unregistered_notification.h index 980e558d6f..f49dac071f 100644 --- a/src/components/application_manager/include/application_manager/commands/hmi/on_app_unregistered_notification.h +++ b/src/components/application_manager/include/application_manager/commands/hmi/on_app_unregistered_notification.h @@ -55,12 +55,22 @@ class OnAppUnregisteredNotification : public NotificationToHMI { /** * @brief OnAppUnregisteredNotification class destructor **/ - virtual ~OnAppUnregisteredNotification(); + ~OnAppUnregisteredNotification() FINAL; + + /** + * @brief Init overrides and skips replacement of app id with hmi id since + * 1) at the moment this notification is being sent there is no application + * registered in application manager + * 2) hmi id is already used whenever this message is being constructed, so + * its already there + * @return True in any case + */ + bool Init() FINAL; /** * @brief Execute command **/ - virtual void Run(); + virtual void Run() FINAL; private: DISALLOW_COPY_AND_ASSIGN(OnAppUnregisteredNotification); diff --git a/src/components/application_manager/include/application_manager/commands/mobile/register_app_interface_request.h b/src/components/application_manager/include/application_manager/commands/mobile/register_app_interface_request.h index cc3d5b685c..369fd68868 100644 --- a/src/components/application_manager/include/application_manager/commands/mobile/register_app_interface_request.h +++ b/src/components/application_manager/include/application_manager/commands/mobile/register_app_interface_request.h @@ -77,15 +77,17 @@ class RegisterAppInterfaceRequest : public CommandRequestImpl { **/ virtual void Run(); + private: + enum class AppicationType { kNewApplication, kSwitchedApplication }; + /** * @brief Sends RegisterAppInterface response to mobile * *@param application_impl application * **/ - void SendRegisterAppInterfaceResponseToMobile(); + void SendRegisterAppInterfaceResponseToMobile(AppicationType app_type); - private: smart_objects::SmartObjectSPtr GetLockScreenIconUrlNotification( const uint32_t connection_key, ApplicationSharedPtr app); @@ -184,6 +186,15 @@ class RegisterAppInterfaceRequest : public CommandRequestImpl { */ void SendSubscribeCustomButtonNotification(); + /** + * @brief IsApplicationSwitched checks whether application is switched from + * another transport. If application id is found, but not in reconnection + * list, returns 'already registered' code. Otherwise - proceed with + * switching. + * @return True if application is detected as switched, otherwise false. + */ + bool IsApplicationSwitched(); + private: std::string response_info_; mobile_apis::Result::eType result_checking_app_hmi_type_; diff --git a/src/components/application_manager/include/application_manager/hmi_state.h b/src/components/application_manager/include/application_manager/hmi_state.h index 939b8b86d0..89c72370a5 100644 --- a/src/components/application_manager/include/application_manager/hmi_state.h +++ b/src/components/application_manager/include/application_manager/hmi_state.h @@ -41,6 +41,7 @@ namespace application_manager { class HmiState; class ApplicationManager; +class Application; typedef utils::SharedPtr<HmiState> HmiStatePtr; @@ -70,8 +71,9 @@ class HmiState { STATE_ID_EMBEDDED_NAVI }; - HmiState(uint32_t app_id, const ApplicationManager& app_mngr); - HmiState(uint32_t app_id, + HmiState(utils::SharedPtr<Application> app, + const ApplicationManager& app_mngr); + HmiState(utils::SharedPtr<Application> app, const ApplicationManager& app_mngr, StateID state_id); @@ -166,7 +168,7 @@ class HmiState { } protected: - uint32_t app_id_; + utils::SharedPtr<Application> app_; StateID state_id_; const ApplicationManager& app_mngr_; HmiStatePtr parent_; @@ -177,26 +179,23 @@ class HmiState { protected: /** * @brief is_navi_app check if app is navi - * @param app_id application id * @return true if app is navi, otherwise return false */ - bool is_navi_app(const uint32_t app_id) const; + bool is_navi_app() const; /** * @brief is_media_app check if app is media - * @param app_id application id * @return true if media_app, otherwise return false */ - bool is_media_app(const uint32_t app_id) const; + bool is_media_app() const; /** * @brief is_voice_communicationn_app check if app is voice comunication - * @param app_id application id * @return true if voice_communicationn_app, otherwise return false */ - bool is_voice_communication_app(const uint32_t app_id) const; + bool is_voice_communication_app() const; - bool is_mobile_projection_app(const uint32_t app_id) const; + bool is_mobile_projection_app() const; private: void operator=(const HmiState&); @@ -209,7 +208,8 @@ class VRHmiState : public HmiState { public: virtual mobile_apis::AudioStreamingState::eType audio_streaming_state() const OVERRIDE; - VRHmiState(uint32_t app_id, const ApplicationManager& app_mngr); + VRHmiState(utils::SharedPtr<Application> app, + const ApplicationManager& app_mngr); }; /** @@ -217,7 +217,8 @@ class VRHmiState : public HmiState { */ class TTSHmiState : public HmiState { public: - TTSHmiState(uint32_t app_id, const ApplicationManager& app_mngr); + TTSHmiState(utils::SharedPtr<Application> app, + const ApplicationManager& app_mngr); virtual mobile_apis::AudioStreamingState::eType audio_streaming_state() const OVERRIDE; }; @@ -228,7 +229,8 @@ class TTSHmiState : public HmiState { */ class NaviStreamingHmiState : public HmiState { public: - NaviStreamingHmiState(uint32_t app_id, const ApplicationManager& app_mngr); + NaviStreamingHmiState(utils::SharedPtr<Application> app, + const ApplicationManager& app_mngr); mobile_apis::AudioStreamingState::eType audio_streaming_state() const OVERRIDE; }; @@ -239,7 +241,8 @@ class NaviStreamingHmiState : public HmiState { */ class PhoneCallHmiState : public HmiState { public: - PhoneCallHmiState(uint32_t app_id, const ApplicationManager& app_mngr); + PhoneCallHmiState(utils::SharedPtr<Application> app, + const ApplicationManager& app_mngr); mobile_apis::HMILevel::eType hmi_level() const OVERRIDE; mobile_apis::AudioStreamingState::eType audio_streaming_state() const OVERRIDE { @@ -253,7 +256,8 @@ class PhoneCallHmiState : public HmiState { */ class SafetyModeHmiState : public HmiState { public: - SafetyModeHmiState(uint32_t app_id, const ApplicationManager& app_mngr); + SafetyModeHmiState(utils::SharedPtr<Application> app, + const ApplicationManager& app_mngr); mobile_apis::AudioStreamingState::eType audio_streaming_state() const OVERRIDE { return mobile_apis::AudioStreamingState::NOT_AUDIBLE; @@ -266,7 +270,8 @@ class SafetyModeHmiState : public HmiState { */ class DeactivateHMI : public HmiState { public: - DeactivateHMI(uint32_t app_id, const ApplicationManager& app_mngr); + DeactivateHMI(utils::SharedPtr<Application> app, + const ApplicationManager& app_mngr); mobile_apis::HMILevel::eType hmi_level() const OVERRIDE; mobile_apis::AudioStreamingState::eType audio_streaming_state() const OVERRIDE { @@ -280,7 +285,8 @@ class DeactivateHMI : public HmiState { */ class AudioSource : public HmiState { public: - AudioSource(uint32_t app_id, const ApplicationManager& app_mngr); + AudioSource(utils::SharedPtr<Application> app, + const ApplicationManager& app_mngr); mobile_apis::HMILevel::eType hmi_level() const OVERRIDE; mobile_apis::AudioStreamingState::eType audio_streaming_state() const OVERRIDE { @@ -295,7 +301,8 @@ class AudioSource : public HmiState { */ class EmbeddedNavi : public HmiState { public: - EmbeddedNavi(uint32_t app_id, const ApplicationManager& app_mngr); + EmbeddedNavi(utils::SharedPtr<Application> app, + const ApplicationManager& app_mngr); mobile_apis::HMILevel::eType hmi_level() const OVERRIDE; mobile_apis::AudioStreamingState::eType audio_streaming_state() const OVERRIDE { diff --git a/src/components/application_manager/include/application_manager/state_controller_impl.h b/src/components/application_manager/include/application_manager/state_controller_impl.h index f2f9fb39a4..1b2033f5a8 100644 --- a/src/components/application_manager/include/application_manager/state_controller_impl.h +++ b/src/components/application_manager/include/application_manager/state_controller_impl.h @@ -289,7 +289,7 @@ class StateControllerImpl : public event_engine::EventObserver, void HMIStateStarted(ApplicationSharedPtr app) { DCHECK_OR_RETURN_VOID(app); HmiStatePtr old_hmi_state = app->CurrentHmiState(); - HmiStatePtr new_hmi_state = CreateHmiState(app->app_id(), ID); + HmiStatePtr new_hmi_state = CreateHmiState(app, ID); DCHECK_OR_RETURN_VOID(new_hmi_state); DCHECK_OR_RETURN_VOID(new_hmi_state->state_id() != HmiState::STATE_ID_REGULAR); @@ -326,7 +326,7 @@ class StateControllerImpl : public event_engine::EventObserver, DCHECK_OR_RETURN_VOID(app); HmiStatePtr cur = app->CurrentHmiState(); HmiStatePtr old_hmi_state = - CreateHmiState(app->app_id(), HmiState::StateID::STATE_ID_REGULAR); + CreateHmiState(app, HmiState::StateID::STATE_ID_REGULAR); DCHECK_OR_RETURN_VOID(old_hmi_state); old_hmi_state->set_hmi_level(cur->hmi_level()); old_hmi_state->set_audio_streaming_state(cur->audio_streaming_state()); @@ -431,7 +431,8 @@ class StateControllerImpl : public event_engine::EventObserver, * @param state_id state id * @return */ - HmiStatePtr CreateHmiState(uint32_t app_id, HmiState::StateID state_id) const; + HmiStatePtr CreateHmiState(utils::SharedPtr<Application> app, + HmiState::StateID state_id) const; mobile_apis::AudioStreamingState::eType CalcAudioState( ApplicationSharedPtr app, diff --git a/src/components/application_manager/src/application_impl.cc b/src/components/application_manager/src/application_impl.cc index 0ba98d67f5..21847ffa1d 100644 --- a/src/components/application_manager/src/application_impl.cc +++ b/src/components/application_manager/src/application_impl.cc @@ -41,6 +41,7 @@ #include "utils/file_system.h" #include "utils/logger.h" #include "utils/gen_hash.h" +#include "utils/shared_ptr.h" #include "utils/make_shared.h" #include "utils/timer_task_impl.h" #include "application_manager/policies/policy_handler_interface.h" @@ -76,10 +77,21 @@ CREATE_LOGGERPTR_GLOBAL(logger_, "ApplicationManager") namespace application_manager { +void SwitchApplicationParameters(ApplicationSharedPtr app, + const uint32_t app_id, + const uint32_t device_id) { + utils::SharedPtr<ApplicationImpl> application = + ApplicationSharedPtr::dynamic_pointer_cast<ApplicationImpl>(app); + DCHECK_OR_RETURN_VOID(application); + application->app_id_ = app_id; + application->device_id_ = device_id; +} + ApplicationImpl::ApplicationImpl( uint32_t application_id, const std::string& mobile_app_id, const std::string& mac_address, + const connection_handler::DeviceHandle device_id, const custom_str::CustomString& app_name, utils::SharedPtr<usage_statistics::StatisticsManager> statistics_manager, ApplicationManager& application_manager) @@ -107,6 +119,7 @@ ApplicationImpl::ApplicationImpl( , list_files_in_none_count_(0) , device_(0) , mac_address_(mac_address) + , device_id_(device_id) , usage_report_(mobile_app_id, statistics_manager) , protocol_version_( protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_3) @@ -137,12 +150,6 @@ ApplicationImpl::ApplicationImpl( SubscribeToButton(mobile_apis::ButtonName::CUSTOM_BUTTON); // load persistent files LoadPersistentFiles(); - HmiStatePtr initial_state = application_manager_.CreateRegularState( - app_id(), - mobile_apis::HMILevel::INVALID_ENUM, - mobile_apis::AudioStreamingState::INVALID_ENUM, - mobile_api::SystemContext::SYSCTXT_MAIN); - state_.InitState(initial_state); video_stream_suspend_timeout_ = application_manager_.get_settings().video_data_stopped_timeout(); @@ -347,7 +354,7 @@ const std::string& ApplicationImpl::bundle_id() const { } connection_handler::DeviceHandle ApplicationImpl::device() const { - return device_; + return device_id_; } const std::string& ApplicationImpl::mac_address() const { @@ -606,10 +613,6 @@ void ApplicationImpl::set_app_allowed(const bool allowed) { is_app_allowed_ = allowed; } -void ApplicationImpl::set_device(connection_handler::DeviceHandle device) { - device_ = device; -} - uint32_t ApplicationImpl::get_grammar_id() const { return grammar_id_; } @@ -863,6 +866,10 @@ bool ApplicationImpl::is_application_data_changed() const { return is_application_data_changed_; } +void ApplicationImpl::SetInitialState(HmiStatePtr state) { + state_.InitState(state); +} + void ApplicationImpl::set_is_application_data_changed( bool state_application_data) { is_application_data_changed_ = state_application_data; diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc index b219635d46..65da6ed87e 100644 --- a/src/components/application_manager/src/application_manager_impl.cc +++ b/src/components/application_manager/src/application_manager_impl.cc @@ -93,9 +93,26 @@ DeviceTypes devicesType = { hmi_apis::Common_TransportType::USB_IOS), std::make_pair(std::string("BLUETOOTH"), hmi_apis::Common_TransportType::BLUETOOTH), + std::make_pair(std::string("IOS_BLUETOOTH"), + hmi_apis::Common_TransportType::BLUETOOTH), std::make_pair(std::string("WIFI"), hmi_apis::Common_TransportType::WIFI)}; } +bool device_id_comparator(const std::string& device_id, + ApplicationSharedPtr app) { + LOG4CXX_DEBUG(logger_, + "Data to compare: device_id : " << device_id << " app mac: " + << app->mac_address()); + + return device_id == app->mac_address(); +} + +bool policy_app_id_comparator(const std::string& policy_app_id, + ApplicationSharedPtr app) { + DCHECK_OR_RETURN(app, false); + return app->policy_app_id() == policy_app_id; +} + uint32_t ApplicationManagerImpl::corelation_id_ = 0; const uint32_t ApplicationManagerImpl::max_corelation_id_ = UINT_MAX; @@ -472,10 +489,10 @@ ApplicationSharedPtr ApplicationManagerImpl::RegisterApplication( // original app_id can be received via ApplicationImpl::mobile_app_id() uint32_t app_id = 0; std::list<int32_t> sessions_list; - uint32_t device_id = 0; + connection_handler::DeviceHandle device_id = 0; DCHECK_OR_RETURN(connection_handler_, ApplicationSharedPtr()); - if (connection_handler().GetDataOnSessionKey( + if (connection_handler().get_session_observer().GetDataOnSessionKey( connection_key, &app_id, &sessions_list, &device_id) == -1) { LOG4CXX_ERROR(logger_, "Failed to create application: no connection info."); utils::SharedPtr<smart_objects::SmartObject> response( @@ -488,6 +505,20 @@ ApplicationSharedPtr ApplicationManagerImpl::RegisterApplication( return ApplicationSharedPtr(); } + smart_objects::SmartObject& params = message[strings::msg_params]; + const std::string& policy_app_id = params[strings::app_id].asString(); + const custom_str::CustomString& app_name = + message[strings::msg_params][strings::app_name].asCustomString(); + std::string device_mac; + std::string connection_type; + if (connection_handler().get_session_observer().GetDataOnDeviceID( + device_id, NULL, NULL, &device_mac, &connection_type) == -1) { + LOG4CXX_DEBUG(logger_, "Failed to extract device mac for id " << device_id); + } else { + LOG4CXX_DEBUG(logger_, + "Device mac for id" << device_id << " is " << device_mac); + } + LOG4CXX_DEBUG(logger_, "Restarting application list update timer"); GetPolicyHandler().OnAppsSearchStarted(); uint32_t timeout = get_settings().application_list_update_timeout(); @@ -506,22 +537,11 @@ ApplicationSharedPtr ApplicationManagerImpl::RegisterApplication( return ApplicationSharedPtr(); } - smart_objects::SmartObject& params = message[strings::msg_params]; - const std::string& policy_app_id = params[strings::app_id].asString(); - const custom_str::CustomString& app_name = - message[strings::msg_params][strings::app_name].asCustomString(); - std::string device_mac = ""; - if (connection_handler().get_session_observer().GetDataOnDeviceID( - device_id, NULL, NULL, &device_mac, NULL) == -1) { - LOG4CXX_ERROR(logger_, "Failed to extract device mac for id " << device_id); - } else { - LOG4CXX_DEBUG(logger_, - "Device mac for id" << device_id << " is " << device_mac); - } ApplicationSharedPtr application( new ApplicationImpl(app_id, policy_app_id, device_mac, + device_id, app_name, GetPolicyHandler().GetStatisticManager(), *this)); @@ -536,12 +556,19 @@ ApplicationSharedPtr ApplicationManagerImpl::RegisterApplication( return ApplicationSharedPtr(); } + HmiStatePtr initial_state = + CreateRegularState(utils::SharedPtr<Application>(application), + mobile_apis::HMILevel::INVALID_ENUM, + mobile_apis::AudioStreamingState::INVALID_ENUM, + mobile_api::SystemContext::SYSCTXT_MAIN); + + application->SetInitialState(initial_state); + application->set_folder_name(policy_app_id + "_" + application->mac_address()); // To load persistent files, app folder name must be known first, which is now // depends on device_id and mobile_app_id application->LoadPersistentFiles(); - application->set_device(device_id); application->set_grammar_id(GenerateGrammarID()); mobile_api::Language::eType launguage_desired = @@ -788,11 +815,11 @@ void ApplicationManagerImpl::SetAllAppsAllowed(const bool allowed) { } HmiStatePtr ApplicationManagerImpl::CreateRegularState( - uint32_t app_id, + utils::SharedPtr<Application> app, mobile_apis::HMILevel::eType hmi_level, mobile_apis::AudioStreamingState::eType audio_state, mobile_apis::SystemContext::eType system_context) const { - HmiStatePtr state(new HmiState(app_id, *this)); + HmiStatePtr state(new HmiState(app, *this)); state->set_hmi_level(hmi_level); state->set_audio_streaming_state(audio_state); state->set_system_context(system_context); @@ -1044,6 +1071,61 @@ void ApplicationManagerImpl::RemoveDevice( LOG4CXX_DEBUG(logger_, "device_handle " << device_handle); } +void ApplicationManagerImpl::OnDeviceSwitchingStart( + const std::string& device_uid) { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock lock(reregister_wait_list_lock_); + auto apps_data_accessor = applications(); + + std::copy_if(apps_data_accessor.GetData().begin(), + apps_data_accessor.GetData().end(), + std::back_inserter(reregister_wait_list_), + std::bind1st(std::ptr_fun(&device_id_comparator), device_uid)); +} + +void ApplicationManagerImpl::OnDeviceSwitchFinish( + const std::string& device_uid) { + LOG4CXX_AUTO_TRACE(logger_); + UNUSED(device_uid); + sync_primitives::AutoLock lock(reregister_wait_list_lock_); + + const bool unexpected_disonnect = true; + const bool is_resuming = true; + for (auto app_it = reregister_wait_list_.begin(); + app_it != reregister_wait_list_.end(); + ++app_it) { + UnregisterApplication((*app_it)->app_id(), + mobile_apis::Result::INVALID_ENUM, + is_resuming, + unexpected_disonnect); + } + reregister_wait_list_.clear(); +} + +void ApplicationManagerImpl::SwitchApplication(ApplicationSharedPtr app, + const uint32_t connection_key, + const uint32_t device_id) { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock lock(applications_list_lock_); + DCHECK_OR_RETURN_VOID(1 == applications_.erase(app)); + + LOG4CXX_DEBUG(logger_, + "Changing app id to " << connection_key + << ". Changing device id to " + << device_id); + + SwitchApplicationParameters(app, connection_key, device_id); + + // Normally this is done during registration, however since switched apps are + // not being registered again need to set protocol version on session. + connection_handler().BindProtocolVersionWithSession( + connection_key, static_cast<uint8_t>(app->protocol_version())); + + // Application need to be re-inserted in order to keep sorting in applications + // container. Otherwise data loss on erasing is possible. + applications_.insert(app); +} + mobile_apis::HMILevel::eType ApplicationManagerImpl::GetDefaultHmiLevel( ApplicationConstSharedPtr application) const { using namespace mobile_apis; @@ -2589,10 +2671,10 @@ void ApplicationManagerImpl::CreateApplications(SmartArray& obj_array, const std::string app_icon_dir(settings_.app_icons_folder()); const std::string full_icon_path(app_icon_dir + "/" + policy_app_id); - uint32_t device_id = 0; + connection_handler::DeviceHandle device_id = 0; if (-1 == - connection_handler().GetDataOnSessionKey( + connection_handler().get_session_observer().GetDataOnSessionKey( connection_key, NULL, NULL, &device_id)) { LOG4CXX_ERROR(logger_, "Failed to create application: no connection info."); @@ -2614,6 +2696,7 @@ void ApplicationManagerImpl::CreateApplications(SmartArray& obj_array, new ApplicationImpl(0, policy_app_id, device_mac, + device_id, appName, GetPolicyHandler().GetStatisticManager(), *this)); @@ -2622,7 +2705,6 @@ void ApplicationManagerImpl::CreateApplications(SmartArray& obj_array, app->SetPackageName(package_name); app->set_app_icon_path(full_icon_path); app->set_hmi_application_id(hmi_app_id); - app->set_device(device_id); app->set_vr_synonyms(vrSynonym); app->set_tts_name(ttsName); @@ -2977,13 +3059,14 @@ void ApplicationManagerImpl::UnregisterApplication( ApplicationSharedPtr app_to_remove; connection_handler::DeviceHandle handle = 0; { - DataAccessor<ApplicationSet> accessor(applications()); - ApplicationSetConstIt it = accessor.GetData().begin(); - for (; it != accessor.GetData().end(); ++it) { - if ((*it)->app_id() == app_id) { - app_to_remove = *it; - handle = app_to_remove->device(); - break; + sync_primitives::AutoLock lock(applications_list_lock_); + auto it_app = applications_.begin(); + while (applications_.end() != it_app) { + if (app_id == (*it_app)->app_id()) { + app_to_remove = *it_app; + applications_.erase(it_app++); + } else { + ++it_app; } } if (!app_to_remove) { @@ -3001,11 +3084,10 @@ void ApplicationManagerImpl::UnregisterApplication( } else { resume_controller().RemoveApplicationFromSaved(app_to_remove); } - applications_.erase(app_to_remove); (hmi_capabilities_->get_hmi_language_handler()) .OnUnregisterApplication(app_id); AppV4DevicePredicate finder(handle); - ApplicationSharedPtr app = FindApp(accessor, finder); + ApplicationSharedPtr app = FindApp(applications(), finder); if (!app) { LOG4CXX_DEBUG( logger_, "There is no more SDL4 apps with device handle: " << handle); @@ -3236,8 +3318,9 @@ bool ApplicationManagerImpl::IsLowVoltage() { std::string ApplicationManagerImpl::GetHashedAppID( uint32_t connection_key, const std::string& mobile_app_id) const { - uint32_t device_id = 0; - connection_handler().GetDataOnSessionKey(connection_key, 0, NULL, &device_id); + connection_handler::DeviceHandle device_id = 0; + connection_handler().get_session_observer().GetDataOnSessionKey( + connection_key, 0, NULL, &device_id); std::string device_name; connection_handler().get_session_observer().GetDataOnDeviceID( device_id, &device_name, NULL, NULL, NULL); @@ -3598,6 +3681,18 @@ bool ApplicationManagerImpl::IsApplicationForbidden( return forbidden_applications.find(name) != forbidden_applications.end(); } +// TODO: check its usage +bool ApplicationManagerImpl::IsAppInReconnectMode( + const std::string& policy_app_id) const { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock lock(reregister_wait_list_lock_); + return reregister_wait_list_.end() != + std::find_if(reregister_wait_list_.begin(), + reregister_wait_list_.end(), + std::bind1st(std::ptr_fun(&policy_app_id_comparator), + policy_app_id)); +} + policy::DeviceConsent ApplicationManagerImpl::GetUserConsentForDevice( const std::string& device_id) const { return GetPolicyHandler().GetUserConsentForDevice(device_id); @@ -3881,6 +3976,52 @@ void ApplicationManagerImpl::OnUpdateHMIAppType( } } +void ApplicationManagerImpl::EraseAppFromReconnectionList( + const ApplicationSharedPtr& app) { + LOG4CXX_AUTO_TRACE(logger_); + if (!app) { + LOG4CXX_WARN(logger_, "Application is not valid."); + return; + } + + const auto policy_app_id = app->policy_app_id(); + sync_primitives::AutoLock lock(reregister_wait_list_lock_); + auto app_it = std::find_if( + reregister_wait_list_.begin(), + reregister_wait_list_.end(), + std::bind1st(std::ptr_fun(&policy_app_id_comparator), policy_app_id)); + if (reregister_wait_list_.end() != app_it) { + reregister_wait_list_.erase(app_it); + } +} + +void ApplicationManagerImpl::ProcessReconnection( + ApplicationSharedPtr application, const uint32_t connection_key) { + LOG4CXX_AUTO_TRACE(logger_); + DCHECK_OR_RETURN_VOID(application); + + connection_handler::DeviceHandle new_device_id = 0; + connection_handler().get_session_observer().GetDataOnSessionKey( + connection_key, NULL, NULL, &new_device_id); + DCHECK_OR_RETURN_VOID(new_device_id); + + std::string device_mac; + std::string connection_type; + connection_handler().get_session_observer().GetDataOnDeviceID( + new_device_id, NULL, NULL, &device_mac, &connection_type); + + DCHECK_OR_RETURN_VOID(application->mac_address() == device_mac); + + EraseAppFromReconnectionList(application); + + connection_handler().OnDeviceConnectionSwitched(device_mac); + + SwitchApplication(application, connection_key, new_device_id); + + // Update connection type for existed device. + GetPolicyHandler().AddDevice(device_mac, connection_type); +} + void ApplicationManagerImpl::OnPTUFinished(const bool ptu_result) { #ifdef SDL_REMOTE_CONTROL if (!ptu_result) { diff --git a/src/components/application_manager/src/commands/command_impl.cc b/src/components/application_manager/src/commands/command_impl.cc index 0a3e65a790..d17f6cdc10 100644 --- a/src/components/application_manager/src/commands/command_impl.cc +++ b/src/components/application_manager/src/commands/command_impl.cc @@ -94,18 +94,20 @@ void CommandImpl::SetAllowedToTerminate(const bool allowed) { allowed_to_terminate_ = allowed; } -void CommandImpl::ReplaceMobileByHMIAppId( +bool CommandImpl::ReplaceMobileByHMIAppId( NsSmartDeviceLink::NsSmartObjects::SmartObject& message) { if (message.keyExists(strings::app_id)) { ApplicationSharedPtr application = application_manager_.application(message[strings::app_id].asUInt()); - if (application.valid()) { - LOG4CXX_DEBUG(logger_, - "ReplaceMobileByHMIAppId from " - << message[strings::app_id].asInt() << " to " - << application->hmi_app_id()); - message[strings::app_id] = application->hmi_app_id(); + if (!application) { + LOG4CXX_ERROR(logger_, "Substitution mobile --> HMI id is failed."); + return false; } + LOG4CXX_DEBUG(logger_, + "ReplaceMobileByHMIAppId from " + << message[strings::app_id].asInt() << " to " + << application->hmi_app_id()); + message[strings::app_id] = application->hmi_app_id(); } else { switch (message.getType()) { case smart_objects::SmartType::SmartType_Array: { @@ -128,22 +130,26 @@ void CommandImpl::ReplaceMobileByHMIAppId( default: { break; } } } + + return true; } -void CommandImpl::ReplaceHMIByMobileAppId( +bool CommandImpl::ReplaceHMIByMobileAppId( NsSmartDeviceLink::NsSmartObjects::SmartObject& message) { if (message.keyExists(strings::app_id)) { ApplicationSharedPtr application = application_manager_.application_by_hmi_app( message[strings::app_id].asUInt()); - if (application.valid()) { - LOG4CXX_DEBUG(logger_, - "ReplaceHMIByMobileAppId from " - << message[strings::app_id].asInt() << " to " - << application->app_id()); - message[strings::app_id] = application->app_id(); + if (!application) { + LOG4CXX_ERROR(logger_, "Substitution HMI --> mobile id is failed."); + return false; } + LOG4CXX_DEBUG(logger_, + "ReplaceHMIByMobileAppId from " + << message[strings::app_id].asInt() << " to " + << application->app_id()); + message[strings::app_id] = application->app_id(); } else { switch (message.getType()) { case smart_objects::SmartType::SmartType_Array: { @@ -165,6 +171,8 @@ void CommandImpl::ReplaceHMIByMobileAppId( default: { break; } } } + + return true; } } // namespace commands diff --git a/src/components/application_manager/src/commands/hmi/notification_to_hmi.cc b/src/components/application_manager/src/commands/hmi/notification_to_hmi.cc index f1e933b7ef..7e24dce8d9 100644 --- a/src/components/application_manager/src/commands/hmi/notification_to_hmi.cc +++ b/src/components/application_manager/src/commands/hmi/notification_to_hmi.cc @@ -39,15 +39,12 @@ namespace commands { NotificationToHMI::NotificationToHMI(const MessageSharedPtr& message, ApplicationManager& application_manager) - : CommandImpl(message, application_manager) { - // Replace Mobile connection id with HMI app id - ReplaceMobileByHMIAppId(*(message.get())); -} + : CommandImpl(message, application_manager) {} NotificationToHMI::~NotificationToHMI() {} bool NotificationToHMI::Init() { - return true; + return ReplaceMobileByHMIAppId(*message_); } bool NotificationToHMI::CleanUp() { diff --git a/src/components/application_manager/src/commands/hmi/on_app_unregistered_notification.cc b/src/components/application_manager/src/commands/hmi/on_app_unregistered_notification.cc index 10ea1ea303..f64e3e111b 100644 --- a/src/components/application_manager/src/commands/hmi/on_app_unregistered_notification.cc +++ b/src/components/application_manager/src/commands/hmi/on_app_unregistered_notification.cc @@ -44,6 +44,12 @@ OnAppUnregisteredNotification::OnAppUnregisteredNotification( OnAppUnregisteredNotification::~OnAppUnregisteredNotification() {} +bool OnAppUnregisteredNotification::Init() { + LOG4CXX_AUTO_TRACE(logger_); + LOG4CXX_DEBUG(logger_, "Replacement of hmi id is skipped."); + return true; +} + void OnAppUnregisteredNotification::Run() { LOG4CXX_AUTO_TRACE(logger_); diff --git a/src/components/application_manager/src/commands/hmi/request_to_hmi.cc b/src/components/application_manager/src/commands/hmi/request_to_hmi.cc index 39d549ac72..f26dc26ef6 100644 --- a/src/components/application_manager/src/commands/hmi/request_to_hmi.cc +++ b/src/components/application_manager/src/commands/hmi/request_to_hmi.cc @@ -61,15 +61,12 @@ bool ChangeInterfaceState(ApplicationManager& application_manager, RequestToHMI::RequestToHMI(const MessageSharedPtr& message, ApplicationManager& application_manager) - : CommandImpl(message, application_manager) { - // Replace Mobile connection id with HMI app id - ReplaceMobileByHMIAppId(*(message.get())); -} + : CommandImpl(message, application_manager) {} RequestToHMI::~RequestToHMI() {} bool RequestToHMI::Init() { - return true; + return ReplaceMobileByHMIAppId(*message_); } bool RequestToHMI::CleanUp() { diff --git a/src/components/application_manager/src/commands/hmi/response_to_hmi.cc b/src/components/application_manager/src/commands/hmi/response_to_hmi.cc index e6f64047ba..77e523378a 100644 --- a/src/components/application_manager/src/commands/hmi/response_to_hmi.cc +++ b/src/components/application_manager/src/commands/hmi/response_to_hmi.cc @@ -39,15 +39,12 @@ namespace commands { ResponseToHMI::ResponseToHMI(const MessageSharedPtr& message, ApplicationManager& application_manager) - : CommandImpl(message, application_manager) { - // Replace Mobile connection id with HMI app id - ReplaceMobileByHMIAppId(*(message.get())); -} + : CommandImpl(message, application_manager) {} ResponseToHMI::~ResponseToHMI() {} bool ResponseToHMI::Init() { - return true; + return ReplaceMobileByHMIAppId(*message_); } bool ResponseToHMI::CleanUp() { diff --git a/src/components/application_manager/src/commands/mobile/register_app_interface_request.cc b/src/components/application_manager/src/commands/mobile/register_app_interface_request.cc index 1a60537874..1939150541 100644 --- a/src/components/application_manager/src/commands/mobile/register_app_interface_request.cc +++ b/src/components/application_manager/src/commands/mobile/register_app_interface_request.cc @@ -217,6 +217,13 @@ void RegisterAppInterfaceRequest::Run() { return; } + if (IsApplicationSwitched()) { + return; + } + + const std::string mobile_app_id = + (*message_)[strings::msg_params][strings::app_id].asString(); + ApplicationSharedPtr application = application_manager_.application(connection_key()); @@ -362,7 +369,7 @@ void RegisterAppInterfaceRequest::Run() { GetPolicyHandler().SetDeviceInfo(device_mac, device_info); - SendRegisterAppInterfaceResponseToMobile(); + SendRegisterAppInterfaceResponseToMobile(AppicationType::kNewApplication); smart_objects::SmartObjectSPtr so = GetLockScreenIconUrlNotification(connection_key(), application); application_manager_.ManageMobileCommand(so, commands::Command::ORIGIN_SDL); @@ -501,7 +508,8 @@ void FillUIRelatedFields(smart_objects::SmartObject& response_params, hmi_capabilities.rc_supported(); } -void RegisterAppInterfaceRequest::SendRegisterAppInterfaceResponseToMobile() { +void RegisterAppInterfaceRequest::SendRegisterAppInterfaceResponseToMobile( + AppicationType app_type) { LOG4CXX_AUTO_TRACE(logger_); smart_objects::SmartObject response_params(smart_objects::SmartType_Map); @@ -631,6 +639,14 @@ void RegisterAppInterfaceRequest::SendRegisterAppInterfaceResponseToMobile() { response_params[strings::system_software_version] = ccpu_version; } + if (AppicationType::kSwitchedApplication == app_type) { + LOG4CXX_DEBUG(logger_, + "Application has been switched from another transport."); + + SendResponse(true, result_code, NULL, &response_params); + return; + } + bool resumption = (*message_)[strings::msg_params].keyExists(strings::hash_id); @@ -1194,6 +1210,43 @@ void RegisterAppInterfaceRequest::SendSubscribeCustomButtonNotification() { CreateHMINotification(FunctionID::Buttons_OnButtonSubscription, msg_params); } +bool RegisterAppInterfaceRequest::IsApplicationSwitched() { + const smart_objects::SmartObject& msg_params = + (*message_)[strings::msg_params]; + + const std::string& policy_app_id = msg_params[strings::app_id].asString(); + + LOG4CXX_DEBUG(logger_, "Looking for application id " << policy_app_id); + + auto app = application_manager_.application_by_policy_id(policy_app_id); + + if (!app) { + LOG4CXX_DEBUG(logger_, + "Application with policy id " << policy_app_id + << " is not found."); + return false; + } + + LOG4CXX_DEBUG(logger_, + "Application with policy id " << policy_app_id << " is found."); + if (!application_manager_.IsAppInReconnectMode(policy_app_id)) { + LOG4CXX_DEBUG(logger_, + "Policy id " << policy_app_id + << " is not found in reconnection list."); + SendResponse(false, mobile_apis::Result::APPLICATION_REGISTERED_ALREADY); + return false; + } + + LOG4CXX_DEBUG(logger_, "Application is found in reconnection list."); + application_manager_.ProcessReconnection(app, connection_key()); + SendRegisterAppInterfaceResponseToMobile( + AppicationType::kSwitchedApplication); + + application_manager_.SendHMIStatusNotification(app); + + return true; +} + policy::PolicyHandlerInterface& RegisterAppInterfaceRequest::GetPolicyHandler() { return application_manager_.GetPolicyHandler(); diff --git a/src/components/application_manager/src/hmi_state.cc b/src/components/application_manager/src/hmi_state.cc index 393a9d7784..d31ff364ea 100644 --- a/src/components/application_manager/src/hmi_state.cc +++ b/src/components/application_manager/src/hmi_state.cc @@ -37,18 +37,19 @@ namespace application_manager { -HmiState::HmiState(uint32_t app_id, +HmiState::HmiState(utils::SharedPtr<Application> app, const ApplicationManager& app_mngr, StateID state_id) - : app_id_(app_id) + : app_(app) , state_id_(state_id) , app_mngr_(app_mngr) , hmi_level_(mobile_apis::HMILevel::INVALID_ENUM) , audio_streaming_state_(mobile_apis::AudioStreamingState::INVALID_ENUM) , system_context_(mobile_apis::SystemContext::INVALID_ENUM) {} -HmiState::HmiState(uint32_t app_id, const ApplicationManager& app_mngr) - : app_id_(app_id) +HmiState::HmiState(utils::SharedPtr<Application> app, + const ApplicationManager& app_mngr) + : app_(app) , state_id_(STATE_ID_REGULAR) , app_mngr_(app_mngr) , hmi_level_(mobile_apis::HMILevel::INVALID_ENUM) @@ -60,24 +61,20 @@ void HmiState::set_parent(HmiStatePtr parent) { parent_ = parent; } -bool HmiState::is_navi_app(const uint32_t app_id) const { - const ApplicationSharedPtr app = app_mngr_.application(app_id); - return app ? app->is_navi() : false; +bool HmiState::is_navi_app() const { + return app_->is_navi(); } -bool HmiState::is_media_app(const uint32_t app_id) const { - const ApplicationSharedPtr app = app_mngr_.application(app_id); - return app ? app->is_media_application() : false; +bool HmiState::is_media_app() const { + return app_->is_media_application(); } -bool HmiState::is_voice_communication_app(const uint32_t app_id) const { - const ApplicationSharedPtr app = app_mngr_.application(app_id); - return app ? app->is_voice_communication_supported() : false; +bool HmiState::is_voice_communication_app() const { + return app_->is_voice_communication_supported(); } -bool HmiState::is_mobile_projection_app(const uint32_t app_id) const { - const ApplicationSharedPtr app = app_mngr_.application(app_id); - return app ? app->mobile_projection_enabled() : false; +bool HmiState::is_mobile_projection_app() const { + return app_->mobile_projection_enabled(); } mobile_apis::AudioStreamingState::eType VRHmiState::audio_streaming_state() @@ -86,11 +83,13 @@ mobile_apis::AudioStreamingState::eType VRHmiState::audio_streaming_state() return AudioStreamingState::NOT_AUDIBLE; } -VRHmiState::VRHmiState(uint32_t app_id, const ApplicationManager& app_mngr) - : HmiState(app_id, app_mngr, STATE_ID_VR_SESSION) {} +VRHmiState::VRHmiState(utils::SharedPtr<Application> app, + const ApplicationManager& app_mngr) + : HmiState(app, app_mngr, STATE_ID_VR_SESSION) {} -TTSHmiState::TTSHmiState(uint32_t app_id, const ApplicationManager& app_mngr) - : HmiState(app_id, app_mngr, STATE_ID_TTS_SESSION) {} +TTSHmiState::TTSHmiState(utils::SharedPtr<Application> app, + const ApplicationManager& app_mngr) + : HmiState(app, app_mngr, STATE_ID_TTS_SESSION) {} mobile_apis::AudioStreamingState::eType TTSHmiState::audio_streaming_state() const { @@ -107,9 +106,9 @@ mobile_apis::AudioStreamingState::eType TTSHmiState::audio_streaming_state() return expected_state; } -NaviStreamingHmiState::NaviStreamingHmiState(uint32_t app_id, +NaviStreamingHmiState::NaviStreamingHmiState(utils::SharedPtr<Application> app, const ApplicationManager& app_mngr) - : HmiState(app_id, app_mngr, STATE_ID_NAVI_STREAMING) {} + : HmiState(app, app_mngr, STATE_ID_NAVI_STREAMING) {} mobile_apis::AudioStreamingState::eType NaviStreamingHmiState::audio_streaming_state() const { @@ -117,7 +116,7 @@ NaviStreamingHmiState::audio_streaming_state() const { using namespace mobile_apis; AudioStreamingState::eType expected_state = parent()->audio_streaming_state(); - if (!is_navi_app(app_id_) && AudioStreamingState::AUDIBLE == expected_state) { + if (!is_navi_app() && AudioStreamingState::AUDIBLE == expected_state) { if (app_mngr_.is_attenuated_supported()) { expected_state = AudioStreamingState::ATTENUATED; } else { @@ -127,9 +126,9 @@ NaviStreamingHmiState::audio_streaming_state() const { return expected_state; } -PhoneCallHmiState::PhoneCallHmiState(uint32_t app_id, +PhoneCallHmiState::PhoneCallHmiState(utils::SharedPtr<Application> app, const ApplicationManager& app_mngr) - : HmiState(app_id, app_mngr, STATE_ID_PHONE_CALL) {} + : HmiState(app, app_mngr, STATE_ID_PHONE_CALL) {} mobile_apis::HMILevel::eType PhoneCallHmiState::hmi_level() const { using namespace helpers; @@ -139,22 +138,22 @@ mobile_apis::HMILevel::eType PhoneCallHmiState::hmi_level() const { HMILevel::HMI_NONE)) { return parent()->hmi_level(); } - if (is_navi_app(app_id_) || is_mobile_projection_app(app_id_)) { + if (is_navi_app() || is_mobile_projection_app()) { return HMILevel::HMI_LIMITED; } - if (!is_media_app(app_id_)) { + if (!is_media_app()) { return parent()->hmi_level(); } return HMILevel::HMI_BACKGROUND; } -SafetyModeHmiState::SafetyModeHmiState(uint32_t app_id, +SafetyModeHmiState::SafetyModeHmiState(utils::SharedPtr<Application> app, const ApplicationManager& app_mngr) - : HmiState(app_id, app_mngr, STATE_ID_SAFETY_MODE) {} + : HmiState(app, app_mngr, STATE_ID_SAFETY_MODE) {} -DeactivateHMI::DeactivateHMI(uint32_t app_id, +DeactivateHMI::DeactivateHMI(utils::SharedPtr<Application> app, const ApplicationManager& app_mngr) - : HmiState(app_id, app_mngr, STATE_ID_DEACTIVATE_HMI) {} + : HmiState(app, app_mngr, STATE_ID_DEACTIVATE_HMI) {} mobile_apis::HMILevel::eType DeactivateHMI::hmi_level() const { using namespace helpers; @@ -167,8 +166,9 @@ mobile_apis::HMILevel::eType DeactivateHMI::hmi_level() const { return HMILevel::HMI_BACKGROUND; } -AudioSource::AudioSource(uint32_t app_id, const ApplicationManager& app_mngr) - : HmiState(app_id, app_mngr, STATE_ID_AUDIO_SOURCE) {} +AudioSource::AudioSource(utils::SharedPtr<Application> app, + const ApplicationManager& app_mngr) + : HmiState(app, app_mngr, STATE_ID_AUDIO_SOURCE) {} mobile_apis::HMILevel::eType AudioSource::hmi_level() const { using namespace mobile_apis; @@ -181,14 +181,15 @@ mobile_apis::HMILevel::eType AudioSource::hmi_level() const { HMILevel::HMI_NONE)) { return parent()->hmi_level(); } - if (is_navi_app(app_id_) || is_voice_communication_app(app_id_)) { + if (is_navi_app() || is_voice_communication_app()) { return HMILevel::HMI_LIMITED; } return HMILevel::HMI_BACKGROUND; } -EmbeddedNavi::EmbeddedNavi(uint32_t app_id, const ApplicationManager& app_mngr) - : HmiState(app_id, app_mngr, STATE_ID_EMBEDDED_NAVI) {} +EmbeddedNavi::EmbeddedNavi(utils::SharedPtr<Application> app, + const ApplicationManager& app_mngr) + : HmiState(app, app_mngr, STATE_ID_EMBEDDED_NAVI) {} mobile_apis::HMILevel::eType EmbeddedNavi::hmi_level() const { using namespace mobile_apis; @@ -198,7 +199,7 @@ mobile_apis::HMILevel::eType EmbeddedNavi::hmi_level() const { HMILevel::HMI_NONE)) { return parent()->hmi_level(); } - if (is_media_app(app_id_)) { + if (is_media_app()) { return HMILevel::HMI_LIMITED; } return HMILevel::HMI_BACKGROUND; diff --git a/src/components/application_manager/src/policies/policy_handler.cc b/src/components/application_manager/src/policies/policy_handler.cc index e6ebaf3b83..570aee180c 100644 --- a/src/components/application_manager/src/policies/policy_handler.cc +++ b/src/components/application_manager/src/policies/policy_handler.cc @@ -1170,7 +1170,7 @@ void PolicyHandler::OnAllowSDLFunctionalityNotification( continue; } policy_manager_->SetUserConsentForDevice(device_id, is_allowed); - uint32_t device_handle = 0; + connection_handler::DeviceHandle device_handle = 0; if (!connection_handler.GetDeviceID(device_id, &device_handle)) { LOG4CXX_WARN(logger_, "Device handle with mac " << device_id @@ -1204,7 +1204,7 @@ void PolicyHandler::OnAllowSDLFunctionalityNotification( } // Case, when specific device was changed - uint32_t device_handle = 0u; + connection_handler::DeviceHandle device_handle = 0u; if (device_specific) { policy_manager_->SetUserConsentForDevice(device_mac, is_allowed); if (!connection_handler.GetDeviceID(device_mac, &device_handle)) { diff --git a/src/components/application_manager/src/state_controller_impl.cc b/src/components/application_manager/src/state_controller_impl.cc index b456ff6abb..84081a3830 100644 --- a/src/components/application_manager/src/state_controller_impl.cc +++ b/src/components/application_manager/src/state_controller_impl.cc @@ -123,7 +123,7 @@ void StateControllerImpl::SetRegularState( HmiStatePtr prev_regular = app->RegularHmiState(); DCHECK_OR_RETURN_VOID(prev_regular); HmiStatePtr hmi_state = - CreateHmiState(app->app_id(), HmiState::StateID::STATE_ID_REGULAR); + CreateHmiState(app, HmiState::StateID::STATE_ID_REGULAR); DCHECK_OR_RETURN_VOID(hmi_state); hmi_state->set_hmi_level(hmi_level); hmi_state->set_audio_streaming_state(audio_state); @@ -144,7 +144,7 @@ void StateControllerImpl::SetRegularState( return; } const HmiStatePtr hmi_state = - CreateHmiState(app->app_id(), HmiState::StateID::STATE_ID_REGULAR); + CreateHmiState(app, HmiState::StateID::STATE_ID_REGULAR); DCHECK_OR_RETURN_VOID(hmi_state); hmi_state->set_hmi_level(hmi_level); @@ -166,7 +166,7 @@ void StateControllerImpl::SetRegularState( return; } HmiStatePtr hmi_state = - CreateHmiState(app->app_id(), HmiState::StateID::STATE_ID_REGULAR); + CreateHmiState(app, HmiState::StateID::STATE_ID_REGULAR); DCHECK_OR_RETURN_VOID(hmi_state); hmi_state->set_hmi_level(hmi_level); hmi_state->set_audio_streaming_state(audio_state); @@ -184,7 +184,7 @@ void StateControllerImpl::SetRegularState( } HmiStatePtr prev_state = app->RegularHmiState(); HmiStatePtr hmi_state = - CreateHmiState(app->app_id(), HmiState::StateID::STATE_ID_REGULAR); + CreateHmiState(app, HmiState::StateID::STATE_ID_REGULAR); DCHECK_OR_RETURN_VOID(hmi_state); hmi_state->set_hmi_level(hmi_level); hmi_state->set_audio_streaming_state(CalcAudioState(app, hmi_level)); @@ -206,7 +206,7 @@ void StateControllerImpl::SetRegularState( HmiStatePtr prev_regular = app->RegularHmiState(); DCHECK_OR_RETURN_VOID(prev_regular); HmiStatePtr hmi_state = - CreateHmiState(app->app_id(), HmiState::StateID::STATE_ID_REGULAR); + CreateHmiState(app, HmiState::StateID::STATE_ID_REGULAR); DCHECK_OR_RETURN_VOID(hmi_state); hmi_state->set_hmi_level(prev_regular->hmi_level()); hmi_state->set_audio_streaming_state( @@ -227,7 +227,7 @@ void StateControllerImpl::SetRegularState( HmiStatePtr prev_state = app->RegularHmiState(); DCHECK_OR_RETURN_VOID(prev_state); HmiStatePtr hmi_state = - CreateHmiState(app->app_id(), HmiState::StateID::STATE_ID_REGULAR); + CreateHmiState(app, HmiState::StateID::STATE_ID_REGULAR); DCHECK_OR_RETURN_VOID(hmi_state); hmi_state->set_hmi_level(prev_state->hmi_level()); hmi_state->set_audio_streaming_state(audio_state); @@ -325,7 +325,7 @@ HmiStatePtr StateControllerImpl::ResolveHmiState(ApplicationSharedPtr app, << state->system_context()); HmiStatePtr available_state = - CreateHmiState(app->app_id(), HmiState::StateID::STATE_ID_REGULAR); + CreateHmiState(app, HmiState::StateID::STATE_ID_REGULAR); DCHECK_OR_RETURN(available_state, HmiStatePtr()); available_state->set_hmi_level(state->hmi_level()); available_state->set_audio_streaming_state(state->audio_streaming_state()); @@ -502,7 +502,7 @@ void StateControllerImpl::SetupRegularHmiState(ApplicationSharedPtr app, << ", system_context " << state->system_context()); HmiStatePtr curr_state = app->CurrentHmiState(); HmiStatePtr old_state = - CreateHmiState(app->app_id(), HmiState::StateID::STATE_ID_REGULAR); + CreateHmiState(app, HmiState::StateID::STATE_ID_REGULAR); DCHECK_OR_RETURN_VOID(old_state); old_state->set_hmi_level(curr_state->hmi_level()); old_state->set_audio_streaming_state(curr_state->audio_streaming_state()); @@ -533,7 +533,7 @@ void StateControllerImpl::SetupRegularHmiState( HmiStatePtr prev_state = app->RegularHmiState(); DCHECK_OR_RETURN_VOID(prev_state); HmiStatePtr new_state = - CreateHmiState(app->app_id(), HmiState::StateID::STATE_ID_REGULAR); + CreateHmiState(app, HmiState::StateID::STATE_ID_REGULAR); DCHECK_OR_RETURN_VOID(new_state); new_state->set_hmi_level(hmi_level); new_state->set_audio_streaming_state(audio_state); @@ -716,7 +716,7 @@ void StateControllerImpl::OnApplicationRegistered( active_states_lock_.Acquire(); StateIDList::iterator it = active_states_.begin(); for (; it != active_states_.end(); ++it) { - HmiStatePtr new_state = CreateHmiState(app->app_id(), *it); + HmiStatePtr new_state = CreateHmiState(app, *it); DCHECK_OR_RETURN_VOID(new_state); DCHECK_OR_RETURN_VOID(new_state->state_id() != HmiState::STATE_ID_REGULAR); HmiStatePtr old_hmi_state = app->CurrentHmiState(); @@ -726,7 +726,7 @@ void StateControllerImpl::OnApplicationRegistered( active_states_lock_.Release(); HmiStatePtr default_state = - CreateHmiState(app->app_id(), HmiState::StateID::STATE_ID_REGULAR); + CreateHmiState(app, HmiState::StateID::STATE_ID_REGULAR); DCHECK_OR_RETURN_VOID(default_state); default_state->set_hmi_level(default_level); default_state->set_audio_streaming_state(CalcAudioState(app, default_level)); @@ -896,49 +896,49 @@ bool StateControllerImpl::IsStateActive(HmiState::StateID state_id) const { } HmiStatePtr StateControllerImpl::CreateHmiState( - uint32_t app_id, HmiState::StateID state_id) const { + utils::SharedPtr<Application> app, HmiState::StateID state_id) const { using namespace utils; LOG4CXX_AUTO_TRACE(logger_); HmiStatePtr new_state; switch (state_id) { case HmiState::STATE_ID_PHONE_CALL: { - new_state = MakeShared<PhoneCallHmiState>(app_id, app_mngr_); + new_state = MakeShared<PhoneCallHmiState>(app, app_mngr_); break; } case HmiState::STATE_ID_SAFETY_MODE: { - new_state = MakeShared<SafetyModeHmiState>(app_id, app_mngr_); + new_state = MakeShared<SafetyModeHmiState>(app, app_mngr_); break; } case HmiState::STATE_ID_VR_SESSION: { - new_state = MakeShared<VRHmiState>(app_id, app_mngr_); + new_state = MakeShared<VRHmiState>(app, app_mngr_); break; } case HmiState::STATE_ID_TTS_SESSION: { - new_state = MakeShared<TTSHmiState>(app_id, app_mngr_); + new_state = MakeShared<TTSHmiState>(app, app_mngr_); break; } case HmiState::STATE_ID_NAVI_STREAMING: { - new_state = MakeShared<NaviStreamingHmiState>(app_id, app_mngr_); + new_state = MakeShared<NaviStreamingHmiState>(app, app_mngr_); break; } case HmiState::STATE_ID_REGULAR: { - new_state = MakeShared<HmiState>(app_id, app_mngr_); + new_state = MakeShared<HmiState>(app, app_mngr_); break; } case HmiState::STATE_ID_POSTPONED: { - new_state = MakeShared<HmiState>(app_id, app_mngr_, state_id); + new_state = MakeShared<HmiState>(app, app_mngr_, state_id); break; } case HmiState::STATE_ID_DEACTIVATE_HMI: { - new_state = MakeShared<DeactivateHMI>(app_id, app_mngr_); + new_state = MakeShared<DeactivateHMI>(app, app_mngr_); break; } case HmiState::STATE_ID_AUDIO_SOURCE: { - new_state = MakeShared<AudioSource>(app_id, app_mngr_); + new_state = MakeShared<AudioSource>(app, app_mngr_); break; } case HmiState::STATE_ID_EMBEDDED_NAVI: { - new_state = MakeShared<EmbeddedNavi>(app_id, app_mngr_); + new_state = MakeShared<EmbeddedNavi>(app, app_mngr_); break; } default: diff --git a/src/components/config_profile/include/config_profile/profile.h b/src/components/config_profile/include/config_profile/profile.h index 67ec9368bc..61dddf55b0 100644 --- a/src/components/config_profile/include/config_profile/profile.h +++ b/src/components/config_profile/include/config_profile/profile.h @@ -656,6 +656,18 @@ class Profile : public protocol_handler::ProtocolHandlerSettings, const bool enable_app_launch_ios() const OVERRIDE; /** + * @brief Returns the millisecond count before timeout + * for transport change feature occures. + */ + uint32_t app_transport_change_timer() const OVERRIDE; + + /** + * @brief Returns the millisecond count used as addition + * value for transport change timer + */ + uint32_t app_transport_change_timer_addition() const OVERRIDE; + + /** * @brief Updates all related values from ini file */ void UpdateValues(); @@ -914,6 +926,8 @@ class Profile : public protocol_handler::ProtocolHandlerSettings, uint16_t max_number_of_ios_device_; uint16_t wait_time_between_apps_; bool enable_app_launch_ios_; + uint32_t app_tranport_change_timer_; + uint32_t app_tranport_change_timer_addition_; bool error_occured_; std::string error_description_; diff --git a/src/components/config_profile/src/profile.cc b/src/components/config_profile/src/profile.cc index 6389375bb8..4137476d63 100644 --- a/src/components/config_profile/src/profile.cc +++ b/src/components/config_profile/src/profile.cc @@ -211,6 +211,9 @@ const char* kRemoveBundleIDattemptsKey = "RemoveBundleIDattempts"; const char* kMaxNumberOfiOSDeviceKey = "MaxNumberOfiOSDevice"; const char* kWaitTimeBetweenAppsKey = "WaitTimeBetweenApps"; const char* kEnableAppLaunchIOSKey = "EnableAppLaunchIOS"; +const char* kAppTransportChangeTimerKey = "AppTransportChangeTimer"; +const char* kAppTransportChangeTimerAdditionKey = + "AppTransportChangeTimerAddition"; #ifdef WEB_HMI const char* kDefaultLinkToWebHMI = "HMI/index.html"; #endif // WEB_HMI @@ -304,6 +307,8 @@ const uint16_t kDefaultRemoveBundleIDattempts = 3; const uint16_t kDefaultMaxNumberOfiOSDevice = 10; const uint16_t kDefaultWaitTimeBetweenApps = 4000; const bool kDefaultEnableAppLaunchIOS = true; +const uint32_t kDefaultAppTransportChangeTimer = 500u; +const uint32_t kDefaultAppTransportChangeTimerAddition = 0u; const std::string kAllowedSymbols = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_.-"; } // namespace @@ -405,6 +410,9 @@ Profile::Profile() , max_number_of_ios_device_(kDefaultMaxNumberOfiOSDevice) , wait_time_between_apps_(kDefaultWaitTimeBetweenApps) , enable_app_launch_ios_(kDefaultEnableAppLaunchIOS) + , app_tranport_change_timer_(kDefaultAppTransportChangeTimer) + , app_tranport_change_timer_addition_( + kDefaultAppTransportChangeTimerAddition) , error_occured_(false) , error_description_() { // SDL version @@ -907,6 +915,14 @@ const bool Profile::enable_app_launch_ios() const { return enable_app_launch_ios_; } +uint32_t Profile::app_transport_change_timer() const { + return app_tranport_change_timer_; +} + +uint32_t Profile::app_transport_change_timer_addition() const { + return app_tranport_change_timer_addition_; +} + const uint16_t Profile::max_number_of_ios_device() const { return max_number_of_ios_device_; } @@ -1884,6 +1900,23 @@ void Profile::UpdateValues() { LOG_UPDATED_BOOL_VALUE( enable_app_launch_ios_, kEnableAppLaunchIOSKey, kAppLaunchSection); + + ReadUIntValue(&app_tranport_change_timer_, + kDefaultAppTransportChangeTimer, + kMainSection, + kAppTransportChangeTimerKey); + + LOG_UPDATED_VALUE( + app_tranport_change_timer_, kAppTransportChangeTimerKey, kMainSection); + + ReadUIntValue(&app_tranport_change_timer_addition_, + kDefaultAppTransportChangeTimerAddition, + kMainSection, + kAppTransportChangeTimerAdditionKey); + + LOG_UPDATED_VALUE(app_tranport_change_timer_addition_, + kAppTransportChangeTimerAdditionKey, + kMainSection); } bool Profile::ReadValue(bool* value, diff --git a/src/components/connection_handler/include/connection_handler/connection_handler_impl.h b/src/components/connection_handler/include/connection_handler/connection_handler_impl.h index 47e573a06d..6638b6f9f7 100644 --- a/src/components/connection_handler/include/connection_handler/connection_handler_impl.h +++ b/src/components/connection_handler/include/connection_handler/connection_handler_impl.h @@ -137,6 +137,13 @@ class ConnectionHandlerImpl void OnDeviceRemoved( const transport_manager::DeviceInfo& device_info) OVERRIDE; + void OnDeviceSwitchingStart(const std::string& device_uid) FINAL; + + void OnDeviceSwitchFinish( + const transport_manager::DeviceUID& device_uid) FINAL; + + void OnDeviceConnectionSwitched(const std::string& device_mac) FINAL; + void OnScanDevicesFinished() OVERRIDE; void OnScanDevicesFailed( const transport_manager::SearchDeviceError& error) OVERRIDE; @@ -461,10 +468,19 @@ class ConnectionHandlerImpl uint8_t session_id, uint8_t& protocol_version) const OVERRIDE; - int32_t GetDataOnSessionKey(uint32_t key, - uint32_t* app_id, - std::list<int32_t>* sessions_list, - uint32_t* device_id) const OVERRIDE; + /** + * \brief information about given Connection Key. + * \param key Unique key used by other components as session identifier + * \param app_id Returned: ApplicationID + * \param sessions_list Returned: List of session keys + * \param device_id Returned: DeviceID + * \return int32_t -1 in case of error or 0 in case of success + */ + int32_t GetDataOnSessionKey( + uint32_t key, + uint32_t* app_id, + std::list<int32_t>* sessions_list, + connection_handler::DeviceHandle* device_id) const OVERRIDE; const ConnectionHandlerSettings& get_settings() const OVERRIDE; diff --git a/src/components/connection_handler/include/connection_handler/device.h b/src/components/connection_handler/include/connection_handler/device.h index cee0bf8875..26376c1d8d 100644 --- a/src/components/connection_handler/include/connection_handler/device.h +++ b/src/components/connection_handler/include/connection_handler/device.h @@ -36,6 +36,7 @@ #include <string> #include <map> #include <vector> +#include "transport_manager/common.h" /** * \namespace connection_handler @@ -46,7 +47,7 @@ namespace connection_handler { /** * \brief Type for DeviceHandle */ -typedef uint32_t DeviceHandle; +typedef transport_manager::DeviceHandle DeviceHandle; typedef std::vector<int32_t> AppList; /** @@ -112,6 +113,6 @@ class Device { /** * \brief Type for Devices map */ -typedef std::map<int32_t, Device> DeviceMap; +typedef std::map<DeviceHandle, Device> DeviceMap; } // namespace connection_handler #endif // SRC_COMPONENTS_CONNECTION_HANDLER_INCLUDE_CONNECTION_HANDLER_DEVICE_H_ diff --git a/src/components/connection_handler/src/connection_handler_impl.cc b/src/components/connection_handler/src/connection_handler_impl.cc index 254bb0194f..bba901e16d 100644 --- a/src/components/connection_handler/src/connection_handler_impl.cc +++ b/src/components/connection_handler/src/connection_handler_impl.cc @@ -38,6 +38,7 @@ #include "connection_handler/connection_handler_impl.h" #include "transport_manager/info.h" +#include "encryption/hashing.h" #ifdef ENABLE_SECURITY #include "security_manager/security_manager.h" @@ -136,15 +137,21 @@ void ConnectionHandlerImpl::OnDeviceFound( void ConnectionHandlerImpl::OnDeviceAdded( const transport_manager::DeviceInfo& device_info) { LOG4CXX_AUTO_TRACE(logger_); - device_list_.insert( - DeviceMap::value_type(device_info.device_handle(), - Device(device_info.device_handle(), - device_info.name(), - device_info.mac_address(), - device_info.connection_type()))); - sync_primitives::AutoReadLock read_lock(connection_handler_observer_lock_); - if (connection_handler_observer_) { - connection_handler_observer_->OnDeviceListUpdated(device_list_); + auto handle = device_info.device_handle(); + + Device device(handle, + device_info.name(), + device_info.mac_address(), + device_info.connection_type()); + + auto result = device_list_.insert(std::make_pair(handle, device)); + + if (!result.second) { + LOG4CXX_ERROR(logger_, + "Device with handle " << handle + << " is known already. " + "Information won't be updated."); + return; } } @@ -182,6 +189,24 @@ void ConnectionHandlerImpl::OnDeviceRemoved( device_list_.erase(device_info.device_handle()); } +void ConnectionHandlerImpl::OnDeviceSwitchFinish( + const transport_manager::DeviceUID& device_uid) { + sync_primitives::AutoReadLock read_lock(connection_handler_observer_lock_); + if (connection_handler_observer_) { + connection_handler_observer_->OnDeviceSwitchFinish( + encryption::MakeHash(device_uid)); + } +} + +void ConnectionHandlerImpl::OnDeviceSwitchingStart( + const std::string& device_uid) { + sync_primitives::AutoReadLock read_lock(connection_handler_observer_lock_); + if (connection_handler_observer_) { + connection_handler_observer_->OnDeviceSwitchingStart( + encryption::MakeHash(device_uid)); + } +} + void ConnectionHandlerImpl::OnScanDevicesFinished() { LOG4CXX_AUTO_TRACE(logger_); } @@ -646,7 +671,7 @@ int32_t ConnectionHandlerImpl::GetDataOnSessionKey( uint32_t key, uint32_t* app_id, std::list<int32_t>* sessions_list, - uint32_t* device_id) const { + transport_manager::DeviceHandle* device_id) const { LOG4CXX_AUTO_TRACE(logger_); const int32_t error_result = -1; @@ -888,6 +913,19 @@ void ConnectionHandlerImpl::RunAppOnDevice(const std::string& device_mac, LOG4CXX_WARN(logger_, "No apps found on device " << device_mac); } +void ConnectionHandlerImpl::OnDeviceConnectionSwitched( + const std::string& device_mac) { + LOG4CXX_AUTO_TRACE(logger_); + auto device_it = device_list_.begin(); + for (; device_it != device_list_.end(); ++device_it) { + const connection_handler::Device& device = device_it->second; + if (device.mac_address() == device_mac) { + transport_manager_.OnDeviceConnectionSwitched(device.device_handle()); + return; + } + } +} + void ConnectionHandlerImpl::ConnectToAllDevices() { for (DeviceMap::iterator i = device_list_.begin(); i != device_list_.end(); ++i) { diff --git a/src/components/include/application_manager/application_manager.h b/src/components/include/application_manager/application_manager.h index 15a9f39348..e0c3414bce 100644 --- a/src/components/include/application_manager/application_manager.h +++ b/src/components/include/application_manager/application_manager.h @@ -313,6 +313,17 @@ class ApplicationManager { virtual void ProcessQueryApp(const smart_objects::SmartObject& sm_object, const uint32_t connection_key) = 0; + /** + * @brief ProcessReconnection handles reconnection flow for application on + * transport switch + * @param application Pointer to switched application, must be validated + * before passing + * @param connection_key Connection key from registration request of switched + * application + */ + virtual void ProcessReconnection(ApplicationSharedPtr application, + const uint32_t connection_key) = 0; + virtual bool is_attenuated_supported() const = 0; /** @@ -534,6 +545,8 @@ class ApplicationManager { virtual bool IsApplicationForbidden( uint32_t connection_key, const std::string& policy_app_id) const = 0; + virtual bool IsAppInReconnectMode(const std::string& policy_app_id) const = 0; + virtual resumption::ResumeCtrl& resume_controller() = 0; /** @@ -594,14 +607,14 @@ class ApplicationManager { /** * @brief CreateRegularState create regular HMI state for application - * @param app_id + * @param app Application * @param hmi_level of returned state * @param audio_state of returned state * @param system_context of returned state * @return new regular HMI state */ virtual HmiStatePtr CreateRegularState( - uint32_t app_id, + utils::SharedPtr<Application> app, mobile_apis::HMILevel::eType hmi_level, mobile_apis::AudioStreamingState::eType audio_state, mobile_apis::SystemContext::eType system_context) const = 0; diff --git a/src/components/include/connection_handler/connection_handler.h b/src/components/include/connection_handler/connection_handler.h index c70861b5f6..678f8e8fab 100644 --- a/src/components/include/connection_handler/connection_handler.h +++ b/src/components/include/connection_handler/connection_handler.h @@ -80,6 +80,8 @@ class ConnectionHandler { virtual void RunAppOnDevice(const std::string& device_handle, const std::string& bundle_id) const = 0; + virtual void OnDeviceConnectionSwitched(const std::string& device_mac) = 0; + virtual void ConnectToAllDevices() = 0; /** @@ -168,18 +170,6 @@ class ConnectionHandler { uint8_t protocol_version) = 0; /** - * \brief information about given Connection Key. - * \param key Unique key used by other components as session identifier - * \param app_id Returned: ApplicationID - * \param sessions_list Returned: List of session keys - * \param device_id Returned: DeviceID - * \return int32_t -1 in case of error or 0 in case of success - */ - virtual int32_t GetDataOnSessionKey(uint32_t key, - uint32_t* app_id, - std::list<int32_t>* sessions_list, - uint32_t* device_id) const = 0; - /** * @brief GetConnectedDevicesMAC allows to obtain MAC adresses for all * currently connected devices. * diff --git a/src/components/include/connection_handler/connection_handler_observer.h b/src/components/include/connection_handler/connection_handler_observer.h index 6bfc78af24..f06c72bd7b 100644 --- a/src/components/include/connection_handler/connection_handler_observer.h +++ b/src/components/include/connection_handler/connection_handler_observer.h @@ -33,6 +33,7 @@ #ifndef SRC_COMPONENTS_INCLUDE_CONNECTION_HANDLER_CONNECTION_HANDLER_OBSERVER_H_ #define SRC_COMPONENTS_INCLUDE_CONNECTION_HANDLER_CONNECTION_HANDLER_OBSERVER_H_ +#include <string> #include "connection_handler/device.h" #include "connection_handler/connection.h" #include "connection_handler/connection_handler.h" @@ -123,6 +124,10 @@ class ConnectionHandlerObserver { const protocol_handler::ServiceType& type, const connection_handler::CloseSessionReason& close_reason) = 0; + virtual void OnDeviceSwitchingStart(const std::string& device_uid) = 0; + + virtual void OnDeviceSwitchFinish(const std::string& device_uid) = 0; + #ifdef ENABLE_SECURITY virtual security_manager::SSLContext::HandshakeContext GetHandshakeContext( uint32_t key) const = 0; diff --git a/src/components/include/protocol_handler/session_observer.h b/src/components/include/protocol_handler/session_observer.h index 7ac7a84d6d..e84172524a 100644 --- a/src/components/include/protocol_handler/session_observer.h +++ b/src/components/include/protocol_handler/session_observer.h @@ -183,10 +183,11 @@ class SessionObserver { * \param device_id Returned: DeviceID * \return int32_t -1 in case of error or 0 in case of success */ - virtual int32_t GetDataOnSessionKey(uint32_t key, - uint32_t* app_id, - std::list<int32_t>* sessions_list, - uint32_t* device_id) const = 0; + virtual int32_t GetDataOnSessionKey( + uint32_t key, + uint32_t* app_id, + std::list<int32_t>* sessions_list, + transport_manager::DeviceHandle* device_id) const = 0; /** * \brief information about device diff --git a/src/components/include/transport_manager/common.h b/src/components/include/transport_manager/common.h index c1fc51dc8a..833a35602a 100644 --- a/src/components/include/transport_manager/common.h +++ b/src/components/include/transport_manager/common.h @@ -58,7 +58,7 @@ enum { /** * @brief Type definition for variable that hold handle of device. */ -typedef unsigned int DeviceHandle; +typedef size_t DeviceHandle; /** * @brief Type definition for variable that hold connection unique identifier. diff --git a/src/components/include/transport_manager/transport_adapter/device.h b/src/components/include/transport_manager/transport_adapter/device.h index 3adb6cd2e6..c0e97e6a98 100644 --- a/src/components/include/transport_manager/transport_adapter/device.h +++ b/src/components/include/transport_manager/transport_adapter/device.h @@ -86,6 +86,14 @@ class Device { UNUSED(bundle_id); } + /** + * @brief Init allows to initialize device. + * Currently overloadded only for iAP devices. + */ + virtual bool Init() { + return true; + } + virtual void Stop() {} inline const DeviceUID& unique_device_id() const { diff --git a/src/components/include/transport_manager/transport_adapter/transport_adapter.h b/src/components/include/transport_manager/transport_adapter/transport_adapter.h index ee726ff1d3..6f2ef7b62e 100644 --- a/src/components/include/transport_manager/transport_adapter/transport_adapter.h +++ b/src/components/include/transport_manager/transport_adapter/transport_adapter.h @@ -59,7 +59,16 @@ class TransportAdapterListener; // TODO(EZamakhov): cahnge to DeviceUID // typedef std::string DeviceType; -enum DeviceType { AOA, PASA_AOA, BLUETOOTH, PASA_BLUETOOTH, MME, TCP, UNKNOWN }; +enum DeviceType { + AOA, + PASA_AOA, + BLUETOOTH, + PASA_BLUETOOTH, + IOS_BT, + IOS_USB, + TCP, + UNKNOWN +}; typedef std::map<DeviceType, std::string> DeviceTypes; @@ -278,6 +287,16 @@ class TransportAdapter { */ virtual std::string DeviceName(const DeviceUID& device_id) const = 0; + /** + * @brief StopDevice Allows to stop all activity on devices without + * removing one from device list + * + * @param device_id unique device identifier that has to be stopped. + */ + virtual void StopDevice(const DeviceUID& device_id) const = 0; + + virtual void DeviceSwitched(const DeviceUID& device_handle) = 0; + #ifdef TELEMETRY_MONITOR /** * @brief Return Time metric observer diff --git a/src/components/include/transport_manager/transport_adapter/transport_adapter_event.h b/src/components/include/transport_manager/transport_adapter/transport_adapter_event.h index 7879a136b2..8221ecf10b 100644 --- a/src/components/include/transport_manager/transport_adapter/transport_adapter_event.h +++ b/src/components/include/transport_manager/transport_adapter/transport_adapter_event.h @@ -39,6 +39,27 @@ namespace transport_manager { +/** + * @enum Available types of events. + */ +enum class EventTypeEnum { + ON_SEARCH_DONE = 0, + ON_SEARCH_FAIL, + ON_DEVICE_LIST_UPDATED, + ON_DEVICE_ADDED, + ON_FIND_NEW_APPLICATIONS_REQUEST, + ON_CONNECT_DONE, + ON_CONNECT_FAIL, + ON_DISCONNECT_DONE, + ON_DISCONNECT_FAIL, + ON_SEND_DONE, + ON_SEND_FAIL, + ON_RECEIVED_DONE, + ON_RECEIVED_FAIL, + ON_COMMUNICATION_ERROR, + ON_UNEXPECTED_DISCONNECT +}; + class TransportAdapterEvent { public: TransportAdapterEvent() {} @@ -52,7 +73,7 @@ class TransportAdapterEvent { * @param data Smart pointer to the raw message. * @param error Error class that contains details of this error situation. */ - TransportAdapterEvent(int type, + TransportAdapterEvent(EventTypeEnum type, transport_adapter::TransportAdapter* adapter, const DeviceUID& device_handle, const ApplicationHandle& application_id, @@ -67,7 +88,7 @@ class TransportAdapterEvent { /** * @brief Value that describe event type. */ - int event_type; + EventTypeEnum event_type; /** * @brief Handle of application */ diff --git a/src/components/include/transport_manager/transport_manager.h b/src/components/include/transport_manager/transport_manager.h index 0847886c46..9b8388107f 100644 --- a/src/components/include/transport_manager/transport_manager.h +++ b/src/components/include/transport_manager/transport_manager.h @@ -132,6 +132,8 @@ class TransportManager { virtual void RunAppOnDevice(const DeviceHandle device_handle, const std::string& bundle_id) = 0; + virtual void OnDeviceConnectionSwitched(const DeviceHandle handle) = 0; + /** * @brief Post event in the event queue. * diff --git a/src/components/include/transport_manager/transport_manager_listener.h b/src/components/include/transport_manager/transport_manager_listener.h index e9f49e3152..2ed75e397c 100644 --- a/src/components/include/transport_manager/transport_manager_listener.h +++ b/src/components/include/transport_manager/transport_manager_listener.h @@ -70,6 +70,23 @@ class TransportManagerListener { virtual void OnDeviceRemoved(const DeviceInfo& device_info) = 0; /** + * @brief OnDeviceSwitchingStart allows to notify listener that device is + *going + * to switch its connection. + * + * @param device_uid the id of the device which has to be switched. + */ + virtual void OnDeviceSwitchingStart(const DeviceUID& device_uid) = 0; + + /** + * @brief OnDeviceSwitchFinish notifies listener that device reconnection + * fails due to some reason. + * + * @param device_uid the id for the device which is fails to reconnect. + */ + virtual void OnDeviceSwitchFinish(const DeviceUID& device_uid) = 0; + + /** * @brief Reaction to the event, when scanning of devices is finished. */ virtual void OnScanDevicesFinished() = 0; diff --git a/src/components/include/transport_manager/transport_manager_listener_empty.h b/src/components/include/transport_manager/transport_manager_listener_empty.h index c5eb0be37c..e248b27341 100644 --- a/src/components/include/transport_manager/transport_manager_listener_empty.h +++ b/src/components/include/transport_manager/transport_manager_listener_empty.h @@ -69,6 +69,22 @@ class TransportManagerListenerEmpty : public TransportManagerListener { void OnDeviceRemoved(const DeviceInfo& device_info) OVERRIDE {} /** + * @brief OnDeviceSwitching allows to notify listener that device is going + * to switch its connection. + * + * @param device_uid the id of the device which has to be switched. + */ + void OnDeviceSwitchingStart(const DeviceUID& device_uid) OVERRIDE {} + + /** + * @brief OnDeviceSwitchFinish notifies listener that device reconnection + * fails due to some reason. + * + * @param device_uid the id for the device which is fails to reconnect. + */ + void OnDeviceSwitchFinish(const DeviceUID& device_uid) OVERRIDE {} + + /** * @brief Reaction to the event, when scanning of devices is finished. */ void OnScanDevicesFinished() OVERRIDE {} diff --git a/src/components/include/transport_manager/transport_manager_settings.h b/src/components/include/transport_manager/transport_manager_settings.h index f33c5344e0..feb3fa2c02 100644 --- a/src/components/include/transport_manager/transport_manager_settings.h +++ b/src/components/include/transport_manager/transport_manager_settings.h @@ -51,6 +51,18 @@ class TransportManagerSettings : public TransportManagerMMESettings { * @brief Returns port for TCP transport adapter */ virtual uint16_t transport_manager_tcp_adapter_port() const = 0; + + /** + * @brief Returns the millisecond count before timeout + * for transport change feature occures. + */ + virtual uint32_t app_transport_change_timer() const = 0; + + /** + * @brief Returns the millisecond count as addition to + * the transport change timeout value. + */ + virtual uint32_t app_transport_change_timer_addition() const = 0; }; } // namespace transport_manager #endif // SRC_COMPONENTS_INCLUDE_TRANSPORT_MANAGER_TRANSPORT_MANAGER_SETTINGS_H_ diff --git a/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_impl.h b/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_impl.h index d4c97d5233..8d1b96bbfd 100644 --- a/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_impl.h +++ b/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_impl.h @@ -408,6 +408,10 @@ class TransportAdapterImpl : public TransportAdapter, */ std::string DeviceName(const DeviceUID& device_id) const OVERRIDE; + void StopDevice(const DeviceUID& device_id) const FINAL; + + void DeviceSwitched(const DeviceUID& device_handle) FINAL; + /** * @brief Allows to obtain connection type used by device. * @return connection type. diff --git a/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_listener.h b/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_listener.h index 0a1eeb6b4a..3ac664fa29 100644 --- a/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_listener.h +++ b/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_listener.h @@ -84,6 +84,8 @@ class TransportAdapterListener { virtual void OnDeviceListUpdated( const TransportAdapter* transport_adapter) = 0; + virtual void OnDeviceAdded(DeviceUID device_uid) = 0; + /** * @brief Reaction to "Find new applications" request * @param adapter Current transport adapter @@ -146,6 +148,7 @@ class TransportAdapterListener { const DeviceUID& device_handle, const ApplicationHandle& app_handle, const CommunicationError& error) = 0; + /** * @brief Search specified device adapter in the container of shared pointers *to device adapters to be sure it is available, diff --git a/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_listener_impl.h b/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_listener_impl.h index a7cd544563..5018549b86 100644 --- a/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_listener_impl.h +++ b/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_listener_impl.h @@ -49,26 +49,6 @@ class TransportAdapterListenerImpl : public transport_adapter::TransportAdapterListener { public: /** - * @enum Available types of events. - */ - enum EventTypeEnum { - ON_SEARCH_DONE = 0, - ON_SEARCH_FAIL, - ON_DEVICE_LIST_UPDATED, - ON_FIND_NEW_APPLICATIONS_REQUEST, - ON_CONNECT_DONE, - ON_CONNECT_FAIL, - ON_DISCONNECT_DONE, - ON_DISCONNECT_FAIL, - ON_SEND_DONE, - ON_SEND_FAIL, - ON_RECEIVED_DONE, - ON_RECEIVED_FAIL, - ON_COMMUNICATION_ERROR, - ON_UNEXPECTED_DISCONNECT - }; - - /** * @brief Constructor. * * @param manager Pointer to the transport manager class. @@ -105,6 +85,8 @@ class TransportAdapterListenerImpl */ virtual void OnDeviceListUpdated(const TransportAdapter* adapter); + virtual void OnDeviceAdded(DeviceUID device_uid); + virtual void OnFindNewApplicationsRequest(const TransportAdapter* adapter); /** diff --git a/src/components/transport_manager/include/transport_manager/transport_manager_impl.h b/src/components/transport_manager/include/transport_manager/transport_manager_impl.h index 4dd74086be..ea0392cf0c 100644 --- a/src/components/transport_manager/include/transport_manager/transport_manager_impl.h +++ b/src/components/transport_manager/include/transport_manager/transport_manager_impl.h @@ -39,6 +39,8 @@ #include <vector> #include <utility> #include <algorithm> +#include <tuple> +#include <functional> #include "utils/timer.h" #include "utils/timer_task_impl.h" @@ -63,6 +65,7 @@ typedef threads::MessageLoopThread<std::queue<protocol_handler::RawMessagePtr> > typedef threads::MessageLoopThread<std::queue<TransportAdapterEvent> > TransportAdapterEventLoopThread; typedef utils::SharedPtr<timer::Timer> TimerSPtr; +typedef std::map<DeviceUID, TransportAdapter*> DeviceToAdapterMap; /** * @brief Implementation of transport manager.s @@ -94,6 +97,7 @@ class TransportManagerImpl bool shutdown_; DeviceHandle device_handle_; int messages_count; + bool active_; ConnectionInternal(TransportManagerImpl* transport_manager, TransportAdapter* transport_adapter, @@ -192,6 +196,8 @@ class TransportManagerImpl void RunAppOnDevice(const DeviceHandle device_handle, const std::string& bundle_id) OVERRIDE; + void OnDeviceConnectionSwitched(const DeviceHandle handle) FINAL; + /** * @brief Post event in the event queue. * @@ -307,44 +313,53 @@ class TransportManagerImpl private: /** - * @brief Structure that contains conversion functions (Device ID -> Device - * Handle; Device Handle -> Device ID) - */ + * @brief Structure that contains conversion functions (Device ID -> Device + * Handle; Device Handle -> Device ID) + */ struct Handle2GUIDConverter { - typedef std::vector<DeviceUID> ConversionTable; - - DeviceHandle UidToHandle(const DeviceUID& dev_uid) { - bool is_new = true; - return UidToHandle(dev_uid, is_new); - } - - DeviceHandle UidToHandle(const DeviceUID& dev_uid, bool& is_new) { - { - sync_primitives::AutoReadLock lock(conversion_table_lock); - ConversionTable::iterator it = std::find( - conversion_table_.begin(), conversion_table_.end(), dev_uid); - if (it != conversion_table_.end()) { - is_new = false; - return std::distance(conversion_table_.begin(), it) + - 1; // handle begin since 1 (one) - } + /** + * @brief ConversionTable Records uid/connection type/handle + */ + typedef std::vector<std::tuple<DeviceUID, std::string, DeviceHandle> > + ConversionTable; + + /** + * @brief The HandleFinder struct helper to search for hanlde in coversion + * table + */ + struct HandleFinder { + explicit HandleFinder(const DeviceHandle& look_for) + : look_for_(look_for) {} + + bool operator()(const ConversionTable::value_type value) const { + return look_for_ == std::get<2>(value); } - is_new = true; - sync_primitives::AutoWriteLock lock(conversion_table_lock); - conversion_table_.push_back(dev_uid); - return conversion_table_.size(); // handle begin since 1 (one) - } - - DeviceUID HandleToUid(const DeviceHandle handle) { - sync_primitives::AutoReadLock lock(conversion_table_lock); - if (handle == 0 || handle > conversion_table_.size()) { - return DeviceUID(); - } - return conversion_table_[handle - 1]; // handle begin since 1 (one) - } + const DeviceHandle look_for_; + }; + + /** + * @brief UidToHandle Converts UID to handle considering connection type as + * UID may be the same in case device is connected over Bluetooth/USB (e.g. + * for IAP2) + * @param dev_uid Device UID + * @param connection_type Connection type + * @return Device handle + */ + DeviceHandle UidToHandle(const DeviceUID& dev_uid, + const std::string& connection_type); + + /** + * @brief HandleToUid Converts handle to device UID + * @param handle Device handle + * @return Device UID + */ + DeviceUID HandleToUid(const DeviceHandle handle); + + private: ConversionTable conversion_table_; - sync_primitives::RWLock conversion_table_lock; + std::hash<std::string> hash_function_; + sync_primitives::RWLock conversion_table_lock_; }; /** @@ -353,6 +368,13 @@ class TransportManagerImpl */ Handle2GUIDConverter converter_; +#ifdef BUILD_TESTS + public: + Handle2GUIDConverter& get_converter() { + return converter_; + } +#endif // BUILD_TESTS + explicit TransportManagerImpl(const TransportManagerImpl&); int connection_id_counter_; sync_primitives::RWLock connections_lock_; @@ -372,13 +394,62 @@ class TransportManagerImpl sync_primitives::RWLock device_list_lock_; DeviceInfoList device_list_; + timer::Timer device_switch_timer_; + sync_primitives::Lock device_lock_; + DeviceUID device_to_reconnect_; + + /** + * @brief Adds new incoming connection to connections list + * @param c New connection + */ void AddConnection(const ConnectionInternal& c); + + /** + * @brief Removes connection from connections list + * @param id Identifier of connection to be removed + * @param transport_adapter Pointer to transport adapter + * that holds connection + */ void RemoveConnection(const uint32_t id, transport_adapter::TransportAdapter* transport_adapter); + + /** + * @brief Deactivates all connections related to certain device + * @param device_uid Device unique identifier + */ + void DeactivateDeviceConnections(const DeviceUID& device_uid); + /** + * @brief Returns connection from connections list by connection identifier + * @param id Connection identifier + * @return Pointer to connection or NULL if connection could not be found + */ ConnectionInternal* GetConnection(const ConnectionUID id); + + /** + * @brief Returns connection from connections list by device unique id + * and application handle + * @param device Device unique identifier + * @param application Application handle + * @return Pointer to connection or NULL if connection could not be found + */ ConnectionInternal* GetConnection(const DeviceUID& device, const ApplicationHandle& application); + /** + * @brief Returns active connection from connections list by device unique + * id + * and application handle + * (this method returns only active connections as opposed to previous one) + * @param device Device unique identifier + * @param application Application handle + * @return Pointer to connection or NULL if connection could not be found + */ + ConnectionInternal* GetActiveConnection(const DeviceUID& device, + const ApplicationHandle& application); + + bool TryDeviceSwitch(TransportAdapter* ta, + DeviceToAdapterMap::iterator value); + void AddDataToContainer( ConnectionUID id, std::map<ConnectionUID, std::pair<unsigned int, unsigned char*> >& @@ -394,11 +465,21 @@ class TransportManagerImpl unsigned int frame_size, unsigned char** frame); + void OnDeviceAdded(TransportAdapter* ta); void OnDeviceListUpdated(TransportAdapter* ta); void DisconnectAllDevices(); void TerminateAllAdapters(); int InitAllAdapters(); static Connection convert(const ConnectionInternal& p); + void ReconnectionTimeout(); + + /** + * @brief UpdateDeviceMapping handles internal device-to-adapter mapping, + * performs its update on adding/removal of devices. Also used by IAP2 + * switching flow to substitute BT with USB transport + * @param ta Pointer to transport adapter + */ + void UpdateDeviceMapping(TransportAdapter* ta); }; // class TransportManagerImpl } // namespace transport_manager -#endif // SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_TRANSPORT_MANAGER_IMPL_H_ +#endif // SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_TRANSPORT_MANAGER_IMPL_H_
\ No newline at end of file diff --git a/src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc b/src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc index 026e53670b..e0f5c0da6d 100644 --- a/src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc +++ b/src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc @@ -46,12 +46,13 @@ namespace transport_adapter { CREATE_LOGGERPTR_GLOBAL(logger_, "TransportManager") namespace { DeviceTypes devicesType = { - std::make_pair(AOA, std::string("USB_AOA")), - std::make_pair(PASA_AOA, std::string("USB_AOA")), - std::make_pair(MME, std::string("USB_IOS")), - std::make_pair(BLUETOOTH, std::string("BLUETOOTH")), - std::make_pair(PASA_BLUETOOTH, std::string("BLUETOOTH")), - std::make_pair(TCP, std::string("WIFI"))}; + std::make_pair(DeviceType::AOA, std::string("USB_AOA")), + std::make_pair(DeviceType::PASA_AOA, std::string("USB_AOA")), + std::make_pair(DeviceType::IOS_USB, std::string("USB_IOS")), + std::make_pair(DeviceType::IOS_BT, std::string("IOS_BLUETOOTH")), + std::make_pair(DeviceType::BLUETOOTH, std::string("BLUETOOTH")), + std::make_pair(DeviceType::PASA_BLUETOOTH, std::string("BLUETOOTH")), + std::make_pair(DeviceType::TCP, std::string("WIFI"))}; } TransportAdapterImpl::TransportAdapterImpl( @@ -389,7 +390,7 @@ DeviceSptr TransportAdapterImpl::AddDevice(DeviceSptr device) { for (TransportAdapterListenerList::iterator it = listeners_.begin(); it != listeners_.end(); ++it) { - (*it)->OnDeviceListUpdated(this); + (*it)->OnDeviceAdded(device->unique_device_id()); } if (ToBeAutoConnected(device)) { ConnectDevice(device); @@ -694,6 +695,13 @@ void TransportAdapterImpl::DataSendFailed( LOG4CXX_TRACE(logger_, "exit"); } +void TransportAdapterImpl::DeviceSwitched(const DeviceUID& device_handle) { + LOG4CXX_DEBUG(logger_, + "Switching is not implemented for that adapter type " + << GetConnectionType().c_str()); + UNUSED(device_handle); +} + DeviceSptr TransportAdapterImpl::FindDevice(const DeviceUID& device_id) const { LOG4CXX_TRACE(logger_, "enter. device_id: " << &device_id); DeviceSptr ret; @@ -864,6 +872,14 @@ std::string TransportAdapterImpl::DeviceName(const DeviceUID& device_id) const { } } +void TransportAdapterImpl::StopDevice(const DeviceUID& device_id) const { + LOG4CXX_AUTO_TRACE(logger_); + DeviceSptr device = FindDevice(device_id); + if (device) { + device->Stop(); + } +} + std::string TransportAdapterImpl::GetConnectionType() const { return devicesType[GetDeviceType()]; } diff --git a/src/components/transport_manager/src/transport_adapter/transport_adapter_listener_impl.cc b/src/components/transport_manager/src/transport_adapter/transport_adapter_listener_impl.cc index 2ab19ade86..5c561ad6e3 100644 --- a/src/components/transport_manager/src/transport_adapter/transport_adapter_listener_impl.cc +++ b/src/components/transport_manager/src/transport_adapter/transport_adapter_listener_impl.cc @@ -48,13 +48,12 @@ TransportAdapterListenerImpl::TransportAdapterListenerImpl( void TransportAdapterListenerImpl::OnSearchDeviceDone( const TransportAdapter* adapter) { LOG4CXX_TRACE(logger_, "enter. adapter* " << adapter); - const TransportAdapterEvent event( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEARCH_DONE, - transport_adapter_, - "", - 0, - ::protocol_handler::RawMessagePtr(), - BaseErrorPtr()); + const TransportAdapterEvent event(EventTypeEnum::ON_SEARCH_DONE, + transport_adapter_, + "", + 0, + ::protocol_handler::RawMessagePtr(), + BaseErrorPtr()); if (transport_manager_ != NULL && transport_manager::E_SUCCESS != transport_manager_->ReceiveEventFromDevice(event)) { @@ -68,13 +67,12 @@ void TransportAdapterListenerImpl::OnSearchDeviceFailed( LOG4CXX_TRACE(logger_, "enter. adapter: " << adapter << ", error: " << &error); SearchDeviceError* err = new SearchDeviceError(error); - const TransportAdapterEvent event( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEARCH_FAIL, - transport_adapter_, - "", - 0, - ::protocol_handler::RawMessagePtr(), - BaseErrorPtr(err)); + const TransportAdapterEvent event(EventTypeEnum::ON_SEARCH_FAIL, + transport_adapter_, + "", + 0, + ::protocol_handler::RawMessagePtr(), + BaseErrorPtr(err)); if (transport_manager_ != NULL && transport_manager::E_SUCCESS != transport_manager_->ReceiveEventFromDevice(event)) { @@ -86,13 +84,12 @@ void TransportAdapterListenerImpl::OnSearchDeviceFailed( void TransportAdapterListenerImpl::OnDeviceListUpdated( const TransportAdapter* adapter) { LOG4CXX_TRACE(logger_, "enter. adapter* " << adapter); - const TransportAdapterEvent event( - TransportAdapterListenerImpl::EventTypeEnum::ON_DEVICE_LIST_UPDATED, - transport_adapter_, - "", - 0, - ::protocol_handler::RawMessagePtr(), - BaseErrorPtr()); + const TransportAdapterEvent event(EventTypeEnum::ON_DEVICE_LIST_UPDATED, + transport_adapter_, + "", + 0, + ::protocol_handler::RawMessagePtr(), + BaseErrorPtr()); if (transport_manager_ != NULL && transport_manager::E_SUCCESS != transport_manager_->ReceiveEventFromDevice(event)) { @@ -101,11 +98,25 @@ void TransportAdapterListenerImpl::OnDeviceListUpdated( LOG4CXX_TRACE(logger_, "exit"); } +void TransportAdapterListenerImpl::OnDeviceAdded(DeviceUID device_uid) { + const TransportAdapterEvent event(EventTypeEnum::ON_DEVICE_ADDED, + transport_adapter_, + device_uid, + 0, + ::protocol_handler::RawMessagePtr(), + BaseErrorPtr()); + if (transport_manager_ != NULL && + transport_manager::E_SUCCESS != + transport_manager_->ReceiveEventFromDevice(event)) { + LOG4CXX_WARN(logger_, "Failed to receive event from device"); + } +} + void TransportAdapterListenerImpl::OnFindNewApplicationsRequest( const TransportAdapter* adapter) { LOG4CXX_TRACE(logger_, "enter. adapter* " << adapter); const TransportAdapterEvent event( - TransportAdapterListenerImpl::ON_FIND_NEW_APPLICATIONS_REQUEST, + EventTypeEnum::ON_FIND_NEW_APPLICATIONS_REQUEST, transport_adapter_, "", 0, @@ -126,13 +137,12 @@ void TransportAdapterListenerImpl::OnConnectDone( LOG4CXX_TRACE(logger_, "enter adapter*: " << adapter << ", device: " << &device << ", application_id: " << &application_id); - const TransportAdapterEvent event( - TransportAdapterListenerImpl::EventTypeEnum::ON_CONNECT_DONE, - transport_adapter_, - device, - application_id, - ::protocol_handler::RawMessagePtr(), - BaseErrorPtr(new BaseError())); + const TransportAdapterEvent event(EventTypeEnum::ON_CONNECT_DONE, + transport_adapter_, + device, + application_id, + ::protocol_handler::RawMessagePtr(), + BaseErrorPtr(new BaseError())); if (transport_manager_ != NULL && transport_manager::E_SUCCESS != transport_manager_->ReceiveEventFromDevice(event)) { @@ -151,13 +161,12 @@ void TransportAdapterListenerImpl::OnConnectFailed( << ", application_id: " << &app_id << ", error: " << &error); ConnectError* err = new ConnectError(error); - const TransportAdapterEvent event( - TransportAdapterListenerImpl::EventTypeEnum::ON_CONNECT_FAIL, - transport_adapter_, - device, - app_id, - ::protocol_handler::RawMessagePtr(), - BaseErrorPtr(err)); + const TransportAdapterEvent event(EventTypeEnum::ON_CONNECT_FAIL, + transport_adapter_, + device, + app_id, + ::protocol_handler::RawMessagePtr(), + BaseErrorPtr(err)); if (transport_manager_ != NULL && transport_manager::E_SUCCESS != transport_manager_->ReceiveEventFromDevice(event)) { @@ -173,13 +182,12 @@ void TransportAdapterListenerImpl::OnDisconnectDone( LOG4CXX_TRACE(logger_, "enter. adapter: " << adapter << ", device: " << &device << ", application_id: " << &app_id); - const TransportAdapterEvent event( - TransportAdapterListenerImpl::EventTypeEnum::ON_DISCONNECT_DONE, - transport_adapter_, - device, - app_id, - ::protocol_handler::RawMessagePtr(), - BaseErrorPtr(new BaseError())); + const TransportAdapterEvent event(EventTypeEnum::ON_DISCONNECT_DONE, + transport_adapter_, + device, + app_id, + ::protocol_handler::RawMessagePtr(), + BaseErrorPtr(new BaseError())); if (transport_manager_ != NULL && transport_manager::E_SUCCESS != transport_manager_->ReceiveEventFromDevice(event)) { @@ -198,13 +206,12 @@ void TransportAdapterListenerImpl::OnDisconnectFailed( << ", application_id: " << &app_id << ", error: " << &error); DisconnectError* err = new DisconnectError(error); - const TransportAdapterEvent event( - TransportAdapterListenerImpl::EventTypeEnum::ON_DISCONNECT_FAIL, - transport_adapter_, - device, - app_id, - ::protocol_handler::RawMessagePtr(), - BaseErrorPtr(err)); + const TransportAdapterEvent event(EventTypeEnum::ON_DISCONNECT_FAIL, + transport_adapter_, + device, + app_id, + ::protocol_handler::RawMessagePtr(), + BaseErrorPtr(err)); if (transport_manager_ != NULL && transport_manager::E_SUCCESS != transport_manager_->ReceiveEventFromDevice(event)) { @@ -230,13 +237,12 @@ void TransportAdapterListenerImpl::OnDataReceiveDone( "enter. adapter: " << adapter << ", device: " << &device << ", application_id: " << &app_id << ", data_container: " << data_container); - const TransportAdapterEvent event( - TransportAdapterListenerImpl::EventTypeEnum::ON_RECEIVED_DONE, - transport_adapter_, - device, - app_id, - data_container, - BaseErrorPtr(new BaseError())); + const TransportAdapterEvent event(EventTypeEnum::ON_RECEIVED_DONE, + transport_adapter_, + device, + app_id, + data_container, + BaseErrorPtr(new BaseError())); if (transport_manager_ != NULL && transport_manager::E_SUCCESS != transport_manager_->ReceiveEventFromDevice(event)) { @@ -255,13 +261,12 @@ void TransportAdapterListenerImpl::OnDataReceiveFailed( << ", application_id: " << &app_id << ", error: " << &error); DataReceiveError* err = new DataReceiveError(error); - const TransportAdapterEvent event( - TransportAdapterListenerImpl::EventTypeEnum::ON_RECEIVED_FAIL, - transport_adapter_, - device, - app_id, - ::protocol_handler::RawMessagePtr(), - BaseErrorPtr(err)); + const TransportAdapterEvent event(EventTypeEnum::ON_RECEIVED_FAIL, + transport_adapter_, + device, + app_id, + ::protocol_handler::RawMessagePtr(), + BaseErrorPtr(err)); if (transport_manager_ != NULL && transport_manager::E_SUCCESS != transport_manager_->ReceiveEventFromDevice(event)) { @@ -279,13 +284,12 @@ void TransportAdapterListenerImpl::OnDataSendDone( "enter. adapter: " << adapter << ", device: " << &device << ", application_id: " << &app_id << ", data_container: " << data_container); - const TransportAdapterEvent event( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEND_DONE, - transport_adapter_, - device, - app_id, - data_container, - new BaseError()); + const TransportAdapterEvent event(EventTypeEnum::ON_SEND_DONE, + transport_adapter_, + device, + app_id, + data_container, + new BaseError()); if (transport_manager_ != NULL && transport_manager::E_SUCCESS != transport_manager_->ReceiveEventFromDevice(event)) { @@ -306,13 +310,12 @@ void TransportAdapterListenerImpl::OnDataSendFailed( << ", data_container: " << data_container << ", error: " << &error); DataSendError* err = new DataSendError(error); - const TransportAdapterEvent event( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEND_FAIL, - transport_adapter_, - device, - app_id, - data_container, - BaseErrorPtr(err)); + const TransportAdapterEvent event(EventTypeEnum::ON_SEND_FAIL, + transport_adapter_, + device, + app_id, + data_container, + BaseErrorPtr(err)); if (transport_manager_ != NULL && transport_manager::E_SUCCESS != transport_manager_->ReceiveEventFromDevice(event)) { @@ -336,13 +339,12 @@ void TransportAdapterListenerImpl::OnUnexpectedDisconnect( << ", application: " << &application << ", error: " << &error); CommunicationError* err = new CommunicationError(error); - const TransportAdapterEvent event( - TransportAdapterListenerImpl::EventTypeEnum::ON_UNEXPECTED_DISCONNECT, - transport_adapter_, - device, - application, - ::protocol_handler::RawMessagePtr(), - BaseErrorPtr(err)); + const TransportAdapterEvent event(EventTypeEnum::ON_UNEXPECTED_DISCONNECT, + transport_adapter_, + device, + application, + ::protocol_handler::RawMessagePtr(), + BaseErrorPtr(err)); if (transport_manager_ != NULL && transport_manager::E_SUCCESS != transport_manager_->ReceiveEventFromDevice(event)) { @@ -358,13 +360,12 @@ void TransportAdapterListenerImpl::OnCommunicationError( LOG4CXX_TRACE(logger_, "enter. adapter: " << adapter << ", device: " << &device << ", application_id: " << &app_id); - const TransportAdapterEvent event( - TransportAdapterListenerImpl::EventTypeEnum::ON_COMMUNICATION_ERROR, - transport_adapter_, - device, - app_id, - ::protocol_handler::RawMessagePtr(), - BaseErrorPtr(new BaseError())); + const TransportAdapterEvent event(EventTypeEnum::ON_COMMUNICATION_ERROR, + transport_adapter_, + device, + app_id, + ::protocol_handler::RawMessagePtr(), + BaseErrorPtr(new BaseError())); if (transport_manager_ != NULL && transport_manager::E_SUCCESS != transport_manager_->ReceiveEventFromDevice(event)) { diff --git a/src/components/transport_manager/src/transport_manager_impl.cc b/src/components/transport_manager/src/transport_manager_impl.cc index 831ff0980e..01baaef8df 100644 --- a/src/components/transport_manager/src/transport_manager_impl.cc +++ b/src/components/transport_manager/src/transport_manager_impl.cc @@ -82,7 +82,11 @@ TransportManagerImpl::TransportManagerImpl( , connection_id_counter_(0) , message_queue_("TM MessageQueue", this) , event_queue_("TM EventQueue", this) - , settings_(settings) { + , settings_(settings) + , device_switch_timer_( + "Device reconection timer", + new timer::TimerTaskImpl<TransportManagerImpl>( + this, &TransportManagerImpl::ReconnectionTimeout)) { LOG4CXX_TRACE(logger_, "TransportManager has created"); } @@ -108,6 +112,12 @@ TransportManagerImpl::~TransportManagerImpl() { LOG4CXX_INFO(logger_, "TransportManager object destroyed"); } +void TransportManagerImpl::ReconnectionTimeout() { + LOG4CXX_AUTO_TRACE(logger_); + RaiseEvent(&TransportManagerListener::OnDeviceSwitchFinish, + device_to_reconnect_); +} + int TransportManagerImpl::ConnectDevice(const DeviceHandle device_handle) { LOG4CXX_TRACE(logger_, "enter. DeviceHandle: " << &device_handle); if (!this->is_initialized_) { @@ -369,6 +379,13 @@ void TransportManagerImpl::RunAppOnDevice(const DeviceHandle device_handle, return; } +void TransportManagerImpl::OnDeviceConnectionSwitched( + const DeviceHandle handle) { + LOG4CXX_AUTO_TRACE(logger_); + UNUSED(handle); + // At the moment does nothing +} + int TransportManagerImpl::ReceiveEventFromDevice( const TransportAdapterEvent& event) { LOG4CXX_TRACE(logger_, "enter. TransportAdapterEvent: " << &event); @@ -562,7 +579,8 @@ void TransportManagerImpl::UpdateDeviceList(TransportAdapter* ta) { const DeviceList dev_list = ta->GetDeviceList(); for (DeviceList::const_iterator it = dev_list.begin(); it != dev_list.end(); ++it) { - DeviceHandle device_handle = converter_.UidToHandle(*it); + DeviceHandle device_handle = + converter_.UidToHandle(*it, ta->GetConnectionType()); DeviceInfo info( device_handle, *it, ta->DeviceName(*it), ta->GetConnectionType()); device_list_.push_back(std::make_pair(ta, info)); @@ -626,25 +644,43 @@ void TransportManagerImpl::RemoveConnection( LOG4CXX_AUTO_TRACE(logger_); LOG4CXX_DEBUG(logger_, "Id: " << id); sync_primitives::AutoWriteLock lock(connections_lock_); - std::vector<ConnectionInternal>::iterator it = connections_.begin(); - while (it != connections_.end()) { - if (it->id == id) { - if (transport_adapter) { - transport_adapter->RemoveFinalizedConnection(it->device, - it->application); - } - connections_.erase(it++); - break; - } else { - ++it; + LOG4CXX_DEBUG(logger_, "Removing connection with id: " << id); + const std::vector<ConnectionInternal>::iterator it = std::find_if( + connections_.begin(), connections_.end(), ConnectionFinder(id)); + if (connections_.end() != it) { + if (transport_adapter) { + transport_adapter->RemoveFinalizedConnection(it->device, it->application); + } + } +} + +void TransportManagerImpl::DeactivateDeviceConnections( + const DeviceUID& device_uid) { + LOG4CXX_AUTO_TRACE(logger_); + + sync_primitives::AutoWriteLock lock(connections_lock_); + LOG4CXX_DEBUG(logger_, + "Deactivating connections for device with UID: " << device_uid); + + size_t counter = 0; + for (std::vector<ConnectionInternal>::iterator it = connections_.begin(); + it != connections_.end(); + ++it) { + if (it->device == device_uid) { + it->active_ = false; + ++counter; } } + LOG4CXX_DEBUG(logger_, + "Deactivated " + << counter + << " connections for device with UID: " << device_uid); } TransportManagerImpl::ConnectionInternal* TransportManagerImpl::GetConnection( const ConnectionUID id) { LOG4CXX_AUTO_TRACE(logger_); - LOG4CXX_DEBUG(logger_, "ConnectionUID: " << &id); + LOG4CXX_DEBUG(logger_, "ConnectionUID: " << id); for (std::vector<ConnectionInternal>::iterator it = connections_.begin(); it != connections_.end(); ++it) { @@ -659,9 +695,8 @@ TransportManagerImpl::ConnectionInternal* TransportManagerImpl::GetConnection( TransportManagerImpl::ConnectionInternal* TransportManagerImpl::GetConnection( const DeviceUID& device, const ApplicationHandle& application) { LOG4CXX_AUTO_TRACE(logger_); - LOG4CXX_DEBUG(logger_, - "DeviceUID: " << &device - << "ApplicationHandle: " << &application); + LOG4CXX_DEBUG( + logger_, "DeviceUID: " << device << "ApplicationHandle: " << application); for (std::vector<ConnectionInternal>::iterator it = connections_.begin(); it != connections_.end(); ++it) { @@ -673,21 +708,110 @@ TransportManagerImpl::ConnectionInternal* TransportManagerImpl::GetConnection( return NULL; } -void TransportManagerImpl::OnDeviceListUpdated(TransportAdapter* ta) { - LOG4CXX_TRACE(logger_, "enter. TransportAdapter: " << ta); +TransportManagerImpl::ConnectionInternal* +TransportManagerImpl::GetActiveConnection( + const DeviceUID& device, const ApplicationHandle& application) { + LOG4CXX_AUTO_TRACE(logger_); + LOG4CXX_DEBUG(logger_, + "DeviceUID: " << device + << " ApplicationHandle: " << application); + for (std::vector<ConnectionInternal>::iterator it = connections_.begin(); + it != connections_.end(); + ++it) { + if (it->device == device && it->application == application && it->active_) { + LOG4CXX_DEBUG(logger_, "ConnectionInternal. It's address: " << &*it); + return &*it; + } + } + return NULL; +} + +bool TransportManagerImpl::TryDeviceSwitch( + transport_adapter::TransportAdapter* ta, + DeviceToAdapterMap::iterator value) { + LOG4CXX_AUTO_TRACE(logger_); + const auto device_uid = value->first; + const auto adapter = value->second; + + if (transport_adapter::DeviceType::IOS_BT != adapter->GetDeviceType()) { + LOG4CXX_DEBUG(logger_, "Adapter type is not IOS_BT."); + return false; + } + adapter->StopDevice(device_uid); + adapter->DeviceSwitched(device_uid); + + DeactivateDeviceConnections(device_uid); + + value->second = ta; + device_to_reconnect_ = device_uid; + + const uint32_t timeout = get_settings().app_transport_change_timer() + + get_settings().app_transport_change_timer_addition(); + device_switch_timer_.Start(timeout, timer::kSingleShot); + RaiseEvent(&TransportManagerListener::OnDeviceSwitchingStart, device_uid); + + LOG4CXX_DEBUG(logger_, + "Device switch for device id " << device_uid << " is done."); + return true; +} + +void TransportManagerImpl::OnDeviceAdded(TransportAdapter* ta) { + LOG4CXX_AUTO_TRACE(logger_); + OnDeviceListUpdated(ta); +} + +void TransportManagerImpl::UpdateDeviceMapping( + transport_adapter::TransportAdapter* ta) { const DeviceList device_list = ta->GetDeviceList(); LOG4CXX_DEBUG(logger_, "DEVICE_LIST_UPDATED " << device_list.size()); + + sync_primitives::AutoWriteLock lock(device_to_adapter_map_lock_); + + LOG4CXX_DEBUG(logger_, + "Before cleanup and update. Device map size is " + << device_to_adapter_map_.size()); + + for (auto item = device_to_adapter_map_.begin(); + device_to_adapter_map_.end() != item;) { + if (item->second != ta) { + ++item; + continue; + } + + if (device_list.end() != + std::find(device_list.begin(), device_list.end(), item->first)) { + ++item; + continue; + } + + device_to_adapter_map_.erase(item); + item = device_to_adapter_map_.begin(); + } + LOG4CXX_DEBUG(logger_, + "After cleanup. Device map size is " + << device_to_adapter_map_.size()); + for (DeviceList::const_iterator it = device_list.begin(); it != device_list.end(); ++it) { - device_to_adapter_map_lock_.AcquireForWriting(); - device_to_adapter_map_.insert(std::make_pair(*it, ta)); - device_to_adapter_map_lock_.Release(); - DeviceHandle device_handle = converter_.UidToHandle(*it); - DeviceInfo info( - device_handle, *it, ta->DeviceName(*it), ta->GetConnectionType()); - RaiseEvent(&TransportManagerListener::OnDeviceFound, info); + auto result = device_to_adapter_map_.insert(std::make_pair(*it, ta)); + if (result.second || TryDeviceSwitch(ta, result.first)) { + DeviceHandle device_handle = + converter_.UidToHandle(*it, ta->GetConnectionType()); + DeviceInfo info( + device_handle, *it, ta->DeviceName(*it), ta->GetConnectionType()); + RaiseEvent(&TransportManagerListener::OnDeviceFound, info); + } } + + LOG4CXX_DEBUG(logger_, + "After update. Device map size is " + << device_to_adapter_map_.size()); +} + +void TransportManagerImpl::OnDeviceListUpdated(TransportAdapter* ta) { + LOG4CXX_TRACE(logger_, "enter. TransportAdapter: " << ta); + UpdateDeviceMapping(ta); UpdateDeviceList(ta); std::vector<DeviceInfo> device_infos; device_list_lock_.AcquireForReading(); @@ -697,37 +821,43 @@ void TransportManagerImpl::OnDeviceListUpdated(TransportAdapter* ta) { device_infos.push_back(it->second); } device_list_lock_.Release(); + RaiseEvent(&TransportManagerListener::OnDeviceListUpdated, device_infos); LOG4CXX_TRACE(logger_, "exit"); } void TransportManagerImpl::Handle(TransportAdapterEvent event) { LOG4CXX_TRACE(logger_, "enter"); switch (event.event_type) { - case TransportAdapterListenerImpl::EventTypeEnum::ON_SEARCH_DONE: { + case EventTypeEnum::ON_SEARCH_DONE: { RaiseEvent(&TransportManagerListener::OnScanDevicesFinished); LOG4CXX_DEBUG(logger_, "event_type = ON_SEARCH_DONE"); break; } - case TransportAdapterListenerImpl::EventTypeEnum::ON_SEARCH_FAIL: { + case EventTypeEnum::ON_SEARCH_FAIL: { // error happened in real search process (external error) RaiseEvent(&TransportManagerListener::OnScanDevicesFailed, *static_cast<SearchDeviceError*>(event.event_error.get())); LOG4CXX_DEBUG(logger_, "event_type = ON_SEARCH_FAIL"); break; } - case TransportAdapterListenerImpl::EventTypeEnum::ON_DEVICE_LIST_UPDATED: { + case EventTypeEnum::ON_DEVICE_LIST_UPDATED: { OnDeviceListUpdated(event.transport_adapter); LOG4CXX_DEBUG(logger_, "event_type = ON_DEVICE_LIST_UPDATED"); break; } - case TransportAdapterListenerImpl::ON_FIND_NEW_APPLICATIONS_REQUEST: { + case EventTypeEnum::ON_DEVICE_ADDED: { + OnDeviceAdded(event.transport_adapter); + LOG4CXX_DEBUG(logger_, "event_type = ON_ADDED"); + break; + } + case EventTypeEnum::ON_FIND_NEW_APPLICATIONS_REQUEST: { RaiseEvent(&TransportManagerListener::OnFindNewApplicationsRequest); LOG4CXX_DEBUG(logger_, "event_type = ON_FIND_NEW_APPLICATIONS_REQUEST"); break; } - case TransportAdapterListenerImpl::EventTypeEnum::ON_CONNECT_DONE: { - const DeviceHandle device_handle = - converter_.UidToHandle(event.device_uid); + case EventTypeEnum::ON_CONNECT_DONE: { + const DeviceHandle device_handle = converter_.UidToHandle( + event.device_uid, event.transport_adapter->GetConnectionType()); AddConnection(ConnectionInternal(this, event.transport_adapter, ++connection_id_counter_, @@ -744,10 +874,12 @@ void TransportManagerImpl::Handle(TransportAdapterEvent event) { LOG4CXX_DEBUG(logger_, "event_type = ON_CONNECT_DONE"); break; } - case TransportAdapterListenerImpl::EventTypeEnum::ON_CONNECT_FAIL: { + case EventTypeEnum::ON_CONNECT_FAIL: { RaiseEvent( &TransportManagerListener::OnConnectionFailed, - DeviceInfo(converter_.UidToHandle(event.device_uid), + DeviceInfo(converter_.UidToHandle( + event.device_uid, + event.transport_adapter->GetConnectionType()), event.device_uid, event.transport_adapter->DeviceName(event.device_uid), event.transport_adapter->GetConnectionType()), @@ -755,7 +887,7 @@ void TransportManagerImpl::Handle(TransportAdapterEvent event) { LOG4CXX_DEBUG(logger_, "event_type = ON_CONNECT_FAIL"); break; } - case TransportAdapterListenerImpl::EventTypeEnum::ON_DISCONNECT_DONE: { + case EventTypeEnum::ON_DISCONNECT_DONE: { connections_lock_.AcquireForReading(); ConnectionInternal* connection = GetConnection(event.device_uid, event.application_id); @@ -774,16 +906,16 @@ void TransportManagerImpl::Handle(TransportAdapterEvent event) { LOG4CXX_DEBUG(logger_, "event_type = ON_DISCONNECT_DONE"); break; } - case TransportAdapterListenerImpl::EventTypeEnum::ON_DISCONNECT_FAIL: { - const DeviceHandle device_handle = - converter_.UidToHandle(event.device_uid); + case EventTypeEnum::ON_DISCONNECT_FAIL: { + const DeviceHandle device_handle = converter_.UidToHandle( + event.device_uid, event.transport_adapter->GetConnectionType()); RaiseEvent(&TransportManagerListener::OnDisconnectFailed, device_handle, DisconnectDeviceError()); LOG4CXX_DEBUG(logger_, "event_type = ON_DISCONNECT_FAIL"); break; } - case TransportAdapterListenerImpl::EventTypeEnum::ON_SEND_DONE: { + case EventTypeEnum::ON_SEND_DONE: { #ifdef TELEMETRY_MONITOR if (metric_observer_) { metric_observer_->StopRawMsg(event.event_data.get()); @@ -810,7 +942,7 @@ void TransportManagerImpl::Handle(TransportAdapterEvent event) { LOG4CXX_DEBUG(logger_, "event_type = ON_SEND_DONE"); break; } - case TransportAdapterListenerImpl::EventTypeEnum::ON_SEND_FAIL: { + case EventTypeEnum::ON_SEND_FAIL: { #ifdef TELEMETRY_MONITOR if (metric_observer_) { metric_observer_->StopRawMsg(event.event_data.get()); @@ -845,11 +977,11 @@ void TransportManagerImpl::Handle(TransportAdapterEvent event) { LOG4CXX_DEBUG(logger_, "eevent_type = ON_SEND_FAIL"); break; } - case TransportAdapterListenerImpl::EventTypeEnum::ON_RECEIVED_DONE: { + case EventTypeEnum::ON_RECEIVED_DONE: { { sync_primitives::AutoReadLock lock(connections_lock_); ConnectionInternal* connection = - GetConnection(event.device_uid, event.application_id); + GetActiveConnection(event.device_uid, event.application_id); if (connection == NULL) { LOG4CXX_ERROR(logger_, "Connection ('" << event.device_uid << ", " @@ -872,11 +1004,11 @@ void TransportManagerImpl::Handle(TransportAdapterEvent event) { LOG4CXX_DEBUG(logger_, "event_type = ON_RECEIVED_DONE"); break; } - case TransportAdapterListenerImpl::EventTypeEnum::ON_RECEIVED_FAIL: { + case EventTypeEnum::ON_RECEIVED_FAIL: { LOG4CXX_DEBUG(logger_, "Event ON_RECEIVED_FAIL"); connections_lock_.AcquireForReading(); ConnectionInternal* connection = - GetConnection(event.device_uid, event.application_id); + GetActiveConnection(event.device_uid, event.application_id); if (connection == NULL) { LOG4CXX_ERROR(logger_, "Connection ('" << event.device_uid << ", " @@ -891,12 +1023,11 @@ void TransportManagerImpl::Handle(TransportAdapterEvent event) { LOG4CXX_DEBUG(logger_, "event_type = ON_RECEIVED_FAIL"); break; } - case TransportAdapterListenerImpl::EventTypeEnum::ON_COMMUNICATION_ERROR: { + case EventTypeEnum::ON_COMMUNICATION_ERROR: { LOG4CXX_DEBUG(logger_, "event_type = ON_COMMUNICATION_ERROR"); break; } - case TransportAdapterListenerImpl::EventTypeEnum:: - ON_UNEXPECTED_DISCONNECT: { + case EventTypeEnum::ON_UNEXPECTED_DISCONNECT: { connections_lock_.AcquireForReading(); ConnectionInternal* connection = GetConnection(event.device_uid, event.application_id); @@ -983,7 +1114,8 @@ TransportManagerImpl::ConnectionInternal::ConnectionInternal( this, &ConnectionInternal::DisconnectFailedRoutine))) , shutdown_(false) , device_handle_(device_handle) - , messages_count(0) { + , messages_count(0) + , active_(true) { Connection::id = id; Connection::device = dev_id; Connection::application = app_id; @@ -999,4 +1131,55 @@ void TransportManagerImpl::ConnectionInternal::DisconnectFailedRoutine() { LOG4CXX_TRACE(logger_, "exit"); } +DeviceHandle TransportManagerImpl::Handle2GUIDConverter::UidToHandle( + const DeviceUID& dev_uid, const std::string& connection_type) { + DeviceHandle handle = hash_function_(dev_uid + connection_type); + + { + sync_primitives::AutoReadLock lock(conversion_table_lock_); + + auto it = std::find_if(conversion_table_.begin(), + conversion_table_.end(), + HandleFinder(handle)); + + if (it != conversion_table_.end()) { + LOG4CXX_DEBUG(logger_, + "Handle for UID is found: " << std::get<0>(*it) << "/" + << std::get<1>(*it) << "/" + << std::get<2>(*it)); + return std::get<2>(*it); + } + } + + sync_primitives::AutoWriteLock lock(conversion_table_lock_); + + auto t = std::make_tuple(dev_uid, connection_type, handle); + conversion_table_.push_back( + std::make_tuple(dev_uid, connection_type, handle)); + LOG4CXX_DEBUG(logger_, + "Handle for UID is added: " << std::get<0>(t) << "/" + << std::get<1>(t) << "/" + << std::get<2>(t)); + return handle; +} + +DeviceUID TransportManagerImpl::Handle2GUIDConverter::HandleToUid( + const DeviceHandle handle) { + sync_primitives::AutoReadLock lock(conversion_table_lock_); + + auto it = std::find_if( + conversion_table_.begin(), conversion_table_.end(), HandleFinder(handle)); + + if (it != conversion_table_.end()) { + LOG4CXX_DEBUG(logger_, + "Handle is found: " << std::get<0>(*it) << "/" + << std::get<1>(*it) << "/" + << std::get<2>(*it)); + return std::get<0>(*it); + } + + LOG4CXX_DEBUG(logger_, "Handle is not found: " << handle); + return DeviceUID("uknown_uid"); +} + } // namespace transport_manager |