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