summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Oleynik (GitHub) <aoleynik@luxoft.com>2017-11-29 18:33:59 +0200
committerAndriy Byzhynar <AByzhynar@luxoft.com>2018-01-18 12:03:51 +0200
commitee1d2d7677a7d94da43cc8b1e047bdd816e5fd83 (patch)
treee1b956cd3c472f792117735a20935587e75cfb79
parent11bef60123b62bbe0f8f624bb24a5f0cf74980aa (diff)
downloadsdl_core-ee1d2d7677a7d94da43cc8b1e047bdd816e5fd83.tar.gz
Changes iAP2 Bluetooth to USB switching flow
These changes update switching flow so now instead of automatic switching start in case of same UUID is detected SDL will wait for external signal from the system to start this flow. Also due to UUID is reliable only while device remains connected (at least on certain systems) SDL now uses Bluetooth MAC and USB serial to manage devices and UUID is used only for detection of devices able to switch their transports. Currently only iAP2 Bluetooth to USB support is implemented.
-rw-r--r--src/components/application_manager/include/application_manager/application_impl.h9
-rw-r--r--src/components/application_manager/include/application_manager/application_manager_impl.h10
-rw-r--r--src/components/application_manager/include/application_manager/commands/mobile/register_app_interface_request.h5
-rw-r--r--src/components/application_manager/include/application_manager/policies/policy_handler.h9
-rw-r--r--src/components/application_manager/src/application_impl.cc4
-rw-r--r--src/components/application_manager/src/application_manager_impl.cc46
-rw-r--r--src/components/application_manager/src/commands/mobile/register_app_interface_request.cc62
-rw-r--r--src/components/application_manager/src/policies/policy_handler.cc7
-rw-r--r--src/components/connection_handler/include/connection_handler/connection_handler_impl.h7
-rw-r--r--src/components/connection_handler/src/connection_handler_impl.cc28
-rw-r--r--src/components/include/application_manager/policies/policy_handler_interface.h9
-rw-r--r--src/components/include/connection_handler/connection_handler_observer.h6
-rw-r--r--src/components/include/policy/policy_external/policy/policy_manager.h3
-rw-r--r--src/components/include/policy/policy_regular/policy/policy_manager.h3
-rw-r--r--src/components/include/transport_manager/common.h8
-rw-r--r--src/components/include/transport_manager/transport_adapter/device.h28
-rw-r--r--src/components/include/transport_manager/transport_adapter/transport_adapter.h7
-rw-r--r--src/components/include/transport_manager/transport_adapter/transport_adapter_event.h3
-rw-r--r--src/components/include/transport_manager/transport_manager_listener.h7
-rw-r--r--src/components/include/transport_manager/transport_manager_listener_empty.h7
-rw-r--r--src/components/policy/policy_external/include/policy/cache_manager.h9
-rw-r--r--src/components/policy/policy_external/include/policy/cache_manager_interface.h9
-rw-r--r--src/components/policy/policy_external/include/policy/policy_manager_impl.h3
-rw-r--r--src/components/policy/policy_external/src/cache_manager.cc25
-rw-r--r--src/components/policy/policy_external/src/policy_manager_impl.cc6
-rw-r--r--src/components/policy/policy_regular/include/policy/cache_manager.h9
-rw-r--r--src/components/policy/policy_regular/include/policy/cache_manager_interface.h9
-rw-r--r--src/components/policy/policy_regular/include/policy/policy_manager_impl.h3
-rw-r--r--src/components/policy/policy_regular/src/cache_manager.cc6
-rw-r--r--src/components/policy/policy_regular/src/policy_manager_impl.cc6
-rw-r--r--src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_impl.h29
-rw-r--r--src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_listener.h7
-rw-r--r--src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_listener_impl.h9
-rw-r--r--src/components/transport_manager/include/transport_manager/transport_manager_impl.h6
-rw-r--r--src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc33
-rw-r--r--src/components/transport_manager/src/transport_adapter/transport_adapter_listener_impl.cc17
-rw-r--r--src/components/transport_manager/src/transport_manager_impl.cc153
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");