diff options
37 files changed, 501 insertions, 106 deletions
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 5d12cab6ba..ffdd83eb5d 100644 --- a/src/components/application_manager/include/application_manager/application_impl.h +++ b/src/components/application_manager/include/application_manager/application_impl.h @@ -71,10 +71,12 @@ namespace custom_str = custom_string; * @param app Pointer to switched application * @param app_id New application id (connection key) * @param device_id New device id + * @param mac_address New device MAC address */ void SwitchApplicationParameters(ApplicationSharedPtr app, const uint32_t app_id, - const uint32_t device_id); + const size_t device_id, + const std::string& mac_address); class ApplicationImpl : public virtual Application, public virtual InitialApplicationDataImpl, @@ -460,7 +462,7 @@ class ApplicationImpl : public virtual Application, uint32_t delete_file_in_none_count_; uint32_t list_files_in_none_count_; std::string app_icon_path_; - const std::string mac_address_; + std::string mac_address_; connection_handler::DeviceHandle device_id_; std::string bundle_id_; AppFilesMap app_files_; @@ -509,7 +511,8 @@ class ApplicationImpl : public virtual Application, friend void SwitchApplicationParameters(ApplicationSharedPtr app, const uint32_t app_id, - const uint32_t device_id); + const size_t device_id, + const std::string& mac_address); 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 66facf7044..280617c25f 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 @@ -893,9 +893,11 @@ class ApplicationManagerImpl * @brief OnDeviceSwitchingStart is invoked on device transport switching * start (e.g. from Bluetooth to USB) and creates waiting list of applications * expected to be re-registered after switching is complete - * @param device_uid UID of device being switched + * @param device_from device params being switched to the new transport + * @param device_to device params on the new transport */ - void OnDeviceSwitchingStart(const std::string& device_uid) FINAL; + void OnDeviceSwitchingStart(const connection_handler::Device& device_from, + const connection_handler::Device& device_to) FINAL; /** * @brief OnDeviceSwitchingFinish is invoked on device trasport switching end @@ -1582,10 +1584,12 @@ class ApplicationManagerImpl * @param connection_key Connection key of switched application from its * registration request * @param device_id Device id of switched application + * @param mac_address New device mac address */ void SwitchApplication(ApplicationSharedPtr app, const uint32_t connection_key, - const uint32_t device_id); + const size_t device_id, + const std::string& mac_address); /** * @brief Converts BSON object containing video parameters to 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 a7c627b529..3e5f9252de 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 @@ -88,14 +88,15 @@ class RegisterAppInterfaceRequest : public CommandRequestImpl { * @brief The AppicationType enum defines whether application is newly * registered or existing and being switched over another transport */ - enum class AppicationType { kNewApplication, kSwitchedApplication }; + enum class ApplicationType { + kNewApplication, kSwitchedApplicationHashOk, kSwitchedApplicationWrongHashId }; /** * @brief Prepares and sends RegisterAppInterface response to mobile * considering application type * @param app_type Type of application **/ - void SendRegisterAppInterfaceResponseToMobile(AppicationType app_type); + void SendRegisterAppInterfaceResponseToMobile(ApplicationType app_type); smart_objects::SmartObjectSPtr GetLockScreenIconUrlNotification( const uint32_t connection_key, ApplicationSharedPtr app); diff --git a/src/components/application_manager/include/application_manager/policies/policy_handler.h b/src/components/application_manager/include/application_manager/policies/policy_handler.h index 9de2d6af68..dff27cf7f1 100644 --- a/src/components/application_manager/include/application_manager/policies/policy_handler.h +++ b/src/components/application_manager/include/application_manager/policies/policy_handler.h @@ -533,6 +533,15 @@ class PolicyHandler : public PolicyHandlerInterface, virtual void OnPTUFinished(const bool ptu_result) OVERRIDE; + /** + * @brief OnDeviceSwitching Notifies policy manager on device switch event so + * policy permissions should be processed accordingly + * @param device_id_from Id of device being switched + * @param device_id_to Id of device on the new transport + */ + void OnDeviceSwitching(const std::string& device_id_from, + const std::string& device_id_to) FINAL; + protected: /** * Starts next retry exchange policy table diff --git a/src/components/application_manager/src/application_impl.cc b/src/components/application_manager/src/application_impl.cc index 8af4c97543..fcdbc25a3e 100644 --- a/src/components/application_manager/src/application_impl.cc +++ b/src/components/application_manager/src/application_impl.cc @@ -79,12 +79,14 @@ namespace application_manager { void SwitchApplicationParameters(ApplicationSharedPtr app, const uint32_t app_id, - const uint32_t device_id) { + const size_t device_id, + const std::string& mac_address) { 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; + application->mac_address_ = mac_address; } ApplicationImpl::ApplicationImpl( diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc index f9fa396d80..b4cb692740 100644 --- a/src/components/application_manager/src/application_manager_impl.cc +++ b/src/components/application_manager/src/application_manager_impl.cc @@ -1073,18 +1073,25 @@ void ApplicationManagerImpl::RemoveDevice( } void ApplicationManagerImpl::OnDeviceSwitchingStart( - const std::string& device_uid) { + const connection_handler::Device& device_from, + const connection_handler::Device& device_to) { 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(), + 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)); + std::bind1st(std::ptr_fun(&device_id_comparator), + device_from.mac_address())); } + { + // During sending of UpdateDeviceList this lock is acquired also so making + // it scoped + sync_primitives::AutoLock lock(reregister_wait_list_lock_); for (auto i = reregister_wait_list_.begin(); reregister_wait_list_.end() != i; ++i) { auto app = *i; @@ -1093,6 +1100,28 @@ void ApplicationManagerImpl::OnDeviceSwitchingStart( } } + policy_handler_->OnDeviceSwitching(device_from.mac_address(), + device_to.mac_address()); + + connection_handler::DeviceMap device_list; + device_list.insert(std::make_pair(device_to.device_handle(), device_to)); + + smart_objects::SmartObjectSPtr msg_params = + MessageHelper::CreateDeviceListSO(device_list, GetPolicyHandler(), *this); + + auto update_list = utils::MakeShared<smart_objects::SmartObject>(); + smart_objects::SmartObject& so_to_send = *update_list; + so_to_send[jhs::S_PARAMS][jhs::S_FUNCTION_ID] = + hmi_apis::FunctionID::BasicCommunication_UpdateDeviceList; + so_to_send[jhs::S_PARAMS][jhs::S_MESSAGE_TYPE] = + hmi_apis::messageType::request; + so_to_send[jhs::S_PARAMS][jhs::S_PROTOCOL_VERSION] = 3; + so_to_send[jhs::S_PARAMS][jhs::S_PROTOCOL_TYPE] = 1; + so_to_send[jhs::S_PARAMS][jhs::S_CORRELATION_ID] = GetNextHMICorrelationID(); + so_to_send[jhs::S_MSG_PARAMS] = *msg_params; + ManageHMICommand(update_list); +} + void ApplicationManagerImpl::OnDeviceSwitchingFinish( const std::string& device_uid) { LOG4CXX_AUTO_TRACE(logger_); @@ -1115,8 +1144,9 @@ void ApplicationManagerImpl::OnDeviceSwitchingFinish( void ApplicationManagerImpl::SwitchApplication(ApplicationSharedPtr app, const uint32_t connection_key, - const uint32_t device_id) { - LOG4CXX_AUTO_TRACE(logger_); + const size_t device_id, + const std::string& mac_address) { + LOG4CXX_AUTO_TRACE(logger_); sync_primitives::AutoLock lock(applications_list_lock_); DCHECK_OR_RETURN_VOID(1 == applications_.erase(app)); @@ -1125,7 +1155,7 @@ void ApplicationManagerImpl::SwitchApplication(ApplicationSharedPtr app, << ". Changing device id to " << device_id); - SwitchApplicationParameters(app, connection_key, device_id); + SwitchApplicationParameters(app, connection_key, device_id, mac_address); // Normally this is done during registration, however since switched apps are // not being registered again need to set protocol version on session. @@ -4056,11 +4086,9 @@ void ApplicationManagerImpl::ProcessReconnection( 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); - SwitchApplication(application, connection_key, new_device_id); + SwitchApplication(application, connection_key, new_device_id, device_mac); // Update connection type for existed device. GetPolicyHandler().AddDevice(device_mac, connection_type); 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 4dd14e2075..fda4d09de2 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 @@ -370,7 +370,7 @@ void RegisterAppInterfaceRequest::Run() { GetPolicyHandler().SetDeviceInfo(device_mac, device_info); - SendRegisterAppInterfaceResponseToMobile(AppicationType::kNewApplication); + SendRegisterAppInterfaceResponseToMobile(ApplicationType::kNewApplication); smart_objects::SmartObjectSPtr so = GetLockScreenIconUrlNotification(connection_key(), application); application_manager_.ManageMobileCommand(so, commands::Command::ORIGIN_SDL); @@ -510,7 +510,7 @@ void FillUIRelatedFields(smart_objects::SmartObject& response_params, } void RegisterAppInterfaceRequest::SendRegisterAppInterfaceResponseToMobile( - AppicationType app_type) { + ApplicationType app_type) { LOG4CXX_AUTO_TRACE(logger_); smart_objects::SmartObject response_params(smart_objects::SmartType_Map); @@ -640,6 +640,28 @@ void RegisterAppInterfaceRequest::SendRegisterAppInterfaceResponseToMobile( response_params[strings::system_software_version] = ccpu_version; } + if (ApplicationType::kSwitchedApplicationWrongHashId == app_type) { + LOG4CXX_DEBUG(logger_, + "Application has been switched from another transport, " + "but doesn't have correct hashID."); + + application_manager::RecallApplicationData(application, + application_manager_); + + SendResponse(true, mobile_apis::Result::RESUME_FAILED, NULL, + &response_params); + return; + } + + if (ApplicationType::kSwitchedApplicationHashOk == app_type) { + LOG4CXX_DEBUG(logger_, + "Application has been switched from another transport " + "and has correct hashID."); + SendResponse(true, mobile_apis::Result::SUCCESS, NULL, + &response_params); + return; + } + bool resumption = (*message_)[strings::msg_params].keyExists(strings::hash_id); @@ -670,27 +692,6 @@ void RegisterAppInterfaceRequest::SendRegisterAppInterfaceResponseToMobile( result_code = result_checking_app_hmi_type_; } - if (AppicationType::kSwitchedApplication == app_type) { - LOG4CXX_DEBUG(logger_, - "Application has been switched from another transport."); - - if (hash_id.empty() && resumer.CheckApplicationHash(application, hash_id)) { - LOG4CXX_INFO(logger_, - "Application does not have hashID saved and neither " - "provided it with RAI. Nothing to resume."); - result_code = mobile_apis::Result::SUCCESS; - } else if (!resumption || - mobile_apis::Result::RESUME_FAILED == result_code) { - application_manager::RecallApplicationData(application, - application_manager_); - resumer.RemoveApplicationFromSaved(application); - result_code = mobile_apis::Result::RESUME_FAILED; - } - - SendResponse(true, result_code, add_info.c_str(), &response_params); - return; - } - // in case application exist in resumption we need to send resumeVrgrammars if (false == resumption) { resumption = resumer.IsApplicationSaved(application->policy_app_id(), @@ -1465,9 +1466,20 @@ bool RegisterAppInterfaceRequest::IsApplicationSwitched() { } LOG4CXX_DEBUG(logger_, "Application is found in reconnection list."); + + auto app_type = ApplicationType::kSwitchedApplicationWrongHashId; + if ((*message_)[strings::msg_params].keyExists(strings::hash_id)) { + const auto hash_id = + (*message_)[strings::msg_params][strings::hash_id].asString(); + + auto& resume_ctrl = application_manager_.resume_controller(); + if (resume_ctrl.CheckApplicationHash(app, hash_id)) { + app_type = ApplicationType::kSwitchedApplicationHashOk; + } + } + application_manager_.ProcessReconnection(app, connection_key()); - SendRegisterAppInterfaceResponseToMobile( - AppicationType::kSwitchedApplication); + SendRegisterAppInterfaceResponseToMobile(app_type); application_manager_.SendHMIStatusNotification(app); diff --git a/src/components/application_manager/src/policies/policy_handler.cc b/src/components/application_manager/src/policies/policy_handler.cc index 570aee180c..e5bf7a2a7c 100644 --- a/src/components/application_manager/src/policies/policy_handler.cc +++ b/src/components/application_manager/src/policies/policy_handler.cc @@ -852,6 +852,13 @@ uint32_t PolicyHandler::ChooseRandomAppForPolicyUpdate( return 0; } +void PolicyHandler::OnDeviceSwitching(const std::string& device_id_from, + const std::string& device_id_to) { + LOG4CXX_AUTO_TRACE(logger_); + POLICY_LIB_CHECK_VOID(); + policy_manager_->OnDeviceSwitching(device_id_from, device_id_to); +} + void PolicyHandler::OnGetStatusUpdate(const uint32_t correlation_id) { LOG4CXX_AUTO_TRACE(logger_); POLICY_LIB_CHECK_VOID(); 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 4c0c7b2985..a4d228f0fe 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 @@ -140,9 +140,12 @@ class ConnectionHandlerImpl /** * @brief OnDeviceSwitchingStart notifies listeners on device transport * switching start - * @param device_uid the id of the device which has to be switched. + * @param device_uid_from the id of the device which has to switch its + * transport + * @param device_uid_to the id of the device on new transport */ - void OnDeviceSwitchingStart(const std::string& device_uid) FINAL; + void OnDeviceSwitchingStart(const std::string& device_uid_from, + const std::string& device_uid_to) FINAL; /** * @brief OnDeviceSwitchingFinish notifies listeners on device transport diff --git a/src/components/connection_handler/src/connection_handler_impl.cc b/src/components/connection_handler/src/connection_handler_impl.cc index 67a54678cc..9f68d5ce31 100644 --- a/src/components/connection_handler/src/connection_handler_impl.cc +++ b/src/components/connection_handler/src/connection_handler_impl.cc @@ -198,12 +198,34 @@ void ConnectionHandlerImpl::OnDeviceSwitchingFinish( } } +namespace { +struct DeviceFinder { + explicit DeviceFinder(const std::string& device_uid) + : device_uid_(device_uid) {} + bool operator()(const DeviceMap::value_type& device) { + return device_uid_ == device.second.mac_address(); + } +private: + const std::string& device_uid_; +}; +} // namespace + void ConnectionHandlerImpl::OnDeviceSwitchingStart( - const std::string& device_uid) { + const std::string& device_uid_from, const std::string& device_uid_to) { + auto device_from = std::find_if( + device_list_.begin(), device_list_.end(), + DeviceFinder(encryption::MakeHash(device_uid_from))); + + auto device_to = std::find_if( + device_list_.begin(), device_list_.end(), + DeviceFinder(encryption::MakeHash(device_uid_to))); + + DCHECK_OR_RETURN_VOID(device_list_.end() != device_from); + DCHECK_OR_RETURN_VOID(device_list_.end() != device_to); sync_primitives::AutoReadLock read_lock(connection_handler_observer_lock_); if (connection_handler_observer_) { - connection_handler_observer_->OnDeviceSwitchingStart( - encryption::MakeHash(device_uid)); + connection_handler_observer_->OnDeviceSwitchingStart(device_from->second, + device_to->second); } } diff --git a/src/components/include/application_manager/policies/policy_handler_interface.h b/src/components/include/application_manager/policies/policy_handler_interface.h index d7e9f1cea7..f0859ece38 100644 --- a/src/components/include/application_manager/policies/policy_handler_interface.h +++ b/src/components/include/application_manager/policies/policy_handler_interface.h @@ -427,6 +427,15 @@ class PolicyHandlerInterface { virtual const PolicySettings& get_settings() const = 0; virtual const std::string RemoteAppsUrl() const = 0; + /** + * @brief OnDeviceSwitching Notifies policy manager on device switch event so + * policy permissions should be processed accordingly + * @param device_id_from Id of device being switched + * @param device_id_to Id of device on the new transport + */ + virtual void OnDeviceSwitching(const std::string& device_id_from, + const std::string& device_id_to) = 0; + #ifdef SDL_REMOTE_CONTROL /** * @brief Sets HMI default type for specified application diff --git a/src/components/include/connection_handler/connection_handler_observer.h b/src/components/include/connection_handler/connection_handler_observer.h index 7ba2233210..7eb17264eb 100644 --- a/src/components/include/connection_handler/connection_handler_observer.h +++ b/src/components/include/connection_handler/connection_handler_observer.h @@ -127,9 +127,11 @@ class ConnectionHandlerObserver { /** * @brief OnDeviceSwitchingStart is invoked on device transport switching * start (e.g. from Bluetooth to USB) - * @param device_uid UID of device being switched + * @param device_from device params being switched to new transport + * @param device_to device params on the new transport */ - virtual void OnDeviceSwitchingStart(const std::string& device_uid) = 0; + virtual void OnDeviceSwitchingStart(const Device& device_from, + const Device& device_to) = 0; /** * @brief OnDeviceSwitchingFinish is invoked on device trasport switching end diff --git a/src/components/include/policy/policy_external/policy/policy_manager.h b/src/components/include/policy/policy_external/policy/policy_manager.h index adf195e3a9..24905671fa 100644 --- a/src/components/include/policy/policy_external/policy/policy_manager.h +++ b/src/components/include/policy/policy_external/policy/policy_manager.h @@ -483,6 +483,9 @@ class PolicyManager : public usage_statistics::StatisticsManager { */ virtual void OnAppRegisteredOnMobile(const std::string& application_id) = 0; + virtual void OnDeviceSwitching(const std::string& device_id_from, + const std::string& device_id_to) = 0; + /** * @brief Gets request types for application * @param policy_app_id Unique application id diff --git a/src/components/include/policy/policy_regular/policy/policy_manager.h b/src/components/include/policy/policy_regular/policy/policy_manager.h index 510e35e699..3e90cfc094 100644 --- a/src/components/include/policy/policy_regular/policy/policy_manager.h +++ b/src/components/include/policy/policy_regular/policy/policy_manager.h @@ -487,6 +487,9 @@ class PolicyManager : public usage_statistics::StatisticsManager { */ virtual void OnAppRegisteredOnMobile(const std::string& application_id) = 0; + virtual void OnDeviceSwitching(const std::string& device_id_from, + const std::string& device_id_to) = 0; + /** * @brief RetrieveCertificate Allows to obtain certificate in order * to start secure connection. diff --git a/src/components/include/transport_manager/common.h b/src/components/include/transport_manager/common.h index 833a35602a..58bcf6bb17 100644 --- a/src/components/include/transport_manager/common.h +++ b/src/components/include/transport_manager/common.h @@ -35,6 +35,7 @@ #include <vector> #include <string> +#include <map> /** * @brief - transport_manager namespace @@ -90,5 +91,12 @@ typedef int ApplicationHandle; * @brief Type definition for vector that contain ApplicationHandle variables. */ typedef std::vector<ApplicationHandle> ApplicationList; + +/** + * @brief SwitchableDevices defines list of devices having transport switch id + * i.e. able to switch their transport. Maps unique device id (MAC, serial etc.) + * to transport switch id (e.g. connection UUID for iAP2 transport) + */ +typedef std::map<DeviceUID, std::string> SwitchableDevices; } // namespace transport_manager #endif // SRC_COMPONENTS_INCLUDE_TRANSPORT_MANAGER_COMMON_H_ diff --git a/src/components/include/transport_manager/transport_adapter/device.h b/src/components/include/transport_manager/transport_adapter/device.h index 3adb6cd2e6..4616a8cfc2 100644 --- a/src/components/include/transport_manager/transport_adapter/device.h +++ b/src/components/include/transport_manager/transport_adapter/device.h @@ -58,6 +58,22 @@ class Device { : name_(name) , unique_device_id_(unique_device_id) , keep_on_disconnect_(false) {} + + /** + * Constructor for creating device supporting transport switch + * @brief Device constructor + * @param name Device name + * @param unique_device_id Unique device id + * @param transport_switch_id Id used for transport switching flow + */ + Device(const std::string& name, + const DeviceUID& unique_device_id, + std::string transport_switch_id) + : name_(name) + , unique_device_id_(unique_device_id) + , transport_switch_id_(transport_switch_id) + , keep_on_disconnect_(false) {} + /** * @brief Destructor. **/ @@ -114,6 +130,13 @@ class Device { keep_on_disconnect_ = keep_on_disconnect; } + /** + * @brief transport_switch_id Returns id used for transport switching + * flow of device. Filled if applicable, otherwise - empty. + */ + inline std::string transport_switch_id() const { + return transport_switch_id_; + } private: /** * @brief Device user-friendly name. @@ -124,6 +147,11 @@ class Device { * @brief Unique device identifier across all devices. **/ DeviceUID unique_device_id_; + /** + * @brief transport_switch_id_ ID used to switch device from one to another + * transport. Filled if applicable, otherwise - empty + */ + std::string transport_switch_id_; /** * @brief If true, device will remain in list even if all its connections 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 cd097b698d..66478c60ac 100644 --- a/src/components/include/transport_manager/transport_adapter/transport_adapter.h +++ b/src/components/include/transport_manager/transport_adapter/transport_adapter.h @@ -287,6 +287,12 @@ class TransportAdapter { virtual void StopDevice(const DeviceUID& device_id) const = 0; /** + * @brief DoTransportSwitch notifies listeners of transport adapter events + * that transport switching is requested by system + */ + virtual void DoTransportSwitch() const = 0; + + /** * @brief DeviceSwitched is triggered for adapter to proceed with possible * further switching steps required on device side. E.g. to notify device * on end of switching so it can disconnect transport being switched from. @@ -294,6 +300,7 @@ class TransportAdapter { */ virtual void DeviceSwitched(const DeviceUID& device_handle) = 0; + virtual SwitchableDevices GetSwitchableDevices() const = 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 c277faa339..18f4ccb2d1 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 @@ -56,7 +56,8 @@ enum class EventTypeEnum { ON_RECEIVED_DONE, ON_RECEIVED_FAIL, ON_COMMUNICATION_ERROR, - ON_UNEXPECTED_DISCONNECT + ON_UNEXPECTED_DISCONNECT, + ON_TRANSPORT_SWITCH_REQUESTED }; class TransportAdapterEvent { diff --git a/src/components/include/transport_manager/transport_manager_listener.h b/src/components/include/transport_manager/transport_manager_listener.h index 80994e700e..d336eade45 100644 --- a/src/components/include/transport_manager/transport_manager_listener.h +++ b/src/components/include/transport_manager/transport_manager_listener.h @@ -72,9 +72,12 @@ class TransportManagerListener { /** * @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. + * @param device_uid_from the id of the device which has to switch its + * transport + * @param device_uid_to the id of the device on new transport */ - virtual void OnDeviceSwitchingStart(const DeviceUID& device_uid) = 0; + virtual void OnDeviceSwitchingStart(const DeviceUID& device_uid_from, + const DeviceUID& device_uid_to) = 0; /** * @brief OnDeviceSwitchingFinish notifies listener that device reconnection 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 f7843c9a68..ca6c573a06 100644 --- a/src/components/include/transport_manager/transport_manager_listener_empty.h +++ b/src/components/include/transport_manager/transport_manager_listener_empty.h @@ -71,9 +71,12 @@ class TransportManagerListenerEmpty : public TransportManagerListener { /** * @brief OnDeviceSwitchingStart allows to notify listener that device is * going to switch its connection. This default implementation does nothing. - * @param device_uid the id of the device which has to be switched. + * @param device_uid_from the id of the device which has to switch its + * transport + * @param device_uid_to the id of the device on new transport */ - void OnDeviceSwitchingStart(const DeviceUID& device_uid) OVERRIDE {} + void OnDeviceSwitchingStart(const DeviceUID& device_uid_from, + const DeviceUID& device_uid_to) OVERRIDE {} /** * @brief OnDeviceSwitchingFinish notifies listener that device reconnection diff --git a/src/components/policy/policy_external/include/policy/cache_manager.h b/src/components/policy/policy_external/include/policy/cache_manager.h index aa5360d2b7..ef93ec72ab 100644 --- a/src/components/policy/policy_external/include/policy/cache_manager.h +++ b/src/components/policy/policy_external/include/policy/cache_manager.h @@ -701,6 +701,15 @@ class CacheManager : public CacheManagerInterface { const PolicySettings& get_settings() const; + /** + * @brief OnDeviceSwitching Processes existing policy permissions for devices + * switching transport + * @param device_id_from Device ID original + * @param device_id_to Device ID new + */ + void OnDeviceSwitching(const std::string& device_id_from, + const std::string& device_id_to) OVERRIDE; + private: std::string currentDateTime(); struct AppHMITypeToString { diff --git a/src/components/policy/policy_external/include/policy/cache_manager_interface.h b/src/components/policy/policy_external/include/policy/cache_manager_interface.h index ae1f8922ba..b9e9f73646 100644 --- a/src/components/policy/policy_external/include/policy/cache_manager_interface.h +++ b/src/components/policy/policy_external/include/policy/cache_manager_interface.h @@ -778,6 +778,15 @@ class CacheManagerInterface { virtual void SetExternalConsentForApp( const PermissionConsent& permissions) = 0; + /** + * @brief OnDeviceSwitching Processes existing policy permissions for devices + * switching transport + * @param device_id_from Device ID original + * @param device_id_to Device ID new + */ + virtual void OnDeviceSwitching(const std::string& device_id_from, + const std::string& device_id_to) = 0; + #ifdef BUILD_TESTS /** * @brief GetPT allows to obtain SharedPtr to PT. diff --git a/src/components/policy/policy_external/include/policy/policy_manager_impl.h b/src/components/policy/policy_external/include/policy/policy_manager_impl.h index 80ceb06e7e..97a2e60055 100644 --- a/src/components/policy/policy_external/include/policy/policy_manager_impl.h +++ b/src/components/policy/policy_external/include/policy/policy_manager_impl.h @@ -559,6 +559,9 @@ class PolicyManagerImpl : public PolicyManager { */ void OnAppRegisteredOnMobile(const std::string& application_id) OVERRIDE; + void OnDeviceSwitching(const std::string& device_id_from, + const std::string& device_id_to) OVERRIDE; + /** * @brief Gets meta information * @return meta information diff --git a/src/components/policy/policy_external/src/cache_manager.cc b/src/components/policy/policy_external/src/cache_manager.cc index b5e44014dd..70739c9159 100644 --- a/src/components/policy/policy_external/src/cache_manager.cc +++ b/src/components/policy/policy_external/src/cache_manager.cc @@ -2629,6 +2629,31 @@ const PolicySettings& CacheManager::get_settings() const { return *settings_; } +void CacheManager::OnDeviceSwitching(const std::string& device_id_from, + const std::string& device_id_to) { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock auto_lock(cache_lock_); + auto device_data = *(pt_->policy_table.device_data); + + auto from = pt_->policy_table.device_data->find(device_id_from); + DCHECK_OR_RETURN_VOID(from != device_data.end()); + + auto to = pt_->policy_table.device_data->find(device_id_to); + DCHECK_OR_RETURN_VOID(to != device_data.end()); + + auto& consents_from = *(from->second.user_consent_records); + auto& consents_to = *(to->second.user_consent_records); + + LOG4CXX_DEBUG(logger_, + "Merging user consents from device: " << device_id_from << + " to device: " << device_id_to); + for (auto f = consents_from.begin(); f != consents_from.end(); ++f) { + const auto app_id = f->first; + LOG4CXX_DEBUG(logger_, "Updating permissions for key: " << app_id); + consents_to[app_id] = f->second; + } +} + CacheManager::BackgroundBackuper::BackgroundBackuper( CacheManager* cache_manager) : cache_manager_(cache_manager) diff --git a/src/components/policy/policy_external/src/policy_manager_impl.cc b/src/components/policy/policy_external/src/policy_manager_impl.cc index d50779383a..24bfd3a4d1 100644 --- a/src/components/policy/policy_external/src/policy_manager_impl.cc +++ b/src/components/policy/policy_external/src/policy_manager_impl.cc @@ -1681,6 +1681,12 @@ void PolicyManagerImpl::OnAppRegisteredOnMobile( SendNotificationOnPermissionsUpdated(application_id); } +void PolicyManagerImpl::OnDeviceSwitching( + const std::string& device_id_from, const std::string& device_id_to) { + LOG4CXX_AUTO_TRACE(logger_); + cache_->OnDeviceSwitching(device_id_from, device_id_to); +} + const MetaInfo PolicyManagerImpl::GetMetaInfo() const { LOG4CXX_AUTO_TRACE(logger_); return cache_->GetMetaInfo(); diff --git a/src/components/policy/policy_regular/include/policy/cache_manager.h b/src/components/policy/policy_regular/include/policy/cache_manager.h index 44827e2602..b711bf6ea2 100644 --- a/src/components/policy/policy_regular/include/policy/cache_manager.h +++ b/src/components/policy/policy_regular/include/policy/cache_manager.h @@ -701,6 +701,15 @@ class CacheManager : public CacheManagerInterface { return pt_; } + /** + * @brief OnDeviceSwitching Processes existing policy permissions for devices + * switching transport + * @param device_id_from Device ID original + * @param device_id_to Device ID new + */ + void OnDeviceSwitching(const std::string& device_id_from, + const std::string& device_id_to) OVERRIDE; + private: std::string currentDateTime(); struct AppHMITypeToString { diff --git a/src/components/policy/policy_regular/include/policy/cache_manager_interface.h b/src/components/policy/policy_regular/include/policy/cache_manager_interface.h index 9712b799dc..9f7c7318db 100644 --- a/src/components/policy/policy_regular/include/policy/cache_manager_interface.h +++ b/src/components/policy/policy_regular/include/policy/cache_manager_interface.h @@ -641,6 +641,15 @@ class CacheManagerInterface { * */ virtual utils::SharedPtr<policy_table::Table> pt() const = 0; + + /** + * @brief OnDeviceSwitching Processes existing policy permissions for devices + * switching transport + * @param device_id_from Device ID original + * @param device_id_to Device ID new + */ + virtual void OnDeviceSwitching(const std::string& device_id_from, + const std::string& device_id_to) = 0; }; typedef utils::SharedPtr<CacheManagerInterface> CacheManagerInterfaceSPtr; diff --git a/src/components/policy/policy_regular/include/policy/policy_manager_impl.h b/src/components/policy/policy_regular/include/policy/policy_manager_impl.h index 1b39392c0c..941db1a67f 100644 --- a/src/components/policy/policy_regular/include/policy/policy_manager_impl.h +++ b/src/components/policy/policy_regular/include/policy/policy_manager_impl.h @@ -553,6 +553,9 @@ class PolicyManagerImpl : public PolicyManager { */ void OnAppRegisteredOnMobile(const std::string& application_id) OVERRIDE; + void OnDeviceSwitching(const std::string& device_id_from, + const std::string& device_id_to) OVERRIDE; + /** * @brief RetrieveCertificate Allows to obtain certificate in order * to start secure connection. diff --git a/src/components/policy/policy_regular/src/cache_manager.cc b/src/components/policy/policy_regular/src/cache_manager.cc index 12b29e0675..94a33a1e04 100644 --- a/src/components/policy/policy_regular/src/cache_manager.cc +++ b/src/components/policy/policy_regular/src/cache_manager.cc @@ -1632,6 +1632,12 @@ const PolicySettings& CacheManager::get_settings() const { return *settings_; } +void CacheManager::OnDeviceSwitching(const std::string& device_id_from, + const std::string& device_id_to) { + LOG4CXX_AUTO_TRACE(logger_); + LOG4CXX_INFO(logger_, "Implementation does not support user consents."); +} + CacheManager::BackgroundBackuper::BackgroundBackuper( CacheManager* cache_manager) : cache_manager_(cache_manager) diff --git a/src/components/policy/policy_regular/src/policy_manager_impl.cc b/src/components/policy/policy_regular/src/policy_manager_impl.cc index 640b9c1457..cf106ceb52 100644 --- a/src/components/policy/policy_regular/src/policy_manager_impl.cc +++ b/src/components/policy/policy_regular/src/policy_manager_impl.cc @@ -366,6 +366,12 @@ void PolicyManagerImpl::OnAppRegisteredOnMobile( SendNotificationOnPermissionsUpdated(application_id); } +void PolicyManagerImpl::OnDeviceSwitching( + const std::string& device_id_from, const std::string& device_id_to) { + LOG4CXX_AUTO_TRACE(logger_); + cache_->OnDeviceSwitching(device_id_from, device_id_to); +} + const std::vector<std::string> PolicyManagerImpl::GetAppRequestTypes( const std::string policy_app_id) const { std::vector<std::string> request_types; 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 df4c932260..2b1ada79ad 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 @@ -400,6 +400,26 @@ class TransportAdapterImpl : public TransportAdapter, const DataSendError& error) OVERRIDE; /** + * @brief DoTransportSwitch notifies listeners of transport adapter events + * that transport switching is requested by system + */ + void DoTransportSwitch() const OVERRIDE; + + /** + * @brief DeviceSwitched Notifies system on successful transport switch for + * particular device + * @param device_handle Device handle of switched device + */ + void DeviceSwitched(const DeviceUID& device_handle) OVERRIDE; + + /** + * @brief GetSwitchableDevices Provides list of devices able to switch their + * transport (e.g. iAP2 Bluetooth to iAP2 USB). + * @return + */ + SwitchableDevices GetSwitchableDevices() const OVERRIDE; + + /** * @brief Return name of device. * * @param device_id Device unique identifier. @@ -416,15 +436,6 @@ class TransportAdapterImpl : public TransportAdapter, void StopDevice(const DeviceUID& device_id) const OVERRIDE; /** - * @brief DeviceSwitched is triggered for adapter to proceed with possible - * further switching steps required on device side. E.g. to notify device - * on end of switching so it can disconnect transport being switched from. - * This is default implemenation does nothing. Must be overloaded if needed. - * @param device_handle Device id to notify on event - */ - void DeviceSwitched(const DeviceUID& device_handle) OVERRIDE; - - /** * @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 db8ab4fce5..424fa53dea 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 @@ -270,6 +270,13 @@ class TransportAdapterListener { virtual void OnCommunicationError(const TransportAdapter* transport_adapter, const DeviceUID& device_handle, const ApplicationHandle& app_handle) = 0; + /** + * @brief OnTransportSwitchRequested notifies on received signal to start + * transport switching flow (at the moment Bluetooth to USB only) + * @param transport_adapter Transport adapter who received the signal + */ + virtual void OnTransportSwitchRequested( + const TransportAdapter* transport_adapter) = 0; }; } // transport_adapter namespace 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 f5a7934ed6..9b853d9610 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 @@ -263,7 +263,14 @@ class TransportAdapterListenerImpl */ virtual void OnCommunicationError(const TransportAdapter* adapter, const DeviceUID& device, - const ApplicationHandle& app_id); + const ApplicationHandle& app_id) OVERRIDE; + + /** + * @brief OnTransportSwitchRequested notifies on received signal to start + * transport switching flow (at the moment Bluetooth to USB only) + * @param transport_adapter Transport adapter who received the signal + */ + void OnTransportSwitchRequested(const TransportAdapter* adapter) OVERRIDE; private: TransportManager* transport_manager_; 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 bd592a4686..eaa71ce3bb 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 @@ -462,14 +462,10 @@ class TransportManagerImpl * initiates switching sequence for upper layers. Also starts timer to wait * for sequence to complete. * @param ta Transport adapter having device to try switching sequence - * @param value Value from device-to-adapter container having all the data - * required * At the moment implementation implies only IAP2-Bluetooth to IAP2-USB * switching - * @return True if sequence has been successfully initiated, otherwise - false */ - bool TryDeviceSwitch(TransportAdapter* ta, - DeviceToAdapterMap::iterator value); + void TryDeviceSwitch(TransportAdapter* ta); void AddDataToContainer( ConnectionUID id, 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 ba85ea8276..7b93bf9044 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 @@ -693,6 +693,16 @@ void TransportAdapterImpl::DataSendFailed( LOG4CXX_TRACE(logger_, "exit"); } +void TransportAdapterImpl::DoTransportSwitch() const { + LOG4CXX_AUTO_TRACE(logger_); + std::for_each( + listeners_.begin(), + listeners_.end(), + std::bind2nd( + std::mem_fun(&TransportAdapterListener::OnTransportSwitchRequested), + this)); +} + void TransportAdapterImpl::DeviceSwitched(const DeviceUID& device_handle) { LOG4CXX_DEBUG(logger_, "Switching is not implemented for that adapter type " @@ -882,6 +892,29 @@ std::string TransportAdapterImpl::GetConnectionType() const { return devicesType[GetDeviceType()]; } +SwitchableDevices TransportAdapterImpl::GetSwitchableDevices() const { + LOG4CXX_AUTO_TRACE(logger_); + SwitchableDevices devices; + sync_primitives::AutoLock locker(devices_mutex_); + for (DeviceMap::const_iterator it = devices_.begin(); it != devices_.end(); + ++it) { + const auto device_uid = it->first; + const auto device = it->second; + const auto transport_switch_id = device->transport_switch_id(); + if (transport_switch_id.empty()) { + LOG4CXX_DEBUG(logger_, + "Device is not suitable for switching: " << device_uid); + continue; + } + LOG4CXX_DEBUG(logger_, + "Device is suitable for switching: " << device_uid); + devices.insert(std::make_pair(device_uid, transport_switch_id)); + } + LOG4CXX_INFO(logger_, + "Found number of switchable devices: " << devices.size()); + return devices; +} + #ifdef TELEMETRY_MONITOR void TransportAdapterImpl::SetTelemetryObserver(TMTelemetryObserver* observer) { metric_observer_ = observer; 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 a559174dd7..f1181ce921 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 @@ -359,4 +359,21 @@ void TransportAdapterListenerImpl::OnCommunicationError( } LOG4CXX_TRACE(logger_, "exit"); } + +void TransportAdapterListenerImpl::OnTransportSwitchRequested( + const transport_adapter::TransportAdapter* adapter) { + LOG4CXX_AUTO_TRACE(logger_); + const TransportAdapterEvent event( + EventTypeEnum::ON_TRANSPORT_SWITCH_REQUESTED, + transport_adapter_, + "", + 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"); + } +} } // namespace transport_manager diff --git a/src/components/transport_manager/src/transport_manager_impl.cc b/src/components/transport_manager/src/transport_manager_impl.cc index 4ab5371b74..7b4e722b4d 100644 --- a/src/components/transport_manager/src/transport_manager_impl.cc +++ b/src/components/transport_manager/src/transport_manager_impl.cc @@ -730,41 +730,116 @@ TransportManagerImpl::GetActiveConnection( return NULL; } -bool TransportManagerImpl::TryDeviceSwitch( - transport_adapter::TransportAdapter* ta, - DeviceToAdapterMap::iterator value) { +namespace { + +struct TAFinder { + bool operator()(const std::vector<TransportAdapter*>::value_type& i) const { + return i->GetDeviceType() == transport_adapter::DeviceType::IOS_BT; + } +}; + +struct SwitchableFinder { + explicit SwitchableFinder(SwitchableDevices::const_iterator what) + : what_(what) {} + bool operator()(const SwitchableDevices::value_type& i) const { + return what_->second == i.second; + } + + private: + SwitchableDevices::const_iterator what_; +}; + +} // namespace + +void TransportManagerImpl::TryDeviceSwitch( + transport_adapter::TransportAdapter* adapter) { LOG4CXX_AUTO_TRACE(logger_); - const auto device_uid = value->first; - const auto old_adapter = value->second; + if (adapter->GetDeviceType() != transport_adapter::DeviceType::IOS_USB) { + LOG4CXX_ERROR(logger_, "Switching requested not from iAP-USB transport."); + return; + } + + const auto ios_bt_adapter = std::find_if( + transport_adapters_.begin(), transport_adapters_.end(), TAFinder()); + + if (transport_adapters_.end() == ios_bt_adapter) { + LOG4CXX_WARN(logger_, + "There is no iAP2 Bluetooth adapter found. Switching is not possible."); + return; + } + + const SwitchableDevices usb_switchable_devices = + adapter->GetSwitchableDevices(); + const auto bt_switchable_devices = (*ios_bt_adapter)->GetSwitchableDevices(); + auto bt = bt_switchable_devices.end(); + auto usb = usb_switchable_devices.begin(); + for (; usb != usb_switchable_devices.end(); ++usb) { + SwitchableFinder finder(usb); + bt = std::find_if( + bt_switchable_devices.begin(), bt_switchable_devices.end(), finder); + + if (bt != bt_switchable_devices.end()) { + break; + } + } + + if (bt_switchable_devices.end() == bt) { + LOG4CXX_WARN(logger_, + "No suitable for switching iAP2 Bluetooth device found."); + return; + } + + LOG4CXX_DEBUG(logger_, + "Found UUID suitable for transport switching: " << bt->second); + LOG4CXX_DEBUG(logger_, + "Device to switch from: " << bt->first + << " to: " << usb->first); - if (transport_adapter::DeviceType::IOS_BT != old_adapter->GetDeviceType()) { - LOG4CXX_DEBUG(logger_, "Adapter type is not IOS_BT."); - return false; + sync_primitives::AutoWriteLock lock(device_to_adapter_map_lock_); + + const auto bt_device_uid = bt->first; + const auto device_to_switch = device_to_adapter_map_.find(bt_device_uid); + if (device_to_adapter_map_.end() == device_to_switch) { + LOG4CXX_ERROR(logger_, "There is no known device found with UID " + << bt_device_uid + << " . Transport switching is not possible."); + DCHECK_OR_RETURN_VOID(false); + return; } - const auto new_adapter = ta; - old_adapter->StopDevice(device_uid); - new_adapter->DeviceSwitched(device_uid); + const auto usb_uid = usb->first; + const auto bt_uid = device_to_switch->first; + const auto bt_adapter = device_to_switch->second; + + LOG4CXX_DEBUG(logger_, "Known device with UID " + << bt_uid << " is appropriate for transport switching."); + + RaiseEvent( + &TransportManagerListener::OnDeviceSwitchingStart, bt_uid, usb_uid); + + bt_adapter->StopDevice(bt_uid); + adapter->DeviceSwitched(usb_uid); - DeactivateDeviceConnections(device_uid); + // Maybe not needed anymore + DeactivateDeviceConnections(bt_uid); - value->second = new_adapter; - device_to_reconnect_ = device_uid; + // Maybe not needed anymore + device_to_switch->second = adapter; + device_to_reconnect_ = bt_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; + "Device switch for device id " << bt_uid << " is done."); + return; } bool TransportManagerImpl::UpdateDeviceMapping( transport_adapter::TransportAdapter* ta) { - const DeviceList device_list = ta->GetDeviceList(); - LOG4CXX_DEBUG(logger_, "DEVICE_LIST_UPDATED " << device_list.size()); + const DeviceList adapter_device_list = ta->GetDeviceList(); + LOG4CXX_DEBUG(logger_, "DEVICE_LIST_UPDATED " << adapter_device_list.size()); sync_primitives::AutoWriteLock lock(device_to_adapter_map_lock_); @@ -774,13 +849,16 @@ bool TransportManagerImpl::UpdateDeviceMapping( for (auto item = device_to_adapter_map_.begin(); device_to_adapter_map_.end() != item;) { - if (item->second != ta) { + const auto adapter = item->second; + if (adapter != ta) { ++item; continue; } - if (device_list.end() != - std::find(device_list.begin(), device_list.end(), item->first)) { + const auto device_uid = item->first; + if (adapter_device_list.end() != std::find(adapter_device_list.begin(), + adapter_device_list.end(), + device_uid)) { ++item; continue; } @@ -788,32 +866,30 @@ bool TransportManagerImpl::UpdateDeviceMapping( 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(); + for (DeviceList::const_iterator it = adapter_device_list.begin(); + it != adapter_device_list.end(); ++it) { const auto device_uid = *it; - auto result = device_to_adapter_map_.insert(std::make_pair(device_uid, ta)); - if (result.second || TryDeviceSwitch(ta, result.first)) { + const auto result = + device_to_adapter_map_.insert(std::make_pair(device_uid, ta)); + if (!result.second) { + LOG4CXX_WARN(logger_, "Device UID " + << device_uid + << " is known already. Processing skipped." + "Connection type is: " << ta->GetConnectionType()); + continue; + } DeviceHandle device_handle = converter_.UidToHandle(device_uid, ta->GetConnectionType()); DeviceInfo info( device_handle, device_uid, ta->DeviceName(device_uid), ta->GetConnectionType()); RaiseEvent(&TransportManagerListener::OnDeviceFound, info); - } else if(device_to_adapter_map_[device_uid]->GetDeviceType() == - ta->GetDeviceType()) { - LOG4CXX_DEBUG(logger_, "Device with UID: " << device_uid - << " is found for the same adapter type. Skipping."); - } else { - LOG4CXX_ERROR( - logger_, - "Same UID " + device_uid + " detected, but transport switching failed."); - return false; - } } LOG4CXX_DEBUG(logger_, @@ -862,6 +938,11 @@ void TransportManagerImpl::Handle(TransportAdapterEvent event) { LOG4CXX_DEBUG(logger_, "event_type = ON_DEVICE_LIST_UPDATED"); break; } + case EventTypeEnum::ON_TRANSPORT_SWITCH_REQUESTED: { + TryDeviceSwitch(event.transport_adapter); + LOG4CXX_DEBUG(logger_, "event_type = ON_TRANSPORT_SWITCH_REQUESTED"); + break; + } case EventTypeEnum::ON_FIND_NEW_APPLICATIONS_REQUEST: { RaiseEvent(&TransportManagerListener::OnFindNewApplicationsRequest); LOG4CXX_DEBUG(logger_, "event_type = ON_FIND_NEW_APPLICATIONS_REQUEST"); |