diff options
author | JackLivio <jack@livio.io> | 2018-01-25 14:10:01 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-01-25 14:10:01 -0500 |
commit | b973e81afb1d38a27a478ce706e16b5352fb026b (patch) | |
tree | 939c4864d1ef9101414b99560ac81f10e303c242 | |
parent | e8911d03dde016a29b01fe80533bc6ac56531678 (diff) | |
parent | 82d13ffda5f1d946f815a9f0a7de13e0add2fc44 (diff) | |
download | sdl_core-b973e81afb1d38a27a478ce706e16b5352fb026b.tar.gz |
Merge pull request #1927 from smartdevicelink/feature/IAP_over_BT
Implementation of transport switching from iAP2 Bluetooth to iAP2 USB
129 files changed, 5850 insertions, 1055 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..eca22afa63 100644 --- a/src/components/application_manager/include/application_manager/application.h +++ b/src/components/application_manager/include/application_manager/application.h @@ -48,6 +48,7 @@ #include "application_manager/application_state.h" #include "protocol_handler/protocol_handler.h" #include "smart_objects/smart_object.h" +#include "utils/macro.h" namespace application_manager { @@ -561,7 +562,8 @@ 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; + DEPRECATED 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 +620,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 @@ -707,6 +716,16 @@ class Application : public virtual InitialApplicationData, virtual bool IsAudioApplication() const = 0; /** + * DEPRECATED + * @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 IsRegistered allows to distinguish if this * application has been registered. * @@ -764,16 +783,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 { 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..10ec8b8eb8 100644 --- a/src/components/application_manager/include/application_manager/application_impl.h +++ b/src/components/application_manager/include/application_manager/application_impl.h @@ -52,6 +52,7 @@ #include "utils/atomic_object.h" #include "utils/custom_string.h" #include "utils/timer.h" +#include "utils/macro.h" namespace usage_statistics { @@ -65,6 +66,19 @@ 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 + * @param mac_address New device MAC address + */ +void SwitchApplicationParameters(ApplicationSharedPtr app, + const uint32_t app_id, + const size_t device_id, + const std::string& mac_address); + class ApplicationImpl : public virtual Application, public virtual InitialApplicationDataImpl, public virtual DynamicApplicationDataImpl { @@ -73,6 +87,15 @@ 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); + + DEPRECATED ApplicationImpl( + uint32_t application_id, + const std::string& policy_app_id, + const std::string& mac_address, const custom_str::CustomString& app_name, utils::SharedPtr<usage_statistics::StatisticsManager> statistics_manager, ApplicationManager& application_manager); @@ -161,7 +184,7 @@ 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); + DEPRECATED 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; @@ -199,13 +222,6 @@ class ApplicationImpl : public virtual Application, virtual const std::string& curHash() const; -#ifdef CUSTOMER_PASA - // DEPRECATED - virtual bool flag_sending_hash_change_after_awake() const; - // DEPRECATED - virtual void set_flag_sending_hash_change_after_awake(bool flag); -#endif // CUSTOMER_PASA - /** * @brief Change Hash for current application * and send notification to mobile @@ -250,6 +266,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 @@ -440,8 +463,8 @@ class ApplicationImpl : public virtual Application, uint32_t delete_file_in_none_count_; uint32_t list_files_in_none_count_; std::string app_icon_path_; - connection_handler::DeviceHandle device_; - const std::string mac_address_; + 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 +509,12 @@ 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 size_t device_id, + const std::string& mac_address); + DISALLOW_COPY_AND_ASSIGN(ApplicationImpl); }; diff --git a/src/components/application_manager/include/application_manager/application_manager_impl.h b/src/components/application_manager/include/application_manager/application_manager_impl.h index a0b8d45de2..e91bdf5d59 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" @@ -310,6 +311,7 @@ class ApplicationManagerImpl bool IsAppTypeExistsInFullOrLimited(ApplicationConstSharedPtr app) const; /** + * DEPRECATED * @brief Checks if Application is subscribed for way points * @param Application AppID * @return true if Application is subscribed for way points @@ -318,18 +320,40 @@ class ApplicationManagerImpl bool IsAppSubscribedForWayPoints(const uint32_t app_id) const OVERRIDE; /** + * DEPRECATED * @brief Subscribe Application for way points * @param Application AppID */ void SubscribeAppForWayPoints(const uint32_t app_id) OVERRIDE; /** + * DEPRECATED * @brief Unsubscribe Application for way points * @param Application AppID */ void UnsubscribeAppFromWayPoints(const uint32_t app_id) OVERRIDE; /** + * @brief Checks if Application is subscribed for way points + * @param Application pointer + * @return true if Application is subscribed for way points + * otherwise false + */ + bool IsAppSubscribedForWayPoints(ApplicationSharedPtr app) const OVERRIDE; + + /** + * @brief Subscribe Application for way points + * @param Application pointer + */ + void SubscribeAppForWayPoints(ApplicationSharedPtr app) OVERRIDE; + + /** + * @brief Unsubscribe Application for way points + * @param Application pointer + */ + void UnsubscribeAppFromWayPoints(ApplicationSharedPtr app) OVERRIDE; + + /** * @brief Is Any Application is subscribed for way points * @return true if some app is subscribed otherwise false */ @@ -353,6 +377,13 @@ class ApplicationManagerImpl void OnApplicationRegistered(ApplicationSharedPtr app) OVERRIDE; + /** + * @brief OnApplicationSwitched starts processing of commands collected + * during device switching process + * @param app Application + */ + void OnApplicationSwitched(ApplicationSharedPtr app) OVERRIDE; + HMICapabilities& hmi_capabilities() OVERRIDE; const HMICapabilities& hmi_capabilities() const OVERRIDE; @@ -422,8 +453,9 @@ class ApplicationManagerImpl */ void UnregisterAllApplications(); - bool RemoveAppDataFromHMI(ApplicationSharedPtr app); - bool LoadAppDataToHMI(ApplicationSharedPtr app); + DEPRECATED bool RemoveAppDataFromHMI(ApplicationSharedPtr app); + + DEPRECATED bool LoadAppDataToHMI(ApplicationSharedPtr app); bool ActivateApplication(ApplicationSharedPtr app) OVERRIDE; /** @@ -473,6 +505,7 @@ class ApplicationManagerImpl void set_driver_distraction(const bool is_distracting) OVERRIDE; /* + * DEPRECATED * @brief Retrieves if VR session has started * * @return Current VR session state (started, stopped) @@ -480,6 +513,7 @@ class ApplicationManagerImpl inline bool vr_session_started() const; /* + * DEPRECATED * @brief Sets VR session state * * @param state Current HMI VR session state @@ -502,13 +536,28 @@ class ApplicationManagerImpl /** * @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 */ 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 Application id + * @param hmi_level of returned state + * @param audio_state of returned state + * @param system_context of returned state + * @return new regular HMI state + */ + DEPRECATED HmiStatePtr CreateRegularState( uint32_t app_id, mobile_apis::HMILevel::eType hmi_level, mobile_apis::AudioStreamingState::eType audio_state, @@ -837,6 +886,26 @@ class ApplicationManagerImpl void OnFindNewApplicationsRequest() OVERRIDE; void RemoveDevice( const connection_handler::DeviceHandle& device_handle) OVERRIDE; + + /** + * @brief OnDeviceSwitchingStart is invoked on device transport switching + * start (e.g. from Bluetooth to USB) and creates waiting list of applications + * expected to be re-registered after switching is complete + * @param device_from device params being switched to the new transport + * @param device_to device params on the new transport + */ + void OnDeviceSwitchingStart( + const connection_handler::Device& device_from, + const connection_handler::Device& device_to) FINAL; + + /** + * @brief OnDeviceSwitchingFinish is invoked on device trasport switching end + * i.e. timeout for switching is expired, unregisters applications from + * waiting list which haven't been re-registered and clears the waiting list + * @param device_uid UID of device being switched + */ + void OnDeviceSwitchingFinish(const std::string& device_uid) FINAL; + DEPRECATED bool OnServiceStartedCallback( const connection_handler::DeviceHandle& device_handle, const int32_t& session_key, @@ -989,15 +1058,15 @@ class ApplicationManagerImpl uint32_t GenerateNewHMIAppID() OVERRIDE; /** + * DERPECATED * @brief Parse smartObject and replace mobile app Id by HMI app ID - * * @param message Smartobject to be parsed */ void ReplaceMobileByHMIAppId(smart_objects::SmartObject& message); /** + * DEPRECATED * @brief Parse smartObject and replace HMI app ID by mobile app Id - * * @param message Smartobject to be parsed */ void ReplaceHMIByMobileAppId(smart_objects::SmartObject& message); @@ -1054,6 +1123,7 @@ class ApplicationManagerImpl void RemoveAppFromTTSGlobalPropertiesList(const uint32_t app_id) OVERRIDE; /** + * DEPRECATED * @brief method adds application in FULL and LIMITED state * to on_phone_call_app_list_. * Also OnHMIStateNotification with BACKGROUND state sent for these apps @@ -1061,6 +1131,7 @@ class ApplicationManagerImpl void CreatePhoneCallAppList(); /** + * DEPRECATED * @brief method removes application from on_phone_call_app_list_. * * Also OnHMIStateNotification with previous HMI state sent for these apps @@ -1167,15 +1238,6 @@ class ApplicationManagerImpl } }; - struct SubscribedToIVIPredicate { - int32_t vehicle_info_; - SubscribedToIVIPredicate(int32_t vehicle_info) - : vehicle_info_(vehicle_info) {} - bool operator()(const ApplicationSharedPtr app) const { - return app ? app->IsSubscribedToIVI(vehicle_info_) : false; - } - }; - struct GrammarIdPredicate { uint32_t grammar_id_; GrammarIdPredicate(uint32_t grammar_id) : grammar_id_(grammar_id) {} @@ -1212,11 +1274,32 @@ class ApplicationManagerImpl bool IsAppsQueriedFrom( const connection_handler::DeviceHandle handle) const OVERRIDE; + /** + * @brief IsAppInReconnectMode check if application belongs to session + * affected by transport switching at the moment by checking internal + * waiting list prepared on switching start + * @param policy_app_id Application id + * @return True if application is in the waiting list, otherwise - false + */ + 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(); @@ -1485,6 +1568,28 @@ 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 + * @param mac_address New device mac address + */ + void SwitchApplication(ApplicationSharedPtr app, + const uint32_t connection_key, + const size_t device_id, + const std::string& mac_address); + + /** * @brief Converts BSON object containing video parameters to * smart object's map object * @param output the smart object to add video parameters @@ -1617,6 +1722,15 @@ class ApplicationManagerImpl std::auto_ptr<app_launch::AppLaunchData> app_launch_dto_; std::auto_ptr<app_launch::AppLaunchCtrl> app_launch_ctrl_; + /** + * @brief ReregisterWaitList is list of applications expected to be + * re-registered after transport switching is complete + */ + 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 @@ -1631,6 +1745,8 @@ class ApplicationManagerImpl volatile bool is_stopping_; + std::unique_ptr<CommandHolder> commands_holder_; + #ifdef BUILD_TESTS public: /** @@ -1646,7 +1762,7 @@ class ApplicationManagerImpl DISALLOW_COPY_AND_ASSIGN(ApplicationManagerImpl); }; -bool ApplicationManagerImpl::vr_session_started() const { +DEPRECATED bool ApplicationManagerImpl::vr_session_started() const { return is_vr_session_strated_; } diff --git a/src/components/application_manager/include/application_manager/command_holder.h b/src/components/application_manager/include/application_manager/command_holder.h new file mode 100644 index 0000000000..d3171aedbb --- /dev/null +++ b/src/components/application_manager/include/application_manager/command_holder.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2017, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_COMMAND_HOLDER_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_COMMAND_HOLDER_H_ + +#include <string> +#include "application_manager/application.h" +#include "smart_objects/smart_object.h" +#include "utils/shared_ptr.h" + +namespace application_manager { +/** + * @brief The CommandHolder class should hold commands for particular + * application until certain event happens + */ +class CommandHolder { + public: + /** + * @brief The CommandType enum defines type of command to suspend or resume + */ + enum class CommandType { kHmiCommand, kMobileCommand }; + + /** + * @brief ~CommandsHolder destructor + */ + virtual ~CommandHolder() {} + + /** + * @brief Suspend collects command for specific application policy id + * internally + * @param application Application pointer + * @param type Command type + * @param command Command + */ + virtual void Suspend(ApplicationSharedPtr application, + CommandType type, + smart_objects::SmartObjectSPtr command) = 0; + + /** + * @brief Resume send all collected commands for further processing and + * removes them afterward + * @param application Application pointer + * @param type Command type + */ + virtual void Resume(ApplicationSharedPtr application, CommandType type) = 0; + + /** + * @brief Clear removes all collected commands w/o processing + * @param application Application pointer + */ + virtual void Clear(ApplicationSharedPtr application) = 0; +}; +} // namespace application_manager + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_COMMAND_HOLDER_H_ diff --git a/src/components/application_manager/include/application_manager/command_holder_impl.h b/src/components/application_manager/include/application_manager/command_holder_impl.h new file mode 100644 index 0000000000..ed5f6baa62 --- /dev/null +++ b/src/components/application_manager/include/application_manager/command_holder_impl.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2017, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_COMMAND_HOLDER_IMPL_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_COMMAND_HOLDER_IMPL_H_ + +#include "application_manager/command_holder.h" + +#include <string> +#include <vector> +#include <map> +#include "application_manager/application.h" +#include "smart_objects/smart_object.h" +#include "utils/lock.h" +#include "utils/shared_ptr.h" +#include "utils/macro.h" + +namespace application_manager { +class ApplicationManager; +/** + * @brief The CommandHolderImpl class should hold commands for particular + * application during application transport switching process and sends for + * processing after switching is completed successfully or drops otherwise + */ +class CommandHolderImpl : public CommandHolder { + public: + /** + * @brief CommandHolderImpl constructor + */ + + explicit CommandHolderImpl(ApplicationManager& app_manager); + + /** + * @brief Suspend collects command for specific application id internally + * @param application Application pointer + * @param type Command type + * @param command Command + */ + void Suspend(ApplicationSharedPtr application, + CommandType type, + smart_objects::SmartObjectSPtr command) FINAL; + + /** + * @brief Resume sends all collected HMI commands to ApplicationManager + * for further processing + * @param application Application pointer + * @param type Command type + */ + void Resume(ApplicationSharedPtr application, CommandType type) FINAL; + + /** + * @brief Clear removes all commands collected for specific application id + * @param application Application pointer + */ + void Clear(ApplicationSharedPtr application) FINAL; + + private: + /** + * @brief ResumeHmiCommand sends suspended HMI commands for processing + * @param application Application which commands to process + */ + void ResumeHmiCommand(ApplicationSharedPtr app); + + /** + * @brief ResumeMobileCommand sends suspended mobile commands for processing + * @param application Application which commands to process + */ + void ResumeMobileCommand(ApplicationSharedPtr application); + + using AppCommands = + std::map<ApplicationSharedPtr, + std::vector<utils::SharedPtr<smart_objects::SmartObject> > >; + + ApplicationManager& app_manager_; + sync_primitives::Lock commands_lock_; + AppCommands app_mobile_commands_; + AppCommands app_hmi_commands_; +}; +} // namespace application_manager + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_COMMAND_HOLDER_IMPL_H_ 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..5fee7500ce 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 @@ -142,16 +142,30 @@ class CommandImpl : public Command { protected: /** - * @brief Parse smartObject and replace mobile app Id by HMI app ID - * - * @param message Smartobject to be parsed + * @brief Parses mobile message and replaces mobile app id with HMI app id + * @param message Message to replace its ids + * @return True if replacement succeeded, otherwise - false + */ + bool ReplaceMobileWithHMIAppId(smart_objects::SmartObject& message); + + /** + * DEPRECATED + * @brief Parses mobile message and replaces mobile app id with HMI app id + * @param message Message to replace its ids */ void ReplaceMobileByHMIAppId(smart_objects::SmartObject& message); /** - * @brief Parse smartObject and replace HMI app ID by mobile app Id - * - * @param message Smartobject to be parsed + * @brief Parses message from HMI and replaces HMI app id with mobile app id + * @param message Message to replace its ids + * @return True if replacement succeeded, otherwise - false + */ + bool ReplaceHMIWithMobileAppId(smart_objects::SmartObject& message); + + /** + * DEPRECATED + * @brief Parses message from HMI and replaces HMI app id with mobile app id + * @param message Message to replace its ids */ void ReplaceHMIByMobileAppId(smart_objects::SmartObject& message); 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..5713e2e814 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 @@ -78,14 +78,29 @@ class RegisterAppInterfaceRequest : public CommandRequestImpl { virtual void Run(); /** - * @brief Sends RegisterAppInterface response to mobile - * - *@param application_impl application - * + * @brief Prepares and sends RegisterAppInterface response to mobile + * considering application type **/ void SendRegisterAppInterfaceResponseToMobile(); private: + /** + * @brief The AppicationType enum defines whether application is newly + * registered or existing and being switched over another transport + */ + enum class ApplicationType { + kNewApplication, + kSwitchedApplicationHashOk, + kSwitchedApplicationWrongHashId + }; + + /** + * @brief Prepares and sends RegisterAppInterface response to mobile + * considering application type + * @param app_type Type of application + **/ + void SendRegisterAppInterfaceResponseToMobile(ApplicationType app_type); + smart_objects::SmartObjectSPtr GetLockScreenIconUrlNotification( const uint32_t connection_key, ApplicationSharedPtr app); @@ -184,6 +199,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/helpers/application_helper.h b/src/components/application_manager/include/application_manager/helpers/application_helper.h new file mode 100644 index 0000000000..cecda0cd6f --- /dev/null +++ b/src/components/application_manager/include/application_manager/helpers/application_helper.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2017, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_HELPERS_APPLICATION_HELPER_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_HELPERS_APPLICATION_HELPER_H_ + +#include "application_manager/application.h" +#include "application_manager/application_manager.h" + +/* + * This file is for code w/o direct usage of ApplicationManagerImpl internals + */ +namespace application_manager { + +/** + * Helper function for lookup through applications list and returning first + * application satisfying predicate logic + */ +template <class UnaryPredicate> +ApplicationSharedPtr FindApp(DataAccessor<ApplicationSet> accessor, + UnaryPredicate finder) { + ApplicationSet::iterator it = std::find_if( + accessor.GetData().begin(), accessor.GetData().end(), finder); + if (accessor.GetData().end() == it) { + return ApplicationSharedPtr(); + } + ApplicationSharedPtr app = *it; + return app; +} + +/** + * Helper function for lookup through applications list and returning all + * applications satisfying predicate logic + */ +template <class UnaryPredicate> +std::vector<ApplicationSharedPtr> FindAllApps( + DataAccessor<ApplicationSet> accessor, UnaryPredicate finder) { + std::vector<ApplicationSharedPtr> result; + ApplicationSetConstIt it = std::find_if( + accessor.GetData().begin(), accessor.GetData().end(), finder); + while (it != accessor.GetData().end()) { + result.push_back(*it); + it = std::find_if(++it, accessor.GetData().end(), finder); + } + return result; +} + +/** + * @brief The SubscribedToIVIPredicate is predicate for lookup within + * applications list for apps subscribed for specific vehicle data + */ +struct SubscribedToIVIPredicate { + uint32_t vehicle_info_; + explicit SubscribedToIVIPredicate(uint32_t vehicle_info); + bool operator()(const ApplicationSharedPtr app) const; +}; + +/** + * @brief RecallApplicationData cleans up data within application instance to + * its initial state and notifies HMI to delete same data on its side + * @param app Application to clean its data + * @param app_manager Application manager + */ +void DeleteApplicationData(ApplicationSharedPtr app, + ApplicationManager& app_manager); +} // namespace application_manager + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_INCLUDE_APPLICATION_MANAGER_HELPERS_APPLICATION_HELPER_H_ 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..f2d665d998 100644 --- a/src/components/application_manager/include/application_manager/hmi_state.h +++ b/src/components/application_manager/include/application_manager/hmi_state.h @@ -36,11 +36,13 @@ #include <list> #include "interfaces/MOBILE_API.h" #include "utils/shared_ptr.h" +#include "utils/macro.h" namespace application_manager { class HmiState; class ApplicationManager; +class Application; typedef utils::SharedPtr<HmiState> HmiStatePtr; @@ -70,7 +72,39 @@ class HmiState { STATE_ID_EMBEDDED_NAVI }; + /** + * @brief HmiState constructor + * @param app Application pointer + * @param app_mngr Application manager + */ + HmiState(utils::SharedPtr<Application> app, + const ApplicationManager& app_mngr); + + /** + * @brief HmiState constructor + * @param app Application pointer + * @param app_mngr Application manager + * @param state_id HMI state to assign + */ + HmiState(utils::SharedPtr<Application> app, + const ApplicationManager& app_mngr, + StateID state_id); + + /** + * DEPRECATED + * @brief HmiState constructor + * @param app_id Application id + * @param app_mngr Application manager + */ HmiState(uint32_t app_id, const ApplicationManager& app_mngr); + + /** + * DEPRECATED + * @brief HmiState constructor + * @param app_id Application id + * @param app_mngr Application manager + * @param state_id HMI state to assign + */ HmiState(uint32_t app_id, const ApplicationManager& app_mngr, StateID state_id); @@ -166,7 +200,7 @@ class HmiState { } protected: - uint32_t app_id_; + utils::SharedPtr<Application> app_; StateID state_id_; const ApplicationManager& app_mngr_; HmiStatePtr parent_; @@ -177,26 +211,28 @@ 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; + /** + * @brief is_mobile_projection_app checks if application of 'projection' + * HMI type + * @return True if application is of 'projection' HMI type, otherwise - false + */ + bool is_mobile_projection_app() const; private: void operator=(const HmiState&); @@ -209,7 +245,10 @@ 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); + + DEPRECATED VRHmiState(uint32_t app_id, const ApplicationManager& app_mngr); }; /** @@ -217,7 +256,11 @@ 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); + + DEPRECATED TTSHmiState(uint32_t app_id, const ApplicationManager& app_mngr); + virtual mobile_apis::AudioStreamingState::eType audio_streaming_state() const OVERRIDE; }; @@ -228,7 +271,12 @@ 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); + + DEPRECATED NaviStreamingHmiState(uint32_t app_id, + const ApplicationManager& app_mngr); + mobile_apis::AudioStreamingState::eType audio_streaming_state() const OVERRIDE; }; @@ -239,7 +287,12 @@ 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); + + DEPRECATED PhoneCallHmiState(uint32_t app_id, + const ApplicationManager& app_mngr); + mobile_apis::HMILevel::eType hmi_level() const OVERRIDE; mobile_apis::AudioStreamingState::eType audio_streaming_state() const OVERRIDE { @@ -253,7 +306,12 @@ 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); + + DEPRECATED SafetyModeHmiState(uint32_t app_id, + const ApplicationManager& app_mngr); + mobile_apis::AudioStreamingState::eType audio_streaming_state() const OVERRIDE { return mobile_apis::AudioStreamingState::NOT_AUDIBLE; @@ -266,7 +324,11 @@ 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); + + DEPRECATED DeactivateHMI(uint32_t app_id, const ApplicationManager& app_mngr); + mobile_apis::HMILevel::eType hmi_level() const OVERRIDE; mobile_apis::AudioStreamingState::eType audio_streaming_state() const OVERRIDE { @@ -280,7 +342,11 @@ 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); + + DEPRECATED AudioSource(uint32_t app_id, const ApplicationManager& app_mngr); + mobile_apis::HMILevel::eType hmi_level() const OVERRIDE; mobile_apis::AudioStreamingState::eType audio_streaming_state() const OVERRIDE { @@ -295,7 +361,11 @@ 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); + + DEPRECATED EmbeddedNavi(uint32_t app_id, 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/message_helper.h b/src/components/application_manager/include/application_manager/message_helper.h index a0b70435b0..dc16e14023 100644 --- a/src/components/application_manager/include/application_manager/message_helper.h +++ b/src/components/application_manager/include/application_manager/message_helper.h @@ -701,6 +701,71 @@ class MessageHelper { int32_t connection_key, mobile_api::AppInterfaceUnregisteredReason::eType reason); + /** + * @brief SendDeleteCommandRequest sends requests to HMI to remove UI/VR + * command data depending on command parameters + * @param cmd Command data + * @param application Application owning the command data + * @param app_mngr Application manager + */ + static void SendDeleteCommandRequest(smart_objects::SmartObject* cmd, + ApplicationSharedPtr application, + ApplicationManager& app_mngr); + + /** + * @brief SendDeleteSubmenuRequest sends UI/VR requests to HMI to remove + * submenues-related data depending on command parameters + * @param cmd Command data + * @param application Application owning the commmand data + * @param app_mngr Application manager + */ + static void SendDeleteSubmenuRequest(smart_objects::SmartObject* cmd, + ApplicationSharedPtr application, + ApplicationManager& app_mngr); + + /** + * @brief SendDeleteChoiceSetRequest sends requests to HMI to remove + * choice sets - related data depending on command parameters + * @param cmd Command data + * @param application Application owning command data + * @param app_mngr Application manager + */ + static void SendDeleteChoiceSetRequest(smart_objects::SmartObject* cmd, + ApplicationSharedPtr application, + ApplicationManager& app_mngr); + + /** + * @brief SendResetPropertiesRequest sends requests to HMI to remove/reset + * global properties for application + * @param application Application to remove/reset global properties for + * @param app_mngr Application manager + */ + static void SendResetPropertiesRequest(ApplicationSharedPtr application, + ApplicationManager& app_mngr); + + /** + * @brief SendUnsubscribeButtonNotification sends notification to HMI to + * remove button subscription for application + * @param button Button type + * @param application Application to unsubscribe + * @param app_mngr Application manager + */ + static void SendUnsubscribeButtonNotification( + mobile_apis::ButtonName::eType button, + ApplicationSharedPtr application, + ApplicationManager& app_mngr); + + /** + * @brief SendUnsubscribeIVIRequest sends request to HMI to remove vehicle + * data subscription for application + * @param ivi_id Vehicle data item id + * @param application Application to unsubscribe + * @param app_mngr Application manager + */ + static void SendUnsubscribeIVIRequest(int32_t ivi_id, + ApplicationSharedPtr application, + ApplicationManager& app_mngr); + #ifdef SDL_REMOTE_CONTROL /** * @brief Sends HMI status notification to mobile @@ -728,11 +793,14 @@ class MessageHelper { private: /** - * @brief Creates new request object and fill its header - * @return New request object + * @brief CreateMessageForHMI Creates HMI message with prepared header + * acccoring to message type + * @param message_type Message type + * @param correlation_id Correlation id + * @return HMI message object with filled header */ - static smart_objects::SmartObjectSPtr CreateRequestObject( - const uint32_t correlation_id); + static smart_objects::SmartObjectSPtr CreateMessageForHMI( + hmi_apis::messageType::eType message_type, const uint32_t correlation_id); /** * @brief Allows to fill SO according to the current permissions. diff --git a/src/components/application_manager/include/application_manager/policies/policy_handler.h b/src/components/application_manager/include/application_manager/policies/policy_handler.h index 9de2d6af68..ce5c0818f1 100644 --- a/src/components/application_manager/include/application_manager/policies/policy_handler.h +++ b/src/components/application_manager/include/application_manager/policies/policy_handler.h @@ -533,6 +533,15 @@ class PolicyHandler : public PolicyHandlerInterface, virtual void OnPTUFinished(const bool ptu_result) OVERRIDE; + /** + * @brief OnDeviceSwitching Notifies policy manager on device switch event so + * policy permissions should be processed accordingly + * @param device_id_from Id of device being switched + * @param device_id_to Id of device on the new transport + */ + void OnDeviceSwitching(const std::string& device_id_from, + const std::string& device_id_to) FINAL; + protected: /** * Starts next retry exchange policy table diff --git a/src/components/application_manager/include/application_manager/resumption/resumption_data.h b/src/components/application_manager/include/application_manager/resumption/resumption_data.h index a9954141af..bee2bce570 100644 --- a/src/components/application_manager/include/application_manager/resumption/resumption_data.h +++ b/src/components/application_manager/include/application_manager/resumption/resumption_data.h @@ -36,6 +36,7 @@ #include "smart_objects/smart_object.h" #include "application_manager/application.h" #include "application_manager/application_manager.h" +#include "utils/macro.h" namespace application_manager { class ApplicationManagerSettings; @@ -97,8 +98,7 @@ class ResumptionData { * @brief Increments ignition counter for all registered applications * and remember ign_off time stamp */ - // DEPRECATED - virtual void OnSuspend() = 0; + DEPRECATED virtual void OnSuspend() = 0; /** * @brief Decrements ignition counter for all registered applications @@ -108,8 +108,7 @@ class ResumptionData { /** * @brief Decrements ignition counter for all registered applications */ - // DEPRECATED - virtual void OnAwake() = 0; + DEPRECATED virtual void OnAwake() = 0; /** * @brief Retrieves hash ID for the given mobile app ID diff --git a/src/components/application_manager/include/application_manager/resumption/resumption_data_db.h b/src/components/application_manager/include/application_manager/resumption/resumption_data_db.h index 8cb70274f3..a8032d1f65 100644 --- a/src/components/application_manager/include/application_manager/resumption/resumption_data_db.h +++ b/src/components/application_manager/include/application_manager/resumption/resumption_data_db.h @@ -55,6 +55,7 @@ struct ApplicationParams { mobile_apis::HMILevel::eType m_hmi_level; bool m_is_media_application; bool m_is_valid; + app_mngr::ApplicationSharedPtr app_ptr; }; /** @@ -113,14 +114,12 @@ class ResumptionDataDB : public ResumptionData { * @brief Increments ignition counter for all registered applications * and remember ign_off time stamp */ - // DEPRECATED - void OnSuspend() FINAL; + DEPRECATED void OnSuspend() FINAL; /** * @brief Decrements ignition counter for all registered applications */ - // DEPRECATED - void OnAwake() FINAL; + DEPRECATED void OnAwake() FINAL; /** * @brief Increments ignition counter for all registered applications diff --git a/src/components/application_manager/include/application_manager/resumption/resumption_data_json.h b/src/components/application_manager/include/application_manager/resumption/resumption_data_json.h index 4da3441037..82ec1d9e5c 100644 --- a/src/components/application_manager/include/application_manager/resumption/resumption_data_json.h +++ b/src/components/application_manager/include/application_manager/resumption/resumption_data_json.h @@ -85,14 +85,12 @@ class ResumptionDataJson : public ResumptionData { * @brief Increments ignition counter for all registered applications * and remember ign_off time stamp */ - // DEPRECATED - void OnSuspend() FINAL; + DEPRECATED void OnSuspend() FINAL; /** * @brief Decrements ignition counter for all registered applications */ - // DEPRECATED - void OnAwake() FINAL; + DEPRECATED void OnAwake() FINAL; /** * @brief Increments ignition counter for all registered applications 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..735a9955a7 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,23 @@ CREATE_LOGGERPTR_GLOBAL(logger_, "ApplicationManager") namespace application_manager { +void SwitchApplicationParameters(ApplicationSharedPtr app, + const uint32_t app_id, + const size_t device_id, + const std::string& mac_address) { + utils::SharedPtr<ApplicationImpl> application = + ApplicationSharedPtr::dynamic_pointer_cast<ApplicationImpl>(app); + DCHECK_OR_RETURN_VOID(application); + application->app_id_ = app_id; + application->device_id_ = device_id; + application->mac_address_ = mac_address; +} + ApplicationImpl::ApplicationImpl( 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) @@ -105,8 +119,8 @@ ApplicationImpl::ApplicationImpl( , put_file_in_none_count_(0) , delete_file_in_none_count_(0) , 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 +151,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 +355,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,8 +614,9 @@ void ApplicationImpl::set_app_allowed(const bool allowed) { is_app_allowed_ = allowed; } -void ApplicationImpl::set_device(connection_handler::DeviceHandle device) { - device_ = device; +DEPRECATED void ApplicationImpl::set_device( + connection_handler::DeviceHandle device) { + device_id_ = device; } uint32_t ApplicationImpl::get_grammar_id() const { @@ -863,6 +872,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..eb3313e492 100644 --- a/src/components/application_manager/src/application_manager_impl.cc +++ b/src/components/application_manager/src/application_manager_impl.cc @@ -50,8 +50,10 @@ #include "application_manager/app_launch/app_launch_ctrl_impl.h" #include "application_manager/app_launch/app_launch_data_db.h" #include "application_manager/app_launch/app_launch_data_json.h" +#include "application_manager/helpers/application_helper.h" #include "protocol_handler/protocol_handler.h" #include "hmi_message_handler/hmi_message_handler.h" +#include "application_manager/command_holder_impl.h" #include "connection_handler/connection_handler_impl.h" #include "formatters/formatter_json_rpc.h" #include "formatters/CFormatterJsonSDLRPCv2.h" @@ -93,9 +95,40 @@ DeviceTypes devicesType = { hmi_apis::Common_TransportType::USB_IOS), std::make_pair(std::string("BLUETOOTH"), hmi_apis::Common_TransportType::BLUETOOTH), + std::make_pair(std::string("BLUETOOTH_IOS"), + hmi_apis::Common_TransportType::BLUETOOTH), std::make_pair(std::string("WIFI"), hmi_apis::Common_TransportType::WIFI)}; } +/** + * @brief device_id_comparator is predicate to compare application device id + * @param device_id Device id to compare with + * @param app Application pointer + * @return True if device id of application matches to device id passed + */ +bool device_id_comparator(const std::string& device_id, + ApplicationSharedPtr app) { + DCHECK_OR_RETURN(app, false); + LOG4CXX_DEBUG(logger_, + "Data to compare: device_id : " << device_id << " app mac: " + << app->mac_address()); + + return device_id == app->mac_address(); +} + +/** + * @brief policy_app_id_comparator is predicate to compare policy application + * ids + * @param policy_app_id Policy id of application + * @param app Application pointer + * @return True if policy id of application matches to policy id passed + */ +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; @@ -164,6 +197,7 @@ ApplicationManagerImpl::ApplicationManagerImpl( const uint32_t timeout_ms = 10000u; clearing_timer->Start(timeout_ms, timer::kSingleShot); timer_pool_.push_back(clearing_timer); + commands_holder_.reset(new CommandHolderImpl(*this)); } ApplicationManagerImpl::~ApplicationManagerImpl() { @@ -193,33 +227,6 @@ ApplicationManagerImpl::~ApplicationManagerImpl() { navi_app_to_end_stream_.clear(); } -template <class UnaryPredicate> -ApplicationSharedPtr FindApp(DataAccessor<ApplicationSet> accessor, - UnaryPredicate finder) { - ApplicationSet::iterator it = std::find_if( - accessor.GetData().begin(), accessor.GetData().end(), finder); - if (accessor.GetData().end() == it) { - LOG4CXX_DEBUG(logger_, "Unable to find application"); - return ApplicationSharedPtr(); - } - ApplicationSharedPtr app = *it; - LOG4CXX_DEBUG(logger_, " Found Application app_id = " << app->app_id()); - return app; -} - -template <class UnaryPredicate> -std::vector<ApplicationSharedPtr> FindAllApps( - DataAccessor<ApplicationSet> accessor, UnaryPredicate finder) { - std::vector<ApplicationSharedPtr> result; - ApplicationSetConstIt it = std::find_if( - accessor.GetData().begin(), accessor.GetData().end(), finder); - while (it != accessor.GetData().end()) { - result.push_back(*it); - it = std::find_if(++it, accessor.GetData().end(), finder); - } - return result; -} - DataAccessor<ApplicationSet> ApplicationManagerImpl::applications() const { DataAccessor<ApplicationSet> accessor(applications_, applications_list_lock_); return accessor; @@ -330,15 +337,6 @@ ApplicationManagerImpl::applications_by_button(uint32_t button) { return FindAllApps(accessor, finder); } -struct SubscribedToIVIPredicate { - int32_t vehicle_info_; - SubscribedToIVIPredicate(int32_t vehicle_info) - : vehicle_info_(vehicle_info) {} - bool operator()(const ApplicationSharedPtr app) const { - return app ? app->IsSubscribedToIVI(vehicle_info_) : false; - } -}; - struct IsApplication { IsApplication(connection_handler::DeviceHandle device_handle, const std::string& policy_app_id) @@ -365,7 +363,7 @@ std::vector<ApplicationSharedPtr> ApplicationManagerImpl::IviInfoUpdated( break; } - SubscribedToIVIPredicate finder(static_cast<int32_t>(vehicle_info)); + SubscribedToIVIPredicate finder(vehicle_info); DataAccessor<ApplicationSet> accessor = applications(); return FindAllApps(accessor, finder); } @@ -393,6 +391,12 @@ void ApplicationManagerImpl::OnApplicationRegistered(ApplicationSharedPtr app) { event.raise(event_dispatcher()); } +void ApplicationManagerImpl::OnApplicationSwitched(ApplicationSharedPtr app) { + LOG4CXX_AUTO_TRACE(logger_); + commands_holder_->Resume(app, CommandHolder::CommandType::kMobileCommand); + commands_holder_->Resume(app, CommandHolder::CommandType::kHmiCommand); +} + bool ApplicationManagerImpl::IsAppTypeExistsInFullOrLimited( ApplicationConstSharedPtr app) const { bool voice_state = app->is_voice_communication_supported(); @@ -472,10 +476,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 +492,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 +524,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 +543,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 = @@ -624,11 +638,13 @@ ApplicationSharedPtr ApplicationManagerImpl::RegisterApplication( return application; } -bool ApplicationManagerImpl::RemoveAppDataFromHMI(ApplicationSharedPtr app) { +DEPRECATED bool ApplicationManagerImpl::RemoveAppDataFromHMI( + ApplicationSharedPtr app) { return true; } -bool ApplicationManagerImpl::LoadAppDataToHMI(ApplicationSharedPtr app) { +DEPRECATED bool ApplicationManagerImpl::LoadAppDataToHMI( + ApplicationSharedPtr app) { return true; } @@ -779,7 +795,8 @@ void ApplicationManagerImpl::set_driver_distraction(const bool is_distracting) { is_distracting_driver_ = is_distracting; } -void ApplicationManagerImpl::set_vr_session_started(const bool state) { +DEPRECATED void ApplicationManagerImpl::set_vr_session_started( + const bool state) { is_vr_session_strated_ = state; } @@ -788,6 +805,18 @@ void ApplicationManagerImpl::SetAllAppsAllowed(const bool allowed) { } HmiStatePtr ApplicationManagerImpl::CreateRegularState( + 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, *this)); + state->set_hmi_level(hmi_level); + state->set_audio_streaming_state(audio_state); + state->set_system_context(system_context); + return state; +} + +HmiStatePtr ApplicationManagerImpl::CreateRegularState( uint32_t app_id, mobile_apis::HMILevel::eType hmi_level, mobile_apis::AudioStreamingState::eType audio_state, @@ -1044,6 +1073,105 @@ void ApplicationManagerImpl::RemoveDevice( LOG4CXX_DEBUG(logger_, "device_handle " << device_handle); } +void ApplicationManagerImpl::OnDeviceSwitchingStart( + const connection_handler::Device& device_from, + const connection_handler::Device& device_to) { + LOG4CXX_AUTO_TRACE(logger_); + { + 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_from.mac_address())); + } + + { + // During sending of UpdateDeviceList this lock is acquired also so making + // it scoped + sync_primitives::AutoLock lock(reregister_wait_list_lock_); + for (auto i = reregister_wait_list_.begin(); + reregister_wait_list_.end() != i; + ++i) { + auto app = *i; + request_ctrl_.terminateAppRequests(app->app_id()); + resume_ctrl_->SaveApplication(app); + } + } + + policy_handler_->OnDeviceSwitching(device_from.mac_address(), + device_to.mac_address()); + + connection_handler::DeviceMap device_list; + device_list.insert(std::make_pair(device_to.device_handle(), device_to)); + + smart_objects::SmartObjectSPtr msg_params = + MessageHelper::CreateDeviceListSO(device_list, GetPolicyHandler(), *this); + if (!msg_params) { + LOG4CXX_ERROR(logger_, "Can't create UpdateDeviceList notification"); + return; + } + + auto update_list = utils::MakeShared<smart_objects::SmartObject>(); + smart_objects::SmartObject& so_to_send = *update_list; + so_to_send[jhs::S_PARAMS][jhs::S_FUNCTION_ID] = + hmi_apis::FunctionID::BasicCommunication_UpdateDeviceList; + so_to_send[jhs::S_PARAMS][jhs::S_MESSAGE_TYPE] = + hmi_apis::messageType::request; + so_to_send[jhs::S_PARAMS][jhs::S_PROTOCOL_VERSION] = 2; + so_to_send[jhs::S_PARAMS][jhs::S_PROTOCOL_TYPE] = 1; + so_to_send[jhs::S_PARAMS][jhs::S_CORRELATION_ID] = GetNextHMICorrelationID(); + so_to_send[jhs::S_MSG_PARAMS] = *msg_params; + ManageHMICommand(update_list); +} + +void ApplicationManagerImpl::OnDeviceSwitchingFinish( + const std::string& device_uid) { + LOG4CXX_AUTO_TRACE(logger_); + 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) { + auto app = *app_it; + UnregisterApplication(app->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 size_t device_id, + const std::string& mac_address) { + LOG4CXX_AUTO_TRACE(logger_); + DCHECK_OR_RETURN_VOID(app); + 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, mac_address); + + // 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; @@ -1434,6 +1562,17 @@ void ApplicationManagerImpl::OnServiceEndedCallback( << type << " with reason " << close_reason << " in session 0x" << std::hex << session_key); + auto app = application(static_cast<uint32_t>(session_key)); + if (!app) { + return; + } + + if (IsAppInReconnectMode(app->policy_app_id())) { + LOG4CXX_DEBUG(logger_, + "Application is in reconnection list and won't be closed."); + return; + } + if (type == kRpc) { LOG4CXX_INFO(logger_, "Remove application."); /* In case it was unexpected disconnect or some special case @@ -1720,6 +1859,16 @@ bool ApplicationManagerImpl::ManageMobileCommand( return false; } + const uint32_t connection_key = static_cast<uint32_t>( + (*message)[strings::params][strings::connection_key].asUInt()); + + auto app_ptr = application(connection_key); + if (app_ptr && IsAppInReconnectMode(app_ptr->policy_app_id())) { + commands_holder_->Suspend( + app_ptr, CommandHolder::CommandType::kMobileCommand, message); + return true; + } + mobile_apis::FunctionID::eType function_id = static_cast<mobile_apis::FunctionID::eType>( (*message)[strings::params][strings::function_id].asInt()); @@ -1730,9 +1879,6 @@ bool ApplicationManagerImpl::ManageMobileCommand( ? (*message)[strings::params][strings::correlation_id].asUInt() : 0; - uint32_t connection_key = - (*message)[strings::params][strings::connection_key].asUInt(); - int32_t protocol_type = (*message)[strings::params][strings::protocol_type].asUInt(); @@ -1949,8 +2095,21 @@ bool ApplicationManagerImpl::ManageHMICommand( return false; } + if ((*message).keyExists(strings::msg_params) && + (*message)[strings::msg_params].keyExists(strings::app_id)) { + const auto connection_key = + (*message)[strings::msg_params][strings::app_id].asUInt(); + + auto app = application(static_cast<uint32_t>(connection_key)); + if (app && IsAppInReconnectMode(app->policy_app_id())) { + commands_holder_->Suspend( + app, CommandHolder::CommandType::kHmiCommand, message); + return true; + } + } + int32_t message_type = - (*(message.get()))[strings::params][strings::message_type].asInt(); + (*message)[strings::params][strings::message_type].asInt(); if (kRequest == message_type) { LOG4CXX_DEBUG(logger_, "ManageHMICommand"); @@ -1961,9 +2120,9 @@ bool ApplicationManagerImpl::ManageHMICommand( command->Run(); if (kResponse == message_type) { const uint32_t correlation_id = - (*(message.get()))[strings::params][strings::correlation_id].asUInt(); + (*message)[strings::params][strings::correlation_id].asUInt(); const int32_t function_id = - (*(message.get()))[strings::params][strings::function_id].asInt(); + (*message)[strings::params][strings::function_id].asInt(); request_ctrl_.OnHMIResponse(correlation_id, function_id); } return true; @@ -2589,10 +2748,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 +2773,7 @@ void ApplicationManagerImpl::CreateApplications(SmartArray& obj_array, new ApplicationImpl(0, policy_app_id, device_mac, + device_id, appName, GetPolicyHandler().GetStatisticManager(), *this)); @@ -2622,7 +2782,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 +3136,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 +3161,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); @@ -3014,6 +3173,9 @@ void ApplicationManagerImpl::UnregisterApplication( SendUpdateAppList(); } } + + commands_holder_->Clear(app_to_remove); + if (audio_pass_thru_active_) { // May be better to put this code in MessageHelper? EndAudioPassThrough(); @@ -3236,8 +3398,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 +3761,17 @@ bool ApplicationManagerImpl::IsApplicationForbidden( return forbidden_applications.find(name) != forbidden_applications.end(); } +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 +4055,48 @@ 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); + + EraseAppFromReconnectionList(application); + + SwitchApplication(application, connection_key, new_device_id, device_mac); + + // 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) { @@ -3981,9 +4197,46 @@ void ApplicationManagerImpl::UnsubscribeAppFromWayPoints( subscribed_way_points_apps_list_.erase(app_id); } +bool ApplicationManagerImpl::IsAppSubscribedForWayPoints( + ApplicationSharedPtr app) const { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock lock(subscribed_way_points_apps_lock_); + LOG4CXX_DEBUG(logger_, + "There are applications subscribed: " + << subscribed_way_points_apps_list_.size()); + if (subscribed_way_points_apps_list_.find(app) == + subscribed_way_points_apps_list_.end()) { + return false; + } + return true; +} + +void ApplicationManagerImpl::SubscribeAppForWayPoints( + ApplicationSharedPtr app) { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock lock(subscribed_way_points_apps_lock_); + subscribed_way_points_apps_list_.insert(app); + LOG4CXX_DEBUG(logger_, + "There are applications subscribed: " + << subscribed_way_points_apps_list_.size()); +} + +void ApplicationManagerImpl::UnsubscribeAppFromWayPoints( + ApplicationSharedPtr app) { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock lock(subscribed_way_points_apps_lock_); + subscribed_way_points_apps_list_.erase(app); + LOG4CXX_DEBUG(logger_, + "There are applications subscribed: " + << subscribed_way_points_apps_list_.size()); +} + bool ApplicationManagerImpl::IsAnyAppSubscribedForWayPoints() const { LOG4CXX_AUTO_TRACE(logger_); sync_primitives::AutoLock lock(subscribed_way_points_apps_lock_); + LOG4CXX_DEBUG(logger_, + "There are applications subscribed: " + << subscribed_way_points_apps_list_.size()); return !subscribed_way_points_apps_list_.empty(); } diff --git a/src/components/application_manager/src/command_holder_impl.cc b/src/components/application_manager/src/command_holder_impl.cc new file mode 100644 index 0000000000..4e2cf89f57 --- /dev/null +++ b/src/components/application_manager/src/command_holder_impl.cc @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2017, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "application_manager/command_holder_impl.h" +#include "application_manager/application_manager.h" +#include "application_manager/commands/command.h" + +namespace application_manager { +CREATE_LOGGERPTR_GLOBAL(logger_, "ApplicationManager") + +CommandHolderImpl::CommandHolderImpl(ApplicationManager& app_manager) + : app_manager_(app_manager) {} + +void CommandHolderImpl::Suspend( + ApplicationSharedPtr application, + CommandType type, + utils::SharedPtr<smart_objects::SmartObject> command) { + LOG4CXX_AUTO_TRACE(logger_); + DCHECK_OR_RETURN_VOID(application); + LOG4CXX_DEBUG(logger_, + "Suspending command(s) for application: " + << application->policy_app_id()); + sync_primitives::AutoLock lock(commands_lock_); + + if (CommandType::kHmiCommand == type) { + app_hmi_commands_[application].push_back(command); + LOG4CXX_DEBUG(logger_, + "Suspended HMI command(s): " << app_hmi_commands_.size()); + } else { + app_mobile_commands_[application].push_back(command); + LOG4CXX_DEBUG(logger_, + "Suspended mobile command(s): " << app_hmi_commands_.size()); + } +} + +void CommandHolderImpl::Resume(ApplicationSharedPtr application, + CommandType type) { + LOG4CXX_AUTO_TRACE(logger_); + DCHECK_OR_RETURN_VOID(application); + LOG4CXX_DEBUG( + logger_, + "Resuming command(s) for application: " << application->policy_app_id()); + if (CommandType::kHmiCommand == type) { + ResumeHmiCommand(application); + } else { + ResumeMobileCommand(application); + } +} + +void CommandHolderImpl::Clear(ApplicationSharedPtr application) { + LOG4CXX_AUTO_TRACE(logger_); + DCHECK_OR_RETURN_VOID(application); + LOG4CXX_DEBUG( + logger_, + "Clearing command(s) for application: " << application->policy_app_id()); + sync_primitives::AutoLock lock(commands_lock_); + auto app_hmi_commands = app_hmi_commands_.find(application); + if (app_hmi_commands_.end() != app_hmi_commands) { + LOG4CXX_DEBUG( + logger_, + "Clearing HMI command(s): " << app_hmi_commands->second.size()); + app_hmi_commands_.erase(app_hmi_commands); + } + + auto app_mobile_commands = app_mobile_commands_.find(application); + if (app_mobile_commands_.end() != app_mobile_commands) { + LOG4CXX_DEBUG( + logger_, + "Clearing mobile command(s): " << app_mobile_commands->second.size()); + app_mobile_commands_.erase(app_mobile_commands); + } +} + +void CommandHolderImpl::ResumeHmiCommand(ApplicationSharedPtr application) { + DCHECK_OR_RETURN_VOID(application); + sync_primitives::AutoLock lock(commands_lock_); + auto app_commands = app_hmi_commands_.find(application); + if (app_hmi_commands_.end() == app_commands) { + return; + } + + LOG4CXX_DEBUG(logger_, + "Resuming HMI command(s): " << app_hmi_commands_.size()); + + for (auto cmd : app_commands->second) { + (*cmd)[strings::msg_params][strings::app_id] = application->hmi_app_id(); + app_manager_.ManageHMICommand(cmd); + } + + app_hmi_commands_.erase(app_commands); +} + +void CommandHolderImpl::ResumeMobileCommand(ApplicationSharedPtr application) { + DCHECK_OR_RETURN_VOID(application); + sync_primitives::AutoLock lock(commands_lock_); + auto app_commands = app_mobile_commands_.find(application); + if (app_mobile_commands_.end() == app_commands) { + return; + } + + LOG4CXX_DEBUG(logger_, + "Resuming mobile command(s): " << app_mobile_commands_.size()); + + for (auto cmd : app_commands->second) { + (*cmd)[strings::params][strings::connection_key] = application->app_id(); + app_manager_.ManageMobileCommand( + cmd, commands::Command::CommandOrigin::ORIGIN_MOBILE); + } + + app_mobile_commands_.erase(app_commands); +} +} // application_manager diff --git a/src/components/application_manager/src/commands/command_impl.cc b/src/components/application_manager/src/commands/command_impl.cc index 0a3e65a790..b928184148 100644 --- a/src/components/application_manager/src/commands/command_impl.cc +++ b/src/components/application_manager/src/commands/command_impl.cc @@ -94,25 +94,30 @@ void CommandImpl::SetAllowedToTerminate(const bool allowed) { allowed_to_terminate_ = allowed; } -void CommandImpl::ReplaceMobileByHMIAppId( +bool CommandImpl::ReplaceMobileWithHMIAppId( NsSmartDeviceLink::NsSmartObjects::SmartObject& message) { + LOG4CXX_AUTO_TRACE(logger_); 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_, + "ReplaceMobileWithHMIAppId 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: { smart_objects::SmartArray* message_array = message.asArray(); smart_objects::SmartArray::iterator it = message_array->begin(); for (; it != message_array->end(); ++it) { - ReplaceMobileByHMIAppId(*it); + if (!ReplaceMobileWithHMIAppId(*it)) { + break; + } } break; } @@ -121,36 +126,51 @@ void CommandImpl::ReplaceMobileByHMIAppId( std::set<std::string>::const_iterator key = keys.begin(); for (; key != keys.end(); ++key) { std::string k = *key; - ReplaceMobileByHMIAppId(message[*key]); + if (!ReplaceMobileWithHMIAppId(message[*key])) { + break; + } } break; } default: { break; } } } + + return true; +} + +DEPRECATED void CommandImpl::ReplaceMobileByHMIAppId( + NsSmartDeviceLink::NsSmartObjects::SmartObject& message) { + if (!ReplaceMobileWithHMIAppId(message)) { + LOG4CXX_ERROR(logger_, "Substitution mobile --> HMI id is failed."); + } } -void CommandImpl::ReplaceHMIByMobileAppId( +bool CommandImpl::ReplaceHMIWithMobileAppId( 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_, + "ReplaceHMIWithMobileAppId 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: { smart_objects::SmartArray* message_array = message.asArray(); smart_objects::SmartArray::iterator it = message_array->begin(); for (; it != message_array->end(); ++it) { - ReplaceHMIByMobileAppId(*it); + if (!ReplaceHMIWithMobileAppId(*it)) { + break; + } } break; } @@ -158,13 +178,24 @@ void CommandImpl::ReplaceHMIByMobileAppId( std::set<std::string> keys = message.enumerate(); std::set<std::string>::const_iterator key = keys.begin(); for (; key != keys.end(); ++key) { - ReplaceHMIByMobileAppId(message[*key]); + if (!ReplaceHMIWithMobileAppId(message[*key])) { + break; + } } break; } default: { break; } } } + + return true; +} + +DEPRECATED void CommandImpl::ReplaceHMIByMobileAppId( + NsSmartDeviceLink::NsSmartObjects::SmartObject& message) { + if (!ReplaceHMIWithMobileAppId(message)) { + LOG4CXX_ERROR(logger_, "Substitution HMI --> mobile id is failed."); + } } } // namespace commands diff --git a/src/components/application_manager/src/commands/hmi/notification_from_hmi.cc b/src/components/application_manager/src/commands/hmi/notification_from_hmi.cc index 64eb63fde8..3c2d73b10c 100644 --- a/src/components/application_manager/src/commands/hmi/notification_from_hmi.cc +++ b/src/components/application_manager/src/commands/hmi/notification_from_hmi.cc @@ -42,7 +42,7 @@ NotificationFromHMI::NotificationFromHMI( const MessageSharedPtr& message, ApplicationManager& application_manager) : CommandImpl(message, application_manager) { // Replace HMI app id with Mobile connection id - ReplaceHMIByMobileAppId(*message); + ReplaceHMIWithMobileAppId(*message); } NotificationFromHMI::~NotificationFromHMI() {} 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..d52df950c3 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,13 @@ 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; + // Replace Mobile connection id with HMI app id + return ReplaceMobileWithHMIAppId(*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_from_hmi.cc b/src/components/application_manager/src/commands/hmi/request_from_hmi.cc index 1119e7c4fd..5a4e7b149e 100644 --- a/src/components/application_manager/src/commands/hmi/request_from_hmi.cc +++ b/src/components/application_manager/src/commands/hmi/request_from_hmi.cc @@ -43,7 +43,7 @@ RequestFromHMI::RequestFromHMI(const MessageSharedPtr& message, : CommandImpl(message, application_manager) , EventObserver(application_manager.event_dispatcher()) { // Replace HMI app id with Mobile connection id - ReplaceHMIByMobileAppId(*(message.get())); + ReplaceHMIWithMobileAppId(*message); } RequestFromHMI::~RequestFromHMI() {} 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..6905e7cdef 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,13 @@ 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; + // Replace Mobile connection id with HMI app id + return ReplaceMobileWithHMIAppId(*message_); } bool RequestToHMI::CleanUp() { diff --git a/src/components/application_manager/src/commands/hmi/response_from_hmi.cc b/src/components/application_manager/src/commands/hmi/response_from_hmi.cc index 23d8e6e229..d6d5d95d07 100644 --- a/src/components/application_manager/src/commands/hmi/response_from_hmi.cc +++ b/src/components/application_manager/src/commands/hmi/response_from_hmi.cc @@ -48,7 +48,7 @@ ResponseFromHMI::ResponseFromHMI(const MessageSharedPtr& message, } // Replace HMI app id with Mobile connection id - ReplaceHMIByMobileAppId(*(message.get())); + ReplaceHMIWithMobileAppId(*message); } ResponseFromHMI::~ResponseFromHMI() {} 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..de1e1e0fde 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,13 @@ 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; + // Replace Mobile connection id with HMI app id + return ReplaceMobileWithHMIAppId(*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..a3a30ddb20 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 @@ -46,6 +46,7 @@ #include "application_manager/message_helper.h" #include "application_manager/resumption/resume_ctrl.h" #include "application_manager/policies/policy_handler.h" +#include "application_manager/helpers/application_helper.h" #include "config_profile/profile.h" #include "interfaces/MOBILE_API.h" #include "interfaces/generated_msg_version.h" @@ -217,6 +218,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 +370,7 @@ void RegisterAppInterfaceRequest::Run() { GetPolicyHandler().SetDeviceInfo(device_mac, device_info); - SendRegisterAppInterfaceResponseToMobile(); + SendRegisterAppInterfaceResponseToMobile(ApplicationType::kNewApplication); smart_objects::SmartObjectSPtr so = GetLockScreenIconUrlNotification(connection_key(), application); application_manager_.ManageMobileCommand(so, commands::Command::ORIGIN_SDL); @@ -501,7 +509,8 @@ void FillUIRelatedFields(smart_objects::SmartObject& response_params, hmi_capabilities.rc_supported(); } -void RegisterAppInterfaceRequest::SendRegisterAppInterfaceResponseToMobile() { +void RegisterAppInterfaceRequest::SendRegisterAppInterfaceResponseToMobile( + ApplicationType app_type) { LOG4CXX_AUTO_TRACE(logger_); smart_objects::SmartObject response_params(smart_objects::SmartType_Map); @@ -572,18 +581,27 @@ void RegisterAppInterfaceRequest::SendRegisterAppInterfaceResponseToMobile() { FillUIRelatedFields(response_params, hmi_capabilities); } + if (HmiInterfaces::STATE_NOT_AVAILABLE != + application_manager_.hmi_interfaces().GetInterfaceState( + HmiInterfaces::HMI_INTERFACE_VehicleInfo)) { + FillVIRelatedFields(response_params, hmi_capabilities); + } + if (hmi_capabilities.button_capabilities()) { response_params[hmi_response::button_capabilities] = *hmi_capabilities.button_capabilities(); } + if (hmi_capabilities.soft_button_capabilities()) { response_params[hmi_response::soft_button_capabilities] = *hmi_capabilities.soft_button_capabilities(); } + if (hmi_capabilities.preset_bank_capabilities()) { response_params[hmi_response::preset_bank_capabilities] = *hmi_capabilities.preset_bank_capabilities(); } + if (hmi_capabilities.hmi_zone_capabilities()) { if (smart_objects::SmartType_Array == hmi_capabilities.hmi_zone_capabilities()->getType()) { @@ -596,23 +614,11 @@ void RegisterAppInterfaceRequest::SendRegisterAppInterfaceResponseToMobile() { } } - if (HmiInterfaces::STATE_NOT_AVAILABLE != - application_manager_.hmi_interfaces().GetInterfaceState( - HmiInterfaces::HMI_INTERFACE_TTS)) { - FillTTSRelatedFields(response_params, hmi_capabilities); - } - if (hmi_capabilities.pcm_stream_capabilities()) { response_params[strings::pcm_stream_capabilities] = *hmi_capabilities.pcm_stream_capabilities(); } - if (HmiInterfaces::STATE_NOT_AVAILABLE != - application_manager_.hmi_interfaces().GetInterfaceState( - HmiInterfaces::HMI_INTERFACE_VehicleInfo)) { - FillVIRelatedFields(response_params, hmi_capabilities); - } - const std::vector<uint32_t>& diag_modes = application_manager_.get_settings().supported_diag_modes(); if (!diag_modes.empty()) { @@ -623,6 +629,7 @@ void RegisterAppInterfaceRequest::SendRegisterAppInterfaceResponseToMobile() { ++index; } } + response_params[strings::sdl_version] = application_manager_.get_settings().sdl_version(); const std::string ccpu_version = @@ -631,6 +638,27 @@ void RegisterAppInterfaceRequest::SendRegisterAppInterfaceResponseToMobile() { response_params[strings::system_software_version] = ccpu_version; } + if (ApplicationType::kSwitchedApplicationWrongHashId == app_type) { + LOG4CXX_DEBUG(logger_, + "Application has been switched from another transport, " + "but doesn't have correct hashID."); + + application_manager::DeleteApplicationData(application, + application_manager_); + + SendResponse( + true, mobile_apis::Result::RESUME_FAILED, NULL, &response_params); + return; + } + + if (ApplicationType::kSwitchedApplicationHashOk == app_type) { + LOG4CXX_DEBUG(logger_, + "Application has been switched from another transport " + "and has correct hashID."); + SendResponse(true, mobile_apis::Result::SUCCESS, NULL, &response_params); + return; + } + bool resumption = (*message_)[strings::msg_params].keyExists(strings::hash_id); @@ -713,6 +741,11 @@ void RegisterAppInterfaceRequest::SendRegisterAppInterfaceResponseToMobile() { SendChangeRegistrationOnHMI(application); } +DEPRECATED void +RegisterAppInterfaceRequest::SendRegisterAppInterfaceResponseToMobile() { + SendRegisterAppInterfaceResponseToMobile(ApplicationType::kNewApplication); +} + void RegisterAppInterfaceRequest::SendChangeRegistration( const hmi_apis::FunctionID::eType function_id, const int32_t language, @@ -1194,6 +1227,56 @@ 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."); + + auto app_type = ApplicationType::kSwitchedApplicationWrongHashId; + if ((*message_)[strings::msg_params].keyExists(strings::hash_id)) { + const auto hash_id = + (*message_)[strings::msg_params][strings::hash_id].asString(); + + auto& resume_ctrl = application_manager_.resume_controller(); + if (resume_ctrl.CheckApplicationHash(app, hash_id)) { + app_type = ApplicationType::kSwitchedApplicationHashOk; + } + } + + application_manager_.ProcessReconnection(app, connection_key()); + SendRegisterAppInterfaceResponseToMobile(app_type); + + application_manager_.SendHMIStatusNotification(app); + + application_manager_.OnApplicationSwitched(app); + + return true; +} + policy::PolicyHandlerInterface& RegisterAppInterfaceRequest::GetPolicyHandler() { return application_manager_.GetPolicyHandler(); diff --git a/src/components/application_manager/src/commands/mobile/subscribe_way_points_request.cc b/src/components/application_manager/src/commands/mobile/subscribe_way_points_request.cc index 965741edf7..8195697dfc 100644 --- a/src/components/application_manager/src/commands/mobile/subscribe_way_points_request.cc +++ b/src/components/application_manager/src/commands/mobile/subscribe_way_points_request.cc @@ -25,13 +25,13 @@ void SubscribeWayPointsRequest::Run() { return; } - if (application_manager_.IsAppSubscribedForWayPoints(app->app_id())) { + if (application_manager_.IsAppSubscribedForWayPoints(app)) { SendResponse(false, mobile_apis::Result::IGNORED); return; } if (application_manager_.IsAnyAppSubscribedForWayPoints()) { - application_manager_.SubscribeAppForWayPoints(app->app_id()); + application_manager_.SubscribeAppForWayPoints(app); SendResponse(true, mobile_apis::Result::SUCCESS); return; } @@ -57,7 +57,7 @@ void SubscribeWayPointsRequest::on_event(const event_engine::Event& event) { const bool result = PrepareResultForMobileResponse( result_code, HmiInterfaces::HMI_INTERFACE_Navigation); if (result) { - application_manager_.SubscribeAppForWayPoints(app->app_id()); + application_manager_.SubscribeAppForWayPoints(app); } SendResponse(result, MessageHelper::HMIToMobileResult(result_code), diff --git a/src/components/application_manager/src/commands/mobile/unsubscribe_way_points_request.cc b/src/components/application_manager/src/commands/mobile/unsubscribe_way_points_request.cc index 88ed396250..dc3404c022 100644 --- a/src/components/application_manager/src/commands/mobile/unsubscribe_way_points_request.cc +++ b/src/components/application_manager/src/commands/mobile/unsubscribe_way_points_request.cc @@ -25,7 +25,7 @@ void UnSubscribeWayPointsRequest::Run() { return; } - if (!application_manager_.IsAppSubscribedForWayPoints(app->app_id())) { + if (!application_manager_.IsAppSubscribedForWayPoints(app)) { SendResponse(false, mobile_apis::Result::IGNORED); return; } @@ -51,7 +51,7 @@ void UnSubscribeWayPointsRequest::on_event(const event_engine::Event& event) { const bool result = PrepareResultForMobileResponse( result_code, HmiInterfaces::HMI_INTERFACE_Navigation); if (result) { - application_manager_.UnsubscribeAppFromWayPoints(app->app_id()); + application_manager_.UnsubscribeAppFromWayPoints(app); } SendResponse(result, MessageHelper::HMIToMobileResult(result_code), diff --git a/src/components/application_manager/src/helpers/application_helper.cc b/src/components/application_manager/src/helpers/application_helper.cc new file mode 100644 index 0000000000..16b49faa2a --- /dev/null +++ b/src/components/application_manager/src/helpers/application_helper.cc @@ -0,0 +1,146 @@ +#include <vector> +#include <string> +#include "application_manager/helpers/application_helper.h" +#include "application_manager/message_helper.h" +#include "utils/logger.h" +#include "utils/file_system.h" + +namespace { +using namespace application_manager; +void DeleteWayPoints(ApplicationSharedPtr app, + ApplicationManager& app_manager) { + app_manager.UnsubscribeAppFromWayPoints(app); + if (!app_manager.IsAnyAppSubscribedForWayPoints()) { + MessageHelper::SendUnsubscribedWayPoints(app_manager); + } +} + +void DeleteCommands(ApplicationSharedPtr app, ApplicationManager& app_manager) { + CommandsMap cmap = app->commands_map().GetData(); + + for (auto cmd : cmap) { + MessageHelper::SendDeleteCommandRequest(cmd.second, app, app_manager); + app->RemoveCommand(cmd.first); + } +} + +void DeleteSubmenus(ApplicationSharedPtr app, ApplicationManager& app_manager) { + SubMenuMap smap = app->sub_menu_map().GetData(); + + for (auto smenu : smap) { + MessageHelper::SendDeleteSubmenuRequest(smenu.second, app, app_manager); + app->RemoveSubMenu(smenu.first); + } +} + +void DeleteChoiceSets(ApplicationSharedPtr app, + ApplicationManager& app_manager) { + ChoiceSetMap csmap = app->choice_set_map().GetData(); + + for (auto choice : csmap) { + MessageHelper::SendDeleteChoiceSetRequest(choice.second, app, app_manager); + app->RemoveChoiceSet(choice.first); + } +} + +void DeleteGlobalProperties(ApplicationSharedPtr app, + ApplicationManager& app_manager) { + using namespace smart_objects; + + const std::vector<std::string>& timeout_prompt = + app_manager.get_settings().time_out_promt(); + + SmartObject so_default_timeout_prompt = SmartObject(SmartType_Array); + + int32_t index = 0; + for (auto prompt : timeout_prompt) { + SmartObject timeoutPrompt = SmartObject(SmartType_Map); + timeoutPrompt[strings::text] = timeout_prompt[static_cast<size_t>(index)]; + timeoutPrompt[strings::type] = hmi_apis::Common_SpeechCapabilities::SC_TEXT; + so_default_timeout_prompt[index] = timeoutPrompt; + ++index; + } + + app->set_timeout_prompt(so_default_timeout_prompt); + + SmartObject empty_so = SmartObject(SmartType_Array); + app->set_help_prompt(empty_so); + app->reset_vr_help_title(); + app->reset_vr_help(); + app->set_keyboard_props(empty_so); + app->set_menu_icon(empty_so); + app->set_menu_title(empty_so); + + MessageHelper::SendResetPropertiesRequest(app, app_manager); +} + +void DeleteButtonSubscriptions(ApplicationSharedPtr app, + ApplicationManager& app_manager) { + ButtonSubscriptions buttons = app->SubscribedButtons().GetData(); + + for (auto button : buttons) { + if (mobile_apis::ButtonName::CUSTOM_BUTTON == button) { + continue; + } + MessageHelper::SendUnsubscribeButtonNotification(button, app, app_manager); + app->UnsubscribeFromButton(button); + } +} + +void DeleteVISubscriptions(ApplicationSharedPtr app, + ApplicationManager& app_manager) { + VehicleInfoSubscriptions ivi = app->SubscribedIVI().GetData(); + + for (auto i : ivi) { + app->UnsubscribeFromIVI(i); + SubscribedToIVIPredicate p(i); + auto app = FindApp(app_manager.applications(), p); + if (!app) { + MessageHelper::SendUnsubscribeIVIRequest(i, app, app_manager); + } + } +} + +void CleanupAppFiles(ApplicationSharedPtr app) { + const auto icon_file = app->app_icon_path(); + + auto files = app->getAppFiles(); + for (auto file : files) { + auto file_name = file.first; + if (icon_file == file_name) { + continue; + } + app->DeleteFile(file_name); + file_system::DeleteFile(file_name); + } +} +} // namespace + +namespace application_manager { + +CREATE_LOGGERPTR_GLOBAL(logger, "ApplicationManager") + +SubscribedToIVIPredicate::SubscribedToIVIPredicate(uint32_t vehicle_info) + : vehicle_info_(vehicle_info) {} + +bool SubscribedToIVIPredicate::operator()( + const ApplicationSharedPtr app) const { + return app ? app->IsSubscribedToIVI(vehicle_info_) : false; +} + +void DeleteApplicationData(ApplicationSharedPtr app, + ApplicationManager& app_manager) { + LOG4CXX_AUTO_TRACE(logger); + DCHECK_OR_RETURN_VOID(app); + + DeleteWayPoints(app, app_manager); + DeleteCommands(app, app_manager); + DeleteSubmenus(app, app_manager); + DeleteChoiceSets(app, app_manager); + DeleteGlobalProperties(app, app_manager); + DeleteButtonSubscriptions(app, app_manager); + DeleteVISubscriptions(app, app_manager); + CleanupAppFiles(app); +} + +} // namespace application_manager diff --git a/src/components/application_manager/src/hmi_state.cc b/src/components/application_manager/src/hmi_state.cc index 393a9d7784..bc1ccd8f42 100644 --- a/src/components/application_manager/src/hmi_state.cc +++ b/src/components/application_manager/src/hmi_state.cc @@ -37,47 +37,65 @@ 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) , audio_streaming_state_(mobile_apis::AudioStreamingState::INVALID_ENUM) , system_context_(mobile_apis::SystemContext::INVALID_ENUM) {} +DEPRECATED HmiState::HmiState(uint32_t app_id, + const ApplicationManager& app_mngr, + StateID state_id) + : 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) { + app_ = app_mngr_.application(app_id); +} + +DEPRECATED HmiState::HmiState(uint32_t app_id, + const ApplicationManager& app_mngr) + : state_id_(STATE_ID_REGULAR) + , 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) { + app_ = app_mngr_.application(app_id); +} + void HmiState::set_parent(HmiStatePtr parent) { DCHECK_OR_RETURN_VOID(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,10 +104,20 @@ mobile_apis::AudioStreamingState::eType VRHmiState::audio_streaming_state() return AudioStreamingState::NOT_AUDIBLE; } -VRHmiState::VRHmiState(uint32_t app_id, const ApplicationManager& app_mngr) +VRHmiState::VRHmiState(utils::SharedPtr<Application> app, + const ApplicationManager& app_mngr) + : HmiState(app, app_mngr, STATE_ID_VR_SESSION) {} + +DEPRECATED VRHmiState::VRHmiState(uint32_t app_id, + const ApplicationManager& app_mngr) : HmiState(app_id, app_mngr, STATE_ID_VR_SESSION) {} -TTSHmiState::TTSHmiState(uint32_t app_id, const ApplicationManager& app_mngr) +TTSHmiState::TTSHmiState(utils::SharedPtr<Application> app, + const ApplicationManager& app_mngr) + : HmiState(app, app_mngr, STATE_ID_TTS_SESSION) {} + +DEPRECATED TTSHmiState::TTSHmiState(uint32_t app_id, + const ApplicationManager& app_mngr) : HmiState(app_id, app_mngr, STATE_ID_TTS_SESSION) {} mobile_apis::AudioStreamingState::eType TTSHmiState::audio_streaming_state() @@ -107,8 +135,12 @@ 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, app_mngr, STATE_ID_NAVI_STREAMING) {} + +DEPRECATED NaviStreamingHmiState::NaviStreamingHmiState( + uint32_t app_id, const ApplicationManager& app_mngr) : HmiState(app_id, app_mngr, STATE_ID_NAVI_STREAMING) {} mobile_apis::AudioStreamingState::eType @@ -117,7 +149,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,8 +159,12 @@ 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, app_mngr, STATE_ID_PHONE_CALL) {} + +DEPRECATED PhoneCallHmiState::PhoneCallHmiState( + uint32_t app_id, const ApplicationManager& app_mngr) : HmiState(app_id, app_mngr, STATE_ID_PHONE_CALL) {} mobile_apis::HMILevel::eType PhoneCallHmiState::hmi_level() const { @@ -139,21 +175,29 @@ 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, app_mngr, STATE_ID_SAFETY_MODE) {} + +DEPRECATED SafetyModeHmiState::SafetyModeHmiState( + uint32_t app_id, const ApplicationManager& app_mngr) : HmiState(app_id, app_mngr, STATE_ID_SAFETY_MODE) {} -DeactivateHMI::DeactivateHMI(uint32_t app_id, +DeactivateHMI::DeactivateHMI(utils::SharedPtr<Application> app, const ApplicationManager& app_mngr) + : HmiState(app, app_mngr, STATE_ID_DEACTIVATE_HMI) {} + +DEPRECATED DeactivateHMI::DeactivateHMI(uint32_t app_id, + const ApplicationManager& app_mngr) : HmiState(app_id, app_mngr, STATE_ID_DEACTIVATE_HMI) {} mobile_apis::HMILevel::eType DeactivateHMI::hmi_level() const { @@ -167,7 +211,12 @@ mobile_apis::HMILevel::eType DeactivateHMI::hmi_level() const { return HMILevel::HMI_BACKGROUND; } -AudioSource::AudioSource(uint32_t app_id, const ApplicationManager& app_mngr) +AudioSource::AudioSource(utils::SharedPtr<Application> app, + const ApplicationManager& app_mngr) + : HmiState(app, app_mngr, STATE_ID_AUDIO_SOURCE) {} + +DEPRECATED AudioSource::AudioSource(uint32_t app_id, + const ApplicationManager& app_mngr) : HmiState(app_id, app_mngr, STATE_ID_AUDIO_SOURCE) {} mobile_apis::HMILevel::eType AudioSource::hmi_level() const { @@ -181,13 +230,18 @@ 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) +EmbeddedNavi::EmbeddedNavi(utils::SharedPtr<Application> app, + const ApplicationManager& app_mngr) + : HmiState(app, app_mngr, STATE_ID_EMBEDDED_NAVI) {} + +DEPRECATED EmbeddedNavi::EmbeddedNavi(uint32_t app_id, + const ApplicationManager& app_mngr) : HmiState(app_id, app_mngr, STATE_ID_EMBEDDED_NAVI) {} mobile_apis::HMILevel::eType EmbeddedNavi::hmi_level() const { @@ -198,7 +252,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/message_helper/message_helper.cc b/src/components/application_manager/src/message_helper/message_helper.cc index cf64152315..4ae6ce4024 100644 --- a/src/components/application_manager/src/message_helper/message_helper.cc +++ b/src/components/application_manager/src/message_helper/message_helper.cc @@ -42,6 +42,7 @@ #include <algorithm> #include <utility> #include <map> +#include <functional> #include "application_manager/application.h" #include "application_manager/application_manager.h" @@ -310,21 +311,20 @@ std::string MessageHelper::CommonLanguageToString( return std::string(); } -smart_objects::SmartObjectSPtr MessageHelper::CreateRequestObject( - const uint32_t correlation_id) { +smart_objects::SmartObjectSPtr MessageHelper::CreateMessageForHMI( + hmi_apis::messageType::eType message_type, const uint32_t correlation_id) { using namespace smart_objects; - SmartObjectSPtr request = utils::MakeShared<SmartObject>(SmartType_Map); - SmartObject& ref = *request; + SmartObjectSPtr message = utils::MakeShared<SmartObject>(SmartType_Map); + SmartObject& ref = *message; - ref[strings::params][strings::message_type] = - static_cast<int>(hmi_apis::messageType::request); + ref[strings::params][strings::message_type] = static_cast<int>(message_type); ref[strings::params][strings::protocol_version] = commands::CommandImpl::protocol_version_; ref[strings::params][strings::protocol_type] = commands::CommandImpl::hmi_protocol_type_; ref[strings::params][strings::correlation_id] = correlation_id; - return request; + return message; } smart_objects::SmartObjectSPtr MessageHelper::CreateHashUpdateNotification( @@ -344,8 +344,8 @@ smart_objects::SmartObjectSPtr MessageHelper::CreateHashUpdateNotification( void MessageHelper::SendDecryptCertificateToHMI(const std::string& file_name, ApplicationManager& app_mngr) { using namespace smart_objects; - SmartObjectSPtr message = - CreateRequestObject(app_mngr.GetNextHMICorrelationID()); + SmartObjectSPtr message = CreateMessageForHMI( + hmi_apis::messageType::request, app_mngr.GetNextHMICorrelationID()); DCHECK(message); SmartObject& object = *message; @@ -400,6 +400,253 @@ MessageHelper::GetOnAppInterfaceUnregisteredNotificationToMobile( return notification; } +void MessageHelper::SendDeleteCommandRequest(smart_objects::SmartObject* cmd, + ApplicationSharedPtr application, + ApplicationManager& app_mngr) { + LOG4CXX_AUTO_TRACE(logger_); + DCHECK_OR_RETURN_VOID(cmd); + using namespace smart_objects; + SmartObject msg_params = SmartObject(smart_objects::SmartType_Map); + + msg_params[strings::cmd_id] = (*cmd)[strings::cmd_id]; + msg_params[strings::app_id] = application->app_id(); + + if ((*cmd).keyExists(strings::menu_params)) { + SmartObjectSPtr message = CreateMessageForHMI( + hmi_apis::messageType::request, app_mngr.GetNextHMICorrelationID()); + DCHECK(message); + + SmartObject& object = *message; + object[strings::params][strings::function_id] = + hmi_apis::FunctionID::UI_DeleteCommand; + + object[strings::msg_params] = msg_params; + + app_mngr.ManageHMICommand(message); + } + + if ((*cmd).keyExists(strings::vr_commands)) { + msg_params[strings::grammar_id] = application->get_grammar_id(); + msg_params[strings::type] = hmi_apis::Common_VRCommandType::Command; + + SmartObjectSPtr message = CreateMessageForHMI( + hmi_apis::messageType::request, app_mngr.GetNextHMICorrelationID()); + DCHECK(message); + + SmartObject& object = *message; + object[strings::params][strings::function_id] = + hmi_apis::FunctionID::VR_DeleteCommand; + + object[strings::msg_params] = msg_params; + + app_mngr.ManageHMICommand(message); + } +} + +void MessageHelper::SendDeleteSubmenuRequest(smart_objects::SmartObject* cmd, + ApplicationSharedPtr application, + ApplicationManager& app_mngr) { + LOG4CXX_AUTO_TRACE(logger_); + DCHECK_OR_RETURN_VOID(cmd); + using namespace smart_objects; + + SmartObject msg_params = SmartObject(smart_objects::SmartType_Map); + + msg_params[strings::menu_id] = (*cmd)[strings::menu_id]; + msg_params[strings::app_id] = application->app_id(); + + SmartObjectSPtr message = CreateMessageForHMI( + hmi_apis::messageType::request, app_mngr.GetNextHMICorrelationID()); + DCHECK(message); + + SmartObject& object = *message; + object[strings::params][strings::function_id] = + hmi_apis::FunctionID::UI_DeleteSubMenu; + + object[strings::msg_params] = msg_params; + + app_mngr.ManageHMICommand(message); + + const DataAccessor<CommandsMap> accessor = application->commands_map(); + const CommandsMap& commands = accessor.GetData(); + CommandsMap::const_iterator it = commands.begin(); + + for (; commands.end() != it; ++it) { + if (!(*it->second).keyExists(strings::vr_commands)) { + continue; + } + + if ((*cmd)[strings::menu_id].asInt() == + (*it->second)[strings::menu_params][hmi_request::parent_id].asInt()) { + SmartObject msg_params = SmartObject(smart_objects::SmartType_Map); + msg_params[strings::cmd_id] = (*it->second)[strings::cmd_id].asInt(); + msg_params[strings::app_id] = application->app_id(); + msg_params[strings::grammar_id] = application->get_grammar_id(); + msg_params[strings::type] = hmi_apis::Common_VRCommandType::Command; + + SmartObjectSPtr message = CreateMessageForHMI( + hmi_apis::messageType::request, app_mngr.GetNextHMICorrelationID()); + DCHECK(message); + + SmartObject& object = *message; + object[strings::params][strings::function_id] = + hmi_apis::FunctionID::VR_DeleteCommand; + + object[strings::msg_params] = msg_params; + + app_mngr.ManageHMICommand(message); + } + } +} + +void MessageHelper::SendDeleteChoiceSetRequest(smart_objects::SmartObject* cmd, + ApplicationSharedPtr application, + ApplicationManager& app_mngr) { + LOG4CXX_AUTO_TRACE(logger_); + DCHECK_OR_RETURN_VOID(cmd); + using namespace smart_objects; + + // Same is deleted with SendDeleteCommandRequest? + + SmartObject msg_params = SmartObject(smart_objects::SmartType_Map); + + msg_params[strings::app_id] = application->app_id(); + msg_params[strings::type] = hmi_apis::Common_VRCommandType::Choice; + msg_params[strings::grammar_id] = (*cmd)[strings::grammar_id]; + cmd = &((*cmd)[strings::choice_set]); + for (uint32_t i = 0; i < (*cmd).length(); ++i) { + msg_params[strings::cmd_id] = (*cmd)[i][strings::choice_id]; + + SmartObjectSPtr message = CreateMessageForHMI( + hmi_apis::messageType::request, app_mngr.GetNextHMICorrelationID()); + DCHECK(message); + + SmartObject& object = *message; + object[strings::params][strings::function_id] = + hmi_apis::FunctionID::VR_DeleteCommand; + + object[strings::msg_params] = msg_params; + + app_mngr.ManageHMICommand(message); + } +} + +void MessageHelper::SendResetPropertiesRequest(ApplicationSharedPtr application, + ApplicationManager& app_mngr) { + LOG4CXX_AUTO_TRACE(logger_); + using namespace smart_objects; + + { + SmartObject msg_params = SmartObject(smart_objects::SmartType_Map); + + msg_params = *MessageHelper::CreateAppVrHelp(application); + msg_params[hmi_request::menu_title] = ""; + + smart_objects::SmartObject key_board_properties = + smart_objects::SmartObject(smart_objects::SmartType_Map); + key_board_properties[strings::language] = + static_cast<int32_t>(hmi_apis::Common_Language::EN_US); + key_board_properties[hmi_request::keyboard_layout] = + static_cast<int32_t>(hmi_apis::Common_KeyboardLayout::QWERTY); + + key_board_properties[hmi_request::auto_complete_text] = ""; + msg_params[hmi_request::keyboard_properties] = key_board_properties; + + msg_params[strings::app_id] = application->app_id(); + + SmartObjectSPtr message = CreateMessageForHMI( + hmi_apis::messageType::request, app_mngr.GetNextHMICorrelationID()); + DCHECK(message); + + SmartObject& object = *message; + object[strings::params][strings::function_id] = + hmi_apis::FunctionID::UI_SetGlobalProperties; + + object[strings::msg_params] = msg_params; + + app_mngr.ManageHMICommand(message); + } + + { + SmartObject msg_params = SmartObject(smart_objects::SmartType_Map); + + msg_params[strings::help_prompt] = application->help_prompt(); + msg_params[strings::timeout_prompt] = application->timeout_prompt(); + msg_params[strings::app_id] = application->app_id(); + + SmartObjectSPtr message = CreateMessageForHMI( + hmi_apis::messageType::request, app_mngr.GetNextHMICorrelationID()); + DCHECK(message); + + SmartObject& object = *message; + object[strings::params][strings::function_id] = + hmi_apis::FunctionID::TTS_SetGlobalProperties; + + object[strings::msg_params] = msg_params; + + app_mngr.ManageHMICommand(message); + } +} + +void MessageHelper::SendUnsubscribeButtonNotification( + mobile_apis::ButtonName::eType button, + ApplicationSharedPtr application, + ApplicationManager& app_mngr) { + using namespace smart_objects; + using namespace hmi_apis; + + SmartObject msg_params = SmartObject(SmartType_Map); + msg_params[strings::app_id] = application->app_id(); + msg_params[strings::name] = button; + msg_params[strings::is_suscribed] = false; + + SmartObjectSPtr message = CreateMessageForHMI( + hmi_apis::messageType::notification, app_mngr.GetNextHMICorrelationID()); + DCHECK(message); + + SmartObject& object = *message; + object[strings::params][strings::function_id] = + hmi_apis::FunctionID::Buttons_OnButtonSubscription; + + object[strings::msg_params] = msg_params; + + app_mngr.ManageHMICommand(message); +} + +void MessageHelper::SendUnsubscribeIVIRequest(int32_t ivi_id, + ApplicationSharedPtr application, + ApplicationManager& app_mngr) { + using namespace smart_objects; + + std::string key_name; + for (auto item : vehicle_data_) { + if (ivi_id == item.second) { + key_name = item.first; + break; + } + } + + if (key_name.empty()) { + return; + } + + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + msg_params[key_name] = true; + + SmartObjectSPtr message = CreateMessageForHMI( + hmi_apis::messageType::request, app_mngr.GetNextHMICorrelationID()); + DCHECK(message); + + SmartObject& object = *message; + object[strings::params][strings::function_id] = + hmi_apis::FunctionID::VehicleInfo_UnsubscribeVehicleData; + + object[strings::msg_params] = msg_params; + + app_mngr.ManageHMICommand(message); +} + const VehicleData& MessageHelper::vehicle_data() { return vehicle_data_; } @@ -950,7 +1197,9 @@ void MessageHelper::SendSetAppIcon( using namespace smart_objects; SmartObjectSPtr set_app_icon = - CreateRequestObject(application_manager.GetNextHMICorrelationID()); + CreateMessageForHMI(hmi_apis::messageType::request, + application_manager.GetNextHMICorrelationID()); + if (set_app_icon) { SmartObject& so_to_send = *set_app_icon; so_to_send[strings::params][strings::function_id] = @@ -1009,7 +1258,7 @@ MessageHelper::CreateGlobalPropertiesRequestsToHMI( if (app->vr_help_title() || app->vr_help()) { smart_objects::SmartObjectSPtr ui_global_properties = - CreateRequestObject(correlation_id); + CreateMessageForHMI(hmi_apis::messageType::request, correlation_id); if (!ui_global_properties) { return requests; } @@ -1044,7 +1293,7 @@ MessageHelper::CreateGlobalPropertiesRequestsToHMI( // TTS global properties if (app->help_prompt() || app->timeout_prompt()) { smart_objects::SmartObjectSPtr tts_global_properties = - CreateRequestObject(correlation_id); + CreateMessageForHMI(hmi_apis::messageType::request, correlation_id); if (!tts_global_properties) { return requests; } @@ -1076,8 +1325,9 @@ void MessageHelper::SendTTSGlobalProperties(ApplicationSharedPtr app, if (!app) { return; } - smart_objects::SmartObjectSPtr tts_global_properties = - CreateRequestObject(app_man.GetNextHMICorrelationID()); + smart_objects::SmartObjectSPtr tts_global_properties = CreateMessageForHMI( + hmi_apis::messageType::request, app_man.GetNextHMICorrelationID()); + if (tts_global_properties) { smart_objects::SmartObject& so_to_send = *tts_global_properties; so_to_send[strings::params][strings::function_id] = @@ -1155,7 +1405,7 @@ smart_objects::SmartObjectList MessageHelper::CreateShowRequestToHMI( if (app->show_command()) { smart_objects::SmartObjectSPtr ui_show = - CreateRequestObject(correlation_id); + CreateMessageForHMI(hmi_apis::messageType::request, correlation_id); (*ui_show)[strings::params][strings::function_id] = static_cast<int>(hmi_apis::FunctionID::UI_Show); @@ -1187,8 +1437,8 @@ void MessageHelper::SendShowConstantTBTRequestToHMI( } if (app->tbt_show_command()) { - smart_objects::SmartObjectSPtr navi_show_tbt = - CreateRequestObject(app_man.GetNextHMICorrelationID()); + smart_objects::SmartObjectSPtr navi_show_tbt = CreateMessageForHMI( + hmi_apis::messageType::request, app_man.GetNextHMICorrelationID()); if (!navi_show_tbt) { return; } @@ -1228,8 +1478,8 @@ smart_objects::SmartObjectList MessageHelper::CreateAddCommandRequestToHMI( for (; commands.end() != i; ++i) { // UI Interface if ((*i->second).keyExists(strings::menu_params)) { - smart_objects::SmartObjectSPtr ui_command = - CreateRequestObject(app_mngr.GetNextHMICorrelationID()); + smart_objects::SmartObjectSPtr ui_command = CreateMessageForHMI( + hmi_apis::messageType::request, app_mngr.GetNextHMICorrelationID()); if (!ui_command) { return requests; } @@ -1281,8 +1531,8 @@ MessageHelper::CreateAddVRCommandRequestFromChoiceToHMI( (*(it->second))[strings::grammar_id].asUInt(); const size_t size = (*(it->second))[strings::choice_set].length(); for (size_t j = 0; j < size; ++j) { - smart_objects::SmartObjectSPtr vr_command = - CreateRequestObject(app_mngr.GetNextHMICorrelationID()); + smart_objects::SmartObjectSPtr vr_command = CreateMessageForHMI( + hmi_apis::messageType::request, app_mngr.GetNextHMICorrelationID()); if (!vr_command) { return requests; } @@ -1315,8 +1565,8 @@ smart_objects::SmartObjectSPtr MessageHelper::CreateChangeRegistration( const uint32_t app_id, const smart_objects::SmartObject* app_types, ApplicationManager& app_mngr) { - smart_objects::SmartObjectSPtr command = - CreateRequestObject(app_mngr.GetNextHMICorrelationID()); + smart_objects::SmartObjectSPtr command = CreateMessageForHMI( + hmi_apis::messageType::request, app_mngr.GetNextHMICorrelationID()); if (!command) { return NULL; } @@ -1372,8 +1622,8 @@ smart_objects::SmartObjectSPtr MessageHelper::CreateAddVRCommandToHMI( const smart_objects::SmartObject& vr_commands, uint32_t app_id, ApplicationManager& app_mngr) { - smart_objects::SmartObjectSPtr vr_command = - CreateRequestObject(app_mngr.GetNextHMICorrelationID()); + smart_objects::SmartObjectSPtr vr_command = CreateMessageForHMI( + hmi_apis::messageType::request, app_mngr.GetNextHMICorrelationID()); if (!vr_command) { return NULL; } @@ -1492,7 +1742,7 @@ smart_objects::SmartObjectList MessageHelper::CreateAddSubMenuRequestToHMI( SubMenuMap::const_iterator i = sub_menu.begin(); for (; sub_menu.end() != i; ++i) { smart_objects::SmartObjectSPtr ui_sub_menu = - CreateRequestObject(correlation_id); + CreateMessageForHMI(hmi_apis::messageType::request, correlation_id); if (!ui_sub_menu) { return requsets; } @@ -1531,7 +1781,7 @@ void MessageHelper::SendOnAppUnregNotificationToHMI( message[strings::params][strings::message_type] = MessageType::kNotification; // we put hmi_app_id because applicaton list does not contain application on // this momment - // and ReplaceHMIByMobileAppId function will be unable to replace app_id to + // and ReplaceHMIWithMobileAppId function will be unable to replace app_id to // hmi_app_id message[strings::msg_params][strings::app_id] = app->hmi_app_id(); message[strings::msg_params][strings::unexpected_disconnect] = @@ -1681,8 +1931,8 @@ void MessageHelper::SendPolicyUpdate(const std::string& file_path, const uint32_t timeout, const std::vector<int>& retries, ApplicationManager& app_mngr) { - smart_objects::SmartObjectSPtr message = - CreateRequestObject(app_mngr.GetNextHMICorrelationID()); + smart_objects::SmartObjectSPtr message = CreateMessageForHMI( + hmi_apis::messageType::request, app_mngr.GetNextHMICorrelationID()); smart_objects::SmartObject& object = *message; object[strings::params][strings::function_id] = hmi_apis::FunctionID::BasicCommunication_PolicyUpdate; @@ -1863,8 +2113,8 @@ void MessageHelper::SendNaviSetVideoConfig( ApplicationManager& app_mngr, const smart_objects::SmartObject& video_params) { LOG4CXX_AUTO_TRACE(logger_); - smart_objects::SmartObjectSPtr request = - CreateRequestObject(app_mngr.GetNextHMICorrelationID()); + smart_objects::SmartObjectSPtr request = CreateMessageForHMI( + hmi_apis::messageType::request, app_mngr.GetNextHMICorrelationID()); if (!request) { return; } @@ -1881,8 +2131,8 @@ void MessageHelper::SendNaviSetVideoConfig( void MessageHelper::SendNaviStartStream(const int32_t app_id, ApplicationManager& app_mngr) { LOG4CXX_AUTO_TRACE(logger_); - smart_objects::SmartObjectSPtr start_stream = - CreateRequestObject(app_mngr.GetNextHMICorrelationID()); + smart_objects::SmartObjectSPtr start_stream = CreateMessageForHMI( + hmi_apis::messageType::request, app_mngr.GetNextHMICorrelationID()); if (!start_stream) { return; } @@ -1920,8 +2170,8 @@ void MessageHelper::SendNaviStartStream(const int32_t app_id, void MessageHelper::SendNaviStopStream(const int32_t app_id, ApplicationManager& app_mngr) { LOG4CXX_AUTO_TRACE(logger_); - smart_objects::SmartObjectSPtr stop_stream = - CreateRequestObject(app_mngr.GetNextHMICorrelationID()); + smart_objects::SmartObjectSPtr stop_stream = CreateMessageForHMI( + hmi_apis::messageType::request, app_mngr.GetNextHMICorrelationID()); if (!stop_stream) { return; } @@ -1937,8 +2187,8 @@ void MessageHelper::SendNaviStopStream(const int32_t app_id, void MessageHelper::SendAudioStartStream(const int32_t app_id, ApplicationManager& app_mngr) { LOG4CXX_AUTO_TRACE(logger_); - smart_objects::SmartObjectSPtr start_stream = - CreateRequestObject(app_mngr.GetNextHMICorrelationID()); + smart_objects::SmartObjectSPtr start_stream = CreateMessageForHMI( + hmi_apis::messageType::request, app_mngr.GetNextHMICorrelationID()); if (!start_stream) { return; @@ -1977,8 +2227,8 @@ void MessageHelper::SendAudioStartStream(const int32_t app_id, void MessageHelper::SendAudioStopStream(const int32_t app_id, ApplicationManager& app_mngr) { LOG4CXX_AUTO_TRACE(logger_); - smart_objects::SmartObjectSPtr stop_stream = - CreateRequestObject(app_mngr.GetNextHMICorrelationID()); + smart_objects::SmartObjectSPtr stop_stream = CreateMessageForHMI( + hmi_apis::messageType::request, app_mngr.GetNextHMICorrelationID()); if (!stop_stream) { return; @@ -2027,8 +2277,8 @@ void MessageHelper::SendOnDataStreaming( bool MessageHelper::SendStopAudioPathThru(ApplicationManager& app_mngr) { LOG4CXX_INFO(logger_, "MessageHelper::SendAudioStopAudioPathThru"); - smart_objects::SmartObjectSPtr result = - CreateRequestObject(app_mngr.GetNextHMICorrelationID()); + smart_objects::SmartObjectSPtr result = CreateMessageForHMI( + hmi_apis::messageType::request, app_mngr.GetNextHMICorrelationID()); (*result)[strings::params][strings::function_id] = hmi_apis::FunctionID::UI_EndAudioPassThru; @@ -2039,8 +2289,8 @@ bool MessageHelper::SendStopAudioPathThru(ApplicationManager& app_mngr) { bool MessageHelper::SendUnsubscribedWayPoints(ApplicationManager& app_mngr) { LOG4CXX_INFO(logger_, "MessageHelper::SendUnsubscribedWayPoints"); - smart_objects::SmartObjectSPtr result = - CreateRequestObject(app_mngr.GetNextHMICorrelationID()); + smart_objects::SmartObjectSPtr result = CreateMessageForHMI( + hmi_apis::messageType::request, app_mngr.GetNextHMICorrelationID()); (*result)[strings::params][strings::function_id] = hmi_apis::FunctionID::Navigation_UnsubscribeWayPoints; @@ -2399,8 +2649,8 @@ void MessageHelper::SendOnStatusUpdate(const std::string& status, } void MessageHelper::SendGetSystemInfoRequest(ApplicationManager& app_mngr) { - smart_objects::SmartObjectSPtr message = - CreateRequestObject(app_mngr.GetNextHMICorrelationID()); + smart_objects::SmartObjectSPtr message = CreateMessageForHMI( + hmi_apis::messageType::request, app_mngr.GetNextHMICorrelationID()); if (!message) { return; } diff --git a/src/components/application_manager/src/policies/policy_handler.cc b/src/components/application_manager/src/policies/policy_handler.cc index e6ebaf3b83..41e7990e43 100644 --- a/src/components/application_manager/src/policies/policy_handler.cc +++ b/src/components/application_manager/src/policies/policy_handler.cc @@ -852,6 +852,13 @@ uint32_t PolicyHandler::ChooseRandomAppForPolicyUpdate( return 0; } +void PolicyHandler::OnDeviceSwitching(const std::string& device_id_from, + const std::string& device_id_to) { + LOG4CXX_AUTO_TRACE(logger_); + POLICY_LIB_CHECK_VOID(); + policy_manager_->OnDeviceSwitching(device_id_from, device_id_to); +} + void PolicyHandler::OnGetStatusUpdate(const uint32_t correlation_id) { LOG4CXX_AUTO_TRACE(logger_); POLICY_LIB_CHECK_VOID(); @@ -1170,7 +1177,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 +1211,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/resumption/resume_ctrl_impl.cc b/src/components/application_manager/src/resumption/resume_ctrl_impl.cc index 435e621169..72f2246e7c 100644 --- a/src/components/application_manager/src/resumption/resume_ctrl_impl.cc +++ b/src/components/application_manager/src/resumption/resume_ctrl_impl.cc @@ -597,7 +597,7 @@ void ResumeCtrlImpl::AddWayPointsSubscription( const smart_objects::SmartObject& subscribed_for_way_points_so = saved_app[strings::subscribed_for_way_points]; if (true == subscribed_for_way_points_so.asBool()) { - application_manager_.SubscribeAppForWayPoints(application->app_id()); + application_manager_.SubscribeAppForWayPoints(application); } } } diff --git a/src/components/application_manager/src/resumption/resumption_data_db.cc b/src/components/application_manager/src/resumption/resumption_data_db.cc index 23fecb7624..b031fd0afd 100644 --- a/src/components/application_manager/src/resumption/resumption_data_db.cc +++ b/src/components/application_manager/src/resumption/resumption_data_db.cc @@ -212,8 +212,7 @@ uint32_t ResumptionDataDB::GetHMIApplicationID( return hmi_app_id; } -// DEPRECATED -void ResumptionDataDB::OnSuspend() {} +DEPRECATED void ResumptionDataDB::OnSuspend() {} void ResumptionDataDB::IncrementIgnOffCount() { LOG4CXX_AUTO_TRACE(logger_); @@ -294,8 +293,7 @@ bool ResumptionDataDB::GetHashId(const std::string& policy_app_id, return SelectHashId(policy_app_id, device_id, hash_id); } -// DEPRECATED -void ResumptionDataDB::OnAwake() {} +DEPRECATED void ResumptionDataDB::OnAwake() {} void ResumptionDataDB::DecrementIgnOffCount() { LOG4CXX_AUTO_TRACE(logger_); @@ -2584,7 +2582,7 @@ bool ResumptionDataDB::InsertApplicationData( const mobile_apis::HMILevel::eType hmi_level = application.m_hmi_level; bool is_media_application = application.m_is_media_application; bool is_subscribed_for_way_points = - application_manager_.IsAppSubscribedForWayPoints(connection_key); + application_manager_.IsAppSubscribedForWayPoints(application.app_ptr); if (!query.Prepare(kInsertApplication)) { LOG4CXX_WARN(logger_, @@ -2810,6 +2808,7 @@ ApplicationParams::ApplicationParams(app_mngr::ApplicationSharedPtr application) m_hmi_app_id = application->hmi_app_id(); m_hmi_level = application->hmi_level(); m_is_media_application = application->IsAudioApplication(); + app_ptr = application; } } diff --git a/src/components/application_manager/src/resumption/resumption_data_json.cc b/src/components/application_manager/src/resumption/resumption_data_json.cc index 203c4889c5..e99d8bae26 100644 --- a/src/components/application_manager/src/resumption/resumption_data_json.cc +++ b/src/components/application_manager/src/resumption/resumption_data_json.cc @@ -66,7 +66,7 @@ void ResumptionDataJson::SaveApplication( const std::string device_mac = application->mac_address(); const mobile_apis::HMILevel::eType hmi_level = application->hmi_level(); const bool is_subscribed_for_way_points = - application_manager_.IsAppSubscribedForWayPoints(application->app_id()); + application_manager_.IsAppSubscribedForWayPoints(application); sync_primitives::AutoLock autolock(resumption_lock_); Json::Value tmp; @@ -143,8 +143,7 @@ uint32_t ResumptionDataJson::GetHMIApplicationID( return hmi_app_id; } -// DEPRECATED -void ResumptionDataJson::OnSuspend() {} +DEPRECATED void ResumptionDataJson::OnSuspend() {} void ResumptionDataJson::IncrementIgnOffCount() { using namespace app_mngr; @@ -170,8 +169,7 @@ void ResumptionDataJson::IncrementIgnOffCount() { LOG4CXX_DEBUG(logger_, GetResumptionData().toStyledString()); } -// DEPRECATED -void ResumptionDataJson::OnAwake() {} +DEPRECATED void ResumptionDataJson::OnAwake() {} void ResumptionDataJson::DecrementIgnOffCount() { using namespace app_mngr; 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/application_manager/test/CMakeLists.txt b/src/components/application_manager/test/CMakeLists.txt index 0580998e84..3e9010e22c 100644 --- a/src/components/application_manager/test/CMakeLists.txt +++ b/src/components/application_manager/test/CMakeLists.txt @@ -31,12 +31,6 @@ include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/platform.cmake) include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) -# TODO{ALeshin}: APPLINK-10792. Do not write tests which use -# application manager(AM) singleton while refactoring of AM is finished. - -# TODO{ILytvynenko}: SDLOPEN-797 Uncomment application_manager_impl_test and -# cover with UT missed files. - include_directories( ${GMOCK_INCLUDE_DIRECTORY} ${CMAKE_BINARY_DIR}/src/components/ @@ -68,9 +62,15 @@ set(testSources ${AM_TEST_DIR}/application_state_test.cc ${AM_TEST_DIR}/usage_statistics_test.cc ${AM_TEST_DIR}/policy_handler_test.cc - ${AM_TEST_DIR}/mock_message_helper.cc ${AM_TEST_DIR}/application_manager_impl_test.cc + ${AM_TEST_DIR}/application_helper_test.cc + ${AM_TEST_DIR}/command_holder_test.cc +) +set(testSourcesMockHmi + ${AM_SOURCE_DIR}/src/message_helper/message_helper.cc + ${AM_TEST_DIR}/application_manager_impl_mock_hmi_test.cc + ${AM_TEST_DIR}/mock_hmi_command_factory.cc ) if(REMOTE_CONTROL) @@ -130,10 +130,11 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath=${CMAKE_CURRENT_BINARY_DIR}" ) create_test("application_manager_test" "${testSources}" "${LIBRARIES}") +create_test("application_manager_mock_hmi_test" "${testSourcesMockHmi}" "${LIBRARIES}") add_dependencies("application_manager_test" libbson) + create_test("request_controller_test" "${RequestController_SOURCES}" "${LIBRARIES}") -# TODO [AKozoriz] : Fix not buildable tests set(ResumptionData_SOURCES ${AM_TEST_DIR}/resumption/resumption_data_test.cc ${AM_TEST_DIR}/resumption/resumption_data_db_test.cc diff --git a/src/components/application_manager/test/application_helper_test.cc b/src/components/application_manager/test/application_helper_test.cc new file mode 100644 index 0000000000..a0b6fd6aa2 --- /dev/null +++ b/src/components/application_manager/test/application_helper_test.cc @@ -0,0 +1,258 @@ +/* + * Copyright (c) 2017, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <gmock/gmock.h> +#include <string> +#include <vector> + +#include "application_manager/mock_application_manager_settings.h" +#include "application_manager/mock_message_helper.h" +#include "policy/usage_statistics/mock_statistics_manager.h" +#include "policy/mock_policy_settings.h" + +#include "application_manager/application.h" +#include "application_manager/application_impl.h" +#include "application_manager/application_manager_impl.h" +#include "application_manager/usage_statistics.h" +#include "application_manager/helpers/application_helper.h" +#include "application_manager/smart_object_keys.h" +#include "interfaces/MOBILE_API.h" +#include "connection_handler/device.h" +#include "smart_objects/smart_object.h" +#include "utils/custom_string.h" +#include "utils/macro.h" +#include "utils/shared_ptr.h" +#include "utils/make_shared.h" + +namespace { +const uint8_t expected_tread_pool_size = 2u; +const uint8_t stop_streaming_timeout = 1u; +const std::string kDirectoryName = "./test_storage"; +const std::vector<std::string> kTimeoutPrompt{"timeoutPrompt"}; +} + +namespace test { +namespace components { +namespace application_manager_test { + +using testing::_; +using ::testing::Mock; +using ::testing::NiceMock; +using ::testing::Return; +using ::testing::ReturnRef; + +using namespace application_manager; +using namespace policy_handler_test; + +class ApplicationHelperTest : public testing::Test { + public: + ApplicationHelperTest() + : mock_message_helper_( + application_manager::MockMessageHelper::message_helper_mock()) + , app_manager_impl_(mock_application_manager_settings_, + mock_policy_settings_) {} + + void SetUp() OVERRIDE { + ON_CALL(mock_application_manager_settings_, thread_pool_size()) + .WillByDefault(Return(expected_tread_pool_size)); + ON_CALL(mock_application_manager_settings_, app_icons_folder()) + .WillByDefault(ReturnRef(kDirectoryName)); + ON_CALL(mock_application_manager_settings_, app_storage_folder()) + .WillByDefault(ReturnRef(kDirectoryName)); + ON_CALL(mock_application_manager_settings_, launch_hmi()) + .WillByDefault(Return(true)); + ON_CALL(mock_application_manager_settings_, stop_streaming_timeout()) + .WillByDefault(Return(stop_streaming_timeout)); + ON_CALL(mock_application_manager_settings_, time_out_promt()) + .WillByDefault(ReturnRef(kTimeoutPrompt)); + + CreateApplication(); + app_manager_impl_.AddMockApplication(app_impl_); + + Mock::VerifyAndClearExpectations(&mock_message_helper_); + } + + void TearDown() OVERRIDE { + Mock::VerifyAndClearExpectations(&mock_message_helper_); + } + + void CreateApplication() { + const uint32_t application_id = 1; + const std::string policy_app_id = "p_app_id"; + const std::string mac_address = "MA:CA:DD:RE:SS"; + const connection_handler::DeviceHandle device_id = 1; + const custom_str::CustomString app_name(""); + + app_impl_ = new ApplicationImpl( + application_id, + policy_app_id, + mac_address, + device_id, + app_name, + utils::MakeShared<usage_statistics_test::MockStatisticsManager>(), + app_manager_impl_); + } + + MockMessageHelper* mock_message_helper_; + NiceMock<MockApplicationManagerSettings> mock_application_manager_settings_; + NiceMock<MockPolicySettings> mock_policy_settings_; + + ApplicationManagerImpl app_manager_impl_; + ApplicationSharedPtr app_impl_; +}; + +TEST_F(ApplicationHelperTest, RecallApplicationData_ExpectAppDataReset) { + const uint32_t cmd_id = 1; + const uint32_t menu_id = 2; + const uint32_t choice_set_id = 3; + const mobile_apis::VehicleDataType::eType vi = + mobile_apis::VehicleDataType::VEHICLEDATA_ACCPEDAL; + const mobile_apis::ButtonName::eType button = mobile_apis::ButtonName::AC; + + smart_objects::SmartObject cmd; + cmd[strings::msg_params][strings::cmd_id] = cmd_id; + cmd[strings::msg_params][strings::vr_commands][0] = "vrCmd"; + cmd[strings::msg_params][strings::menu_id] = menu_id; + cmd[strings::msg_params][strings::interaction_choice_set_id] = choice_set_id; + + app_impl_->AddCommand(cmd_id, cmd[strings::msg_params]); + app_impl_->AddSubMenu(menu_id, cmd[strings::menu_params]); + app_impl_->AddChoiceSet(choice_set_id, cmd[strings::msg_params]); + EXPECT_TRUE(app_impl_->SubscribeToIVI(static_cast<uint32_t>(vi))); + EXPECT_TRUE(app_impl_->SubscribeToButton(button)); + + const std::string some_string = "some_string"; + smart_objects::SmartObject dummy_data = + smart_objects::SmartObject(smart_objects::SmartType_String); + dummy_data = some_string; + app_impl_->set_help_prompt(dummy_data); + app_impl_->set_timeout_prompt(dummy_data); + app_impl_->set_vr_help(dummy_data); + app_impl_->set_vr_help_title(dummy_data); + app_impl_->set_keyboard_props(dummy_data); + app_impl_->set_menu_title(dummy_data); + app_impl_->set_menu_icon(dummy_data); + + const bool persistent = false; + const bool downloaded = true; + const std::string filename = "filename"; + AppFile file(filename, persistent, downloaded, mobile_apis::FileType::BINARY); + + app_impl_->AddFile(file); + + EXPECT_TRUE(NULL != app_impl_->FindCommand(cmd_id)); + EXPECT_TRUE(NULL != app_impl_->FindSubMenu(menu_id)); + EXPECT_TRUE(NULL != app_impl_->FindChoiceSet(choice_set_id)); + EXPECT_TRUE(app_impl_->IsSubscribedToButton(button)); + EXPECT_TRUE(app_impl_->IsSubscribedToIVI(static_cast<uint32_t>(vi))); + auto help_prompt = app_impl_->help_prompt(); + EXPECT_TRUE(help_prompt->asString() == some_string); + auto timeout_prompt = app_impl_->timeout_prompt(); + EXPECT_TRUE(timeout_prompt->asString() == some_string); + auto vr_help = app_impl_->vr_help(); + EXPECT_TRUE(vr_help->asString() == some_string); + auto vr_help_title = app_impl_->vr_help_title(); + EXPECT_TRUE(vr_help_title->asString() == some_string); + auto kb_properties = app_impl_->keyboard_props(); + EXPECT_TRUE(kb_properties->asString() == some_string); + auto menu_title = app_impl_->menu_title(); + EXPECT_TRUE(menu_title->asString() == some_string); + auto menu_icon = app_impl_->menu_icon(); + EXPECT_TRUE(menu_icon->asString() == some_string); + auto file_ptr = app_impl_->GetFile(filename); + EXPECT_TRUE(NULL != file_ptr); + EXPECT_TRUE(file_ptr->file_name == filename); + + // Act + application_manager::DeleteApplicationData(app_impl_, app_manager_impl_); + EXPECT_FALSE(NULL != app_impl_->FindCommand(cmd_id)); + EXPECT_FALSE(NULL != app_impl_->FindSubMenu(menu_id)); + EXPECT_FALSE(NULL != app_impl_->FindChoiceSet(choice_set_id)); + EXPECT_FALSE(app_impl_->IsSubscribedToButton(button)); + EXPECT_FALSE(app_impl_->IsSubscribedToIVI(static_cast<uint32_t>(vi))); + help_prompt = app_impl_->help_prompt(); + EXPECT_FALSE(help_prompt->asString() == some_string); + timeout_prompt = app_impl_->timeout_prompt(); + EXPECT_FALSE(timeout_prompt->asString() == some_string); + vr_help = app_impl_->vr_help(); + EXPECT_TRUE(vr_help == NULL); + vr_help_title = app_impl_->vr_help_title(); + EXPECT_TRUE(vr_help_title == NULL); + kb_properties = app_impl_->keyboard_props(); + EXPECT_FALSE(kb_properties->asString() == some_string); + menu_title = app_impl_->menu_title(); + EXPECT_FALSE(menu_title->asString() == some_string); + menu_icon = app_impl_->menu_icon(); + EXPECT_FALSE(menu_icon->asString() == some_string); + file_ptr = app_impl_->GetFile(filename); + EXPECT_TRUE(NULL == file_ptr); +} + +TEST_F(ApplicationHelperTest, RecallApplicationData_ExpectHMICleanupRequests) { + const uint32_t cmd_id = 1; + const uint32_t menu_id = 2; + const uint32_t choice_set_id = 3; + smart_objects::SmartObject cmd; + cmd[strings::msg_params][strings::cmd_id] = cmd_id; + cmd[strings::msg_params][strings::vr_commands][0] = "vrCmd"; + cmd[strings::msg_params][strings::menu_id] = menu_id; + cmd[strings::msg_params][strings::interaction_choice_set_id] = choice_set_id; + + app_impl_->AddCommand(cmd_id, cmd[strings::msg_params]); + app_impl_->AddSubMenu(menu_id, cmd[strings::menu_params]); + app_impl_->AddChoiceSet(choice_set_id, cmd[strings::msg_params]); + app_impl_->SubscribeToIVI(static_cast<uint32_t>( + mobile_apis::VehicleDataType::VEHICLEDATA_ACCPEDAL)); + app_impl_->SubscribeToButton(mobile_apis::ButtonName::AC); + + EXPECT_CALL(*mock_message_helper_, SendUnsubscribedWayPoints(_)); + + EXPECT_CALL(*mock_message_helper_, SendDeleteCommandRequest(_, _, _)); + + EXPECT_CALL(*mock_message_helper_, SendDeleteSubmenuRequest(_, _, _)); + + EXPECT_CALL(*mock_message_helper_, SendDeleteChoiceSetRequest(_, _, _)); + + EXPECT_CALL(*mock_message_helper_, SendResetPropertiesRequest(_, _)); + + EXPECT_CALL(*mock_message_helper_, + SendUnsubscribeButtonNotification(_, _, _)); + + EXPECT_CALL(*mock_message_helper_, SendUnsubscribeIVIRequest(_, _, _)); + + // Act + application_manager::DeleteApplicationData(app_impl_, app_manager_impl_); +} + +} // application_manager_test +} // components +} // test diff --git a/src/components/application_manager/test/application_impl_test.cc b/src/components/application_manager/test/application_impl_test.cc index 02a257e5d9..e02191e4da 100644 --- a/src/components/application_manager/test/application_impl_test.cc +++ b/src/components/application_manager/test/application_impl_test.cc @@ -78,14 +78,12 @@ class ApplicationImplTest : public ::testing::Test { policy_app_id = "policy_app_id"; app_name = "app_name"; mac_address = "mac_address"; + device_handle = 0; test_lvl = HMILevel::INVALID_ENUM; state_id = HmiState::STATE_ID_REGULAR; audiostate = AudioStreamingState::NOT_AUDIBLE; syst_context = SystemContext::SYSCTXT_MAIN; - testHmiState = CreateTestHmiState(); - EXPECT_CALL(mock_application_manager_, CreateRegularState(app_id, _, _, _)) - .WillOnce(Return(testHmiState)); EXPECT_CALL(mock_application_manager_, get_settings()) .WillRepeatedly(ReturnRef(mock_application_manager_settings_)); EXPECT_CALL(mock_application_manager_settings_, app_icons_folder()) @@ -96,15 +94,17 @@ class ApplicationImplTest : public ::testing::Test { audio_data_stopped_timeout()).WillOnce(Return(0)); EXPECT_CALL(mock_application_manager_settings_, video_data_stopped_timeout()).WillOnce(Return(0)); - app_impl = new ApplicationImpl(app_id, - policy_app_id, - mac_address, - app_name, - utils::MakeShared<MockStatisticsManager>(), - mock_application_manager_); - } - void TearDown() OVERRIDE { - delete app_impl; + app_impl.reset( + new ApplicationImpl(app_id, + policy_app_id, + mac_address, + device_handle, + app_name, + utils::MakeShared<MockStatisticsManager>(), + mock_application_manager_)); + + HmiStatePtr initial_state = CreateTestHmiState(); + app_impl->SetInitialState(initial_state); } HmiStatePtr CreateTestHmiState(); @@ -115,10 +115,11 @@ class ApplicationImplTest : public ::testing::Test { void CheckCurrentHMIState(); MockApplicationManagerSettings mock_application_manager_settings_; MockApplicationManager mock_application_manager_; - ApplicationImpl* app_impl; + utils::SharedPtr<ApplicationImpl> app_impl; uint32_t app_id; std::string policy_app_id; std::string mac_address; + connection_handler::DeviceHandle device_handle; custom_str::CustomString app_name; const std::string directory_name = "./test_storage"; HmiState::StateID state_id; @@ -129,8 +130,10 @@ class ApplicationImplTest : public ::testing::Test { }; HmiStatePtr ApplicationImplTest::CreateTestHmiState() { - HmiStatePtr testState = - utils::MakeShared<HmiState>(app_id, mock_application_manager_, state_id); + HmiStatePtr testState = utils::MakeShared<HmiState>( + static_cast<utils::SharedPtr<Application> >(app_impl), + mock_application_manager_, + state_id); testState->set_hmi_level(test_lvl); testState->set_audio_streaming_state(audiostate); testState->set_system_context(syst_context); @@ -143,7 +146,7 @@ HmiStatePtr ApplicationImplTest::TestAddHmiState(HMILevel::eType hmi_lvl, test_lvl = hmi_lvl; state_id = id_state; HmiStatePtr state = CreateTestHmiState(); - (app_impl->*hmi_action)(state); + ((app_impl.get())->*hmi_action)(state); return state; } @@ -566,7 +569,7 @@ TEST_F(ApplicationImplTest, SubscribeToSoftButton_UnsubscribeFromSoftButton) { TEST_F(ApplicationImplTest, ChangeSupportingAppHMIType_TypeNotNaviNotVoice) { smart_objects::SmartObject type_media; - type_media[0] = AppHMIType::MEDIA; + type_media[0] = mobile_apis::AppHMIType::MEDIA; EXPECT_FALSE(app_impl->is_navi()); EXPECT_FALSE(app_impl->is_voice_communication_supported()); @@ -582,7 +585,7 @@ TEST_F(ApplicationImplTest, ChangeSupportingAppHMIType_TypeNotNaviNotVoice) { TEST_F(ApplicationImplTest, ChangeSupportingAppHMIType_TypeIsVoice) { smart_objects::SmartObject type_comm; - type_comm[0] = AppHMIType::COMMUNICATION; + type_comm[0] = mobile_apis::AppHMIType::COMMUNICATION; EXPECT_FALSE(app_impl->is_navi()); EXPECT_FALSE(app_impl->is_voice_communication_supported()); @@ -598,7 +601,7 @@ TEST_F(ApplicationImplTest, ChangeSupportingAppHMIType_TypeIsVoice) { TEST_F(ApplicationImplTest, ChangeSupportingAppHMIType_TypeIsNavi) { smart_objects::SmartObject type_navi; - type_navi[0] = AppHMIType::NAVIGATION; + type_navi[0] = mobile_apis::AppHMIType::NAVIGATION; EXPECT_FALSE(app_impl->is_navi()); EXPECT_FALSE(app_impl->is_voice_communication_supported()); @@ -614,9 +617,9 @@ TEST_F(ApplicationImplTest, ChangeSupportingAppHMIType_TypeIsNavi) { TEST_F(ApplicationImplTest, ChangeSupportingAppHMIType_TypeIsNaviAndVoice) { smart_objects::SmartObject app_types; - app_types[0] = AppHMIType::NAVIGATION; - app_types[1] = AppHMIType::COMMUNICATION; - app_types[2] = AppHMIType::MEDIA; + app_types[0] = mobile_apis::AppHMIType::NAVIGATION; + app_types[1] = mobile_apis::AppHMIType::COMMUNICATION; + app_types[2] = mobile_apis::AppHMIType::MEDIA; EXPECT_FALSE(app_impl->is_navi()); EXPECT_FALSE(app_impl->is_voice_communication_supported()); @@ -633,10 +636,10 @@ TEST_F(ApplicationImplTest, ChangeSupportingAppHMIType_TypeIsNaviAndVoice) { TEST_F(ApplicationImplTest, ChangeSupportingAppHMIType_TypeIsNaviAndVoiceAndProjection) { smart_objects::SmartObject app_types; - app_types[0] = AppHMIType::NAVIGATION; - app_types[1] = AppHMIType::COMMUNICATION; - app_types[2] = AppHMIType::MEDIA; - app_types[3] = AppHMIType::PROJECTION; + app_types[0] = mobile_apis::AppHMIType::NAVIGATION; + app_types[1] = mobile_apis::AppHMIType::COMMUNICATION; + app_types[2] = mobile_apis::AppHMIType::MEDIA; + app_types[3] = mobile_apis::AppHMIType::PROJECTION; EXPECT_FALSE(app_impl->is_navi()); EXPECT_FALSE(app_impl->is_voice_communication_supported()); diff --git a/src/components/application_manager/test/application_manager_impl_mock_hmi_test.cc b/src/components/application_manager/test/application_manager_impl_mock_hmi_test.cc new file mode 100644 index 0000000000..b9437d55e0 --- /dev/null +++ b/src/components/application_manager/test/application_manager_impl_mock_hmi_test.cc @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2017, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <stdint.h> +#include <memory> +#include <string> + +#include "gtest/gtest.h" +#include "application_manager/application.h" +#include "application_manager/application_impl.h" +#include "application_manager/application_manager_impl.h" +#include "utils/custom_string.h" +#include "utils/make_shared.h" +#include "encryption/hashing.h" + +#include "application_manager/mock_application_manager_settings.h" +#include "application_manager/mock_resumption_data.h" +#include "application_manager/mock_hmi_command_factory.h" +#include "application_manager/mock_request.h" +#include "connection_handler/mock_connection_handler.h" +#include "policy/mock_policy_settings.h" +#include "policy/usage_statistics/mock_statistics_manager.h" +#include "protocol_handler/mock_session_observer.h" + +namespace test { +namespace components { +namespace application_manager_test { + +namespace am = application_manager; + +using testing::_; +using ::testing::DoAll; +using ::testing::Mock; +using ::testing::Return; +using ::testing::ReturnRef; +using ::testing::NiceMock; +using ::testing::SetArgPointee; + +using namespace application_manager; + +namespace { +const uint32_t kApplicationId = 0u; +const std::string kDirectoryName = "./test_storage"; +const uint32_t kTimeout = 10000u; +} // namespace + +/** + * @brief The ApplicationManagerImplMockHmiTest class uses mocked HMI factory + * which calls its static method and real (non-mocked) MessageHelper. + * Class is separated from ApplicationManagerImplTest since it requires real + * HMI factory and mocked MessageHelper. So it is not possible to combine + * this code together. + */ +class ApplicationManagerImplMockHmiTest : public ::testing::Test { + public: + ApplicationManagerImplMockHmiTest() + : mock_storage_( + ::utils::MakeShared<NiceMock<resumption_test::MockResumptionData> >( + mock_app_mngr_)) {} + + protected: + void SetUp() OVERRIDE { + const uint8_t expected_tread_pool_size = 2u; + const uint8_t stop_streaming_timeout = 1u; + + ON_CALL(mock_application_manager_settings_, thread_pool_size()) + .WillByDefault(Return(expected_tread_pool_size)); + ON_CALL(mock_application_manager_settings_, app_icons_folder()) + .WillByDefault(ReturnRef(kDirectoryName)); + ON_CALL(mock_application_manager_settings_, app_storage_folder()) + .WillByDefault(ReturnRef(kDirectoryName)); + ON_CALL(mock_application_manager_settings_, launch_hmi()) + .WillByDefault(Return(true)); + ON_CALL(mock_application_manager_settings_, stop_streaming_timeout()) + .WillByDefault(Return(stop_streaming_timeout)); + ON_CALL(mock_application_manager_settings_, default_timeout()) + .WillByDefault(ReturnRef(kTimeout)); + + ON_CALL(mock_connection_handler_, get_session_observer()) + .WillByDefault(ReturnRef(mock_session_observer_)); + + app_manager_impl_.reset(new am::ApplicationManagerImpl( + mock_application_manager_settings_, mock_policy_settings_)); + + app_manager_impl_->set_connection_handler(&mock_connection_handler_); + app_manager_impl_->resume_controller().set_resumption_storage( + mock_storage_); + } + + void SetCommonExpectationOnAppReconnection( + const connection_handler::DeviceHandle new_device_id, + const uint32_t new_application_id, + const std::string& mac_address) { + EXPECT_CALL( + mock_session_observer_, + GetDataOnSessionKey(new_application_id, + _, + _, + testing::An<connection_handler::DeviceHandle*>())) + .WillOnce(DoAll(SetArgPointee<3u>(new_device_id), Return(0))); + + const std::string connection_type = "MyConnectionType"; + EXPECT_CALL( + mock_session_observer_, + GetDataOnDeviceID( + ::testing::Matcher<connection_handler::DeviceHandle>(new_device_id), + _, + _, + _, + _)) + .WillOnce(DoAll(SetArgPointee<3u>(mac_address), + SetArgPointee<4u>(connection_type), + Return(0))); + } + + utils::SharedPtr<NiceMock<resumption_test::MockResumptionData> > + mock_storage_; + application_manager_test::MockApplicationManager mock_app_mngr_; + NiceMock<policy_handler_test::MockPolicySettings> mock_policy_settings_; + NiceMock<connection_handler_test::MockConnectionHandler> + mock_connection_handler_; + NiceMock<protocol_handler_test::MockSessionObserver> mock_session_observer_; + NiceMock<MockApplicationManagerSettings> mock_application_manager_settings_; + std::unique_ptr<am::ApplicationManagerImpl> app_manager_impl_; +}; + +TEST_F(ApplicationManagerImplMockHmiTest, + PostponeCommandsDuringSwitching_ExpectSendingOnSwitchingEnd) { + const uint32_t application_id = 1u; + const std::string policy_app_id = "p_app_id"; + const std::string mac_address = "MA:CA:DD:RE:SS"; + const connection_handler::DeviceHandle device_id = 1u; + const custom_str::CustomString app_name(""); + + utils::SharedPtr<ApplicationImpl> app_impl = new ApplicationImpl( + application_id, + policy_app_id, + encryption::MakeHash(mac_address), + device_id, + app_name, + utils::SharedPtr<usage_statistics::StatisticsManager>( + new usage_statistics_test::MockStatisticsManager()), + *app_manager_impl_); + + app_manager_impl_->AddMockApplication(app_impl); + + const connection_handler::Device bt( + device_id, "BT_device", mac_address, "BLUETOOTH"); + + const connection_handler::Device usb( + device_id + 1, "USB_device", "USB_serial", "USB_IOS"); + + MockHMICommandFactory* mock_hmi_factory = + MockHMICommandFactory::mock_hmi_command_factory(); + + // Skip sending notification on device switching as it is not the goal here + EXPECT_CALL(*mock_hmi_factory, CreateCommand(_, _)) + .WillOnce(Return(utils::SharedPtr<commands::Command>())); + + app_manager_impl_->OnDeviceSwitchingStart(bt, usb); + + const uint32_t connection_key = 1u; + const uint32_t correlation_id_1 = 1u; + const uint32_t correlation_id_2 = 2u; + const uint32_t correlation_id_3 = 3u; + utils::SharedPtr<NiceMock<MockRequest> > cmd_1 = + utils::MakeShared<NiceMock<MockRequest> >(connection_key, + correlation_id_1); + utils::SharedPtr<NiceMock<MockRequest> > cmd_2 = + utils::MakeShared<NiceMock<MockRequest> >(connection_key, + correlation_id_2); + utils::SharedPtr<NiceMock<MockRequest> > cmd_3 = + utils::MakeShared<NiceMock<MockRequest> >(connection_key, + correlation_id_3); + + EXPECT_CALL(*mock_hmi_factory, CreateCommand(_, _)) + .WillOnce(Return(cmd_1)) + .WillOnce(Return(cmd_2)) + .WillOnce(Return(cmd_3)); + + commands::MessageSharedPtr hmi_msg_1 = + utils::MakeShared<smart_objects::SmartObject>(); + commands::MessageSharedPtr hmi_msg_2 = + utils::MakeShared<smart_objects::SmartObject>(); + commands::MessageSharedPtr hmi_msg_3 = + utils::MakeShared<smart_objects::SmartObject>(); + + (*hmi_msg_1)[strings::msg_params][strings::app_id] = + (*hmi_msg_2)[strings::msg_params][strings::app_id] = + (*hmi_msg_3)[strings::msg_params][strings::app_id] = application_id; + + EXPECT_CALL(*cmd_1, Init()).Times(0); + EXPECT_CALL(*cmd_2, Init()).Times(0); + EXPECT_CALL(*cmd_3, Init()).Times(0); + + // Act + app_manager_impl_->ManageHMICommand(hmi_msg_1); + app_manager_impl_->ManageHMICommand(hmi_msg_2); + app_manager_impl_->ManageHMICommand(hmi_msg_3); + + EXPECT_CALL(*mock_hmi_factory, CreateCommand(_, _)) + .WillOnce(Return(cmd_1)) + .WillOnce(Return(cmd_2)) + .WillOnce(Return(cmd_3)); + + EXPECT_CALL(*cmd_1, Init()).WillOnce(Return(true)); + EXPECT_CALL(*cmd_1, Run()); + EXPECT_CALL(*cmd_2, Init()).WillOnce(Return(true)); + EXPECT_CALL(*cmd_2, Run()); + EXPECT_CALL(*cmd_3, Init()).WillOnce(Return(true)); + EXPECT_CALL(*cmd_3, Run()); + + const connection_handler::DeviceHandle new_device_id = 2; + const uint32_t new_application_id = 2; + SetCommonExpectationOnAppReconnection( + new_device_id, new_application_id, mac_address); + + app_manager_impl_->ProcessReconnection(app_impl, new_application_id); + app_manager_impl_->OnApplicationSwitched(app_impl); + + Mock::VerifyAndClearExpectations(&mock_hmi_factory); +} + +} // application_manager_test +} // namespace components +} // namespace test diff --git a/src/components/application_manager/test/application_manager_impl_test.cc b/src/components/application_manager/test/application_manager_impl_test.cc index d19d3cd8ed..e54bc612ca 100644 --- a/src/components/application_manager/test/application_manager_impl_test.cc +++ b/src/components/application_manager/test/application_manager_impl_test.cc @@ -32,6 +32,8 @@ #include <stdint.h> #include <memory> #include <set> +#include <string> +#include <vector> #include <bson_object.h> #include "gtest/gtest.h" @@ -54,6 +56,7 @@ #include "utils/lock.h" #include "utils/make_shared.h" #include "utils/push_log.h" +#include "encryption/hashing.h" namespace test { namespace components { @@ -64,6 +67,7 @@ namespace policy_test = test::components::policy_handler_test; namespace con_test = connection_handler_test; using testing::_; +using ::testing::Matcher; using ::testing::ByRef; using ::testing::DoAll; using ::testing::Mock; @@ -83,8 +87,7 @@ ACTION_P6(InvokeMemberFuncWithArg4, ptr, memberFunc, a, b, c, d) { namespace { const std::string kDirectoryName = "./test_storage"; const uint32_t kTimeout = 10000u; -sync_primitives::Lock state_lock_; -sync_primitives::ConditionalVariable state_condition_; +connection_handler::DeviceHandle kDeviceId = 12345u; } // namespace class ApplicationManagerImplTest : public ::testing::Test { @@ -92,7 +95,7 @@ class ApplicationManagerImplTest : public ::testing::Test { ApplicationManagerImplTest() : mock_storage_( ::utils::MakeShared<NiceMock<resumption_test::MockResumptionData> >( - app_mngr_)) + mock_app_mngr_)) , mock_message_helper_( application_manager::MockMessageHelper::message_helper_mock()) , app_id_(0u) { @@ -106,8 +109,7 @@ class ApplicationManagerImplTest : public ::testing::Test { protected: void SetUp() OVERRIDE { CreateAppManager(); - - ON_CALL(mock_connection_handler_, GetDataOnSessionKey(_, _, _, _)) + ON_CALL(mock_connection_handler_, GetDataOnSessionKey(_, _, _, &kDeviceId)) .WillByDefault(DoAll(SetArgPointee<3u>(app_id_), Return(0))); ON_CALL(mock_connection_handler_, get_session_observer()) .WillByDefault(ReturnRef(mock_session_observer_)); @@ -128,11 +130,12 @@ class ApplicationManagerImplTest : public ::testing::Test { ON_CALL(mock_application_manager_settings_, app_storage_folder()) .WillByDefault(ReturnRef(kDirectoryName)); ON_CALL(mock_application_manager_settings_, launch_hmi()) - .WillByDefault(Return(true)); + .WillByDefault(Return(false)); ON_CALL(mock_application_manager_settings_, stop_streaming_timeout()) .WillByDefault(Return(stop_streaming_timeout)); ON_CALL(mock_application_manager_settings_, default_timeout()) .WillByDefault(ReturnRef(kTimeout)); + app_manager_impl_.reset(new am::ApplicationManagerImpl( mock_application_manager_settings_, mock_policy_settings_)); mock_app_ptr_ = utils::SharedPtr<MockApplication>(new MockApplication()); @@ -145,17 +148,42 @@ class ApplicationManagerImplTest : public ::testing::Test { app_manager_impl_->AddMockApplication(mock_app_ptr_); } + void SetCommonExpectationOnAppReconnection( + const connection_handler::DeviceHandle new_device_id, + const uint32_t new_application_id, + const std::string& mac_address) { + EXPECT_CALL( + mock_session_observer_, + GetDataOnSessionKey(new_application_id, + _, + _, + testing::An<connection_handler::DeviceHandle*>())) + .WillOnce(DoAll(SetArgPointee<3u>(new_device_id), Return(0))); + + const std::string connection_type = "MyConnectionType"; + EXPECT_CALL( + mock_session_observer_, + GetDataOnDeviceID( + ::testing::Matcher<connection_handler::DeviceHandle>(new_device_id), + _, + _, + _, + _)) + .WillOnce(DoAll(SetArgPointee<3u>(mac_address), + SetArgPointee<4u>(connection_type), + Return(0))); + } + NiceMock<policy_test::MockPolicySettings> mock_policy_settings_; utils::SharedPtr<NiceMock<resumption_test::MockResumptionData> > mock_storage_; NiceMock<con_test::MockConnectionHandler> mock_connection_handler_; NiceMock<protocol_handler_test::MockSessionObserver> mock_session_observer_; NiceMock<MockApplicationManagerSettings> mock_application_manager_settings_; - application_manager_test::MockApplicationManager app_mngr_; + application_manager_test::MockApplicationManager mock_app_mngr_; std::auto_ptr<am::ApplicationManagerImpl> app_manager_impl_; application_manager::MockMessageHelper* mock_message_helper_; uint32_t app_id_; - application_manager::MessageHelper* message_helper_; utils::SharedPtr<MockApplication> mock_app_ptr_; }; @@ -181,16 +209,20 @@ TEST_F(ApplicationManagerImplTest, ProcessQueryApp_ExpectSuccess) { TEST_F(ApplicationManagerImplTest, SubscribeAppForWayPoints_ExpectSubscriptionApp) { - app_manager_impl_->SubscribeAppForWayPoints(app_id_); - EXPECT_TRUE(app_manager_impl_->IsAppSubscribedForWayPoints(app_id_)); + auto app_ptr = + ApplicationSharedPtr::static_pointer_cast<am::Application>(mock_app_ptr_); + app_manager_impl_->SubscribeAppForWayPoints(app_ptr); + EXPECT_TRUE(app_manager_impl_->IsAppSubscribedForWayPoints(app_ptr)); } TEST_F(ApplicationManagerImplTest, UnsubscribeAppForWayPoints_ExpectUnsubscriptionApp) { - app_manager_impl_->SubscribeAppForWayPoints(app_id_); - EXPECT_TRUE(app_manager_impl_->IsAppSubscribedForWayPoints(app_id_)); - app_manager_impl_->UnsubscribeAppFromWayPoints(app_id_); - EXPECT_FALSE(app_manager_impl_->IsAppSubscribedForWayPoints(app_id_)); + auto app_ptr = + ApplicationSharedPtr::static_pointer_cast<am::Application>(mock_app_ptr_); + app_manager_impl_->SubscribeAppForWayPoints(app_ptr); + EXPECT_TRUE(app_manager_impl_->IsAppSubscribedForWayPoints(app_ptr)); + app_manager_impl_->UnsubscribeAppFromWayPoints(app_ptr); + EXPECT_FALSE(app_manager_impl_->IsAppSubscribedForWayPoints(app_ptr)); const std::set<int32_t> result = app_manager_impl_->GetAppsSubscribedForWayPoints(); EXPECT_TRUE(result.empty()); @@ -207,10 +239,12 @@ TEST_F( TEST_F( ApplicationManagerImplTest, GetAppsSubscribedForWayPoints_SubcribeAppForWayPoints_ExpectCorrectResult) { - app_manager_impl_->SubscribeAppForWayPoints(app_id_); + auto app_ptr = + ApplicationSharedPtr::static_pointer_cast<am::Application>(mock_app_ptr_); + app_manager_impl_->SubscribeAppForWayPoints(app_ptr); std::set<int32_t> result = app_manager_impl_->GetAppsSubscribedForWayPoints(); EXPECT_EQ(1u, result.size()); - EXPECT_TRUE(result.find(app_id_) != result.end()); + EXPECT_TRUE(result.find(app_ptr) != result.end()); } TEST_F(ApplicationManagerImplTest, OnServiceStartedCallback_RpcService) { @@ -639,6 +673,157 @@ TEST_F(ApplicationManagerImplTest, EXPECT_TRUE(rejected_params.empty()); } +TEST_F(ApplicationManagerImplTest, + OnDeviceSwitchingStart_ExpectPutAppsInWaitList) { + utils::SharedPtr<MockApplication> switching_app_ptr = + utils::MakeShared<MockApplication>(); + + const std::string switching_device_id = "switching"; + const std::string switching_device_id_hash = + encryption::MakeHash(switching_device_id); + app_manager_impl_->AddMockApplication(switching_app_ptr); + EXPECT_CALL(*switching_app_ptr, mac_address()) + .WillRepeatedly(ReturnRef(switching_device_id_hash)); + + const std::string policy_app_id_switch = "abc"; + EXPECT_CALL(*switching_app_ptr, policy_app_id()) + .WillRepeatedly(Return(policy_app_id_switch)); + + const auto hmi_level_switching_app = mobile_apis::HMILevel::HMI_FULL; + EXPECT_CALL(*switching_app_ptr, hmi_level()) + .WillRepeatedly(Return(hmi_level_switching_app)); + + utils::SharedPtr<MockApplication> nonswitching_app_ptr = + utils::MakeShared<MockApplication>(); + + const std::string nonswitching_device_id = "nonswitching"; + const std::string nonswitching_device_id_hash = + encryption::MakeHash(nonswitching_device_id); + app_manager_impl_->AddMockApplication(nonswitching_app_ptr); + EXPECT_CALL(*nonswitching_app_ptr, mac_address()) + .WillRepeatedly(ReturnRef(nonswitching_device_id_hash)); + + const std::string policy_app_id_nonswitch = "efg"; + EXPECT_CALL(*nonswitching_app_ptr, policy_app_id()) + .WillRepeatedly(Return(policy_app_id_nonswitch)); + + const auto hmi_level_nonswitching_app = mobile_apis::HMILevel::HMI_LIMITED; + EXPECT_CALL(*nonswitching_app_ptr, hmi_level()) + .WillRepeatedly(Return(hmi_level_nonswitching_app)); + + // Act + const connection_handler::DeviceHandle switching_handle = 1; + const connection_handler::Device switching_device( + switching_handle, "switching_device", switching_device_id, "BLUETOOTH"); + + const connection_handler::DeviceHandle non_switching_handle = 2; + const connection_handler::Device non_switching_device(non_switching_handle, + "non_switching_device", + nonswitching_device_id, + "USB"); + + EXPECT_CALL(*mock_message_helper_, CreateDeviceListSO(_, _, _)) + .WillOnce(Return(smart_objects::SmartObjectSPtr())); + app_manager_impl_->OnDeviceSwitchingStart(switching_device, + non_switching_device); + EXPECT_TRUE(app_manager_impl_->IsAppInReconnectMode(policy_app_id_switch)); + EXPECT_FALSE( + app_manager_impl_->IsAppInReconnectMode(policy_app_id_nonswitch)); +} + +TEST_F(ApplicationManagerImplTest, + OnDeviceSwitchingFinish_ExpectUnregisterAppsInWaitList) { + utils::SharedPtr<MockApplication> switching_app_ptr = + utils::MakeShared<MockApplication>(); + + const std::string switching_device_id = "switching"; + const std::string switching_device_id_hash = + encryption::MakeHash(switching_device_id); + app_manager_impl_->AddMockApplication(switching_app_ptr); + EXPECT_CALL(*switching_app_ptr, mac_address()) + .WillRepeatedly(ReturnRef(switching_device_id_hash)); + + const std::string policy_app_id_switch = "abc"; + EXPECT_CALL(*switching_app_ptr, policy_app_id()) + .WillRepeatedly(Return(policy_app_id_switch)); + + const auto hmi_level_switching_app = mobile_apis::HMILevel::HMI_FULL; + EXPECT_CALL(*switching_app_ptr, hmi_level()) + .WillRepeatedly(Return(hmi_level_switching_app)); + + utils::SharedPtr<MockApplication> nonswitching_app_ptr = + utils::MakeShared<MockApplication>(); + + const std::string nonswitching_device_id = "nonswitching"; + const std::string nonswitching_device_id_hash = + encryption::MakeHash(nonswitching_device_id); + app_manager_impl_->AddMockApplication(nonswitching_app_ptr); + EXPECT_CALL(*nonswitching_app_ptr, mac_address()) + .WillRepeatedly(ReturnRef(nonswitching_device_id_hash)); + + const std::string policy_app_id_nonswitch = "efg"; + EXPECT_CALL(*nonswitching_app_ptr, policy_app_id()) + .WillRepeatedly(Return(policy_app_id_nonswitch)); + + const auto hmi_level_nonswitching_app = mobile_apis::HMILevel::HMI_LIMITED; + EXPECT_CALL(*nonswitching_app_ptr, hmi_level()) + .WillRepeatedly(Return(hmi_level_nonswitching_app)); + + // Act + const connection_handler::DeviceHandle switching_handle = 1; + const connection_handler::Device switching_device( + switching_handle, "switching_device", switching_device_id, "BLUETOOTH"); + + const connection_handler::DeviceHandle non_switching_handle = 2; + const connection_handler::Device non_switching_device(non_switching_handle, + "non_switching_device", + nonswitching_device_id, + "USB"); + + EXPECT_CALL(*mock_message_helper_, CreateDeviceListSO(_, _, _)) + .WillOnce(Return(smart_objects::SmartObjectSPtr())); + + app_manager_impl_->OnDeviceSwitchingStart(switching_device, + non_switching_device); + + EXPECT_TRUE(app_manager_impl_->IsAppInReconnectMode(policy_app_id_switch)); + + app_manager_impl_->OnDeviceSwitchingFinish(switching_device_id); + EXPECT_FALSE( + app_manager_impl_->application_by_policy_id(policy_app_id_switch)); +} + +TEST_F(ApplicationManagerImplTest, + ProcessReconnection_ExpectChangeAppIdDeviceId) { + const uint32_t application_id = 1; + const std::string policy_app_id = "p_app_id"; + const std::string mac_address = "MA:CA:DD:RE:SS"; + const connection_handler::DeviceHandle device_id = 1; + const custom_str::CustomString app_name(""); + + utils::SharedPtr<ApplicationImpl> app_impl = new ApplicationImpl( + application_id, + policy_app_id, + mac_address, + device_id, + app_name, + utils::SharedPtr<usage_statistics::StatisticsManager>( + new usage_statistics_test::MockStatisticsManager()), + *app_manager_impl_); + + app_manager_impl_->AddMockApplication(app_impl); + + const connection_handler::DeviceHandle new_device_id = 2; + const uint32_t new_application_id = 2; + SetCommonExpectationOnAppReconnection( + new_device_id, new_application_id, mac_address); + + // Act + app_manager_impl_->ProcessReconnection(app_impl, new_application_id); + EXPECT_EQ(new_device_id, app_impl->device()); + EXPECT_EQ(new_application_id, app_impl->app_id()); +} + } // application_manager_test } // namespace components } // namespace test diff --git a/src/components/application_manager/test/application_state_test.cc b/src/components/application_manager/test/application_state_test.cc index 7bc34966b4..33f23022f0 100644 --- a/src/components/application_manager/test/application_state_test.cc +++ b/src/components/application_manager/test/application_state_test.cc @@ -34,6 +34,7 @@ #include "gtest/gtest.h" #include "application_manager/hmi_state.h" #include "application_manager/mock_application_manager.h" +#include "application_manager/mock_application.h" #include "application_manager/event_engine/event_dispatcher.h" #include "resumption/last_state.h" #include "application_manager/policies/policy_handler.h" @@ -64,12 +65,17 @@ std::vector<StateID> GenerateCurrentStates() { } class ApplicationStateTest : public ::testing::Test { + public: + void SetUp() OVERRIDE { + mock_app_.reset(new MockApplication); + } + protected: static std::vector<StateID> added_states_; ApplicationState app_state; const StateID current_id = StateID::STATE_ID_CURRENT; const StateID postponed_id = StateID::STATE_ID_POSTPONED; - const uint32_t app_id = 10; + utils::SharedPtr<MockApplication> mock_app_; MockApplicationManager app_mngr_; }; @@ -79,8 +85,10 @@ std::vector<StateID> ApplicationStateTest::added_states_ = TEST_F(ApplicationStateTest, AddStates_GetCurrentStates) { std::vector<StateID>::iterator new_state = added_states_.begin(); for (; new_state != added_states_.end(); ++new_state) { - HmiStatePtr state = - utils::MakeShared<HmiState>(app_id, app_mngr_, *new_state); + HmiStatePtr state = utils::MakeShared<HmiState>( + static_cast<utils::SharedPtr<Application> >(mock_app_), + app_mngr_, + *new_state); app_state.AddState(state); EXPECT_EQ(state, app_state.GetState(current_id)); } @@ -89,8 +97,10 @@ TEST_F(ApplicationStateTest, AddStates_GetCurrentStates) { TEST_F(ApplicationStateTest, AddStates_RemoveStates_GetCurrentState) { std::vector<StateID>::iterator new_state = added_states_.begin(); for (; new_state != added_states_.end(); ++new_state) { - HmiStatePtr state = - utils::MakeShared<HmiState>(app_id, app_mngr_, *new_state); + HmiStatePtr state = utils::MakeShared<HmiState>( + static_cast<utils::SharedPtr<Application> >(mock_app_), + app_mngr_, + *new_state); app_state.AddState(state); HmiStatePtr curr_state = app_state.GetState(current_id); @@ -110,16 +120,20 @@ TEST_F(ApplicationStateTest, AddStatesAddPostponedState_GetPostponedState) { // Added some states std::vector<StateID>::iterator new_state = added_states_.begin(); for (; new_state != added_states_.end(); ++new_state) { - HmiStatePtr state = - utils::MakeShared<HmiState>(app_id, app_mngr_, *new_state); + HmiStatePtr state = utils::MakeShared<HmiState>( + static_cast<utils::SharedPtr<Application> >(mock_app_), + app_mngr_, + *new_state); app_state.AddState(state); } // Postponed state wasn't added HmiStatePtr get_postponed_id = app_state.GetState(postponed_id); EXPECT_EQ(NULL, get_postponed_id); // Add posponed state - HmiStatePtr state = - utils::MakeShared<HmiState>(app_id, app_mngr_, postponed_id); + HmiStatePtr state = utils::MakeShared<HmiState>( + static_cast<utils::SharedPtr<Application> >(mock_app_), + app_mngr_, + postponed_id); app_state.AddState(state); // Postponed state exists get_postponed_id = app_state.GetState(postponed_id); @@ -129,14 +143,19 @@ TEST_F(ApplicationStateTest, AddStatesAddPostponedState_GetPostponedState) { TEST_F(ApplicationStateTest, AddStates_GetRegularState) { // Add state std::vector<StateID>::iterator new_state = added_states_.begin(); - HmiStatePtr state = - utils::MakeShared<HmiState>(app_id, app_mngr_, *new_state); + HmiStatePtr state = utils::MakeShared<HmiState>( + static_cast<utils::SharedPtr<Application> >(mock_app_), + app_mngr_, + *new_state); state->set_hmi_level(HMILevel::HMI_FULL); app_state.AddState(state); ++new_state; // Add some other for (; new_state != added_states_.end(); ++new_state) { - state = utils::MakeShared<HmiState>(app_id, app_mngr_, *new_state); + state = utils::MakeShared<HmiState>( + static_cast<utils::SharedPtr<Application> >(mock_app_), + app_mngr_, + *new_state); app_state.AddState(state); state->set_hmi_level(HMILevel::HMI_LIMITED); } @@ -150,13 +169,18 @@ TEST_F(ApplicationStateTest, AddStates_GetRegularState) { TEST_F(ApplicationStateTest, AddRegularState_RemoveFirstState_GetRegularState) { std::vector<StateID>::iterator new_state = added_states_.begin(); - HmiStatePtr state = - utils::MakeShared<HmiState>(app_id, app_mngr_, *new_state); + HmiStatePtr state = utils::MakeShared<HmiState>( + static_cast<utils::SharedPtr<Application> >(mock_app_), + app_mngr_, + *new_state); app_state.AddState(state); ++new_state; // Add postponed state - state = utils::MakeShared<HmiState>(app_id, app_mngr_, postponed_id); + state = utils::MakeShared<HmiState>( + static_cast<utils::SharedPtr<Application> >(mock_app_), + app_mngr_, + postponed_id); app_state.AddState(state); // Make sure that the state was added @@ -164,7 +188,10 @@ TEST_F(ApplicationStateTest, AddRegularState_RemoveFirstState_GetRegularState) { ASSERT_EQ(state, post_state); for (; new_state != added_states_.end(); ++new_state) { - state = utils::MakeShared<HmiState>(app_id, app_mngr_, *new_state); + state = utils::MakeShared<HmiState>( + static_cast<utils::SharedPtr<Application> >(mock_app_), + app_mngr_, + *new_state); app_state.AddState(state); } @@ -184,22 +211,32 @@ TEST_F(ApplicationStateTest, AddRegularState_RemoveFirstState_GetRegularState) { TEST_F(ApplicationStateTest, AddRegularState_PreviousStatePostponed) { // Add some state StateID first_state = StateID::STATE_ID_PHONE_CALL; - HmiStatePtr state = - utils::MakeShared<HmiState>(app_id, app_mngr_, first_state); + HmiStatePtr state = utils::MakeShared<HmiState>( + static_cast<utils::SharedPtr<Application> >(mock_app_), + app_mngr_, + first_state); app_state.AddState(state); // Add postponed state - state = utils::MakeShared<HmiState>(app_id, app_mngr_, postponed_id); + state = utils::MakeShared<HmiState>( + static_cast<utils::SharedPtr<Application> >(mock_app_), + app_mngr_, + postponed_id); app_state.AddState(state); // Add new postponed state - const uint32_t app_id2 = 10; - state = utils::MakeShared<HmiState>(app_id2, app_mngr_, postponed_id); + utils::SharedPtr<MockApplication> mock_app_2(new MockApplication); + state = utils::MakeShared<HmiState>( + static_cast<utils::SharedPtr<Application> >(mock_app_), + app_mngr_, + postponed_id); app_state.AddState(state); // Add regular state - state = - utils::MakeShared<HmiState>(app_id, app_mngr_, StateID::STATE_ID_REGULAR); + state = utils::MakeShared<HmiState>( + static_cast<utils::SharedPtr<Application> >(mock_app_), + app_mngr_, + StateID::STATE_ID_REGULAR); app_state.AddState(state); // Postponed state is the first @@ -213,8 +250,10 @@ TEST_F(ApplicationStateTest, AddRegularState_PreviousStatePostponed) { TEST_F(ApplicationStateTest, InitState_GetRegularState) { StateID init_state = StateID::STATE_ID_REGULAR; - HmiStatePtr state = - utils::MakeShared<HmiState>(app_id, app_mngr_, init_state); + HmiStatePtr state = utils::MakeShared<HmiState>( + static_cast<utils::SharedPtr<Application> >(mock_app_), + app_mngr_, + init_state); app_state.InitState(state); @@ -228,14 +267,19 @@ TEST_F(ApplicationStateTest, InitState_GetRegularState) { TEST_F(ApplicationStateTest, AddPosponedState_DeletePosponedState) { // Precondition StateID init_state = StateID::STATE_ID_REGULAR; - HmiStatePtr state = - utils::MakeShared<HmiState>(app_id, app_mngr_, init_state); + HmiStatePtr state = utils::MakeShared<HmiState>( + static_cast<utils::SharedPtr<Application> >(mock_app_), + app_mngr_, + init_state); state->set_hmi_level(mobile_apis::HMILevel::HMI_FULL); app_state.InitState(state); // Add postponed state - state = utils::MakeShared<HmiState>(app_id, app_mngr_, postponed_id); + state = utils::MakeShared<HmiState>( + static_cast<utils::SharedPtr<Application> >(mock_app_), + app_mngr_, + postponed_id); app_state.AddState(state); // Make sure that state was added @@ -252,7 +296,10 @@ TEST_F(ApplicationStateTest, AddPosponedState_DeletePosponedState) { TEST_F(ApplicationStateTest, AddRegularState_RemoveRegularState_RegularStateNotDeleted) { StateID reg_state = StateID::STATE_ID_REGULAR; - HmiStatePtr state = utils::MakeShared<HmiState>(app_id, app_mngr_, reg_state); + HmiStatePtr state = utils::MakeShared<HmiState>( + static_cast<utils::SharedPtr<Application> >(mock_app_), + app_mngr_, + reg_state); app_state.InitState(state); // Try deleting regular state diff --git a/src/components/application_manager/test/command_holder_test.cc b/src/components/application_manager/test/command_holder_test.cc new file mode 100644 index 0000000000..e10cd5d008 --- /dev/null +++ b/src/components/application_manager/test/command_holder_test.cc @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2017, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <gmock/gmock.h> + +#include "application_manager/command_holder_impl.h" +#include "application_manager/commands/command.h" +#include "smart_objects/smart_object.h" +#include "utils/shared_ptr.h" +#include "utils/make_shared.h" + +#include "application_manager/mock_application_manager.h" +#include "application_manager/mock_application.h" + +namespace test { +namespace components { +namespace application_manager_test { + +using testing::_; +using testing::Return; + +namespace am = application_manager; + +class CommandHolderImplTest : public testing::Test { + public: + CommandHolderImplTest() + : kPolicyAppId_("p_app_id") + , kHmiApplicationId_(123) + , kConnectionKey_(56789) + , cmd_ptr_(new smart_objects::SmartObject) + , mock_app_ptr_(new MockApplication) {} + + void SetUp() OVERRIDE { + ON_CALL(*mock_app_ptr_, app_id()).WillByDefault(Return(kConnectionKey_)); + ON_CALL(*mock_app_ptr_, hmi_app_id()) + .WillByDefault(Return(kHmiApplicationId_)); + ON_CALL(*mock_app_ptr_, policy_app_id()) + .WillByDefault(Return(kPolicyAppId_)); + } + + MockApplicationManager mock_app_manager_; + const std::string kPolicyAppId_; + const uint32_t kHmiApplicationId_; + const uint32_t kConnectionKey_; + utils::SharedPtr<smart_objects::SmartObject> cmd_ptr_; + utils::SharedPtr<MockApplication> mock_app_ptr_; +}; + +TEST_F(CommandHolderImplTest, HoldOne_ExpectReleaseOne) { + am::CommandHolderImpl cmd_holder(mock_app_manager_); + cmd_holder.Suspend( + mock_app_ptr_, am::CommandHolder::CommandType::kHmiCommand, cmd_ptr_); + + // Act + EXPECT_CALL(mock_app_manager_, ManageHMICommand(cmd_ptr_)); + cmd_holder.Resume(mock_app_ptr_, am::CommandHolder::CommandType::kHmiCommand); +} + +TEST_F(CommandHolderImplTest, HoldMany_ExpectReleaseSame) { + am::CommandHolderImpl cmd_holder(mock_app_manager_); + + int32_t iterations = 0; + do { + cmd_holder.Suspend( + mock_app_ptr_, am::CommandHolder::CommandType::kHmiCommand, cmd_ptr_); + ++iterations; + } while (iterations < 5); + + // Act + EXPECT_CALL(mock_app_manager_, ManageHMICommand(cmd_ptr_)).Times(iterations); + cmd_holder.Resume(mock_app_ptr_, am::CommandHolder::CommandType::kHmiCommand); +} + +TEST_F(CommandHolderImplTest, Hold_Drop_ExpectNoReleased) { + am::CommandHolderImpl cmd_holder(mock_app_manager_); + cmd_holder.Suspend( + mock_app_ptr_, am::CommandHolder::CommandType::kHmiCommand, cmd_ptr_); + cmd_holder.Suspend( + mock_app_ptr_, am::CommandHolder::CommandType::kHmiCommand, cmd_ptr_); + + // Act + cmd_holder.Clear(mock_app_ptr_); + EXPECT_CALL(mock_app_manager_, ManageHMICommand(cmd_ptr_)).Times(0); + cmd_holder.Resume(mock_app_ptr_, am::CommandHolder::CommandType::kHmiCommand); +} + +TEST_F(CommandHolderImplTest, Hold_ReleaseAnotherId_ExpectNoReleased) { + am::CommandHolderImpl cmd_holder(mock_app_manager_); + cmd_holder.Suspend( + mock_app_ptr_, am::CommandHolder::CommandType::kHmiCommand, cmd_ptr_); + cmd_holder.Suspend( + mock_app_ptr_, am::CommandHolder::CommandType::kHmiCommand, cmd_ptr_); + + // Act + utils::SharedPtr<MockApplication> another_app = + utils::MakeShared<MockApplication>(); + + EXPECT_CALL(mock_app_manager_, ManageHMICommand(cmd_ptr_)).Times(0); + cmd_holder.Resume(another_app, am::CommandHolder::CommandType::kHmiCommand); +} + +TEST_F(CommandHolderImplTest, Hold_DropAnotherId_ExpectReleased) { + am::CommandHolderImpl cmd_holder(mock_app_manager_); + + int32_t iterations = 0; + do { + cmd_holder.Suspend( + mock_app_ptr_, am::CommandHolder::CommandType::kHmiCommand, cmd_ptr_); + ++iterations; + } while (iterations < 3); + + // Act + utils::SharedPtr<MockApplication> another_app = + utils::MakeShared<MockApplication>(); + cmd_holder.Clear(another_app); + + EXPECT_CALL(mock_app_manager_, ManageHMICommand(cmd_ptr_)).Times(iterations); + cmd_holder.Resume(mock_app_ptr_, am::CommandHolder::CommandType::kHmiCommand); +} + +TEST_F(CommandHolderImplTest, Hold_Mobile_and_HMI_commands_ExpectReleased) { + am::CommandHolderImpl cmd_holder(mock_app_manager_); + + cmd_holder.Suspend( + mock_app_ptr_, am::CommandHolder::CommandType::kHmiCommand, cmd_ptr_); + + cmd_holder.Suspend( + mock_app_ptr_, am::CommandHolder::CommandType::kMobileCommand, cmd_ptr_); + + // Act + EXPECT_CALL(mock_app_manager_, ManageHMICommand(cmd_ptr_)); + cmd_holder.Resume(mock_app_ptr_, am::CommandHolder::CommandType::kHmiCommand); + + EXPECT_CALL( + mock_app_manager_, + ManageMobileCommand(cmd_ptr_, + am::commands::Command::CommandOrigin::ORIGIN_MOBILE)); + cmd_holder.Resume(mock_app_ptr_, + am::CommandHolder::CommandType::kMobileCommand); +} + +} // application_manager_test +} // components +} // test diff --git a/src/components/application_manager/test/commands/CMakeLists.txt b/src/components/application_manager/test/commands/CMakeLists.txt index f204c35456..8dafc16471 100644 --- a/src/components/application_manager/test/commands/CMakeLists.txt +++ b/src/components/application_manager/test/commands/CMakeLists.txt @@ -46,6 +46,7 @@ set(COMMANDS_TEST_DIR ${AM_TEST_DIR}/commands) file(GLOB SOURCES ${COMMANDS_TEST_DIR}/* ${COMPONENTS_DIR}/application_manager/test/mock_message_helper.cc + ${COMPONENTS_DIR}/application_manager/test/mock_application_helper.cc ${COMPONENTS_DIR}/application_manager/src/smart_object_keys.cc ${COMPONENTS_DIR}/application_manager/src/message.cc ${COMMANDS_TEST_DIR}/hmi/* diff --git a/src/components/application_manager/test/commands/command_impl_test.cc b/src/components/application_manager/test/commands/command_impl_test.cc index fd660af210..ff9634cbb1 100644 --- a/src/components/application_manager/test/commands/command_impl_test.cc +++ b/src/components/application_manager/test/commands/command_impl_test.cc @@ -83,8 +83,8 @@ class CommandImplTest : public CommandsTest<CommandsTestMocks::kIsNice> { public: class UnwrappedCommandImpl : CommandImpl { public: - using CommandImpl::ReplaceMobileByHMIAppId; - using CommandImpl::ReplaceHMIByMobileAppId; + using CommandImpl::ReplaceMobileWithHMIAppId; + using CommandImpl::ReplaceHMIWithMobileAppId; UnwrappedCommandImpl(const MessageSharedPtr& message, ApplicationManager& application_manager) @@ -151,16 +151,16 @@ TEST_F(CommandImplTest, GetMethods_SUCCESS) { EXPECT_NO_THROW(command->onTimeOut()); } -TEST_F(CommandImplTest, ReplaceMobileByHMIAppId_NoAppIdInMessage_UNSUCCESS) { +TEST_F(CommandImplTest, ReplaceMobileWithHMIAppId_NoAppIdInMessage_UNSUCCESS) { MessageSharedPtr msg; UCommandImplPtr command = CreateCommand<UCommandImpl>(msg); EXPECT_CALL(app_mngr_, application(_)).Times(0); - command->ReplaceMobileByHMIAppId(*msg); + command->ReplaceMobileWithHMIAppId(*msg); } -TEST_F(CommandImplTest, ReplaceMobileByHMIAppId_SUCCESS) { +TEST_F(CommandImplTest, ReplaceMobileWithHMIAppId_SUCCESS) { MessageSharedPtr msg = CreateMessage(); (*msg)[strings::app_id] = kAppId1; @@ -171,12 +171,12 @@ TEST_F(CommandImplTest, ReplaceMobileByHMIAppId_SUCCESS) { EXPECT_CALL(app_mngr_, application(kAppId1)).WillOnce(Return(app)); ON_CALL(*app, hmi_app_id()).WillByDefault(Return(kAppId2)); - command->ReplaceMobileByHMIAppId(*msg); + command->ReplaceMobileWithHMIAppId(*msg); EXPECT_EQ(kAppId2, (*msg)[strings::app_id].asUInt()); } -TEST_F(CommandImplTest, ReplaceMobileByHMIAppId_Array_SUCCESS) { +TEST_F(CommandImplTest, ReplaceMobileWithHMIAppId_Array_SUCCESS) { MessageSharedPtr msg = CreateArrayMessage(kDefaultMsgCount); UCommandImplPtr command = CreateCommand<UCommandImpl>(msg); @@ -187,14 +187,14 @@ TEST_F(CommandImplTest, ReplaceMobileByHMIAppId_Array_SUCCESS) { .WillRepeatedly(Return(app)); ON_CALL(*app, hmi_app_id()).WillByDefault(Return(kAppId2)); - command->ReplaceMobileByHMIAppId(*msg); + command->ReplaceMobileWithHMIAppId(*msg); EXPECT_TRUE(msg->asArray()); std::for_each( msg->asArray()->begin(), msg->asArray()->end(), ExpectEqualAppId); } -TEST_F(CommandImplTest, ReplaceMobileByHMIAppId_Map_SUCCESS) { +TEST_F(CommandImplTest, ReplaceMobileWithHMIAppId_Map_SUCCESS) { MessageSharedPtr msg = CreateMapMessage(kDefaultMsgCount); UCommandImplPtr command = CreateCommand<UCommandImpl>(msg); @@ -205,7 +205,7 @@ TEST_F(CommandImplTest, ReplaceMobileByHMIAppId_Map_SUCCESS) { .WillRepeatedly(Return(app)); ON_CALL(*app, hmi_app_id()).WillByDefault(Return(kAppId2)); - command->ReplaceMobileByHMIAppId(*msg); + command->ReplaceMobileWithHMIAppId(*msg); std::set<std::string> keys(msg->enumerate()); std::for_each(keys.begin(), @@ -213,16 +213,17 @@ TEST_F(CommandImplTest, ReplaceMobileByHMIAppId_Map_SUCCESS) { std::bind2nd(std::ptr_fun(&ExpectEqualKeyAppId), msg)); } -TEST_F(CommandImplTest, ReplaceHMIByMobileAppId_NoHMIAppIdInMessage_UNSUCCESS) { +TEST_F(CommandImplTest, + ReplaceHMIWithMobileAppId_NoHMIAppIdInMessage_UNSUCCESS) { MessageSharedPtr msg; UCommandImplPtr command = CreateCommand<UCommandImpl>(msg); EXPECT_CALL(app_mngr_, application_by_hmi_app(_)).Times(0); - command->ReplaceHMIByMobileAppId(*msg); + command->ReplaceHMIWithMobileAppId(*msg); } -TEST_F(CommandImplTest, ReplaceHMIByMobileAppId_SUCCESS) { +TEST_F(CommandImplTest, ReplaceHMIWithMobileAppId_SUCCESS) { MessageSharedPtr msg = CreateMessage(); (*msg)[strings::app_id] = kAppId1; @@ -233,12 +234,12 @@ TEST_F(CommandImplTest, ReplaceHMIByMobileAppId_SUCCESS) { EXPECT_CALL(app_mngr_, application_by_hmi_app(kAppId1)).WillOnce(Return(app)); ON_CALL(*app, app_id()).WillByDefault(Return(kAppId2)); - command->ReplaceHMIByMobileAppId(*msg); + command->ReplaceHMIWithMobileAppId(*msg); EXPECT_EQ(kAppId2, (*msg)[strings::app_id].asUInt()); } -TEST_F(CommandImplTest, ReplaceHMIByMobileAppId_Array_SUCCESS) { +TEST_F(CommandImplTest, ReplaceHMIWithMobileAppId_Array_SUCCESS) { MessageSharedPtr msg = CreateArrayMessage(kDefaultMsgCount); UCommandImplPtr command = CreateCommand<UCommandImpl>(msg); @@ -249,14 +250,14 @@ TEST_F(CommandImplTest, ReplaceHMIByMobileAppId_Array_SUCCESS) { .WillRepeatedly(Return(app)); ON_CALL(*app, app_id()).WillByDefault(Return(kAppId2)); - command->ReplaceHMIByMobileAppId(*msg); + command->ReplaceHMIWithMobileAppId(*msg); EXPECT_TRUE(msg->asArray()); std::for_each( msg->asArray()->begin(), msg->asArray()->end(), ExpectEqualAppId); } -TEST_F(CommandImplTest, ReplaceHMIByMobileAppId_Map_SUCCESS) { +TEST_F(CommandImplTest, ReplaceHMIWithMobileAppId_Map_SUCCESS) { MessageSharedPtr msg = CreateMapMessage(kDefaultMsgCount); UCommandImplPtr command = CreateCommand<UCommandImpl>(msg); @@ -267,7 +268,7 @@ TEST_F(CommandImplTest, ReplaceHMIByMobileAppId_Map_SUCCESS) { .WillRepeatedly(Return(app)); ON_CALL(*app, app_id()).WillByDefault(Return(kAppId2)); - command->ReplaceHMIByMobileAppId(*msg); + command->ReplaceHMIWithMobileAppId(*msg); std::set<std::string> keys = msg->enumerate(); std::for_each(keys.begin(), diff --git a/src/components/application_manager/test/commands/hmi/activate_app_request_test.cc b/src/components/application_manager/test/commands/hmi/activate_app_request_test.cc index 771d13924c..7f7911a01d 100644 --- a/src/components/application_manager/test/commands/hmi/activate_app_request_test.cc +++ b/src/components/application_manager/test/commands/hmi/activate_app_request_test.cc @@ -34,9 +34,9 @@ #include "application_manager/commands/hmi/activate_app_request.h" #include "utils/shared_ptr.h" #include "smart_objects/smart_object.h" -#include "application_manager/mock_application.h" #include "application_manager/commands/command_impl.h" #include "commands/commands_test.h" +#include "application_manager/mock_application.h" namespace test { namespace components { @@ -45,12 +45,16 @@ namespace hmi_commands_test { namespace activate_app_request { using ::testing::_; +using ::utils::SharedPtr; namespace am = ::application_manager; namespace strings = ::application_manager::strings; using am::commands::MessageSharedPtr; using am::commands::ActivateAppRequest; using am::commands::CommandImpl; +using ::test::components::application_manager_test::MockApplication; + +typedef SharedPtr<MockApplication> MockAppPtr; typedef ::utils::SharedPtr<ActivateAppRequest> ActivateAppRequestPtr; MATCHER_P(CheckMessage, level, "") { @@ -83,10 +87,13 @@ class ActivateAppRequestTest : public CommandsTest<CommandsTestMocks::kIsNice> { TEST_F(ActivateAppRequestTest, Run_SUCCESS) { MessageSharedPtr msg = CreateMsgParams(); + MockAppPtr app = CreateMockApp(); + + EXPECT_CALL(app_mngr_, application(_)).WillRepeatedly(Return(app)); + + ON_CALL(*app, hmi_app_id()).WillByDefault(Return(kAppId)); - MockAppPtr mock_app = CreateMockApp(); - EXPECT_CALL(app_mngr_, application(kAppId)).WillOnce(Return(mock_app)); -// TODO(OKozlov) Invastigate and fix issue with using log +// TODO(OKozlov) Investigate and fix issue with using log #ifdef ENABLE_LOG (*msg)[strings::msg_params][strings::activate_app_hmi_level] = mobile_apis::HMILevel::HMI_FULL; diff --git a/src/components/application_manager/test/commands/hmi/hmi_notifications/hmi_notifications_test.cc b/src/components/application_manager/test/commands/hmi/hmi_notifications/hmi_notifications_test.cc index 03e1187d35..5a40a4e582 100644 --- a/src/components/application_manager/test/commands/hmi/hmi_notifications/hmi_notifications_test.cc +++ b/src/components/application_manager/test/commands/hmi/hmi_notifications/hmi_notifications_test.cc @@ -1595,7 +1595,10 @@ TEST_F(HMICommandsNotificationsTest, ON_CALL(mock_connection_handler_, get_session_observer()) .WillByDefault(ReturnRef(mock_session_observer_)); const int32_t device_id = 1; - ON_CALL(mock_session_observer_, GetDataOnDeviceID(_, NULL, NULL, _, NULL)) + ON_CALL( + mock_session_observer_, + GetDataOnDeviceID( + testing::An<transport_manager::DeviceHandle>(), NULL, NULL, _, NULL)) .WillByDefault(Return(device_id)); EXPECT_CALL(policy_interface_, GetUserConsentForDevice(_)) @@ -1645,7 +1648,10 @@ TEST_F(HMICommandsNotificationsTest, ON_CALL(mock_connection_handler_, get_session_observer()) .WillByDefault(ReturnRef(mock_session_observer_)); const int32_t device_id = 1; - ON_CALL(mock_session_observer_, GetDataOnDeviceID(_, NULL, NULL, _, NULL)) + ON_CALL( + mock_session_observer_, + GetDataOnDeviceID( + testing::An<transport_manager::DeviceHandle>(), NULL, NULL, _, NULL)) .WillByDefault(Return(device_id)); EXPECT_CALL(policy_interface_, GetUserConsentForDevice(_)) diff --git a/src/components/application_manager/test/commands/mobile/register_app_interface_request_test.cc b/src/components/application_manager/test/commands/mobile/register_app_interface_request_test.cc index 844f87d57e..b7a004f199 100644 --- a/src/components/application_manager/test/commands/mobile/register_app_interface_request_test.cc +++ b/src/components/application_manager/test/commands/mobile/register_app_interface_request_test.cc @@ -43,17 +43,19 @@ #include "application_manager/application.h" #include "application_manager/mock_application_manager.h" #include "application_manager/mock_application.h" +#include "application_manager/mock_application_helper.h" #include "interfaces/MOBILE_API.h" #include "application_manager/smart_object_keys.h" #include "application_manager/policies/mock_policy_handler_interface.h" -#include "utils/data_accessor.h" #include "protocol_handler/mock_session_observer.h" #include "connection_handler/mock_connection_handler.h" #include "application_manager/mock_hmi_capabilities.h" #include "application_manager/mock_resume_ctrl.h" #include "application_manager/mock_hmi_interface.h" +#include "utils/data_accessor.h" #include "utils/custom_string.h" #include "utils/lock.h" +#include "utils/macro.h" namespace test { namespace components { @@ -90,11 +92,22 @@ class RegisterAppInterfaceRequestTest RegisterAppInterfaceRequestTest() : msg_(CreateMessage()) , command_(CreateCommand<RegisterAppInterfaceRequest>(msg_)) - , app_name_("test_app_name_") { + , app_name_("test_app_name_") + , mock_application_helper_( + application_manager_test::MockApplicationHelper:: + application_helper_mock()) { InitGetters(); InitLanguage(); } + void SetUp() OVERRIDE { + testing::Mock::VerifyAndClearExpectations(&mock_application_helper_); + } + + void TearDown() OVERRIDE { + testing::Mock::VerifyAndClearExpectations(&mock_application_helper_); + } + void InitBasicMessage() { (*msg_)[am::strings::params][am::strings::connection_key] = kConnectionKey; (*msg_)[am::strings::msg_params][am::strings::app_id] = kAppId; @@ -112,6 +125,7 @@ class RegisterAppInterfaceRequestTest ON_CALL(*mock_app, app_icon_path()).WillByDefault(ReturnRef(kDummyString)); ON_CALL(*mock_app, language()).WillByDefault(ReturnRef(kMobileLanguage)); ON_CALL(*mock_app, ui_language()).WillByDefault(ReturnRef(kMobileLanguage)); + ON_CALL(*mock_app, policy_app_id()).WillByDefault(Return(kAppId)); return mock_app; } @@ -151,6 +165,9 @@ class RegisterAppInterfaceRequestTest .WillByDefault(Return(policy::DeviceConsent::kDeviceAllowed)); ON_CALL(app_mngr_, GetDeviceTransportType(_)) .WillByDefault(Return(hmi_apis::Common_TransportType::WIFI)); + ON_CALL(app_mngr_, IsAppInReconnectMode(_)).WillByDefault(Return(false)); + ON_CALL(app_mngr_, application_by_policy_id(_)) + .WillByDefault(Return(ApplicationSharedPtr())); ON_CALL(mock_hmi_interfaces_, GetInterfaceState(_)) .WillByDefault(Return(am::HmiInterfaces::STATE_NOT_AVAILABLE)); ON_CALL( @@ -167,6 +184,43 @@ class RegisterAppInterfaceRequestTest .WillByDefault(Return(am::HmiInterfaces::HMI_INTERFACE_UI)); } + void SetCommonExpectionsOnSwitchedApplication( + MockAppPtr mock_app, mobile_apis::Result::eType response_result_code) { + EXPECT_CALL(mock_policy_handler_, AddApplication(_, _)).Times(0); + + EXPECT_CALL( + app_mngr_, + ManageMobileCommand(MobileResultCodeIs(response_result_code), _)); + + EXPECT_CALL(app_mngr_, + ManageHMICommand(HMIResultCodeIs( + hmi_apis::FunctionID::BasicCommunication_OnAppRegistered))) + .Times(0); + + EXPECT_CALL(app_mngr_, + ManageHMICommand(HMIResultCodeIs( + hmi_apis::FunctionID::Buttons_OnButtonSubscription))) + .Times(0); + + EXPECT_CALL(app_mngr_, + ManageHMICommand(HMIResultCodeIs( + hmi_apis::FunctionID::UI_ChangeRegistration))).Times(0); + + EXPECT_CALL(app_mngr_, + ManageHMICommand(HMIResultCodeIs( + hmi_apis::FunctionID::TTS_ChangeRegistration))).Times(0); + + EXPECT_CALL(app_mngr_, + ManageHMICommand(HMIResultCodeIs( + hmi_apis::FunctionID::VR_ChangeRegistration))).Times(0); + + EXPECT_CALL( + app_mngr_, + OnApplicationSwitched( + MockAppPtr::static_pointer_cast<application_manager::Application>( + mock_app))); + } + MessageSharedPtr msg_; SharedPtr<RegisterAppInterfaceRequest> command_; @@ -194,6 +248,7 @@ class RegisterAppInterfaceRequestTest MockConnectionHandler mock_connection_handler_; MockSessionObserver mock_session_observer_; MockHMICapabilities mock_hmi_capabilities_; + application_manager_test::MockApplicationHelper& mock_application_helper_; }; TEST_F(RegisterAppInterfaceRequestTest, Init_SUCCESS) { @@ -353,6 +408,113 @@ TEST_F(RegisterAppInterfaceRequestTest, command_->Run(); } +TEST_F(RegisterAppInterfaceRequestTest, + SwitchApplication_CorrectHash_ExpectNoCleanupSuccess) { + InitBasicMessage(); + + const std::string request_hash_id = "abc123"; + (*msg_)[am::strings::msg_params][am::strings::hash_id] = request_hash_id; + + MockAppPtr mock_app = CreateBasicMockedApp(); + EXPECT_CALL(app_mngr_, application_by_policy_id(kAppId)) + .WillRepeatedly(Return(mock_app)); + + EXPECT_CALL(app_mngr_, IsAppInReconnectMode(kAppId)).WillOnce(Return(true)); + + EXPECT_CALL(app_mngr_, ProcessReconnection(_, kConnectionKey)); + + EXPECT_CALL(app_mngr_, RegisterApplication(msg_)).Times(0); + + EXPECT_CALL( + mock_resume_crt_, + CheckApplicationHash( + MockAppPtr::static_pointer_cast<application_manager::Application>( + mock_app), + request_hash_id)).WillOnce(Return(true)); + + EXPECT_CALL(mock_resume_crt_, RemoveApplicationFromSaved(_)).Times(0); + + EXPECT_CALL(mock_application_helper_, RecallApplicationData(_, _)).Times(0); + + EXPECT_CALL(app_mngr_, application(kConnectionKey)) + .WillRepeatedly(Return(mock_app)); + + SetCommonExpectionsOnSwitchedApplication(mock_app, + mobile_apis::Result::SUCCESS); + + command_->Run(); +} + +TEST_F(RegisterAppInterfaceRequestTest, + SwitchApplication_WrongHash_ExpectCleanupResumeFailed) { + InitBasicMessage(); + + const std::string request_hash_id = "abc123"; + (*msg_)[am::strings::msg_params][am::strings::hash_id] = request_hash_id; + + MockAppPtr mock_app = CreateBasicMockedApp(); + EXPECT_CALL(app_mngr_, application_by_policy_id(kAppId)) + .WillRepeatedly(Return(mock_app)); + + EXPECT_CALL(app_mngr_, IsAppInReconnectMode(kAppId)).WillOnce(Return(true)); + + EXPECT_CALL(app_mngr_, ProcessReconnection(_, kConnectionKey)); + + EXPECT_CALL( + mock_resume_crt_, + CheckApplicationHash( + MockAppPtr::static_pointer_cast<application_manager::Application>( + mock_app), + request_hash_id)).WillOnce(Return(false)); + + EXPECT_CALL( + mock_application_helper_, + RecallApplicationData( + MockAppPtr::static_pointer_cast<application_manager::Application>( + mock_app), + _)); + + EXPECT_CALL(app_mngr_, RegisterApplication(msg_)).Times(0); + + EXPECT_CALL(app_mngr_, application(kConnectionKey)) + .WillRepeatedly(Return(mock_app)); + + SetCommonExpectionsOnSwitchedApplication(mock_app, + mobile_apis::Result::RESUME_FAILED); + + command_->Run(); +} + +TEST_F(RegisterAppInterfaceRequestTest, + SwitchApplication_NoHash_ExpectCleanupResumeFailed) { + InitBasicMessage(); + + MockAppPtr mock_app = CreateBasicMockedApp(); + EXPECT_CALL(app_mngr_, application_by_policy_id(kAppId)) + .WillRepeatedly(Return(mock_app)); + + EXPECT_CALL(app_mngr_, IsAppInReconnectMode(kAppId)).WillOnce(Return(true)); + + EXPECT_CALL(app_mngr_, ProcessReconnection(_, kConnectionKey)); + + EXPECT_CALL( + mock_application_helper_, + RecallApplicationData( + MockAppPtr::static_pointer_cast<application_manager::Application>( + mock_app), + _)); + + EXPECT_CALL(app_mngr_, RegisterApplication(msg_)).Times(0); + + EXPECT_CALL(app_mngr_, application(kConnectionKey)) + .WillRepeatedly(Return(mock_app)); + + SetCommonExpectionsOnSwitchedApplication(mock_app, + mobile_apis::Result::RESUME_FAILED); + + command_->Run(); +} + } // namespace register_app_interface_request } // namespace mobile_commands_test } // namespace commands_test diff --git a/src/components/application_manager/test/commands/mobile/subscribe_way_points_request_test.cc b/src/components/application_manager/test/commands/mobile/subscribe_way_points_request_test.cc index d9497cd900..87127231be 100644 --- a/src/components/application_manager/test/commands/mobile/subscribe_way_points_request_test.cc +++ b/src/components/application_manager/test/commands/mobile/subscribe_way_points_request_test.cc @@ -51,6 +51,7 @@ namespace mobile_commands_test { namespace subscribe_way_points_request { using ::testing::_; +using ::testing::A; using ::testing::Return; using ::testing::ReturnRef; using ::testing::DoAll; @@ -70,14 +71,15 @@ TEST_F(SubscribeWayPointsRequestTest, Run_SUCCESS) { MockAppPtr app(CreateMockApp()); ON_CALL(app_mngr_, application(_)).WillByDefault(Return(app)); - ON_CALL(app_mngr_, IsAppSubscribedForWayPoints(_)) + ON_CALL(app_mngr_, IsAppSubscribedForWayPoints(A<am::ApplicationSharedPtr>())) .WillByDefault(Return(false)); ON_CALL(app_mngr_, IsAnyAppSubscribedForWayPoints()) .WillByDefault(Return(true)); { InSequence dummy; - EXPECT_CALL(app_mngr_, SubscribeAppForWayPoints(_)); + EXPECT_CALL(app_mngr_, + SubscribeAppForWayPoints(A<am::ApplicationSharedPtr>())); EXPECT_CALL(*app, UpdateHash()); } @@ -108,7 +110,10 @@ TEST_F(SubscribeWayPointsRequestTest, OnEvent_SUCCESS) { { InSequence dummy; - EXPECT_CALL(app_mngr_, SubscribeAppForWayPoints(_)); + EXPECT_CALL(app_mngr_, + SubscribeAppForWayPoints(A<am::ApplicationSharedPtr>())); + EXPECT_CALL(mock_message_helper_, HMIToMobileResult(result_code)) + .WillOnce(Return(mobile_apis::Result::SUCCESS)); EXPECT_CALL(app_mngr_, ManageMobileCommand(_, _)); EXPECT_CALL(*app, UpdateHash()); } diff --git a/src/components/application_manager/test/commands/mobile/unsubscribe_way_points_request_test.cc b/src/components/application_manager/test/commands/mobile/unsubscribe_way_points_request_test.cc index 733d037afb..5615b0cabd 100644 --- a/src/components/application_manager/test/commands/mobile/unsubscribe_way_points_request_test.cc +++ b/src/components/application_manager/test/commands/mobile/unsubscribe_way_points_request_test.cc @@ -100,9 +100,9 @@ TEST_F(UnSubscribeWayPointsRequestTest, EXPECT_CALL(app_mngr_, application(kConnectionKey)) .WillOnce(Return(mock_app)); - EXPECT_CALL(*mock_app, app_id()).WillOnce(Return(kAppId)); - - EXPECT_CALL(app_mngr_, IsAppSubscribedForWayPoints(kAppId)) + EXPECT_CALL(app_mngr_, + IsAppSubscribedForWayPoints( + ::testing::Matcher<am::ApplicationSharedPtr>(mock_app))) .WillOnce(Return(false)); EXPECT_CALL( @@ -117,9 +117,9 @@ TEST_F(UnSubscribeWayPointsRequestTest, Run_AppSubscribedForWayPoints_SUCCESS) { EXPECT_CALL(app_mngr_, application(kConnectionKey)) .WillOnce(Return(mock_app)); - EXPECT_CALL(*mock_app, app_id()).WillOnce(Return(kAppId)); - - EXPECT_CALL(app_mngr_, IsAppSubscribedForWayPoints(kAppId)) + EXPECT_CALL(app_mngr_, + IsAppSubscribedForWayPoints( + ::testing::Matcher<am::ApplicationSharedPtr>(mock_app))) .WillOnce(Return(true)); EXPECT_CALL(app_mngr_, @@ -154,9 +154,9 @@ TEST_F(UnSubscribeWayPointsRequestTest, Event event(hmi_apis::FunctionID::Navigation_UnsubscribeWayPoints); event.set_smart_object(*event_msg); - EXPECT_CALL(*mock_app, app_id()).WillOnce(Return(kAppId)); - - EXPECT_CALL(app_mngr_, UnsubscribeAppFromWayPoints(kAppId)); + EXPECT_CALL(app_mngr_, + UnsubscribeAppFromWayPoints( + ::testing::Matcher<am::ApplicationSharedPtr>(mock_app))); EXPECT_CALL( app_mngr_, diff --git a/src/components/application_manager/test/include/application_manager/mock_application.h b/src/components/application_manager/test/include/application_manager/mock_application.h index a8c4f96b35..10cf5f746e 100644 --- a/src/components/application_manager/test/include/application_manager/mock_application.h +++ b/src/components/application_manager/test/include/application_manager/mock_application.h @@ -50,10 +50,9 @@ class MockApplication : public ::application_manager::Application { MOCK_CONST_METHOD0(active_message, const smart_objects::SmartObject*()); MOCK_CONST_METHOD0(curHash, const std::string&()); MOCK_METHOD0(UpdateHash, void()); - // DEPRECATED - MOCK_CONST_METHOD0(flag_sending_hash_change_after_awake, bool()); - // DEPRECATED - MOCK_METHOD1(set_flag_sending_hash_change_after_awake, void(bool flag)); + DEPRECATED MOCK_CONST_METHOD0(flag_sending_hash_change_after_awake, bool()); + DEPRECATED MOCK_METHOD1(set_flag_sending_hash_change_after_awake, + void(bool flag)); MOCK_CONST_METHOD0(IsHashChangedDuringSuspend, bool()); MOCK_METHOD1(SetHashChangedDuringSuspend, void(const bool flag)); MOCK_CONST_METHOD0(is_application_data_changed, bool()); @@ -157,6 +156,7 @@ class MockApplication : public ::application_manager::Application { bool(mobile_apis::FunctionID::eType cmd_id, ::application_manager::TLimitSource source)); MOCK_METHOD0(usage_report, ::application_manager::UsageStatistics&()); + MOCK_METHOD1(SetInitialState, void(::application_manager::HmiStatePtr state)); MOCK_METHOD1(SetRegularState, void(::application_manager::HmiStatePtr state)); MOCK_METHOD1(SetPostponedState, void(::application_manager::HmiStatePtr state)); diff --git a/src/components/application_manager/test/include/application_manager/mock_application_helper.h b/src/components/application_manager/test/include/application_manager/mock_application_helper.h new file mode 100644 index 0000000000..1013af26bd --- /dev/null +++ b/src/components/application_manager/test/include/application_manager/mock_application_helper.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2017, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_TEST_INCLUDE_APPLICATION_MANAGER_MOCK_APPLICATION_HELPER_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_TEST_INCLUDE_APPLICATION_MANAGER_MOCK_APPLICATION_HELPER_H_ + +#include <gmock/gmock.h> +#include "application_manager/application.h" +#include "application_manager/application_manager.h" + +namespace test { +namespace components { +namespace application_manager_test { + +class MockApplicationHelper { + public: + MOCK_METHOD2(RecallApplicationData, + void(application_manager::ApplicationSharedPtr, + application_manager::ApplicationManager&)); + + static MockApplicationHelper& application_helper_mock(); +}; + +} // namespace application_manager_test +} // namespace components +} // namespace test + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_TEST_INCLUDE_APPLICATION_MANAGER_MOCK_APPLICATION_HELPER_H_ diff --git a/src/components/application_manager/test/include/application_manager/mock_hmi_command_factory.h b/src/components/application_manager/test/include/application_manager/mock_hmi_command_factory.h new file mode 100644 index 0000000000..cf40d7b98b --- /dev/null +++ b/src/components/application_manager/test/include/application_manager/mock_hmi_command_factory.h @@ -0,0 +1,60 @@ +/* + Copyright (c) 2017, Ford Motor Company + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following + disclaimer in the documentation and/or other materials provided with the + distribution. + + Neither the name of the Ford Motor Company nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_TEST_INCLUDE_APPLICATION_MANAGER_MOCK_HMI_COMMAND_FACTORY_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_TEST_INCLUDE_APPLICATION_MANAGER_MOCK_HMI_COMMAND_FACTORY_H_ + +#include <gmock/gmock.h> +#include "application_manager/application_manager.h" +#include "application_manager/commands/command.h" +#include "smart_objects/smart_object.h" +#include "utils/shared_ptr.h" + +namespace test { +namespace components { +namespace application_manager_test { + +class MockHMICommandFactory { + public: + MOCK_METHOD2(CreateCommand, + utils::SharedPtr<application_manager::commands::Command>( + const utils::SharedPtr<smart_objects::SmartObject>&, + application_manager::ApplicationManager&)); + + static MockHMICommandFactory* mock_hmi_command_factory(); +}; + +} // namespace application_manager_test +} // namespace components +} // namespace test + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_TEST_INCLUDE_APPLICATION_MANAGER_MOCK_HMI_COMMAND_FACTORY_H_ diff --git a/src/components/application_manager/test/include/application_manager/mock_message_helper.h b/src/components/application_manager/test/include/application_manager/mock_message_helper.h index f927f6bb72..7598e33e19 100644 --- a/src/components/application_manager/test/include/application_manager/mock_message_helper.h +++ b/src/components/application_manager/test/include/application_manager/mock_message_helper.h @@ -268,6 +268,29 @@ class MockMessageHelper { MOCK_METHOD2(GetDeviceMacAddressForHandle, std::string(const uint32_t device_handle, const ApplicationManager& app_mngr)); + MOCK_METHOD3(SendDeleteCommandRequest, + void(smart_objects::SmartObject* cmd, + ApplicationSharedPtr application, + ApplicationManager& app_mngr)); + MOCK_METHOD3(SendDeleteSubmenuRequest, + void(smart_objects::SmartObject* cmd, + ApplicationSharedPtr application, + ApplicationManager& app_mngr)); + MOCK_METHOD3(SendDeleteChoiceSetRequest, + void(smart_objects::SmartObject* cmd, + ApplicationSharedPtr application, + ApplicationManager& app_mngr)); + MOCK_METHOD2(SendResetPropertiesRequest, + void(ApplicationSharedPtr application, + ApplicationManager& app_mngr)); + MOCK_METHOD3(SendUnsubscribeButtonNotification, + void(mobile_apis::ButtonName::eType button, + ApplicationSharedPtr application, + ApplicationManager& app_mngr)); + MOCK_METHOD3(SendUnsubscribeIVIRequest, + void(int32_t ivi_id, + ApplicationSharedPtr application, + ApplicationManager& app_mngr)); static MockMessageHelper* message_helper_mock(); }; diff --git a/src/components/application_manager/test/message_helper/CMakeLists.txt b/src/components/application_manager/test/message_helper/CMakeLists.txt index ccf05fc1c9..8ebb2dea0e 100755 --- a/src/components/application_manager/test/message_helper/CMakeLists.txt +++ b/src/components/application_manager/test/message_helper/CMakeLists.txt @@ -49,8 +49,8 @@ set(LIBRARIES if(REMOTE_CONTROL) SET (LIBRARIES - FunctionalModule - ${LIBRARIES} + FunctionalModule + ${LIBRARIES} ) endif(REMOTE_CONTROL) diff --git a/src/components/application_manager/test/mock_application_helper.cc b/src/components/application_manager/test/mock_application_helper.cc new file mode 100644 index 0000000000..c64a56e53e --- /dev/null +++ b/src/components/application_manager/test/mock_application_helper.cc @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2017, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "application_manager/mock_application_helper.h" + +namespace test { +namespace components { +namespace application_manager_test { + +MockApplicationHelper& MockApplicationHelper::application_helper_mock() { + static ::testing::NiceMock<MockApplicationHelper> application_helper_mock; + return application_helper_mock; +} + +} // application_manager_test +} // components +} // test + +namespace application_manager { + +void DeleteApplicationData(ApplicationSharedPtr app, + ApplicationManager& app_manager) { + test::components::application_manager_test::MockApplicationHelper:: + application_helper_mock().RecallApplicationData(app, app_manager); +} +} // application_managers diff --git a/src/components/application_manager/test/mock_hmi_command_factory.cc b/src/components/application_manager/test/mock_hmi_command_factory.cc new file mode 100644 index 0000000000..c2b4644f86 --- /dev/null +++ b/src/components/application_manager/test/mock_hmi_command_factory.cc @@ -0,0 +1,57 @@ +/* + Copyright (c) 2017, Ford Motor Company + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following + disclaimer in the documentation and/or other materials provided with the + distribution. + + Neither the name of the Ford Motor Company nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ + +#include <gmock/gmock.h> +#include "application_manager/hmi_command_factory.h" +#include "application_manager/mock_hmi_command_factory.h" + +namespace test { +namespace components { +namespace application_manager_test { + +MockHMICommandFactory* MockHMICommandFactory::mock_hmi_command_factory() { + static MockHMICommandFactory mock_hmi_command_factory; + return &mock_hmi_command_factory; +} + +} // application_manager_test +} // components +} // test + +namespace application_manager { +CommandSharedPtr HMICommandFactory::CreateCommand( + const commands::MessageSharedPtr& message, + ApplicationManager& application_manager) { + return test::components::application_manager_test::MockHMICommandFactory:: + mock_hmi_command_factory()->CreateCommand(message, application_manager); +} +} // application_manager diff --git a/src/components/application_manager/test/mock_message_helper.cc b/src/components/application_manager/test/mock_message_helper.cc index 5f221a105b..2a74f5b3b1 100644 --- a/src/components/application_manager/test/mock_message_helper.cc +++ b/src/components/application_manager/test/mock_message_helper.cc @@ -501,4 +501,46 @@ std::string MessageHelper::GetDeviceMacAddressForHandle( device_handle, app_mngr); } +void MessageHelper::SendDeleteCommandRequest(smart_objects::SmartObject* cmd, + ApplicationSharedPtr application, + ApplicationManager& app_mngr) { + return MockMessageHelper::message_helper_mock()->SendDeleteCommandRequest( + cmd, application, app_mngr); +} + +void MessageHelper::SendDeleteSubmenuRequest(smart_objects::SmartObject* cmd, + ApplicationSharedPtr application, + ApplicationManager& app_mngr) { + return MockMessageHelper::message_helper_mock()->SendDeleteSubmenuRequest( + cmd, application, app_mngr); +} + +void MessageHelper::SendDeleteChoiceSetRequest(smart_objects::SmartObject* cmd, + ApplicationSharedPtr application, + ApplicationManager& app_mngr) { + return MockMessageHelper::message_helper_mock()->SendDeleteChoiceSetRequest( + cmd, application, app_mngr); +} + +void MessageHelper::SendResetPropertiesRequest(ApplicationSharedPtr application, + ApplicationManager& app_mngr) { + return MockMessageHelper::message_helper_mock()->SendResetPropertiesRequest( + application, app_mngr); +} + +void MessageHelper::SendUnsubscribeButtonNotification( + mobile_apis::ButtonName::eType button, + ApplicationSharedPtr application, + ApplicationManager& app_mngr) { + return MockMessageHelper::message_helper_mock() + ->SendUnsubscribeButtonNotification(button, application, app_mngr); +} + +void MessageHelper::SendUnsubscribeIVIRequest(int32_t ivi_id, + ApplicationSharedPtr application, + ApplicationManager& app_mngr) { + return MockMessageHelper::message_helper_mock()->SendUnsubscribeIVIRequest( + ivi_id, application, app_mngr); +} + } // namespace application_manager diff --git a/src/components/application_manager/test/policy_handler_test.cc b/src/components/application_manager/test/policy_handler_test.cc index 4c3e882eae..66efe45e30 100644 --- a/src/components/application_manager/test/policy_handler_test.cc +++ b/src/components/application_manager/test/policy_handler_test.cc @@ -803,8 +803,14 @@ void PolicyHandlerTest::TestActivateApp(const uint32_t connection_key, EXPECT_CALL(*application1, is_audio()).WillRepeatedly(Return(false)); EXPECT_CALL(mock_message_helper_, SendOnAppPermissionsChangedNotification(kAppId1_, _, _)); - EXPECT_CALL(mock_session_observer, - GetDataOnDeviceID(device_handle, _, _, _, _)); + EXPECT_CALL( + mock_session_observer, + GetDataOnDeviceID( + testing::Matcher<transport_manager::DeviceHandle>(device_handle), + _, + _, + _, + _)); #endif // EXTERNAL_PROPRIETARY_MODE EXPECT_CALL(*application1, policy_app_id()).WillOnce(Return(kPolicyAppId_)); @@ -1162,7 +1168,15 @@ TEST_F(PolicyHandlerTest, OnCurrentDeviceIdUpdateRequired) { EXPECT_CALL(conn_handler, get_session_observer()) .WillOnce(ReturnRef(session_observer)); - EXPECT_CALL(session_observer, GetDataOnDeviceID(0u, _, _, _, _)); + const transport_manager::DeviceHandle handle = 0u; + + EXPECT_CALL(session_observer, + GetDataOnDeviceID( + testing::Matcher<transport_manager::DeviceHandle>(handle), + _, + _, + _, + _)); // Act policy_handler_.OnCurrentDeviceIdUpdateRequired(kPolicyAppId_); @@ -1463,7 +1477,9 @@ TEST_F(PolicyHandlerTest, OnGetListOfPermissions) { EXPECT_CALL(app_manager_, application(app_id)) .WillRepeatedly(Return(mock_app_)); EXPECT_CALL(*mock_app_, policy_app_id()).WillOnce(Return(std::string())); - EXPECT_CALL(mock_session_observer, GetDataOnDeviceID(_, _, _, _, _)); + EXPECT_CALL(mock_session_observer, + GetDataOnDeviceID( + testing::An<transport_manager::DeviceHandle>(), _, _, _, _)); policy_handler_.OnGetListOfPermissions(app_id, corr_id); } @@ -1489,7 +1505,9 @@ TEST_F(PolicyHandlerTest, OnGetListOfPermissions_WithoutConnectionKey) { EXPECT_CALL(app_manager_, applications()).WillRepeatedly(Return(app_set)); EXPECT_CALL(*mock_app_, device()).WillOnce(Return(0)); EXPECT_CALL(*mock_app_, policy_app_id()).WillOnce(Return(std::string())); - EXPECT_CALL(mock_session_observer, GetDataOnDeviceID(_, _, _, _, _)); + EXPECT_CALL(mock_session_observer, + GetDataOnDeviceID( + testing::An<transport_manager::DeviceHandle>(), _, _, _, _)); #ifdef EXTERNAL_PROPRIETARY_MODE policy::ExternalConsentStatus external_consent_status = @@ -1563,7 +1581,9 @@ TEST_F(PolicyHandlerTest, OnGetListOfPermissions_GroupPermissions_SUCCESS) { EXPECT_CALL(app_manager_, applications()).WillRepeatedly(Return(app_set)); EXPECT_CALL(*mock_app_, device()).WillOnce(Return(0)); EXPECT_CALL(*mock_app_, policy_app_id()).WillOnce(Return(std::string())); - EXPECT_CALL(mock_session_observer, GetDataOnDeviceID(_, _, _, _, _)); + EXPECT_CALL(mock_session_observer, + GetDataOnDeviceID( + testing::An<transport_manager::DeviceHandle>(), _, _, _, _)); #ifdef EXTERNAL_PROPRIETARY_MODE policy::ExternalConsentStatus external_consent_status = @@ -1878,7 +1898,9 @@ void PolicyHandlerTest::GetAppIDForSending() { EXPECT_CALL(*mock_app_, IsRegistered()).WillOnce(Return(true)); EXPECT_CALL(*mock_app_, hmi_level()) .WillRepeatedly(Return(mobile_api::HMILevel::HMI_FULL)); - EXPECT_CALL(mock_session_observer, GetDataOnDeviceID(_, _, _, _, _)) + EXPECT_CALL(mock_session_observer, + GetDataOnDeviceID( + testing::An<transport_manager::DeviceHandle>(), _, _, _, _)) .WillOnce(DoAll(SetArgPointee<3>(kMacAddr_), Return(0))); EXPECT_CALL(*mock_policy_manager_, GetUserConsentForDevice(kMacAddr_)) @@ -1944,7 +1966,9 @@ TEST_F(PolicyHandlerTest, GetAppIdForSending_ExpectReturnAnyIdButNone) { // Check expectations - EXPECT_CALL(mock_session_observer, GetDataOnDeviceID(_, _, _, _, _)) + EXPECT_CALL(mock_session_observer, + GetDataOnDeviceID( + testing::An<transport_manager::DeviceHandle>(), _, _, _, _)) .WillOnce(DoAll(SetArgPointee<3>(kMacAddr_), Return(0))); EXPECT_CALL(*mock_policy_manager_, GetUserConsentForDevice(kMacAddr_)) @@ -1984,7 +2008,9 @@ TEST_F(PolicyHandlerTest, GetAppIdForSending_ExpectReturnAnyAppInNone) { // Check expectations - EXPECT_CALL(mock_session_observer, GetDataOnDeviceID(_, _, _, _, _)) + EXPECT_CALL(mock_session_observer, + GetDataOnDeviceID( + testing::An<transport_manager::DeviceHandle>(), _, _, _, _)) .WillOnce(DoAll(SetArgPointee<3>(kMacAddr_), Return(0))); EXPECT_CALL(*mock_policy_manager_, GetUserConsentForDevice(kMacAddr_)) @@ -2077,7 +2103,9 @@ TEST_F(PolicyHandlerTest, CanUpdate_TwoApplicationForSending_SUCCESS) { test_app.insert(mock_app_); test_app.insert(second_mock_app); - EXPECT_CALL(mock_session_observer, GetDataOnDeviceID(_, _, _, _, _)) + EXPECT_CALL(mock_session_observer, + GetDataOnDeviceID( + testing::An<transport_manager::DeviceHandle>(), _, _, _, _)) .WillOnce(DoAll(SetArgPointee<3>(kMacAddr_), Return(0))); EXPECT_CALL(*mock_policy_manager_, GetUserConsentForDevice(kMacAddr_)) @@ -2111,8 +2139,13 @@ TEST_F(PolicyHandlerTest, .WillOnce(ReturnRef(conn_handler)); EXPECT_CALL(conn_handler, get_session_observer()) .WillOnce(ReturnRef(mock_session_observer)); - EXPECT_CALL(mock_session_observer, GetDataOnDeviceID(device, _, NULL, _, _)) - .WillOnce(Return(1u)); + EXPECT_CALL(mock_session_observer, + GetDataOnDeviceID( + testing::Matcher<transport_manager::DeviceHandle>(device), + _, + NULL, + _, + _)).WillOnce(Return(1u)); EXPECT_CALL(app_manager_, application(kConnectionKey_)) .WillOnce(Return(mock_app_)); @@ -2265,7 +2298,10 @@ TEST_F(PolicyHandlerTest, EXPECT_CALL(*mock_app_, policy_app_id()) .WillRepeatedly(Return(kPolicyAppId_)); - EXPECT_CALL(mock_session_observer, GetDataOnDeviceID(_, _, NULL, _, _)) + EXPECT_CALL( + mock_session_observer, + GetDataOnDeviceID( + testing::An<transport_manager::DeviceHandle>(), _, NULL, _, _)) .WillRepeatedly(DoAll(SetDeviceParamsMacAdress(kMacAddr_), (Return(1u)))); EXPECT_CALL(app_manager_, connection_handler()) @@ -2326,7 +2362,10 @@ TEST_F(PolicyHandlerTest, EXPECT_CALL(*mock_app_, policy_app_id()) .WillRepeatedly(Return(kPolicyAppId_)); - EXPECT_CALL(mock_session_observer, GetDataOnDeviceID(_, _, NULL, _, _)) + EXPECT_CALL( + mock_session_observer, + GetDataOnDeviceID( + testing::An<transport_manager::DeviceHandle>(), _, NULL, _, _)) .WillRepeatedly(DoAll(SetDeviceParamsMacAdress(kMacAddr_), (Return(1u)))); EXPECT_CALL(app_manager_, connection_handler()) diff --git a/src/components/application_manager/test/resumption/resume_ctrl_test.cc b/src/components/application_manager/test/resumption/resume_ctrl_test.cc index bbb814fb5b..f3e49001fa 100644 --- a/src/components/application_manager/test/resumption/resume_ctrl_test.cc +++ b/src/components/application_manager/test/resumption/resume_ctrl_test.cc @@ -54,6 +54,7 @@ namespace components { namespace resumption_test { using ::testing::_; +using ::testing::A; using ::testing::Return; using ::testing::ReturnRef; using ::testing::DoAll; @@ -505,7 +506,9 @@ TEST_F(ResumeCtrlTest, StartResumption_AppWithSubscriptionToWayPoints) { GetSavedApplication(kTestPolicyAppId_, kMacAddress_, _)) .WillByDefault(DoAll(SetArgReferee<2>(saved_app), Return(true))); EXPECT_CALL(*app_mock_, set_grammar_id(kTestGrammarId_)); - EXPECT_CALL(app_mngr_, SubscribeAppForWayPoints(_)); + EXPECT_CALL( + app_mngr_, + SubscribeAppForWayPoints(A<application_manager::ApplicationSharedPtr>())); const mobile_apis::HMILevel::eType hmi_test_level = mobile_apis::HMILevel::HMI_FULL; ON_CALL(app_mngr_, GetDefaultHmiLevel(const_app_)) diff --git a/src/components/application_manager/test/state_controller/state_controller_test.cc b/src/components/application_manager/test/state_controller/state_controller_test.cc index eb718c8b8b..694e105fbd 100644 --- a/src/components/application_manager/test/state_controller/state_controller_test.cc +++ b/src/components/application_manager/test/state_controller/state_controller_test.cc @@ -213,7 +213,7 @@ class StateControllerImplTest : public ::testing::Test { namespace SystemContext = mobile_apis::SystemContext; am::HmiStatePtr state = - utils::MakeShared<am::HmiState>(simple_app_id_, app_manager_mock_); + utils::MakeShared<am::HmiState>(simple_app_, app_manager_mock_); state->set_hmi_level(hmi_level); state->set_audio_streaming_state(aidio_ss); state->set_system_context(system_context); @@ -229,9 +229,9 @@ class StateControllerImplTest : public ::testing::Test { const mobile_apis::HMILevel::eType hmi_level, const mobile_apis::AudioStreamingState::eType audio_ss, const mobile_apis::SystemContext::eType system_context, - const uint32_t app_id) { + const am::ApplicationSharedPtr app) { am::HmiStatePtr new_state = - utils::MakeShared<HmiStateType>(app_id, app_manager_mock_); + utils::MakeShared<HmiStateType>(app, app_manager_mock_); new_state->set_hmi_level(hmi_level); new_state->set_audio_streaming_state(audio_ss); @@ -591,9 +591,9 @@ class StateControllerImplTest : public ::testing::Test { app_type = AppType(app_id); app = (*it_begin); am::HmiStatePtr state_first = - utils::MakeShared<T>(app_id, app_manager_mock_); + utils::MakeShared<T>(app, app_manager_mock_); am::HmiStatePtr state_second = - utils::MakeShared<Q>(app_id, app_manager_mock_); + utils::MakeShared<Q>(app, app_manager_mock_); TestSetSeveralState( app, state_first, state_second, app_type, call_back_result); TestSetSeveralState( @@ -1981,8 +1981,8 @@ TEST_F(StateControllerImplTest, ApplyTempStatesForMediaNaviVCApp) { } TEST_F(StateControllerImplTest, SetStatePhoneCallForNonMediaApplication) { - am::HmiStatePtr state_phone_call = utils::MakeShared<am::PhoneCallHmiState>( - simple_app_id_, app_manager_mock_); + am::HmiStatePtr state_phone_call = + utils::MakeShared<am::PhoneCallHmiState>(simple_app_, app_manager_mock_); TestSetState(simple_app_, state_phone_call, APP_TYPE_NON_MEDIA, @@ -1990,8 +1990,8 @@ TEST_F(StateControllerImplTest, SetStatePhoneCallForNonMediaApplication) { } TEST_F(StateControllerImplTest, SetStatePhoneCallForMediaApplication) { - am::HmiStatePtr state_phone_call = utils::MakeShared<am::PhoneCallHmiState>( - media_app_id_, app_manager_mock_); + am::HmiStatePtr state_phone_call = + utils::MakeShared<am::PhoneCallHmiState>(media_app_, app_manager_mock_); TestSetState(media_app_, state_phone_call, APP_TYPE_MEDIA, @@ -2000,7 +2000,7 @@ TEST_F(StateControllerImplTest, SetStatePhoneCallForMediaApplication) { TEST_F(StateControllerImplTest, SetStatePhoneCallForMediaNaviApplication) { am::HmiStatePtr state_phone_call = utils::MakeShared<am::PhoneCallHmiState>( - media_navi_app_id_, app_manager_mock_); + media_navi_app_, app_manager_mock_); TestSetState(media_navi_app_, state_phone_call, APP_TYPE_NAVI, @@ -2009,7 +2009,7 @@ TEST_F(StateControllerImplTest, SetStatePhoneCallForMediaNaviApplication) { TEST_F(StateControllerImplTest, SetVRStateForNonMediaApplication) { am::HmiStatePtr state_vr = - utils::MakeShared<am::VRHmiState>(simple_app_id_, app_manager_mock_); + utils::MakeShared<am::VRHmiState>(simple_app_, app_manager_mock_); TestSetState(simple_app_, state_vr, APP_TYPE_NON_MEDIA, @@ -2018,7 +2018,7 @@ TEST_F(StateControllerImplTest, SetVRStateForNonMediaApplication) { TEST_F(StateControllerImplTest, SetVRStateForMediaApplication) { am::HmiStatePtr state_vr = - utils::MakeShared<am::VRHmiState>(media_app_id_, app_manager_mock_); + utils::MakeShared<am::VRHmiState>(media_app_, app_manager_mock_); TestSetState(media_app_, state_vr, APP_TYPE_MEDIA, @@ -2026,8 +2026,8 @@ TEST_F(StateControllerImplTest, SetVRStateForMediaApplication) { } TEST_F(StateControllerImplTest, SetVRStateForMediaNaviVoiceApplication) { - am::HmiStatePtr state_vr = utils::MakeShared<am::VRHmiState>( - media_navi_vc_app_id_, app_manager_mock_); + am::HmiStatePtr state_vr = + utils::MakeShared<am::VRHmiState>(media_navi_vc_app_, app_manager_mock_); TestSetState(media_navi_vc_app_, state_vr, APP_TYPE_MEDIA, @@ -2037,7 +2037,7 @@ TEST_F(StateControllerImplTest, SetVRStateForMediaNaviVoiceApplication) { TEST_F(StateControllerImplTest, SetTTSStateForNonMediaApplicationAttenuatedNotSupported) { am::HmiStatePtr state_tts = - utils::MakeShared<am::TTSHmiState>(simple_app_id_, app_manager_mock_); + utils::MakeShared<am::TTSHmiState>(simple_app_, app_manager_mock_); EXPECT_CALL(app_manager_mock_, is_attenuated_supported()) .WillRepeatedly(Return(false)); TestSetState(simple_app_, @@ -2049,7 +2049,7 @@ TEST_F(StateControllerImplTest, TEST_F(StateControllerImplTest, SetTTSStateForNonMediaApplicationAttenuatedSupported) { am::HmiStatePtr state_tts = - utils::MakeShared<am::TTSHmiState>(simple_app_id_, app_manager_mock_); + utils::MakeShared<am::TTSHmiState>(simple_app_, app_manager_mock_); EXPECT_CALL(app_manager_mock_, is_attenuated_supported()) .WillRepeatedly(Return(true)); TestSetState(simple_app_, @@ -2061,7 +2061,7 @@ TEST_F(StateControllerImplTest, TEST_F(StateControllerImplTest, SetTTSStateForMediaApplicationAttenuatedNotSupported) { am::HmiStatePtr state_tts = - utils::MakeShared<am::TTSHmiState>(media_app_id_, app_manager_mock_); + utils::MakeShared<am::TTSHmiState>(media_app_, app_manager_mock_); EXPECT_CALL(app_manager_mock_, is_attenuated_supported()) .WillRepeatedly(Return(false)); TestSetState(media_app_, @@ -2073,7 +2073,7 @@ TEST_F(StateControllerImplTest, TEST_F(StateControllerImplTest, SetTTSStateForMediaApplicationAttenuatedSupported) { am::HmiStatePtr state_tts = - utils::MakeShared<am::TTSHmiState>(media_app_id_, app_manager_mock_); + utils::MakeShared<am::TTSHmiState>(media_app_, app_manager_mock_); EXPECT_CALL(app_manager_mock_, is_attenuated_supported()) .WillRepeatedly(Return(true)); TestSetState(media_app_, @@ -2084,8 +2084,8 @@ TEST_F(StateControllerImplTest, TEST_F(StateControllerImplTest, SetTTSStateForMediaNaviVCApplicationAttenuatedNotSupported) { - am::HmiStatePtr state_tts = utils::MakeShared<am::TTSHmiState>( - media_navi_vc_app_id_, app_manager_mock_); + am::HmiStatePtr state_tts = + utils::MakeShared<am::TTSHmiState>(media_navi_vc_app_, app_manager_mock_); EXPECT_CALL(app_manager_mock_, is_attenuated_supported()) .WillRepeatedly(Return(false)); TestSetState(media_navi_vc_app_, @@ -2096,8 +2096,8 @@ TEST_F(StateControllerImplTest, TEST_F(StateControllerImplTest, SetTTSStateForMediaNaviVCApplicationAttenuatedSupported) { - am::HmiStatePtr state_tts = utils::MakeShared<am::TTSHmiState>( - media_navi_vc_app_id_, app_manager_mock_); + am::HmiStatePtr state_tts = + utils::MakeShared<am::TTSHmiState>(media_navi_vc_app_, app_manager_mock_); EXPECT_CALL(app_manager_mock_, is_attenuated_supported()) .WillRepeatedly(Return(true)); TestSetState(media_navi_vc_app_, @@ -2108,7 +2108,7 @@ TEST_F(StateControllerImplTest, TEST_F(StateControllerImplTest, SetNaviStreamingStateForNonMediaApplication) { am::HmiStatePtr state_navi_streming = - utils::MakeShared<am::NaviStreamingHmiState>(simple_app_id_, + utils::MakeShared<am::NaviStreamingHmiState>(simple_app_, app_manager_mock_); TestSetState(simple_app_, state_navi_streming, @@ -2119,7 +2119,7 @@ TEST_F(StateControllerImplTest, SetNaviStreamingStateForNonMediaApplication) { TEST_F(StateControllerImplTest, SetNaviStreamingStateMediaApplicationAttenuatedNotSupported) { am::HmiStatePtr state_navi_streming = - utils::MakeShared<am::NaviStreamingHmiState>(media_app_id_, + utils::MakeShared<am::NaviStreamingHmiState>(media_app_, app_manager_mock_); EXPECT_CALL(app_manager_mock_, is_attenuated_supported()) .WillRepeatedly(Return(false)); @@ -2132,7 +2132,7 @@ TEST_F(StateControllerImplTest, TEST_F(StateControllerImplTest, SetNaviStreamingStateMediaApplicationAttenuatedSupported) { am::HmiStatePtr state_navi_streming = - utils::MakeShared<am::NaviStreamingHmiState>(media_app_id_, + utils::MakeShared<am::NaviStreamingHmiState>(media_app_, app_manager_mock_); EXPECT_CALL(app_manager_mock_, is_attenuated_supported()) .WillRepeatedly(Return(true)); @@ -2145,8 +2145,7 @@ TEST_F(StateControllerImplTest, TEST_F(StateControllerImplTest, SetNaviStreamingStateVCApplicationAttenuatedNotSupported) { am::HmiStatePtr state_navi_streming = - utils::MakeShared<am::NaviStreamingHmiState>(vc_app_id_, - app_manager_mock_); + utils::MakeShared<am::NaviStreamingHmiState>(vc_app_, app_manager_mock_); EXPECT_CALL(app_manager_mock_, is_attenuated_supported()) .WillRepeatedly(Return(false)); TestSetState(vc_app_, @@ -2158,8 +2157,7 @@ TEST_F(StateControllerImplTest, TEST_F(StateControllerImplTest, SetNaviStreamingStateVCApplicationAttenuatedSupported) { am::HmiStatePtr state_navi_streming = - utils::MakeShared<am::NaviStreamingHmiState>(vc_app_id_, - app_manager_mock_); + utils::MakeShared<am::NaviStreamingHmiState>(vc_app_, app_manager_mock_); EXPECT_CALL(app_manager_mock_, is_attenuated_supported()) .WillRepeatedly(Return(true)); TestSetState(vc_app_, @@ -2170,7 +2168,7 @@ TEST_F(StateControllerImplTest, TEST_F(StateControllerImplTest, SetNaviStreamingStateNaviApplication) { am::HmiStatePtr state_navi_streming = - utils::MakeShared<am::NaviStreamingHmiState>(navi_app_id_, + utils::MakeShared<am::NaviStreamingHmiState>(navi_app_, app_manager_mock_); TestSetState(navi_app_, state_navi_streming, @@ -2180,7 +2178,7 @@ TEST_F(StateControllerImplTest, SetNaviStreamingStateNaviApplication) { TEST_F(StateControllerImplTest, SetNaviStreamingStateMediaNaviApplication) { am::HmiStatePtr state_navi_streming = - utils::MakeShared<am::NaviStreamingHmiState>(media_navi_app_id_, + utils::MakeShared<am::NaviStreamingHmiState>(media_navi_app_, app_manager_mock_); TestSetState(media_navi_app_, state_navi_streming, @@ -2189,8 +2187,8 @@ TEST_F(StateControllerImplTest, SetNaviStreamingStateMediaNaviApplication) { } TEST_F(StateControllerImplTest, SetSafetyModeStateForNonMediaApplication) { - am::HmiStatePtr state_safety_mode = utils::MakeShared<am::SafetyModeHmiState>( - simple_app_id_, app_manager_mock_); + am::HmiStatePtr state_safety_mode = + utils::MakeShared<am::SafetyModeHmiState>(simple_app_, app_manager_mock_); TestSetState(simple_app_, state_safety_mode, APP_TYPE_NON_MEDIA, @@ -2199,7 +2197,7 @@ TEST_F(StateControllerImplTest, SetSafetyModeStateForNonMediaApplication) { TEST_F(StateControllerImplTest, SetSafetyModeStateForMediaApplication) { am::HmiStatePtr state_safety_mode = - utils::MakeShared<am::VRHmiState>(media_app_id_, app_manager_mock_); + utils::MakeShared<am::VRHmiState>(media_app_, app_manager_mock_); TestSetState(media_app_, state_safety_mode, APP_TYPE_MEDIA, @@ -2208,8 +2206,8 @@ TEST_F(StateControllerImplTest, SetSafetyModeStateForMediaApplication) { TEST_F(StateControllerImplTest, SetSafetyModeStateForMediaNaviVoiceApplication) { - am::HmiStatePtr state_safety_mode = utils::MakeShared<am::VRHmiState>( - media_navi_vc_app_id_, app_manager_mock_); + am::HmiStatePtr state_safety_mode = + utils::MakeShared<am::VRHmiState>(media_navi_vc_app_, app_manager_mock_); TestSetState(media_navi_vc_app_, state_safety_mode, APP_TYPE_MEDIA, @@ -2909,7 +2907,7 @@ TEST_F(StateControllerImplTest, OnApplicationRegisteredDifferentStates) { mobile_apis::HMILevel::HMI_FULL, mobile_apis::AudioStreamingState::AUDIBLE, mobile_apis::SystemContext::SYSCTXT_MAIN, - app_id); + simple_app_); EXPECT_CALL(*simple_app_ptr_, app_id()).WillRepeatedly(Return(app_id)); EXPECT_CALL(*simple_app_ptr_, CurrentHmiState()) @@ -2921,7 +2919,7 @@ TEST_F(StateControllerImplTest, OnApplicationRegisteredDifferentStates) { mobile_apis::HMILevel::HMI_BACKGROUND, mobile_apis::AudioStreamingState::AUDIBLE, mobile_apis::SystemContext::SYSCTXT_MAIN, - app_id); + simple_app_); EXPECT_CALL(*simple_app_ptr_, RegularHmiState()).WillOnce(Return(old_state)); EXPECT_CALL(*simple_app_ptr_, CurrentHmiState()) @@ -2958,7 +2956,7 @@ TEST_F(StateControllerImplTest, OnApplicationRegisteredEqualStates) { mobile_apis::HMILevel::HMI_FULL, mobile_apis::AudioStreamingState::AUDIBLE, mobile_apis::SystemContext::SYSCTXT_MAIN, - app_id); + simple_app_); EXPECT_CALL(*simple_app_ptr_, app_id()).WillRepeatedly(Return(app_id)); EXPECT_CALL(*simple_app_ptr_, CurrentHmiState()) @@ -2970,7 +2968,7 @@ TEST_F(StateControllerImplTest, OnApplicationRegisteredEqualStates) { mobile_apis::HMILevel::HMI_BACKGROUND, mobile_apis::AudioStreamingState::AUDIBLE, mobile_apis::SystemContext::SYSCTXT_MAIN, - app_id); + simple_app_); EXPECT_CALL(*simple_app_ptr_, RegularHmiState()) .WillOnce(Return(default_state)); EXPECT_CALL(*simple_app_ptr_, CurrentHmiState()) 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..c2bac31c1b 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,24 @@ class ConnectionHandlerImpl void OnDeviceRemoved( const transport_manager::DeviceInfo& device_info) OVERRIDE; + /** + * @brief OnDeviceSwitchingStart notifies listeners on device transport + * switching start + * @param device_uid_from the id of the device which has to switch its + * transport + * @param device_uid_to the id of the device on new transport + */ + void OnDeviceSwitchingStart(const std::string& device_uid_from, + const std::string& device_uid_to) FINAL; + + /** + * @brief OnDeviceSwitchingFinish notifies listeners on device transport + * switching completion + * @param device_uid the id for the device which is fails to reconnect. + */ + void OnDeviceSwitchingFinish( + const transport_manager::DeviceUID& device_uid) FINAL; + void OnScanDevicesFinished() OVERRIDE; void OnScanDevicesFailed( const transport_manager::SearchDeviceError& error) OVERRIDE; @@ -461,10 +479,33 @@ 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; + + /** + * DEPRECATED + * \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 + */ + DEPRECATED int32_t GetDataOnSessionKey(uint32_t key, + uint32_t* app_id, + std::list<int32_t>* sessions_list, + uint32_t* 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..c8f3dd8932 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,49 @@ void ConnectionHandlerImpl::OnDeviceRemoved( device_list_.erase(device_info.device_handle()); } +void ConnectionHandlerImpl::OnDeviceSwitchingFinish( + const transport_manager::DeviceUID& device_uid) { + sync_primitives::AutoReadLock read_lock(connection_handler_observer_lock_); + if (connection_handler_observer_) { + connection_handler_observer_->OnDeviceSwitchingFinish( + encryption::MakeHash(device_uid)); + } +} + +namespace { +struct DeviceFinder { + explicit DeviceFinder(const std::string& device_uid) + : device_uid_(device_uid) {} + bool operator()(const DeviceMap::value_type& device) { + return device_uid_ == device.second.mac_address(); + } + + private: + const std::string& device_uid_; +}; +} // namespace + +void ConnectionHandlerImpl::OnDeviceSwitchingStart( + const std::string& device_uid_from, const std::string& device_uid_to) { + auto device_from = + std::find_if(device_list_.begin(), + device_list_.end(), + DeviceFinder(encryption::MakeHash(device_uid_from))); + + auto device_to = + std::find_if(device_list_.begin(), + device_list_.end(), + DeviceFinder(encryption::MakeHash(device_uid_to))); + + DCHECK_OR_RETURN_VOID(device_list_.end() != device_from); + DCHECK_OR_RETURN_VOID(device_list_.end() != device_to); + sync_primitives::AutoReadLock read_lock(connection_handler_observer_lock_); + if (connection_handler_observer_) { + connection_handler_observer_->OnDeviceSwitchingStart(device_from->second, + device_to->second); + } +} + void ConnectionHandlerImpl::OnScanDevicesFinished() { LOG4CXX_AUTO_TRACE(logger_); } @@ -646,7 +696,7 @@ int32_t ConnectionHandlerImpl::GetDataOnSessionKey( uint32_t key, uint32_t* app_id, std::list<int32_t>* sessions_list, - uint32_t* device_id) const { + connection_handler::DeviceHandle* device_id) const { LOG4CXX_AUTO_TRACE(logger_); const int32_t error_result = -1; @@ -690,6 +740,15 @@ int32_t ConnectionHandlerImpl::GetDataOnSessionKey( return 0; } +DEPRECATED int32_t +ConnectionHandlerImpl::GetDataOnSessionKey(uint32_t key, + uint32_t* app_id, + std::list<int32_t>* sessions_list, + uint32_t* device_id) const { + LOG4CXX_AUTO_TRACE(logger_); + return GetDataOnSessionKey(key, app_id, sessions_list, device_id); +} + const ConnectionHandlerSettings& ConnectionHandlerImpl::get_settings() const { return settings_; } diff --git a/src/components/connection_handler/test/connection_handler_impl_test.cc b/src/components/connection_handler/test/connection_handler_impl_test.cc index 0a05983623..b6783c64ef 100644 --- a/src/components/connection_handler/test/connection_handler_impl_test.cc +++ b/src/components/connection_handler/test/connection_handler_impl_test.cc @@ -342,9 +342,10 @@ TEST_F(ConnectionHandlerTest, GetAppIdOnSessionKey) { uint32_t app_id = 0; const uint32_t testid = SessionHash(uid_, start_session_id_); + connection_handler::DeviceHandle null_handle = 0; EXPECT_EQ(0, connection_handler_->GetDataOnSessionKey( - connection_key_, &app_id, NULL, NULL)); + connection_key_, &app_id, NULL, &null_handle)); EXPECT_EQ(testid, app_id); } @@ -352,9 +353,10 @@ TEST_F(ConnectionHandlerTest, GetAppIdOnSessionKey_SessionNotStarted) { AddTestDeviceConnection(); uint32_t app_id = 0; + connection_handler::DeviceHandle null_handle = 0; EXPECT_EQ(-1, connection_handler_->GetDataOnSessionKey( - connection_key_, &app_id, NULL, NULL)); + connection_key_, &app_id, NULL, &null_handle)); } TEST_F(ConnectionHandlerTest, GetDeviceID) { @@ -469,6 +471,13 @@ TEST_F(ConnectionHandlerTest, IsHeartBeatSupported) { connection_handler_->IsHeartBeatSupported(uid_, start_session_id_)); } +MATCHER_P(SameDevice, device, "") { + return arg.device_handle() == device.device_handle() && + arg.user_friendly_name() == device.user_friendly_name() && + arg.mac_address() == device.mac_address() && + arg.connection_type() == device.connection_type(); +} + TEST_F(ConnectionHandlerTest, SendEndServiceWithoutSetProtocolHandler) { AddTestDeviceConnection(); AddTestSession(); @@ -1892,6 +1901,41 @@ TEST_F(ConnectionHandlerTest, RunAppOnDevice_AppOnDevice_SUCCESS) { connection_handler_->RunAppOnDevice(hash_of_mac_address, bundle_id); } +TEST_F(ConnectionHandlerTest, OnDeviceConnectionSwitching) { + connection_handler_test::MockConnectionHandlerObserver + mock_connection_handler_observer; + connection_handler_->set_connection_handler_observer( + &mock_connection_handler_observer); + + const transport_manager::DeviceInfo device_info_1( + device_handle_, mac_address_, device_name_, connection_type_); + + connection_handler_->OnDeviceAdded(device_info_1); + + const auto second_mac_address = "second_mac_address"; + const transport_manager::DeviceInfo device_info_2(device_handle_ + 1, + second_mac_address, + "second_device_name", + "second_connection_type"); + + connection_handler_->OnDeviceAdded(device_info_2); + + connection_handler::Device d1(device_info_1.device_handle(), + device_info_1.name(), + device_info_1.mac_address(), + device_info_1.connection_type()); + + connection_handler::Device d2(device_info_2.device_handle(), + device_info_2.name(), + device_info_2.mac_address(), + device_info_2.connection_type()); + + EXPECT_CALL(mock_connection_handler_observer, + OnDeviceSwitchingStart(SameDevice(d1), SameDevice(d2))); + + connection_handler_->OnDeviceSwitchingStart(mac_address_, second_mac_address); +} + } // namespace connection_handler_test } // namespace components } // namespace test diff --git a/src/components/functional_module/test/include/mock_application.h b/src/components/functional_module/test/include/mock_application.h index 1192d5ede5..95bd4a0505 100644 --- a/src/components/functional_module/test/include/mock_application.h +++ b/src/components/functional_module/test/include/mock_application.h @@ -115,6 +115,7 @@ class MockApplication : public Application { bool(mobile_apis::FunctionID::eType cmd_id, TLimitSource source)); MOCK_METHOD0(usage_report, UsageStatistics&()); + MOCK_METHOD1(SetInitialState, void(HmiStatePtr state)); MOCK_METHOD2(SubscribeToSoftButtons, void(int32_t cmd_id, const SoftButtonID& softbuttons_id)); MOCK_METHOD1(IsSubscribedToSoftButton, bool(const uint32_t softbutton_id)); diff --git a/src/components/include/application_manager/application_manager.h b/src/components/include/application_manager/application_manager.h index 15a9f39348..96803e69a8 100644 --- a/src/components/include/application_manager/application_manager.h +++ b/src/components/include/application_manager/application_manager.h @@ -254,6 +254,7 @@ class ApplicationManager { const utils::SharedPtr<Application> app) = 0; /** + * DEPRECATED * @brief Checks if Application is subscribed for way points * @param Application AppID * @return true if Application is subscribed for way points @@ -262,18 +263,40 @@ class ApplicationManager { virtual bool IsAppSubscribedForWayPoints(const uint32_t app_id) const = 0; /** + * DEPRECATED * @brief Subscribe Application for way points * @param Application AppID */ virtual void SubscribeAppForWayPoints(const uint32_t app_id) = 0; /** + * DEPRECATED * @brief Unsubscribe Application for way points * @param Application AppID */ virtual void UnsubscribeAppFromWayPoints(const uint32_t app_id) = 0; /** + * @brief Checks if Application is subscribed for way points + * @param Application pointer + * @return true if Application is subscribed for way points + * otherwise false + */ + virtual bool IsAppSubscribedForWayPoints(ApplicationSharedPtr app) const = 0; + + /** + * @brief Subscribe Application for way points + * @param Application pointer + */ + virtual void SubscribeAppForWayPoints(ApplicationSharedPtr app) = 0; + + /** + * @brief Unsubscribe Application for way points + * @param Application pointer + */ + virtual void UnsubscribeAppFromWayPoints(ApplicationSharedPtr app) = 0; + + /** * @brief Is Any Application is subscribed for way points * @return true if some app is subscribed otherwise false */ @@ -313,6 +336,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; /** @@ -334,6 +368,13 @@ class ApplicationManager { */ virtual void OnApplicationRegistered(ApplicationSharedPtr app) = 0; + /** + * @brief OnApplicationSwitched starts activies postponed during application + * transport switching + * @param app Application + */ + virtual void OnApplicationSwitched(ApplicationSharedPtr app) = 0; + virtual connection_handler::ConnectionHandler& connection_handler() const = 0; virtual protocol_handler::ProtocolHandler& protocol_handler() const = 0; virtual policy::PolicyHandlerInterface& GetPolicyHandler() = 0; @@ -534,6 +575,15 @@ class ApplicationManager { virtual bool IsApplicationForbidden( uint32_t connection_key, const std::string& policy_app_id) const = 0; + /** + * @brief IsAppInReconnectMode check if application belongs to session + * affected by transport switching at the moment + * @param policy_app_id Application id + * @return True if application is registered within session being switched, + * otherwise - false + */ + virtual bool IsAppInReconnectMode(const std::string& policy_app_id) const = 0; + virtual resumption::ResumeCtrl& resume_controller() = 0; /** @@ -594,7 +644,22 @@ 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( + utils::SharedPtr<Application> app, + mobile_apis::HMILevel::eType hmi_level, + mobile_apis::AudioStreamingState::eType audio_state, + mobile_apis::SystemContext::eType system_context) const = 0; + + /** + * DEPRECATED + * @brief CreateRegularState create regular HMI state for application + * @param app_id Application id * @param hmi_level of returned state * @param audio_state of returned state * @param system_context of returned state diff --git a/src/components/include/application_manager/policies/policy_handler_interface.h b/src/components/include/application_manager/policies/policy_handler_interface.h index d7e9f1cea7..f0859ece38 100644 --- a/src/components/include/application_manager/policies/policy_handler_interface.h +++ b/src/components/include/application_manager/policies/policy_handler_interface.h @@ -427,6 +427,15 @@ class PolicyHandlerInterface { virtual const PolicySettings& get_settings() const = 0; virtual const std::string RemoteAppsUrl() const = 0; + /** + * @brief OnDeviceSwitching Notifies policy manager on device switch event so + * policy permissions should be processed accordingly + * @param device_id_from Id of device being switched + * @param device_id_to Id of device on the new transport + */ + virtual void OnDeviceSwitching(const std::string& device_id_from, + const std::string& device_id_to) = 0; + #ifdef SDL_REMOTE_CONTROL /** * @brief Sets HMI default type for specified application diff --git a/src/components/include/connection_handler/connection_handler.h b/src/components/include/connection_handler/connection_handler.h index c70861b5f6..1fcf5e4477 100644 --- a/src/components/include/connection_handler/connection_handler.h +++ b/src/components/include/connection_handler/connection_handler.h @@ -39,6 +39,7 @@ #include "connection_handler/device.h" #include "connection_handler/connection.h" #include "connection_handler/devices_discovery_starter.h" +#include "utils/macro.h" /** * \namespace connection_handler @@ -175,10 +176,27 @@ class ConnectionHandler { * \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, + connection_handler::DeviceHandle* device_id) const = 0; + + /** + * DEPRECATED + * \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 + */ + DEPRECATED 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..7eb17264eb 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,22 @@ class ConnectionHandlerObserver { const protocol_handler::ServiceType& type, const connection_handler::CloseSessionReason& close_reason) = 0; + /** + * @brief OnDeviceSwitchingStart is invoked on device transport switching + * start (e.g. from Bluetooth to USB) + * @param device_from device params being switched to new transport + * @param device_to device params on the new transport + */ + virtual void OnDeviceSwitchingStart(const Device& device_from, + const Device& device_to) = 0; + + /** + * @brief OnDeviceSwitchingFinish is invoked on device trasport switching end + * i.e. timeout for switching is expired + * @param device_uid UID of device being switched + */ + virtual void OnDeviceSwitchingFinish(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/policy/policy_external/policy/policy_manager.h b/src/components/include/policy/policy_external/policy/policy_manager.h index adf195e3a9..24905671fa 100644 --- a/src/components/include/policy/policy_external/policy/policy_manager.h +++ b/src/components/include/policy/policy_external/policy/policy_manager.h @@ -483,6 +483,9 @@ class PolicyManager : public usage_statistics::StatisticsManager { */ virtual void OnAppRegisteredOnMobile(const std::string& application_id) = 0; + virtual void OnDeviceSwitching(const std::string& device_id_from, + const std::string& device_id_to) = 0; + /** * @brief Gets request types for application * @param policy_app_id Unique application id diff --git a/src/components/include/policy/policy_regular/policy/policy_manager.h b/src/components/include/policy/policy_regular/policy/policy_manager.h index 510e35e699..3e90cfc094 100644 --- a/src/components/include/policy/policy_regular/policy/policy_manager.h +++ b/src/components/include/policy/policy_regular/policy/policy_manager.h @@ -487,6 +487,9 @@ class PolicyManager : public usage_statistics::StatisticsManager { */ virtual void OnAppRegisteredOnMobile(const std::string& application_id) = 0; + virtual void OnDeviceSwitching(const std::string& device_id_from, + const std::string& device_id_to) = 0; + /** * @brief RetrieveCertificate Allows to obtain certificate in order * to start secure connection. diff --git a/src/components/include/protocol_handler/session_observer.h b/src/components/include/protocol_handler/session_observer.h index 7ac7a84d6d..4648e678c2 100644 --- a/src/components/include/protocol_handler/session_observer.h +++ b/src/components/include/protocol_handler/session_observer.h @@ -36,6 +36,7 @@ #include <list> #include <string> #include "transport_manager/transport_manager.h" +#include "utils/macro.h" #ifdef ENABLE_SECURITY #include "security_manager/ssl_context.h" #endif // ENABLE_SECURITY @@ -176,6 +177,7 @@ class SessionObserver { uint8_t* sessionId) const = 0; /** + * DEPRECATED * \brief information about given Connection Key. * \param key Unique key used by other components as session identifier * \param app_id Returned: ApplicationID @@ -189,6 +191,20 @@ class SessionObserver { uint32_t* device_id) const = 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, + transport_manager::DeviceHandle* device_id) const = 0; + + /** * \brief information about device * \param device_handle * \param device_name Returned: name of device diff --git a/src/components/include/test/application_manager/mock_application_manager.h b/src/components/include/test/application_manager/mock_application_manager.h index 7d1384b7ac..4f2d964488 100644 --- a/src/components/include/test/application_manager/mock_application_manager.h +++ b/src/components/include/test/application_manager/mock_application_manager.h @@ -151,6 +151,8 @@ class MockApplicationManager : public application_manager::ApplicationManager { bool(application_manager::ApplicationConstSharedPtr app)); MOCK_METHOD1(OnApplicationRegistered, void(application_manager::ApplicationSharedPtr app)); + MOCK_METHOD1(OnApplicationSwitched, + void(application_manager::ApplicationSharedPtr app)); MOCK_CONST_METHOD0(connection_handler, connection_handler::ConnectionHandler&()); MOCK_CONST_METHOD0(protocol_handler, protocol_handler::ProtocolHandler&()); @@ -244,10 +246,18 @@ class MockApplicationManager : public application_manager::ApplicationManager { bool state)); MOCK_CONST_METHOD4(CreateRegularState, application_manager::HmiStatePtr( - uint32_t app_id, + application_manager::ApplicationSharedPtr app, mobile_apis::HMILevel::eType hmi_level, mobile_apis::AudioStreamingState::eType audio_state, mobile_apis::SystemContext::eType system_context)); + DEPRECATED MOCK_CONST_METHOD4( + CreateRegularState, + application_manager::HmiStatePtr( + uint32_t app_id, + mobile_apis::HMILevel::eType hmi_level, + mobile_apis::AudioStreamingState::eType audio_state, + mobile_apis::SystemContext::eType system_context)); + MOCK_METHOD2(SendAudioPassThroughNotification, void(uint32_t session_key, std::vector<uint8_t>& binary_data)); MOCK_CONST_METHOD2(CanAppStream, @@ -259,9 +269,16 @@ class MockApplicationManager : public application_manager::ApplicationManager { MOCK_METHOD0(event_dispatcher, application_manager::event_engine::EventDispatcher&()); - MOCK_CONST_METHOD1(IsAppSubscribedForWayPoints, bool(const uint32_t)); - MOCK_METHOD1(SubscribeAppForWayPoints, void(const uint32_t)); - MOCK_METHOD1(UnsubscribeAppFromWayPoints, void(const uint32_t)); + DEPRECATED MOCK_CONST_METHOD1(IsAppSubscribedForWayPoints, + bool(const uint32_t)); + DEPRECATED MOCK_METHOD1(SubscribeAppForWayPoints, void(const uint32_t)); + DEPRECATED MOCK_METHOD1(UnsubscribeAppFromWayPoints, void(const uint32_t)); + MOCK_CONST_METHOD1(IsAppSubscribedForWayPoints, + bool(application_manager::ApplicationSharedPtr)); + MOCK_METHOD1(SubscribeAppForWayPoints, + void(application_manager::ApplicationSharedPtr)); + MOCK_METHOD1(UnsubscribeAppFromWayPoints, + void(application_manager::ApplicationSharedPtr)); MOCK_CONST_METHOD0(IsAnyAppSubscribedForWayPoints, bool()); MOCK_CONST_METHOD0(GetAppsSubscribedForWayPoints, const std::set<int32_t>()); MOCK_CONST_METHOD1( @@ -271,9 +288,9 @@ class MockApplicationManager : public application_manager::ApplicationManager { AppsWaitingForRegistration, DataAccessor<application_manager::AppsWaitRegistrationSet>()); - MOCK_METHOD1(ReplaceMobileByHMIAppId, + MOCK_METHOD1(ReplaceMobileWithHMIAppId, void(smart_objects::SmartObject& message)); - MOCK_METHOD1(ReplaceHMIByMobileAppId, + MOCK_METHOD1(ReplaceHMIWithMobileAppId, void(smart_objects::SmartObject& message)); MOCK_METHOD1(GetAvailableSpaceForApp, uint32_t(const std::string& folder_name)); @@ -288,6 +305,11 @@ class MockApplicationManager : public application_manager::ApplicationManager { MOCK_METHOD1(ValidateMessageBySchema, application_manager::MessageValidationResult( const application_manager::Message& message)); + MOCK_METHOD2(ProcessReconnection, + void(application_manager::ApplicationSharedPtr application, + const uint32_t connection_key)); + MOCK_CONST_METHOD1(IsAppInReconnectMode, + bool(const std::string& policy_app_id)); }; } // namespace application_manager_test diff --git a/src/components/include/test/application_manager/policies/mock_policy_handler_interface.h b/src/components/include/test/application_manager/policies/mock_policy_handler_interface.h index 812df19ccd..931fd6cfb4 100644 --- a/src/components/include/test/application_manager/policies/mock_policy_handler_interface.h +++ b/src/components/include/test/application_manager/policies/mock_policy_handler_interface.h @@ -255,6 +255,9 @@ class MockPolicyHandlerInterface : public policy::PolicyHandlerInterface { MOCK_METHOD2(SetDefaultHmiTypes, void(const std::string& application_id, const smart_objects::SmartObject* app_types)); + MOCK_METHOD2(OnDeviceSwitching, + void(const std::string& device_id_from, + const std::string& device_id_to)); #endif // SDL_REMOTE_CONTROL private: diff --git a/src/components/include/test/connection_handler/mock_connection_handler.h b/src/components/include/test/connection_handler/mock_connection_handler.h index 5cb5f471b5..20be7b64e9 100644 --- a/src/components/include/test/connection_handler/mock_connection_handler.h +++ b/src/components/include/test/connection_handler/mock_connection_handler.h @@ -84,11 +84,17 @@ class MockConnectionHandler : public connection_handler::ConnectionHandler { void(uint32_t connection_key, uint8_t session_id)); MOCK_METHOD2(BindProtocolVersionWithSession, void(uint32_t connection_key, uint8_t protocol_version)); + + DEPRECATED MOCK_CONST_METHOD4(GetDataOnSessionKey, + int32_t(uint32_t key, + uint32_t* app_id, + std::list<int32_t>* sessions_list, + uint32_t* device_id)); MOCK_CONST_METHOD4(GetDataOnSessionKey, int32_t(uint32_t key, uint32_t* app_id, std::list<int32_t>* sessions_list, - uint32_t* device_id)); + connection_handler::DeviceHandle* device_id)); MOCK_CONST_METHOD0(get_settings, const connection_handler::ConnectionHandlerSettings&()); MOCK_METHOD0(get_session_observer, diff --git a/src/components/include/test/connection_handler/mock_connection_handler_observer.h b/src/components/include/test/connection_handler/mock_connection_handler_observer.h index dead5bc61e..bb5ad7cad0 100644 --- a/src/components/include/test/connection_handler/mock_connection_handler_observer.h +++ b/src/components/include/test/connection_handler/mock_connection_handler_observer.h @@ -48,11 +48,11 @@ class MockConnectionHandlerObserver MOCK_METHOD0(OnFindNewApplicationsRequest, void()); MOCK_METHOD1(RemoveDevice, void(const connection_handler::DeviceHandle& device_handle)); - // DEPRECATED - MOCK_METHOD3(OnServiceStartedCallback, - bool(const connection_handler::DeviceHandle& device_handle, - const int32_t& session_key, - const protocol_handler::ServiceType& type)); + DEPRECATED MOCK_METHOD3( + OnServiceStartedCallback, + bool(const connection_handler::DeviceHandle& device_handle, + const int32_t& session_key, + const protocol_handler::ServiceType& type)); MOCK_METHOD4(OnServiceStartedCallback, void(const connection_handler::DeviceHandle& device_handle, const int32_t& session_key, @@ -66,6 +66,11 @@ class MockConnectionHandlerObserver MOCK_CONST_METHOD1( GetHandshakeContext, security_manager::SSLContext::HandshakeContext(uint32_t key)); + + MOCK_METHOD2(OnDeviceSwitchingStart, + void(const connection_handler::Device& device_from, + const connection_handler::Device& device_to)); + MOCK_METHOD1(OnDeviceSwitchingFinish, void(const std::string& device_uid)); }; } // namespace connection_handler_test diff --git a/src/components/include/test/policy/policy_external/policy/mock_cache_manager.h b/src/components/include/test/policy/policy_external/policy/mock_cache_manager.h index e90fa63075..5aa92446b6 100644 --- a/src/components/include/test/policy/policy_external/policy/mock_cache_manager.h +++ b/src/components/include/test/policy/policy_external/policy/mock_cache_manager.h @@ -247,6 +247,9 @@ class MockCacheManagerInterface : public ::policy::CacheManagerInterface { GroupsByExternalConsentStatus(const ExternalConsentStatus&)); MOCK_METHOD0(GetKnownLinksFromPT, std::map<std::string, std::string>()); MOCK_METHOD1(SetExternalConsentForApp, void(const PermissionConsent&)); + MOCK_METHOD2(OnDeviceSwitching, + void(const std::string& device_id_from, + const std::string& device_id_to)); }; } // namespace policy_test diff --git a/src/components/include/test/policy/policy_external/policy/mock_policy_manager.h b/src/components/include/test/policy/policy_external/policy/mock_policy_manager.h index 6227e7e85c..9e487da4ba 100644 --- a/src/components/include/test/policy/policy_external/policy/mock_policy_manager.h +++ b/src/components/include/test/policy/policy_external/policy/mock_policy_manager.h @@ -215,6 +215,9 @@ class MockPolicyManager : public PolicyManager { MOCK_METHOD0(GetExternalConsentStatus, ExternalConsentStatus()); MOCK_CONST_METHOD1(IsNeedToUpdateExternalConsentStatus, bool(const ExternalConsentStatus&)); + MOCK_METHOD2(OnDeviceSwitching, + void(const std::string& device_id_from, + const std::string& device_id_to)); }; } // namespace policy_manager_test } // namespace components diff --git a/src/components/include/test/policy/policy_regular/policy/mock_cache_manager.h b/src/components/include/test/policy/policy_regular/policy/mock_cache_manager.h index 39876cf713..ed3a5088c1 100644 --- a/src/components/include/test/policy/policy_regular/policy/mock_cache_manager.h +++ b/src/components/include/test/policy/policy_regular/policy/mock_cache_manager.h @@ -211,6 +211,9 @@ class MockCacheManagerInterface : public CacheManagerInterface { MOCK_CONST_METHOD2(AppHasHMIType, bool(const std::string& application_id, policy_table::AppHMIType hmi_type)); + MOCK_METHOD2(OnDeviceSwitching, + void(const std::string& device_id_from, + const std::string& device_id_to)); }; } // namespace policy_test diff --git a/src/components/include/test/policy/policy_regular/policy/mock_policy_manager.h b/src/components/include/test/policy/policy_regular/policy/mock_policy_manager.h index cfe41ee64c..82012b83c7 100644 --- a/src/components/include/test/policy/policy_regular/policy/mock_policy_manager.h +++ b/src/components/include/test/policy/policy_regular/policy/mock_policy_manager.h @@ -222,6 +222,10 @@ class MockPolicyManager : public PolicyManager { CheckPendingPermissionsChanges, void(const std::string& policy_app_id, const std::vector<FunctionalGroupPermission>& current_permissions)); + + MOCK_METHOD2(OnDeviceSwitching, + void(const std::string& device_id_from, + const std::string& device_id_to)); }; } // namespace policy_manager_test diff --git a/src/components/include/test/protocol_handler/mock_session_observer.h b/src/components/include/test/protocol_handler/mock_session_observer.h index 4d2072624d..350704ae86 100644 --- a/src/components/include/test/protocol_handler/mock_session_observer.h +++ b/src/components/include/test/protocol_handler/mock_session_observer.h @@ -46,8 +46,7 @@ namespace protocol_handler_test { */ class MockSessionObserver : public ::protocol_handler::SessionObserver { public: - // DEPRECATED - MOCK_METHOD5( + DEPRECATED MOCK_METHOD5( OnSessionStartedCallback, uint32_t(const transport_manager::ConnectionUID connection_handle, const uint8_t sessionId, @@ -88,13 +87,27 @@ class MockSessionObserver : public ::protocol_handler::SessionObserver { int32_t(uint32_t key, uint32_t* app_id, std::list<int32_t>* sessions_list, - uint32_t* device_id)); + transport_manager::DeviceHandle* device_id)); + DEPRECATED MOCK_CONST_METHOD4(GetDataOnSessionKey, + int32_t(uint32_t key, + uint32_t* app_id, + std::list<int32_t>* sessions_list, + uint32_t* device_id)); + MOCK_CONST_METHOD5(GetDataOnDeviceID, - int32_t(uint32_t device_handle, + int32_t(transport_manager::DeviceHandle device_handle, std::string* device_name, std::list<uint32_t>* applications_list, std::string* mac_address, std::string* connection_type)); + + DEPRECATED MOCK_CONST_METHOD5(GetDataOnDeviceID, + int32_t(uint32_t device_handle, + std::string* device_name, + std::list<uint32_t>* applications_list, + std::string* mac_address, + std::string* connection_type)); + MOCK_CONST_METHOD2(IsHeartBeatSupported, bool(transport_manager::ConnectionUID connection_handle, uint8_t session_id)); diff --git a/src/components/include/test/transport_manager/mock_transport_manager_listener.h b/src/components/include/test/transport_manager/mock_transport_manager_listener.h index dfa2cbc31d..f4c4fdcf68 100644 --- a/src/components/include/test/transport_manager/mock_transport_manager_listener.h +++ b/src/components/include/test/transport_manager/mock_transport_manager_listener.h @@ -81,6 +81,10 @@ class MockTransportManagerListener : public TransportManagerListener { MOCK_METHOD2(OnTMMessageSendFailed, void(const DataSendError& error, const ::protocol_handler::RawMessagePtr message)); + MOCK_METHOD2(OnDeviceSwitchingStart, + void(const DeviceUID& device_uid_from, + const DeviceUID& device_uid_to)); + MOCK_METHOD1(OnDeviceSwitchingFinish, void(const DeviceUID& device_uid)); }; } // namespace transport_manager_test diff --git a/src/components/include/test/transport_manager/mock_transport_manager_settings.h b/src/components/include/test/transport_manager/mock_transport_manager_settings.h index 00da2025dd..88112df003 100644 --- a/src/components/include/test/transport_manager/mock_transport_manager_settings.h +++ b/src/components/include/test/transport_manager/mock_transport_manager_settings.h @@ -59,6 +59,8 @@ class MockTransportManagerSettings MOCK_CONST_METHOD0(iap_system_config, const std::string&()); MOCK_CONST_METHOD0(iap2_system_config, const std::string&()); MOCK_CONST_METHOD0(iap_hub_connection_wait_timeout, uint32_t()); + MOCK_CONST_METHOD0(app_transport_change_timer, uint32_t()); + MOCK_CONST_METHOD0(app_transport_change_timer_addition, uint32_t()); }; } // namespace transport_manager_test diff --git a/src/components/include/test/transport_manager/transport_adapter/mock_transport_adapter.h b/src/components/include/test/transport_manager/transport_adapter/mock_transport_adapter.h index 16e6ddcb7a..c37c41d4f8 100644 --- a/src/components/include/test/transport_manager/transport_adapter/mock_transport_adapter.h +++ b/src/components/include/test/transport_manager/transport_adapter/mock_transport_adapter.h @@ -96,6 +96,13 @@ class MockTransportAdapter DeviceName, std::string(const ::transport_manager::DeviceUID& device_handle)); + MOCK_CONST_METHOD1(StopDevice, + void(const ::transport_manager::DeviceUID& device_id)); + MOCK_CONST_METHOD0(DoTransportSwitch, void()); + MOCK_METHOD1(DeviceSwitched, + void(const ::transport_manager::DeviceUID& device_handle)); + MOCK_CONST_METHOD0(GetSwitchableDevices, + transport_manager::SwitchableDevices()); #ifdef TELEMETRY_MONITOR MOCK_METHOD0(GetTelemetryObserver, ::transport_manager::TMTelemetryObserver*()); diff --git a/src/components/include/test/utils/test_async_waiter.h b/src/components/include/test/utils/test_async_waiter.h index 2d53d5d7c8..fee7672e93 100644 --- a/src/components/include/test/utils/test_async_waiter.h +++ b/src/components/include/test/utils/test_async_waiter.h @@ -30,7 +30,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#pragma once +#ifndef SRC_COMPONENTS_INCLUDE_TEST_UTILS_TEST_ASYNC_WAITER_H_ +#define SRC_COMPONENTS_INCLUDE_TEST_UTILS_TEST_ASYNC_WAITER_H_ #include <stdint.h> @@ -102,3 +103,4 @@ ACTION_P(NotifyTestAsyncWaiter, test_async_waiter) { } } // namespace test +#endif // SRC_COMPONENTS_INCLUDE_TEST_UTILS_TEST_ASYNC_WAITER_H_ diff --git a/src/components/include/transport_manager/common.h b/src/components/include/transport_manager/common.h index c1fc51dc8a..58bcf6bb17 100644 --- a/src/components/include/transport_manager/common.h +++ b/src/components/include/transport_manager/common.h @@ -35,6 +35,7 @@ #include <vector> #include <string> +#include <map> /** * @brief - transport_manager namespace @@ -58,7 +59,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. @@ -90,5 +91,12 @@ typedef int ApplicationHandle; * @brief Type definition for vector that contain ApplicationHandle variables. */ typedef std::vector<ApplicationHandle> ApplicationList; + +/** + * @brief SwitchableDevices defines list of devices having transport switch id + * i.e. able to switch their transport. Maps unique device id (MAC, serial etc.) + * to transport switch id (e.g. connection UUID for iAP2 transport) + */ +typedef std::map<DeviceUID, std::string> SwitchableDevices; } // namespace transport_manager #endif // SRC_COMPONENTS_INCLUDE_TRANSPORT_MANAGER_COMMON_H_ diff --git a/src/components/include/transport_manager/transport_adapter/device.h b/src/components/include/transport_manager/transport_adapter/device.h index 3adb6cd2e6..148e715050 100644 --- a/src/components/include/transport_manager/transport_adapter/device.h +++ b/src/components/include/transport_manager/transport_adapter/device.h @@ -58,6 +58,22 @@ class Device { : name_(name) , unique_device_id_(unique_device_id) , keep_on_disconnect_(false) {} + + /** + * Constructor for creating device supporting transport switch + * @brief Device constructor + * @param name Device name + * @param unique_device_id Unique device id + * @param transport_switch_id Id used for transport switching flow + */ + Device(const std::string& name, + const DeviceUID& unique_device_id, + std::string transport_switch_id) + : name_(name) + , unique_device_id_(unique_device_id) + , transport_switch_id_(transport_switch_id) + , keep_on_disconnect_(false) {} + /** * @brief Destructor. **/ @@ -114,6 +130,14 @@ class Device { keep_on_disconnect_ = keep_on_disconnect; } + /** + * @brief transport_switch_id Returns id used for transport switching + * flow of device. Filled if applicable, otherwise - empty. + */ + inline std::string transport_switch_id() const { + return transport_switch_id_; + } + private: /** * @brief Device user-friendly name. @@ -124,6 +148,11 @@ class Device { * @brief Unique device identifier across all devices. **/ DeviceUID unique_device_id_; + /** + * @brief transport_switch_id_ ID used to switch device from one to another + * transport. Filled if applicable, otherwise - empty + */ + std::string transport_switch_id_; /** * @brief If true, device will remain in list even if all its connections diff --git a/src/components/include/transport_manager/transport_adapter/transport_adapter.h b/src/components/include/transport_manager/transport_adapter/transport_adapter.h index ee726ff1d3..7f6d347535 100644 --- a/src/components/include/transport_manager/transport_adapter/transport_adapter.h +++ b/src/components/include/transport_manager/transport_adapter/transport_adapter.h @@ -56,10 +56,22 @@ namespace transport_adapter { class TransportAdapterListener; -// TODO(EZamakhov): cahnge to DeviceUID -// typedef std::string DeviceType; - -enum DeviceType { AOA, PASA_AOA, BLUETOOTH, PASA_BLUETOOTH, MME, TCP, UNKNOWN }; +/** + * @brief The DeviceType enum defines types based on available transport + * adapters + * @deprecated PASA_AOA, PASA_BLUETOOTH, MME + */ +enum DeviceType { + AOA, + PASA_AOA, + BLUETOOTH, + PASA_BLUETOOTH, + MME, + IOS_BT, + IOS_USB, + TCP, + UNKNOWN +}; typedef std::map<DeviceType, std::string> DeviceTypes; @@ -278,6 +290,28 @@ class TransportAdapter { */ virtual std::string DeviceName(const DeviceUID& device_id) const = 0; + /** + * @brief StopDevice Stop all activity on device without removing it from + * devices list + * @param device_id unique device identifier that has to be stopped. + */ + virtual void StopDevice(const DeviceUID& device_id) const = 0; + + /** + * @brief DoTransportSwitch notifies listeners of transport adapter events + * that transport switching is requested by system + */ + virtual void DoTransportSwitch() const = 0; + + /** + * @brief DeviceSwitched is triggered for adapter to proceed with possible + * further switching steps required on device side. E.g. to notify device + * on end of switching so it can disconnect transport being switched from. + * @param device_handle Device id to notify on event + */ + virtual void DeviceSwitched(const DeviceUID& device_handle) = 0; + + virtual SwitchableDevices GetSwitchableDevices() const = 0; #ifdef TELEMETRY_MONITOR /** * @brief Return Time metric observer diff --git a/src/components/include/transport_manager/transport_adapter/transport_adapter_event.h b/src/components/include/transport_manager/transport_adapter/transport_adapter_event.h index 7879a136b2..18f4ccb2d1 100644 --- a/src/components/include/transport_manager/transport_adapter/transport_adapter_event.h +++ b/src/components/include/transport_manager/transport_adapter/transport_adapter_event.h @@ -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_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, + ON_TRANSPORT_SWITCH_REQUESTED +}; + 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, @@ -64,10 +85,35 @@ class TransportAdapterEvent { , transport_adapter(adapter) , event_data(data) , event_error(error) {} + + /** + * DEPRECATED + * @brief Constructor. + * + * @param type Event type. + * @param transport_adapter Transport adapter + * @param device_handle Handle of device. + * @param application_id Handle of application. + * @param data Smart pointer to the raw message. + * @param error Error class that contains details of this error situation. + */ + TransportAdapterEvent(int type, + transport_adapter::TransportAdapter* adapter, + const DeviceUID& device_handle, + const ApplicationHandle& application_id, + ::protocol_handler::RawMessagePtr data, + BaseErrorPtr error) + : event_type(static_cast<EventTypeEnum>(type)) + , application_id(application_id) + , device_uid(device_handle) + , transport_adapter(adapter) + , event_data(data) + , event_error(error) {} + /** * @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_listener.h b/src/components/include/transport_manager/transport_manager_listener.h index e9f49e3152..d336eade45 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_from the id of the device which has to switch its + * transport + * @param device_uid_to the id of the device on new transport + */ + virtual void OnDeviceSwitchingStart(const DeviceUID& device_uid_from, + const DeviceUID& device_uid_to) = 0; + + /** + * @brief OnDeviceSwitchingFinish 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 OnDeviceSwitchingFinish(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..ca6c573a06 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,23 @@ class TransportManagerListenerEmpty : public TransportManagerListener { void OnDeviceRemoved(const DeviceInfo& device_info) OVERRIDE {} /** + * @brief OnDeviceSwitchingStart allows to notify listener that device is + * going to switch its connection. This default implementation does nothing. + * @param device_uid_from the id of the device which has to switch its + * transport + * @param device_uid_to the id of the device on new transport + */ + void OnDeviceSwitchingStart(const DeviceUID& device_uid_from, + const DeviceUID& device_uid_to) OVERRIDE {} + + /** + * @brief OnDeviceSwitchingFinish notifies listener that device reconnection + * fails due to some reason. This default implementation does nothing. + * @param device_uid the id for the device which is fails to reconnect. + */ + void OnDeviceSwitchingFinish(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/policy/policy_external/include/policy/cache_manager.h b/src/components/policy/policy_external/include/policy/cache_manager.h index aa5360d2b7..ef93ec72ab 100644 --- a/src/components/policy/policy_external/include/policy/cache_manager.h +++ b/src/components/policy/policy_external/include/policy/cache_manager.h @@ -701,6 +701,15 @@ class CacheManager : public CacheManagerInterface { const PolicySettings& get_settings() const; + /** + * @brief OnDeviceSwitching Processes existing policy permissions for devices + * switching transport + * @param device_id_from Device ID original + * @param device_id_to Device ID new + */ + void OnDeviceSwitching(const std::string& device_id_from, + const std::string& device_id_to) OVERRIDE; + private: std::string currentDateTime(); struct AppHMITypeToString { diff --git a/src/components/policy/policy_external/include/policy/cache_manager_interface.h b/src/components/policy/policy_external/include/policy/cache_manager_interface.h index ae1f8922ba..b9e9f73646 100644 --- a/src/components/policy/policy_external/include/policy/cache_manager_interface.h +++ b/src/components/policy/policy_external/include/policy/cache_manager_interface.h @@ -778,6 +778,15 @@ class CacheManagerInterface { virtual void SetExternalConsentForApp( const PermissionConsent& permissions) = 0; + /** + * @brief OnDeviceSwitching Processes existing policy permissions for devices + * switching transport + * @param device_id_from Device ID original + * @param device_id_to Device ID new + */ + virtual void OnDeviceSwitching(const std::string& device_id_from, + const std::string& device_id_to) = 0; + #ifdef BUILD_TESTS /** * @brief GetPT allows to obtain SharedPtr to PT. diff --git a/src/components/policy/policy_external/include/policy/policy_manager_impl.h b/src/components/policy/policy_external/include/policy/policy_manager_impl.h index 80ceb06e7e..97a2e60055 100644 --- a/src/components/policy/policy_external/include/policy/policy_manager_impl.h +++ b/src/components/policy/policy_external/include/policy/policy_manager_impl.h @@ -559,6 +559,9 @@ class PolicyManagerImpl : public PolicyManager { */ void OnAppRegisteredOnMobile(const std::string& application_id) OVERRIDE; + void OnDeviceSwitching(const std::string& device_id_from, + const std::string& device_id_to) OVERRIDE; + /** * @brief Gets meta information * @return meta information diff --git a/src/components/policy/policy_external/src/cache_manager.cc b/src/components/policy/policy_external/src/cache_manager.cc index b5e44014dd..a9b599f981 100644 --- a/src/components/policy/policy_external/src/cache_manager.cc +++ b/src/components/policy/policy_external/src/cache_manager.cc @@ -2629,6 +2629,31 @@ const PolicySettings& CacheManager::get_settings() const { return *settings_; } +void CacheManager::OnDeviceSwitching(const std::string& device_id_from, + const std::string& device_id_to) { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock auto_lock(cache_lock_); + auto device_data = *(pt_->policy_table.device_data); + + auto from = pt_->policy_table.device_data->find(device_id_from); + DCHECK_OR_RETURN_VOID(from != device_data.end()); + + auto to = pt_->policy_table.device_data->find(device_id_to); + DCHECK_OR_RETURN_VOID(to != device_data.end()); + + auto& consents_from = *(from->second.user_consent_records); + auto& consents_to = *(to->second.user_consent_records); + + LOG4CXX_DEBUG(logger_, + "Merging user consents from device: " + << device_id_from << " to device: " << device_id_to); + for (auto f = consents_from.begin(); f != consents_from.end(); ++f) { + const auto app_id = f->first; + LOG4CXX_DEBUG(logger_, "Updating permissions for key: " << app_id); + consents_to[app_id] = f->second; + } +} + CacheManager::BackgroundBackuper::BackgroundBackuper( CacheManager* cache_manager) : cache_manager_(cache_manager) diff --git a/src/components/policy/policy_external/src/policy_manager_impl.cc b/src/components/policy/policy_external/src/policy_manager_impl.cc index d50779383a..806b7e13ba 100644 --- a/src/components/policy/policy_external/src/policy_manager_impl.cc +++ b/src/components/policy/policy_external/src/policy_manager_impl.cc @@ -1681,6 +1681,12 @@ void PolicyManagerImpl::OnAppRegisteredOnMobile( SendNotificationOnPermissionsUpdated(application_id); } +void PolicyManagerImpl::OnDeviceSwitching(const std::string& device_id_from, + const std::string& device_id_to) { + LOG4CXX_AUTO_TRACE(logger_); + cache_->OnDeviceSwitching(device_id_from, device_id_to); +} + const MetaInfo PolicyManagerImpl::GetMetaInfo() const { LOG4CXX_AUTO_TRACE(logger_); return cache_->GetMetaInfo(); diff --git a/src/components/policy/policy_regular/include/policy/cache_manager.h b/src/components/policy/policy_regular/include/policy/cache_manager.h index 44827e2602..b711bf6ea2 100644 --- a/src/components/policy/policy_regular/include/policy/cache_manager.h +++ b/src/components/policy/policy_regular/include/policy/cache_manager.h @@ -701,6 +701,15 @@ class CacheManager : public CacheManagerInterface { return pt_; } + /** + * @brief OnDeviceSwitching Processes existing policy permissions for devices + * switching transport + * @param device_id_from Device ID original + * @param device_id_to Device ID new + */ + void OnDeviceSwitching(const std::string& device_id_from, + const std::string& device_id_to) OVERRIDE; + private: std::string currentDateTime(); struct AppHMITypeToString { diff --git a/src/components/policy/policy_regular/include/policy/cache_manager_interface.h b/src/components/policy/policy_regular/include/policy/cache_manager_interface.h index 9712b799dc..9f7c7318db 100644 --- a/src/components/policy/policy_regular/include/policy/cache_manager_interface.h +++ b/src/components/policy/policy_regular/include/policy/cache_manager_interface.h @@ -641,6 +641,15 @@ class CacheManagerInterface { * */ virtual utils::SharedPtr<policy_table::Table> pt() const = 0; + + /** + * @brief OnDeviceSwitching Processes existing policy permissions for devices + * switching transport + * @param device_id_from Device ID original + * @param device_id_to Device ID new + */ + virtual void OnDeviceSwitching(const std::string& device_id_from, + const std::string& device_id_to) = 0; }; typedef utils::SharedPtr<CacheManagerInterface> CacheManagerInterfaceSPtr; diff --git a/src/components/policy/policy_regular/include/policy/policy_manager_impl.h b/src/components/policy/policy_regular/include/policy/policy_manager_impl.h index 1b39392c0c..941db1a67f 100644 --- a/src/components/policy/policy_regular/include/policy/policy_manager_impl.h +++ b/src/components/policy/policy_regular/include/policy/policy_manager_impl.h @@ -553,6 +553,9 @@ class PolicyManagerImpl : public PolicyManager { */ void OnAppRegisteredOnMobile(const std::string& application_id) OVERRIDE; + void OnDeviceSwitching(const std::string& device_id_from, + const std::string& device_id_to) OVERRIDE; + /** * @brief RetrieveCertificate Allows to obtain certificate in order * to start secure connection. diff --git a/src/components/policy/policy_regular/src/cache_manager.cc b/src/components/policy/policy_regular/src/cache_manager.cc index 12b29e0675..94a33a1e04 100644 --- a/src/components/policy/policy_regular/src/cache_manager.cc +++ b/src/components/policy/policy_regular/src/cache_manager.cc @@ -1632,6 +1632,12 @@ const PolicySettings& CacheManager::get_settings() const { return *settings_; } +void CacheManager::OnDeviceSwitching(const std::string& device_id_from, + const std::string& device_id_to) { + LOG4CXX_AUTO_TRACE(logger_); + LOG4CXX_INFO(logger_, "Implementation does not support user consents."); +} + CacheManager::BackgroundBackuper::BackgroundBackuper( CacheManager* cache_manager) : cache_manager_(cache_manager) diff --git a/src/components/policy/policy_regular/src/policy_manager_impl.cc b/src/components/policy/policy_regular/src/policy_manager_impl.cc index 640b9c1457..055b57d985 100644 --- a/src/components/policy/policy_regular/src/policy_manager_impl.cc +++ b/src/components/policy/policy_regular/src/policy_manager_impl.cc @@ -366,6 +366,12 @@ void PolicyManagerImpl::OnAppRegisteredOnMobile( SendNotificationOnPermissionsUpdated(application_id); } +void PolicyManagerImpl::OnDeviceSwitching(const std::string& device_id_from, + const std::string& device_id_to) { + LOG4CXX_AUTO_TRACE(logger_); + cache_->OnDeviceSwitching(device_id_from, device_id_to); +} + const std::vector<std::string> PolicyManagerImpl::GetAppRequestTypes( const std::string policy_app_id) const { std::vector<std::string> request_types; diff --git a/src/components/remote_control/test/include/mock_application.h b/src/components/remote_control/test/include/mock_application.h index 3dc18e29f7..e50a869be7 100644 --- a/src/components/remote_control/test/include/mock_application.h +++ b/src/components/remote_control/test/include/mock_application.h @@ -59,10 +59,9 @@ class MockApplication : public ::application_manager::Application { MOCK_CONST_METHOD0(active_message, const smart_objects::SmartObject*()); MOCK_CONST_METHOD0(curHash, const std::string&()); MOCK_METHOD0(UpdateHash, void()); - // DEPRECATED - MOCK_CONST_METHOD0(flag_sending_hash_change_after_awake, bool()); - // DEPRECATED - MOCK_METHOD1(set_flag_sending_hash_change_after_awake, void(bool flag)); + DEPRECATED MOCK_CONST_METHOD0(flag_sending_hash_change_after_awake, bool()); + DEPRECATED MOCK_METHOD1(set_flag_sending_hash_change_after_awake, + void(bool flag)); MOCK_CONST_METHOD0(IsHashChangedDuringSuspend, bool()); MOCK_METHOD1(SetHashChangedDuringSuspend, void(const bool state)); MOCK_CONST_METHOD0(is_application_data_changed, bool()); @@ -164,6 +163,7 @@ class MockApplication : public ::application_manager::Application { bool(mobile_apis::FunctionID::eType cmd_id, ::application_manager::TLimitSource source)); MOCK_METHOD0(usage_report, ::application_manager::UsageStatistics&()); + MOCK_METHOD1(SetInitialState, void(::application_manager::HmiStatePtr state)); MOCK_METHOD1(SetRegularState, void(::application_manager::HmiStatePtr state)); MOCK_METHOD1(SetPostponedState, void(::application_manager::HmiStatePtr state)); diff --git a/src/components/transport_manager/CMakeLists.txt b/src/components/transport_manager/CMakeLists.txt index 8c7980a96a..8cd3fe617c 100644 --- a/src/components/transport_manager/CMakeLists.txt +++ b/src/components/transport_manager/CMakeLists.txt @@ -92,6 +92,13 @@ else() ) endif() +if(NOT BUILD_TESTS) + list (APPEND EXCLUDE_PATH + ${CMAKE_CURRENT_SOURCE_DIR}/include/iap2_emulation/iap2_transport_adapter.h + ${CMAKE_CURRENT_SOURCE_DIR}/src/iap2_emulation/iap2_transport_adapter.cc + ) +endif() + collect_sources(SOURCES "${PATHS}" "${EXCLUDE_PATHS}") add_library("TransportManager" ${SOURCES}) diff --git a/src/components/transport_manager/include/transport_manager/iap2_emulation/iap2_transport_adapter.h b/src/components/transport_manager/include/transport_manager/iap2_emulation/iap2_transport_adapter.h new file mode 100644 index 0000000000..36a2b374dd --- /dev/null +++ b/src/components/transport_manager/include/transport_manager/iap2_emulation/iap2_transport_adapter.h @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2017, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_IAP2_EMULATION_IAP2_TRANSPORT_ADAPTER_H_ +#define SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_IAP2_EMULATION_IAP2_TRANSPORT_ADAPTER_H_ + +#include "transport_manager/tcp/tcp_transport_adapter.h" +#include "transport_manager/transport_manager_settings.h" +#include "resumption/last_state.h" +#include "utils/macro.h" +#include "utils/threads/thread_delegate.h" + +namespace threads { +class Thread; +} + +namespace transport_manager { +namespace transport_adapter { + +/** + * @brief The IAP2BluetoothEmulationTransportAdapter class implements iAP2 + * Bluetooth transport over TCP + */ +class IAP2BluetoothEmulationTransportAdapter : public TcpTransportAdapter { + public: + /** + * @brief IAP2BluetoothEmulationTransportAdapter constructor + * @param port TCP port to listen on + * @param last_state LastState instance reference + * @param settings Settings reference + */ + IAP2BluetoothEmulationTransportAdapter( + const uint16_t port, + resumption::LastState& last_state, + const TransportManagerSettings& settings); + + /** + * @brief DeviceSwitched is called during switching from iAP2 Bluetooth to + * iAP2 USB transport. + * Currently there is no logic to switch back from iAP2 USB to iAP2 Bluetooth + * due to Bluetooth reconnection takes much time and this violates some Apple + * restrictions for iAP2 protocol, so if this method will be called - assert + * will be called + * @param device_handle Device handle of switched device + */ + void DeviceSwitched(const DeviceUID& device_handle) OVERRIDE; + + protected: + /** + * @brief GetDeviceType Provides SDL device type for transport adapter + * @return Device type + */ + DeviceType GetDeviceType() const OVERRIDE; +}; + +/** + * @brief The IAP2USBEmulationTransportAdapter class implements emulation of + * iAP2 USB transport over TCP + */ +class IAP2USBEmulationTransportAdapter : public TcpTransportAdapter { + public: + /** + * @brief IAP2USBEmulationTransportAdapter constructor + * @param port TCP port to listen on + * @param last_state LastState instance reference + * @param settings Settings reference + */ + IAP2USBEmulationTransportAdapter(const uint16_t port, + resumption::LastState& last_state, + const TransportManagerSettings& settings); + + /** + * Destructor + */ + ~IAP2USBEmulationTransportAdapter(); + + /** + * @brief DeviceSwitched is called during switching from iAP2 Bluetooth to + * iAP2 USB transport. Sends ACK signal for switching request. + * @param device_handle Device handle of switched device + */ + void DeviceSwitched(const DeviceUID& device_handle) OVERRIDE; + + protected: + /** + * @brief GetDeviceType Provides SDL device type for transport adapter + * @return Device type + */ + DeviceType GetDeviceType() const OVERRIDE; + + private: + /** + * @brief The IAPSignalHandlerDelegate class handles signals from the system + * to start transport switching flow + */ + class IAPSignalHandlerDelegate : public threads::ThreadDelegate { + public: + /** + * @brief IAPSignalHandlerDelegate Constructor + * @param adapter Pointer to iAP2 USB adapter + */ + IAPSignalHandlerDelegate(IAP2USBEmulationTransportAdapter& adapter); + + /** + * @brief threadMain Main loop to track incoming signals + */ + void threadMain() OVERRIDE; + + /** + * @brief exitThreadMain Stops main loop + */ + void exitThreadMain() OVERRIDE; + + private: + /** + * @brief adapter_ Reference to owning adapter + */ + IAP2USBEmulationTransportAdapter& adapter_; + + /** + * @brief run_flag_ Flag defines whether main loop is active + */ + bool run_flag_; + + /** + * @brief in_ Input signals channel descriptor + */ + int in_; + }; + + threads::Thread* signal_handler_; + int out_; +}; +} // namespace transport_adapter +} // namespace transport_manager +#endif // SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_IAP2_EMULATION_IAP2_TRANSPORT_ADAPTER_H_ diff --git a/src/components/transport_manager/include/transport_manager/tcp/tcp_device.h b/src/components/transport_manager/include/transport_manager/tcp/tcp_device.h index 981ba9f6ee..7aa0b72687 100644 --- a/src/components/transport_manager/include/transport_manager/tcp/tcp_device.h +++ b/src/components/transport_manager/include/transport_manager/tcp/tcp_device.h @@ -66,6 +66,18 @@ class TcpDevice : public Device { **/ TcpDevice(const in_addr_t& in_addr, const std::string& name); +#if defined(BUILD_TESTS) + /** + * @brief TcpDevice + * @param in_addr IP address of device + * @param device_uid Unique device id + * @param transport_switch_id Id used for transport switching + */ + TcpDevice(const in_addr_t& in_addr, + const std::string& device_uid, + const std::string& transport_switch_id); +#endif + virtual ~TcpDevice(); /** 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..2b1ada79ad 100644 --- a/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_impl.h +++ b/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_impl.h @@ -400,6 +400,26 @@ class TransportAdapterImpl : public TransportAdapter, const DataSendError& error) OVERRIDE; /** + * @brief DoTransportSwitch notifies listeners of transport adapter events + * that transport switching is requested by system + */ + void DoTransportSwitch() const OVERRIDE; + + /** + * @brief DeviceSwitched Notifies system on successful transport switch for + * particular device + * @param device_handle Device handle of switched device + */ + void DeviceSwitched(const DeviceUID& device_handle) OVERRIDE; + + /** + * @brief GetSwitchableDevices Provides list of devices able to switch their + * transport (e.g. iAP2 Bluetooth to iAP2 USB). + * @return + */ + SwitchableDevices GetSwitchableDevices() const OVERRIDE; + + /** * @brief Return name of device. * * @param device_id Device unique identifier. @@ -409,6 +429,13 @@ class TransportAdapterImpl : public TransportAdapter, std::string DeviceName(const DeviceUID& device_id) const OVERRIDE; /** + * @brief StopDevice looks for specific device in devices list and calls + * Stop() interface of that device + * @param device_id unique device identifier that has to be stopped. + */ + void StopDevice(const DeviceUID& device_id) const OVERRIDE; + + /** * @brief Allows to obtain connection type used by device. * @return connection type. */ diff --git a/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_listener.h b/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_listener.h index 0a1eeb6b4a..424fa53dea 100644 --- a/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_listener.h +++ b/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_listener.h @@ -146,6 +146,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, @@ -269,6 +270,13 @@ class TransportAdapterListener { virtual void OnCommunicationError(const TransportAdapter* transport_adapter, const DeviceUID& device_handle, const ApplicationHandle& app_handle) = 0; + /** + * @brief OnTransportSwitchRequested notifies on received signal to start + * transport switching flow (at the moment Bluetooth to USB only) + * @param transport_adapter Transport adapter who received the signal + */ + virtual void OnTransportSwitchRequested( + const TransportAdapter* transport_adapter) = 0; }; } // transport_adapter namespace diff --git a/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_listener_impl.h b/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_listener_impl.h index a7cd544563..8a8031c3cf 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. @@ -283,7 +263,14 @@ class TransportAdapterListenerImpl */ virtual void OnCommunicationError(const TransportAdapter* adapter, const DeviceUID& device, - const ApplicationHandle& app_id); + const ApplicationHandle& app_id) OVERRIDE; + + /** + * @brief OnTransportSwitchRequested notifies on received signal to start + * transport switching flow (at the moment Bluetooth to USB only) + * @param transport_adapter Transport adapter who received the signal + */ + void OnTransportSwitchRequested(const TransportAdapter* adapter) OVERRIDE; private: TransportManager* transport_manager_; diff --git a/src/components/transport_manager/include/transport_manager/transport_manager_impl.h b/src/components/transport_manager/include/transport_manager/transport_manager_impl.h index 4dd74086be..eaa71ce3bb 100644 --- a/src/components/transport_manager/include/transport_manager/transport_manager_impl.h +++ b/src/components/transport_manager/include/transport_manager/transport_manager_impl.h @@ -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, @@ -241,11 +245,20 @@ class TransportManagerImpl int Visibility(const bool& on_off) const OVERRIDE; /** + * DEPRECATED + * Must be moved under 'private' section * @brief Updates total device list with info from specific transport adapter. * @param ta Transport adapter */ void UpdateDeviceList(TransportAdapter* ta); + /** + * @brief OnDeviceListUpdated updates device list and sends appropriate + * notifications to listeners in case of something is changed + * @param ta Transport adapter to check for updated devices state + */ + void OnDeviceListUpdated(TransportAdapter* ta); + #ifdef TELEMETRY_MONITOR /** * @brief Setup observer for time metric. @@ -307,44 +320,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 +375,15 @@ class TransportManagerImpl */ Handle2GUIDConverter converter_; +#ifdef BUILD_TESTS + public: + Handle2GUIDConverter& get_converter() { + return converter_; + } + + private: +#endif // BUILD_TESTS + explicit TransportManagerImpl(const TransportManagerImpl&); int connection_id_counter_; sync_primitives::RWLock connections_lock_; @@ -372,13 +403,70 @@ 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); + + /** + * @brief TryDeviceSwitch in case USB device is connected and there is + * appropriate Bluetooth device with same UUID stops Bluetooth device and + * initiates switching sequence for upper layers. Also starts timer to wait + * for sequence to complete. + * @param ta Transport adapter having device to try switching sequence + * At the moment implementation implies only IAP2-Bluetooth to IAP2-USB + * switching + */ + void TryDeviceSwitch(TransportAdapter* ta); + void AddDataToContainer( ConnectionUID id, std::map<ConnectionUID, std::pair<unsigned int, unsigned char*> >& @@ -394,11 +482,25 @@ class TransportManagerImpl unsigned int frame_size, unsigned char** frame); - void OnDeviceListUpdated(TransportAdapter* ta); void DisconnectAllDevices(); void TerminateAllAdapters(); int InitAllAdapters(); static Connection convert(const ConnectionInternal& p); + + /** + * @brief ReconnectionTimeout notifies upper layers on switching sequence + * timeout expiration + */ + 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 + * @return True if mapping has been updated, otherwise - false + */ + bool UpdateDeviceMapping(TransportAdapter* ta); }; // class TransportManagerImpl } // namespace transport_manager #endif // SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_TRANSPORT_MANAGER_IMPL_H_ diff --git a/src/components/transport_manager/src/iap2_emulation/iap2_transport_adapter.cc b/src/components/transport_manager/src/iap2_emulation/iap2_transport_adapter.cc new file mode 100644 index 0000000000..4704f7dd27 --- /dev/null +++ b/src/components/transport_manager/src/iap2_emulation/iap2_transport_adapter.cc @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2017, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "transport_manager/iap2_emulation/iap2_transport_adapter.h" + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdio.h> + +#include "utils/threads/thread.h" +#include "utils/file_system.h" + +namespace { +static const mode_t mode = 0666; +static const auto in_signals_channel = "iap_signals_in"; +static const auto out_signals_channel = "iap_signals_out"; +} // namespace + +namespace transport_manager { +namespace transport_adapter { + +CREATE_LOGGERPTR_GLOBAL(logger_, "IAP2Emulation"); + +IAP2BluetoothEmulationTransportAdapter::IAP2BluetoothEmulationTransportAdapter( + const uint16_t port, + resumption::LastState& last_state, + const TransportManagerSettings& settings) + : TcpTransportAdapter(port, last_state, settings) {} + +void IAP2BluetoothEmulationTransportAdapter::DeviceSwitched( + const DeviceUID& device_handle) { + LOG4CXX_AUTO_TRACE(logger_); + UNUSED(device_handle); + DCHECK(!"Switching for iAP2 Bluetooth is not supported."); +} + +DeviceType IAP2BluetoothEmulationTransportAdapter::GetDeviceType() const { + return IOS_BT; +} + +IAP2USBEmulationTransportAdapter::IAP2USBEmulationTransportAdapter( + const uint16_t port, + resumption::LastState& last_state, + const TransportManagerSettings& settings) + : TcpTransportAdapter(port, last_state, settings), out_(0) { + auto delegate = new IAPSignalHandlerDelegate(*this); + signal_handler_ = threads::CreateThread("iAP signal handler", delegate); + signal_handler_->start(); + const auto result = mkfifo(out_signals_channel, mode); + LOG4CXX_DEBUG(logger_, "Out signals channel creation result: " << result); +} + +IAP2USBEmulationTransportAdapter::~IAP2USBEmulationTransportAdapter() { + signal_handler_->join(); + auto delegate = signal_handler_->delegate(); + signal_handler_->set_delegate(NULL); + delete delegate; + threads::DeleteThread(signal_handler_); + LOG4CXX_DEBUG(logger_, "Out close result: " << close(out_)); + LOG4CXX_DEBUG(logger_, "Out unlink result: " << unlink(out_signals_channel)); +} + +void IAP2USBEmulationTransportAdapter::DeviceSwitched( + const DeviceUID& device_handle) { + LOG4CXX_AUTO_TRACE(logger_); + UNUSED(device_handle); + const auto switch_signal_ack = std::string("SDL_TRANSPORT_SWITCH_ACK\n"); + + auto out_ = open(out_signals_channel, O_WRONLY); + LOG4CXX_DEBUG(logger_, "Out channel descriptor: " << out_); + + const auto bytes = + write(out_, switch_signal_ack.c_str(), switch_signal_ack.size()); + UNUSED(bytes); + LOG4CXX_DEBUG(logger_, "Written bytes to out: " << bytes); + + LOG4CXX_DEBUG(logger_, "Switching signal ACK is sent"); + LOG4CXX_DEBUG(logger_, "iAP2 USB device is switched with iAP2 Bluetooth"); +} + +DeviceType IAP2USBEmulationTransportAdapter::GetDeviceType() const { + return IOS_USB; +} + +IAP2USBEmulationTransportAdapter::IAPSignalHandlerDelegate:: + IAPSignalHandlerDelegate(IAP2USBEmulationTransportAdapter& adapter) + : adapter_(adapter), run_flag_(true), in_(0) { + const auto result = mkfifo(in_signals_channel, mode); + LOG4CXX_DEBUG(logger_, "In signals channel creation result: " << result); +} + +void IAP2USBEmulationTransportAdapter::IAPSignalHandlerDelegate::threadMain() { + LOG4CXX_AUTO_TRACE(logger_); + LOG4CXX_DEBUG(logger_, "Signal handling is started"); + const auto switch_signal = "SDL_TRANSPORT_SWITCH"; + LOG4CXX_DEBUG(logger_, "Waiting for signal: " << switch_signal); + + in_ = open(in_signals_channel, O_RDONLY); + LOG4CXX_DEBUG(logger_, "In channel descriptor: " << in_); + + const auto size = 32; + while (run_flag_) { + char buffer[size]; + auto bytes = read(in_, &buffer, size); + if (0 == bytes) { + continue; + } + if (-1 == bytes) { + LOG4CXX_DEBUG(logger_, "Error during input pipe read"); + break; + } + LOG4CXX_DEBUG(logger_, "Read in bytes: " << bytes); + std::string str(buffer); + if (std::string::npos != str.find(switch_signal)) { + LOG4CXX_DEBUG(logger_, "Switch signal received."); + adapter_.DoTransportSwitch(); + } + } + + LOG4CXX_DEBUG(logger_, "In close result: " << close(in_)); + LOG4CXX_DEBUG(logger_, "In unlink result: " << unlink(in_signals_channel)); +} + +void IAP2USBEmulationTransportAdapter::IAPSignalHandlerDelegate:: + exitThreadMain() { + LOG4CXX_AUTO_TRACE(logger_); + LOG4CXX_DEBUG(logger_, "Stopping signal handling."); + run_flag_ = false; + ThreadDelegate::exitThreadMain(); +} +} +} // namespace transport_manager::transport_adapter diff --git a/src/components/transport_manager/src/tcp/tcp_client_listener.cc b/src/components/transport_manager/src/tcp/tcp_client_listener.cc index 52a566c5ff..207149eb8c 100644 --- a/src/components/transport_manager/src/tcp/tcp_client_listener.cc +++ b/src/components/transport_manager/src/tcp/tcp_client_listener.cc @@ -230,13 +230,23 @@ void TcpClientListener::Loop() { inet_ntoa(client_address.sin_addr), sizeof(device_name) / sizeof(device_name[0])); LOG4CXX_INFO(logger_, "Connected client " << device_name); + LOG4CXX_INFO(logger_, "Port is: " << port_); if (enable_keepalive_) { SetKeepaliveOptions(connection_fd); } + const auto device_uid = + device_name + std::string(":") + std::to_string(port_); + +#if defined(BUILD_TESTS) + TcpDevice* tcp_device = + new TcpDevice(client_address.sin_addr.s_addr, device_uid, device_name); +#else TcpDevice* tcp_device = - new TcpDevice(client_address.sin_addr.s_addr, device_name); + new TcpDevice(client_address.sin_addr.s_addr, device_uid); +#endif // BUILD_TESTS + DeviceSptr device = controller_->AddDevice(tcp_device); tcp_device = static_cast<TcpDevice*>(device.get()); const ApplicationHandle app_handle = diff --git a/src/components/transport_manager/src/tcp/tcp_device.cc b/src/components/transport_manager/src/tcp/tcp_device.cc index d3f132759a..dbcb5d38cb 100644 --- a/src/components/transport_manager/src/tcp/tcp_device.cc +++ b/src/components/transport_manager/src/tcp/tcp_device.cc @@ -46,6 +46,23 @@ TcpDevice::TcpDevice(const in_addr_t& in_addr, const std::string& name) LOG4CXX_AUTO_TRACE(logger_); } +#if defined(BUILD_TESTS) +TcpDevice::TcpDevice(const in_addr_t& in_addr, + const std::string& device_uid, + const std::string& transport_switch_id) + : Device(device_uid, device_uid, transport_switch_id) + , applications_mutex_() + , in_addr_(in_addr) + , last_handle_(0) { + LOG4CXX_AUTO_TRACE(logger_); + LOG4CXX_DEBUG(logger_, + "Device created with transport switch emulation support."); + LOG4CXX_DEBUG(logger_, + "Device parameters: " << device_uid << " / " + << transport_switch_id); +} +#endif // BUILD_TESTS + bool TcpDevice::IsSameAs(const Device* other) const { LOG4CXX_AUTO_TRACE(logger_); LOG4CXX_DEBUG(logger_, "Device: " << other); 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..9fb0921c4b 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 @@ -45,13 +45,16 @@ namespace transport_adapter { CREATE_LOGGERPTR_GLOBAL(logger_, "TransportManager") namespace { +// @deprecated DeviceTypes: PASA_AOA, PASA_BLUETOOTH, MME 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::BLUETOOTH, std::string("BLUETOOTH")), + std::make_pair(DeviceType::PASA_BLUETOOTH, std::string("BLUETOOTH")), + std::make_pair(DeviceType::MME, std::string("USB_IOS")), + std::make_pair(DeviceType::IOS_BT, std::string("BLUETOOTH_IOS")), + std::make_pair(DeviceType::IOS_USB, std::string("USB_IOS")), + std::make_pair(DeviceType::TCP, std::string("WIFI"))}; } TransportAdapterImpl::TransportAdapterImpl( @@ -502,15 +505,13 @@ void TransportAdapterImpl::SearchDeviceFailed(const SearchDeviceError& error) { } bool TransportAdapterImpl::IsSearchDevicesSupported() const { - LOG4CXX_TRACE(logger_, "enter"); + LOG4CXX_AUTO_TRACE(logger_); return device_scanner_ != 0; - LOG4CXX_TRACE(logger_, "exit"); } bool TransportAdapterImpl::IsServerOriginatedConnectSupported() const { - LOG4CXX_TRACE(logger_, "enter"); + LOG4CXX_AUTO_TRACE(logger_); return server_connection_factory_ != 0; - LOG4CXX_TRACE(logger_, "exit"); } bool TransportAdapterImpl::IsClientOriginatedConnectSupported() const { @@ -694,6 +695,23 @@ void TransportAdapterImpl::DataSendFailed( LOG4CXX_TRACE(logger_, "exit"); } +void TransportAdapterImpl::DoTransportSwitch() const { + LOG4CXX_AUTO_TRACE(logger_); + std::for_each( + listeners_.begin(), + listeners_.end(), + std::bind2nd( + std::mem_fun(&TransportAdapterListener::OnTransportSwitchRequested), + this)); +} + +void TransportAdapterImpl::DeviceSwitched(const DeviceUID& device_handle) { + LOG4CXX_DEBUG(logger_, + "Switching is not implemented for that adapter type " + << 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,10 +882,40 @@ 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()]; } +SwitchableDevices TransportAdapterImpl::GetSwitchableDevices() const { + LOG4CXX_AUTO_TRACE(logger_); + SwitchableDevices devices; + sync_primitives::AutoLock locker(devices_mutex_); + for (DeviceMap::const_iterator it = devices_.begin(); it != devices_.end(); + ++it) { + const auto device_uid = it->first; + const auto device = it->second; + const auto transport_switch_id = device->transport_switch_id(); + if (transport_switch_id.empty()) { + LOG4CXX_DEBUG(logger_, + "Device is not suitable for switching: " << device_uid); + continue; + } + LOG4CXX_DEBUG(logger_, "Device is suitable for switching: " << device_uid); + devices.insert(std::make_pair(device_uid, transport_switch_id)); + } + LOG4CXX_INFO(logger_, + "Found number of switchable devices: " << devices.size()); + return devices; +} + #ifdef TELEMETRY_MONITOR void TransportAdapterImpl::SetTelemetryObserver(TMTelemetryObserver* observer) { metric_observer_ = observer; diff --git a/src/components/transport_manager/src/transport_adapter/transport_adapter_listener_impl.cc b/src/components/transport_manager/src/transport_adapter/transport_adapter_listener_impl.cc index 2ab19ade86..f1181ce921 100644 --- a/src/components/transport_manager/src/transport_adapter/transport_adapter_listener_impl.cc +++ b/src/components/transport_manager/src/transport_adapter/transport_adapter_listener_impl.cc @@ -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)) { @@ -105,7 +102,7 @@ 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 +123,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 +147,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 +168,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 +192,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 +223,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 +247,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 +270,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 +296,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 +325,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,18 +346,34 @@ void TransportAdapterListenerImpl::OnCommunicationError( LOG4CXX_TRACE(logger_, "enter. adapter: " << adapter << ", device: " << &device << ", application_id: " << &app_id); + 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)) { + LOG4CXX_WARN(logger_, "Failed to receive event from device"); + } + LOG4CXX_TRACE(logger_, "exit"); +} + +void TransportAdapterListenerImpl::OnTransportSwitchRequested( + const transport_adapter::TransportAdapter* adapter) { + LOG4CXX_AUTO_TRACE(logger_); const TransportAdapterEvent event( - TransportAdapterListenerImpl::EventTypeEnum::ON_COMMUNICATION_ERROR, + EventTypeEnum::ON_TRANSPORT_SWITCH_REQUESTED, transport_adapter_, - device, - app_id, + "", + 0, ::protocol_handler::RawMessagePtr(), - BaseErrorPtr(new BaseError())); + BaseErrorPtr()); if (transport_manager_ != NULL && transport_manager::E_SUCCESS != transport_manager_->ReceiveEventFromDevice(event)) { LOG4CXX_WARN(logger_, "Failed to receive event from device"); } - LOG4CXX_TRACE(logger_, "exit"); } } // namespace transport_manager diff --git a/src/components/transport_manager/src/transport_manager_default.cc b/src/components/transport_manager/src/transport_manager_default.cc index 31f398233b..196ad09af4 100644 --- a/src/components/transport_manager/src/transport_manager_default.cc +++ b/src/components/transport_manager/src/transport_manager_default.cc @@ -44,6 +44,10 @@ #include "transport_manager/usb/usb_aoa_adapter.h" #endif // USB_SUPPORT +#if defined(BUILD_TESTS) +#include "transport_manager/iap2_emulation/iap2_transport_adapter.h" +#endif // BUILD_TEST + namespace transport_manager { CREATE_LOGGERPTR_GLOBAL(logger_, "TransportManager") @@ -97,6 +101,23 @@ int TransportManagerDefault::Init(resumption::LastState& last_state) { ta_usb = NULL; #endif // USB_SUPPORT +#if defined BUILD_TESTS + const uint16_t iap2_bt_emu_port = 23456; + transport_adapter::IAP2BluetoothEmulationTransportAdapter* + iap2_bt_emu_adapter = + new transport_adapter::IAP2BluetoothEmulationTransportAdapter( + iap2_bt_emu_port, last_state, get_settings()); + + AddTransportAdapter(iap2_bt_emu_adapter); + + const uint16_t iap2_usb_emu_port = 34567; + transport_adapter::IAP2USBEmulationTransportAdapter* iap2_usb_emu_adapter = + new transport_adapter::IAP2USBEmulationTransportAdapter( + iap2_usb_emu_port, last_state, get_settings()); + + AddTransportAdapter(iap2_usb_emu_adapter); +#endif // BUILD_TEST + LOG4CXX_TRACE(logger_, "exit with E_SUCCESS"); return E_SUCCESS; } diff --git a/src/components/transport_manager/src/transport_manager_impl.cc b/src/components/transport_manager/src/transport_manager_impl.cc index 831ff0980e..03e6bd58f6 100644 --- a/src/components/transport_manager/src/transport_manager_impl.cc +++ b/src/components/transport_manager/src/transport_manager_impl.cc @@ -55,6 +55,17 @@ using ::transport_manager::transport_adapter::TransportAdapter; +namespace { +struct ConnectionFinder { + const uint32_t id_; + explicit ConnectionFinder(const uint32_t id) : id_(id) {} + bool operator()(const transport_manager::TransportManagerImpl::Connection& + connection) const { + return id_ == connection.id; + } +}; +} // namespace + namespace transport_manager { CREATE_LOGGERPTR_GLOBAL(logger_, "TransportManager") @@ -82,7 +93,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 +123,12 @@ TransportManagerImpl::~TransportManagerImpl() { LOG4CXX_INFO(logger_, "TransportManager object destroyed"); } +void TransportManagerImpl::ReconnectionTimeout() { + LOG4CXX_AUTO_TRACE(logger_); + RaiseEvent(&TransportManagerListener::OnDeviceSwitchingFinish, + device_to_reconnect_); +} + int TransportManagerImpl::ConnectDevice(const DeviceHandle device_handle) { LOG4CXX_TRACE(logger_, "enter. DeviceHandle: " << &device_handle); if (!this->is_initialized_) { @@ -562,7 +583,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 +648,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 +699,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 +712,201 @@ TransportManagerImpl::ConnectionInternal* TransportManagerImpl::GetConnection( return NULL; } -void TransportManagerImpl::OnDeviceListUpdated(TransportAdapter* ta) { - LOG4CXX_TRACE(logger_, "enter. TransportAdapter: " << ta); - const DeviceList device_list = ta->GetDeviceList(); - LOG4CXX_DEBUG(logger_, "DEVICE_LIST_UPDATED " << device_list.size()); - for (DeviceList::const_iterator it = device_list.begin(); - it != device_list.end(); +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; +} + +namespace { + +struct IOSBTAdapterFinder { + bool operator()(const std::vector<TransportAdapter*>::value_type& i) const { + return i->GetDeviceType() == transport_adapter::DeviceType::IOS_BT; + } +}; + +struct SwitchableFinder { + explicit SwitchableFinder(SwitchableDevices::const_iterator what) + : what_(what) {} + bool operator()(const SwitchableDevices::value_type& i) const { + return what_->second == i.second; + } + + private: + SwitchableDevices::const_iterator what_; +}; + +} // namespace + +void TransportManagerImpl::TryDeviceSwitch( + transport_adapter::TransportAdapter* adapter) { + LOG4CXX_AUTO_TRACE(logger_); + if (adapter->GetDeviceType() != transport_adapter::DeviceType::IOS_USB) { + LOG4CXX_ERROR(logger_, "Switching requested not from iAP-USB transport."); + return; + } + + const auto ios_bt_adapter = std::find_if(transport_adapters_.begin(), + transport_adapters_.end(), + IOSBTAdapterFinder()); + + if (transport_adapters_.end() == ios_bt_adapter) { + LOG4CXX_WARN( + logger_, + "There is no iAP2 Bluetooth adapter found. Switching is not possible."); + return; + } + + const SwitchableDevices usb_switchable_devices = + adapter->GetSwitchableDevices(); + const auto bt_switchable_devices = (*ios_bt_adapter)->GetSwitchableDevices(); + auto bt = bt_switchable_devices.end(); + auto usb = usb_switchable_devices.begin(); + for (; usb != usb_switchable_devices.end(); ++usb) { + SwitchableFinder finder(usb); + bt = std::find_if( + bt_switchable_devices.begin(), bt_switchable_devices.end(), finder); + + if (bt != bt_switchable_devices.end()) { + break; + } + } + + if (bt_switchable_devices.end() == bt) { + LOG4CXX_WARN(logger_, + "No suitable for switching iAP2 Bluetooth device found."); + return; + } + + LOG4CXX_DEBUG(logger_, + "Found UUID suitable for transport switching: " << bt->second); + LOG4CXX_DEBUG( + logger_, "Device to switch from: " << bt->first << " to: " << usb->first); + + sync_primitives::AutoWriteLock lock(device_to_adapter_map_lock_); + + const auto bt_device_uid = bt->first; + const auto device_to_switch = device_to_adapter_map_.find(bt_device_uid); + if (device_to_adapter_map_.end() == device_to_switch) { + LOG4CXX_ERROR(logger_, + "There is no known device found with UID " + << bt_device_uid + << " . Transport switching is not possible."); + DCHECK_OR_RETURN_VOID(false); + return; + } + + const auto usb_uid = usb->first; + const auto bt_uid = device_to_switch->first; + const auto bt_adapter = device_to_switch->second; + + LOG4CXX_DEBUG(logger_, + "Known device with UID " + << bt_uid << " is appropriate for transport switching."); + + RaiseEvent( + &TransportManagerListener::OnDeviceSwitchingStart, bt_uid, usb_uid); + + bt_adapter->StopDevice(bt_uid); + adapter->DeviceSwitched(usb_uid); + + DeactivateDeviceConnections(bt_uid); + + device_to_reconnect_ = bt_uid; + + const uint32_t timeout = get_settings().app_transport_change_timer() + + get_settings().app_transport_change_timer_addition(); + device_switch_timer_.Start(timeout, timer::kSingleShot); + + LOG4CXX_DEBUG(logger_, + "Device switch for device id " << bt_uid << " is done."); + return; +} + +bool TransportManagerImpl::UpdateDeviceMapping( + transport_adapter::TransportAdapter* ta) { + const DeviceList adapter_device_list = ta->GetDeviceList(); + LOG4CXX_DEBUG(logger_, "DEVICE_LIST_UPDATED " << adapter_device_list.size()); + + sync_primitives::AutoWriteLock lock(device_to_adapter_map_lock_); + + 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;) { + const auto adapter = item->second; + if (adapter != ta) { + ++item; + continue; + } + + const auto device_uid = item->first; + if (adapter_device_list.end() != std::find(adapter_device_list.begin(), + adapter_device_list.end(), + device_uid)) { + ++item; + continue; + } + + 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 = adapter_device_list.begin(); + it != adapter_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()); + const auto device_uid = *it; + const auto result = + device_to_adapter_map_.insert(std::make_pair(device_uid, ta)); + if (!result.second) { + LOG4CXX_WARN(logger_, + "Device UID " + << device_uid + << " is known already. Processing skipped." + "Connection type is: " << ta->GetConnectionType()); + continue; + } + DeviceHandle device_handle = + converter_.UidToHandle(device_uid, ta->GetConnectionType()); + DeviceInfo info(device_handle, + device_uid, + ta->DeviceName(device_uid), + ta->GetConnectionType()); RaiseEvent(&TransportManagerListener::OnDeviceFound, info); } + + LOG4CXX_DEBUG(logger_, + "After update. Device map size is " + << device_to_adapter_map_.size()); + + return true; +} + +void TransportManagerImpl::OnDeviceListUpdated(TransportAdapter* ta) { + LOG4CXX_TRACE(logger_, "enter. TransportAdapter: " << ta); + if (!UpdateDeviceMapping(ta)) { + LOG4CXX_ERROR(logger_, "Device list update failed."); + return; + } UpdateDeviceList(ta); std::vector<DeviceInfo> device_infos; device_list_lock_.AcquireForReading(); @@ -697,37 +916,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_TRANSPORT_SWITCH_REQUESTED: { + TryDeviceSwitch(event.transport_adapter); + LOG4CXX_DEBUG(logger_, "event_type = ON_TRANSPORT_SWITCH_REQUESTED"); + break; + } + case EventTypeEnum::ON_FIND_NEW_APPLICATIONS_REQUEST: { RaiseEvent(&TransportManagerListener::OnFindNewApplicationsRequest); LOG4CXX_DEBUG(logger_, "event_type = ON_FIND_NEW_APPLICATIONS_REQUEST"); 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 +969,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 +982,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 +1001,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 +1037,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 +1072,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 +1099,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 +1118,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 +1209,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 +1226,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 diff --git a/src/components/transport_manager/src/usb/usb_aoa_adapter.cc b/src/components/transport_manager/src/usb/usb_aoa_adapter.cc index 3462b557ce..b7faf1ef6b 100644 --- a/src/components/transport_manager/src/usb/usb_aoa_adapter.cc +++ b/src/components/transport_manager/src/usb/usb_aoa_adapter.cc @@ -60,7 +60,7 @@ UsbAoaAdapter::UsbAoaAdapter(resumption::LastState& last_state, UsbAoaAdapter::~UsbAoaAdapter() {} DeviceType UsbAoaAdapter::GetDeviceType() const { - return PASA_AOA; + return AOA; } bool UsbAoaAdapter::IsInitialised() const { diff --git a/src/components/transport_manager/test/include/transport_manager/transport_adapter/mock_transport_adapter_impl.h b/src/components/transport_manager/test/include/transport_manager/transport_adapter/mock_transport_adapter_impl.h index 0636448e58..384f55605a 100644 --- a/src/components/transport_manager/test/include/transport_manager/transport_adapter/mock_transport_adapter_impl.h +++ b/src/components/transport_manager/test/include/transport_manager/transport_adapter/mock_transport_adapter_impl.h @@ -68,7 +68,7 @@ class MockTransportAdapterImpl : public TransportAdapterImpl { const ApplicationHandle& app_handle) { return this->FindEstablishedConnection(device_handle, app_handle); } - virtual ~MockTransportAdapterImpl(){}; + virtual ~MockTransportAdapterImpl() {} virtual DeviceType GetDeviceType() const { return DeviceType::UNKNOWN; @@ -76,6 +76,9 @@ class MockTransportAdapterImpl : public TransportAdapterImpl { MOCK_CONST_METHOD0(Store, void()); MOCK_METHOD0(Restore, bool()); + MOCK_CONST_METHOD1(FindDevice, + transport_manager::transport_adapter::DeviceSptr( + const DeviceUID& device_id)); }; } // namespace transport_manager_test diff --git a/src/components/transport_manager/test/include/transport_manager/transport_adapter/mock_transport_adapter_listener.h b/src/components/transport_manager/test/include/transport_manager/transport_adapter/mock_transport_adapter_listener.h index 8302a63beb..03e7630e8b 100644 --- a/src/components/transport_manager/test/include/transport_manager/transport_adapter/mock_transport_adapter_listener.h +++ b/src/components/transport_manager/test/include/transport_manager/transport_adapter/mock_transport_adapter_listener.h @@ -120,6 +120,8 @@ class MockTransportAdapterListener : public TransportAdapterListener { void(const TransportAdapter*, const DeviceUID&, const ApplicationHandle&)); + MOCK_METHOD1(OnTransportSwitchRequested, + void(const TransportAdapter* transport_adapter)); }; } // namespace transport_manager_test diff --git a/src/components/transport_manager/test/transport_adapter_listener_test.cc b/src/components/transport_manager/test/transport_adapter_listener_test.cc index c8e9af7d63..14b8850b49 100644 --- a/src/components/transport_manager/test/transport_adapter_listener_test.cc +++ b/src/components/transport_manager/test/transport_adapter_listener_test.cc @@ -45,16 +45,16 @@ using namespace ::transport_manager; class TransportAdapterListenerTest : public ::testing::Test { public: TransportAdapterListenerTest() - : app_handle(1) - , dev_id("device_id") - , transport_listener(&tr_mock, &adapter_mock) {} + : dev_id("device_id") + , transport_listener(&tr_mock, &adapter_mock) + , app_handle(1) {} protected: - const int app_handle; const std::string dev_id; MockTransportManager tr_mock; MockTransportAdapter adapter_mock; TransportAdapterListenerImpl transport_listener; + const int app_handle; }; MATCHER_P4(IsEvent, eventType, adapter, dev_id, app_id, "") { @@ -73,33 +73,30 @@ MATCHER_P5(IsEvent, eventType, adapter, dev_id, app_id, data, "") { TEST_F(TransportAdapterListenerTest, OnCommunicationError) { EXPECT_CALL( tr_mock, - ReceiveEventFromDevice(IsEvent( - TransportAdapterListenerImpl::EventTypeEnum::ON_COMMUNICATION_ERROR, - &adapter_mock, - dev_id, - app_handle))).WillOnce(Return(E_SUCCESS)); + ReceiveEventFromDevice(IsEvent(EventTypeEnum::ON_COMMUNICATION_ERROR, + &adapter_mock, + dev_id, + app_handle))).WillOnce(Return(E_SUCCESS)); transport_listener.OnCommunicationError(&adapter_mock, dev_id, app_handle); } TEST_F(TransportAdapterListenerTest, OnConnectDone) { - EXPECT_CALL(tr_mock, - ReceiveEventFromDevice(IsEvent( - TransportAdapterListenerImpl::EventTypeEnum::ON_CONNECT_DONE, - &adapter_mock, - dev_id, - app_handle))).WillOnce(Return(E_SUCCESS)); + EXPECT_CALL( + tr_mock, + ReceiveEventFromDevice(IsEvent( + EventTypeEnum::ON_CONNECT_DONE, &adapter_mock, dev_id, app_handle))) + .WillOnce(Return(E_SUCCESS)); transport_listener.OnConnectDone(&adapter_mock, dev_id, app_handle); } TEST_F(TransportAdapterListenerTest, OnConnectFailed) { ConnectError er; - EXPECT_CALL(tr_mock, - ReceiveEventFromDevice(IsEvent( - TransportAdapterListenerImpl::EventTypeEnum::ON_CONNECT_FAIL, - &adapter_mock, - dev_id, - app_handle))).WillOnce(Return(E_SUCCESS)); + EXPECT_CALL( + tr_mock, + ReceiveEventFromDevice(IsEvent( + EventTypeEnum::ON_CONNECT_FAIL, &adapter_mock, dev_id, app_handle))) + .WillOnce(Return(E_SUCCESS)); transport_listener.OnConnectFailed(&adapter_mock, dev_id, app_handle, er); } @@ -107,12 +104,12 @@ TEST_F(TransportAdapterListenerTest, OnDataReceiveDone) { ::protocol_handler::RawMessagePtr data_container; EXPECT_CALL(tr_mock, - ReceiveEventFromDevice(IsEvent( - TransportAdapterListenerImpl::EventTypeEnum::ON_RECEIVED_DONE, - &adapter_mock, - dev_id, - app_handle, - data_container))).WillOnce(Return(E_SUCCESS)); + ReceiveEventFromDevice(IsEvent(EventTypeEnum::ON_RECEIVED_DONE, + &adapter_mock, + dev_id, + app_handle, + data_container))) + .WillOnce(Return(E_SUCCESS)); transport_listener.OnDataReceiveDone( &adapter_mock, dev_id, app_handle, data_container); } @@ -120,12 +117,11 @@ TEST_F(TransportAdapterListenerTest, OnDataReceiveDone) { TEST_F(TransportAdapterListenerTest, OnDataReceiveFailed) { DataReceiveError err; - EXPECT_CALL(tr_mock, - ReceiveEventFromDevice(IsEvent( - TransportAdapterListenerImpl::EventTypeEnum::ON_RECEIVED_FAIL, - &adapter_mock, - dev_id, - app_handle))).WillOnce(Return(E_SUCCESS)); + EXPECT_CALL( + tr_mock, + ReceiveEventFromDevice(IsEvent( + EventTypeEnum::ON_RECEIVED_FAIL, &adapter_mock, dev_id, app_handle))) + .WillOnce(Return(E_SUCCESS)); transport_listener.OnDataReceiveFailed( &adapter_mock, dev_id, app_handle, err); } @@ -136,12 +132,12 @@ TEST_F(TransportAdapterListenerTest, OnDataSendDone) { new ::protocol_handler::RawMessage(1, 1, data, 3); EXPECT_CALL(tr_mock, - ReceiveEventFromDevice(IsEvent( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEND_DONE, - &adapter_mock, - dev_id, - app_handle, - data_container))).WillOnce(Return(E_SUCCESS)); + ReceiveEventFromDevice(IsEvent(EventTypeEnum::ON_SEND_DONE, + &adapter_mock, + dev_id, + app_handle, + data_container))) + .WillOnce(Return(E_SUCCESS)); transport_listener.OnDataSendDone( &adapter_mock, dev_id, app_handle, data_container); } @@ -153,56 +149,50 @@ TEST_F(TransportAdapterListenerTest, OnDataSendFailed) { DataSendError err; EXPECT_CALL(tr_mock, - ReceiveEventFromDevice(IsEvent( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEND_FAIL, - &adapter_mock, - dev_id, - app_handle, - data_container))).WillOnce(Return(E_SUCCESS)); + ReceiveEventFromDevice(IsEvent(EventTypeEnum::ON_SEND_FAIL, + &adapter_mock, + dev_id, + app_handle, + data_container))) + .WillOnce(Return(E_SUCCESS)); transport_listener.OnDataSendFailed( &adapter_mock, dev_id, app_handle, data_container, err); } TEST_F(TransportAdapterListenerTest, OnDeviceListUpdated) { - EXPECT_CALL( - tr_mock, - ReceiveEventFromDevice(IsEvent( - TransportAdapterListenerImpl::EventTypeEnum::ON_DEVICE_LIST_UPDATED, - &adapter_mock, - "", - 0))).WillOnce(Return(E_SUCCESS)); + EXPECT_CALL(tr_mock, + ReceiveEventFromDevice(IsEvent( + EventTypeEnum::ON_DEVICE_LIST_UPDATED, &adapter_mock, "", 0))) + .WillOnce(Return(E_SUCCESS)); transport_listener.OnDeviceListUpdated(&adapter_mock); } TEST_F(TransportAdapterListenerTest, OnDisconnectDeviceDone) { - EXPECT_CALL( - tr_mock, - ReceiveEventFromDevice(IsEvent( - TransportAdapterListenerImpl::EventTypeEnum::ON_DISCONNECT_DONE, - &adapter_mock, - dev_id, - app_handle))).WillOnce(Return(E_SUCCESS)); + EXPECT_CALL(tr_mock, + ReceiveEventFromDevice(IsEvent(EventTypeEnum::ON_DISCONNECT_DONE, + &adapter_mock, + dev_id, + app_handle))) + .WillOnce(Return(E_SUCCESS)); transport_listener.OnDisconnectDone(&adapter_mock, dev_id, app_handle); } TEST_F(TransportAdapterListenerTest, OnDisconnectFailed) { DisconnectError err; - EXPECT_CALL( - tr_mock, - ReceiveEventFromDevice(IsEvent( - TransportAdapterListenerImpl::EventTypeEnum::ON_DISCONNECT_FAIL, - &adapter_mock, - dev_id, - app_handle))).WillOnce(Return(E_SUCCESS)); + EXPECT_CALL(tr_mock, + ReceiveEventFromDevice(IsEvent(EventTypeEnum::ON_DISCONNECT_FAIL, + &adapter_mock, + dev_id, + app_handle))) + .WillOnce(Return(E_SUCCESS)); transport_listener.OnDisconnectFailed(&adapter_mock, dev_id, app_handle, err); } TEST_F(TransportAdapterListenerTest, OnFindNewApplicationsRequest) { EXPECT_CALL(tr_mock, ReceiveEventFromDevice( - IsEvent(TransportAdapterListenerImpl::EventTypeEnum:: - ON_FIND_NEW_APPLICATIONS_REQUEST, + IsEvent(EventTypeEnum::ON_FIND_NEW_APPLICATIONS_REQUEST, &adapter_mock, "", 0))).WillOnce(Return(E_SUCCESS)); @@ -211,11 +201,9 @@ TEST_F(TransportAdapterListenerTest, OnFindNewApplicationsRequest) { TEST_F(TransportAdapterListenerTest, OnSearchDeviceDone) { EXPECT_CALL(tr_mock, - ReceiveEventFromDevice(IsEvent( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEARCH_DONE, - &adapter_mock, - "", - 0))).WillOnce(Return(E_SUCCESS)); + ReceiveEventFromDevice( + IsEvent(EventTypeEnum::ON_SEARCH_DONE, &adapter_mock, "", 0))) + .WillOnce(Return(E_SUCCESS)); transport_listener.OnSearchDeviceDone(&adapter_mock); } @@ -223,11 +211,9 @@ TEST_F(TransportAdapterListenerTest, OnSearchDeviceFailed) { SearchDeviceError er; EXPECT_CALL(tr_mock, - ReceiveEventFromDevice(IsEvent( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEARCH_FAIL, - &adapter_mock, - "", - 0))).WillOnce(Return(E_SUCCESS)); + ReceiveEventFromDevice( + IsEvent(EventTypeEnum::ON_SEARCH_FAIL, &adapter_mock, "", 0))) + .WillOnce(Return(E_SUCCESS)); transport_listener.OnSearchDeviceFailed(&adapter_mock, er); } @@ -236,11 +222,10 @@ TEST_F(TransportAdapterListenerTest, OnUnexpectedDisconnect) { EXPECT_CALL( tr_mock, - ReceiveEventFromDevice(IsEvent( - TransportAdapterListenerImpl::EventTypeEnum::ON_UNEXPECTED_DISCONNECT, - &adapter_mock, - dev_id, - app_handle))).WillOnce(Return(E_SUCCESS)); + ReceiveEventFromDevice(IsEvent(EventTypeEnum::ON_UNEXPECTED_DISCONNECT, + &adapter_mock, + dev_id, + app_handle))).WillOnce(Return(E_SUCCESS)); transport_listener.OnUnexpectedDisconnect( &adapter_mock, dev_id, app_handle, err); } diff --git a/src/components/transport_manager/test/transport_adapter_test.cc b/src/components/transport_manager/test/transport_adapter_test.cc index 0c59e912ba..6d709e0c17 100644 --- a/src/components/transport_manager/test/transport_adapter_test.cc +++ b/src/components/transport_manager/test/transport_adapter_test.cc @@ -189,9 +189,10 @@ TEST_F(TransportAdapterTest, AddDevice) { MockTransportAdapterListener mock_listener; transport_adapter.AddListener(&mock_listener); - MockDevice* mockdev = new MockDevice(dev_id, uniq_id); + utils::SharedPtr<MockDevice> mockdev = + utils::MakeShared<MockDevice>(dev_id, uniq_id); - EXPECT_CALL(mock_listener, OnDeviceListUpdated(_)); + EXPECT_CALL(mock_listener, OnDeviceListUpdated(&transport_adapter)); transport_adapter.AddDevice(mockdev); } @@ -276,7 +277,8 @@ TEST_F(TransportAdapterTest, ConnectDevice_ServerNotAdded_DeviceAdded) { EXPECT_CALL(transport_adapter, Restore()).WillOnce(Return(true)); transport_adapter.Init(); - MockDevice* mockdev = new MockDevice(dev_id, uniq_id); + utils::SharedPtr<MockDevice> mockdev = + utils::MakeShared<MockDevice>(dev_id, uniq_id); transport_adapter.AddDevice(mockdev); std::vector<std::string> devList = transport_adapter.GetDeviceList(); @@ -286,6 +288,7 @@ TEST_F(TransportAdapterTest, ConnectDevice_ServerNotAdded_DeviceAdded) { int app_handle = 1; std::vector<int> intList = {app_handle}; EXPECT_CALL(*mockdev, GetApplicationList()).WillOnce(Return(intList)); + EXPECT_CALL(transport_adapter, FindDevice(uniq_id)).WillOnce(Return(mockdev)); TransportAdapter::Error res = transport_adapter.ConnectDevice(uniq_id); EXPECT_EQ(TransportAdapter::FAIL, res); @@ -303,6 +306,8 @@ TEST_F(TransportAdapterTest, ConnectDevice_DeviceNotAdded) { EXPECT_CALL(*serverMock, IsInitialised()).Times(0); EXPECT_CALL(*serverMock, CreateConnection(_, _)).Times(0); + EXPECT_CALL(transport_adapter, FindDevice(uniq_id)) + .WillOnce(Return(utils::SharedPtr<MockDevice>())); TransportAdapter::Error res = transport_adapter.ConnectDevice(uniq_id); EXPECT_EQ(TransportAdapter::BAD_PARAM, res); @@ -318,7 +323,8 @@ TEST_F(TransportAdapterTest, ConnectDevice_DeviceAdded) { EXPECT_CALL(transport_adapter, Restore()).WillOnce(Return(true)); transport_adapter.Init(); - MockDevice* mockdev = new MockDevice(dev_id, uniq_id); + utils::SharedPtr<MockDevice> mockdev = + utils::MakeShared<MockDevice>(dev_id, uniq_id); transport_adapter.AddDevice(mockdev); std::vector<std::string> devList = transport_adapter.GetDeviceList(); @@ -332,6 +338,7 @@ TEST_F(TransportAdapterTest, ConnectDevice_DeviceAdded) { EXPECT_CALL(*serverMock, IsInitialised()).WillOnce(Return(true)); EXPECT_CALL(*serverMock, CreateConnection(uniq_id, app_handle)) .WillOnce(Return(TransportAdapter::OK)); + EXPECT_CALL(transport_adapter, FindDevice(uniq_id)).WillOnce(Return(mockdev)); TransportAdapter::Error res = transport_adapter.ConnectDevice(uniq_id); EXPECT_EQ(TransportAdapter::OK, res); @@ -347,7 +354,8 @@ TEST_F(TransportAdapterTest, ConnectDevice_DeviceAddedTwice) { EXPECT_CALL(transport_adapter, Restore()).WillOnce(Return(true)); transport_adapter.Init(); - MockDevice* mockdev = new MockDevice(dev_id, uniq_id); + utils::SharedPtr<MockDevice> mockdev = + utils::MakeShared<MockDevice>(dev_id, uniq_id); transport_adapter.AddDevice(mockdev); std::vector<std::string> devList = transport_adapter.GetDeviceList(); @@ -361,6 +369,7 @@ TEST_F(TransportAdapterTest, ConnectDevice_DeviceAddedTwice) { EXPECT_CALL(*serverMock, IsInitialised()).WillOnce(Return(true)); EXPECT_CALL(*serverMock, CreateConnection(uniq_id, app_handle)) .WillOnce(Return(TransportAdapter::OK)); + EXPECT_CALL(transport_adapter, FindDevice(uniq_id)).WillOnce(Return(mockdev)); TransportAdapter::Error res = transport_adapter.ConnectDevice(uniq_id); EXPECT_EQ(TransportAdapter::OK, res); @@ -370,6 +379,7 @@ TEST_F(TransportAdapterTest, ConnectDevice_DeviceAddedTwice) { EXPECT_CALL(*serverMock, IsInitialised()).WillOnce(Return(true)); EXPECT_CALL(*serverMock, CreateConnection(uniq_id, app_handle)).Times(0); + EXPECT_CALL(transport_adapter, FindDevice(uniq_id)).WillOnce(Return(mockdev)); TransportAdapter::Error newres = transport_adapter.ConnectDevice(uniq_id); EXPECT_EQ(TransportAdapter::OK, newres); @@ -415,7 +425,8 @@ TEST_F(TransportAdapterTest, DisconnectDevice_DeviceAddedConnectionCreated) { EXPECT_CALL(transport_adapter, Restore()).WillOnce(Return(true)); transport_adapter.Init(); - MockDevice* mockdev = new MockDevice(dev_id, uniq_id); + utils::SharedPtr<MockDevice> mockdev = + utils::MakeShared<MockDevice>(dev_id, uniq_id); transport_adapter.AddDevice(mockdev); std::vector<std::string> devList = transport_adapter.GetDeviceList(); @@ -428,6 +439,7 @@ TEST_F(TransportAdapterTest, DisconnectDevice_DeviceAddedConnectionCreated) { EXPECT_CALL(*serverMock, IsInitialised()).WillOnce(Return(true)); EXPECT_CALL(*serverMock, CreateConnection(uniq_id, app_handle)) .WillOnce(Return(TransportAdapter::OK)); + EXPECT_CALL(transport_adapter, FindDevice(uniq_id)).WillOnce(Return(mockdev)); TransportAdapter::Error res = transport_adapter.ConnectDevice(uniq_id); EXPECT_EQ(TransportAdapter::OK, res); @@ -455,8 +467,9 @@ TEST_F(TransportAdapterTest, DeviceDisconnected) { MockTransportAdapterListener mock_listener; transport_adapter.AddListener(&mock_listener); - MockDevice* mockdev = new MockDevice(dev_id, uniq_id); - EXPECT_CALL(mock_listener, OnDeviceListUpdated(_)); + utils::SharedPtr<MockDevice> mockdev = + utils::MakeShared<MockDevice>(dev_id, uniq_id); + EXPECT_CALL(mock_listener, OnDeviceListUpdated(&transport_adapter)); transport_adapter.AddDevice(mockdev); std::vector<std::string> devList = transport_adapter.GetDeviceList(); @@ -465,23 +478,25 @@ TEST_F(TransportAdapterTest, DeviceDisconnected) { std::vector<int> intList = {app_handle}; EXPECT_CALL(*mockdev, GetApplicationList()).WillOnce(Return(intList)); - + EXPECT_CALL(transport_adapter, FindDevice(uniq_id)).WillOnce(Return(mockdev)); EXPECT_CALL(*serverMock, IsInitialised()).WillOnce(Return(true)); EXPECT_CALL(*serverMock, CreateConnection(uniq_id, app_handle)) .WillOnce(Return(TransportAdapter::OK)); TransportAdapter::Error res = transport_adapter.ConnectDevice(uniq_id); EXPECT_EQ(TransportAdapter::OK, res); - MockConnection* mock_connection = new MockConnection(); + utils::SharedPtr<MockConnection> mock_connection = + utils::MakeShared<MockConnection>(); transport_adapter.ConnectionCreated(mock_connection, uniq_id, app_handle); + EXPECT_CALL(mock_listener, OnDeviceListUpdated(&transport_adapter)); EXPECT_CALL(*mockdev, GetApplicationList()).WillOnce(Return(intList)); EXPECT_CALL( mock_listener, OnUnexpectedDisconnect(&transport_adapter, uniq_id, app_handle, _)); EXPECT_CALL(mock_listener, OnDisconnectDeviceDone(&transport_adapter, uniq_id)); - EXPECT_CALL(mock_listener, OnDeviceListUpdated(&transport_adapter)); + EXPECT_CALL(transport_adapter, FindDevice(uniq_id)).WillOnce(Return(mockdev)); DisconnectDeviceError error; transport_adapter.DeviceDisconnected(uniq_id, error); @@ -697,7 +712,8 @@ TEST_F(TransportAdapterTest, GetDeviceAndApplicationLists) { EXPECT_CALL(transport_adapter, Restore()).WillOnce(Return(true)); transport_adapter.Init(); - MockDevice* mockdev = new MockDevice(dev_id, uniq_id); + utils::SharedPtr<MockDevice> mockdev = + utils::MakeShared<MockDevice>(dev_id, uniq_id); transport_adapter.AddDevice(mockdev); std::vector<std::string> devList = transport_adapter.GetDeviceList(); @@ -707,6 +723,7 @@ TEST_F(TransportAdapterTest, GetDeviceAndApplicationLists) { int app_handle = 1; std::vector<int> intList = {app_handle}; EXPECT_CALL(*mockdev, GetApplicationList()).WillOnce(Return(intList)); + EXPECT_CALL(transport_adapter, FindDevice(uniq_id)).WillOnce(Return(mockdev)); std::vector<int> res = transport_adapter.GetApplicationList(uniq_id); ASSERT_EQ(1u, res.size()); EXPECT_EQ(intList[0], res[0]); @@ -752,6 +769,8 @@ TEST_F(TransportAdapterTest, RunAppOnDevice_NoDeviseWithAskedId_UNSUCCESS) { transport_adapter.AddDevice(mock_device); EXPECT_CALL(*mock_device, LaunchApp(bundle_id)).Times(0); + EXPECT_CALL(transport_adapter, FindDevice("test_device_uid1")) + .WillOnce(Return(utils::SharedPtr<MockDevice>())); transport_adapter.RunAppOnDevice("test_device_uid1", bundle_id); } @@ -769,10 +788,27 @@ TEST_F(TransportAdapterTest, RunAppOnDevice_DeviseWithAskedIdWasFound_SUCCESS) { transport_adapter.AddDevice(mock_device); EXPECT_CALL(*mock_device, LaunchApp(bundle_id)); + EXPECT_CALL(transport_adapter, FindDevice(device_uid)) + .WillOnce(Return(mock_device)); transport_adapter.RunAppOnDevice(device_uid, bundle_id); } +TEST_F(TransportAdapterTest, StopDevice) { + MockTransportAdapterImpl transport_adapter( + NULL, NULL, NULL, last_state_, transport_manager_settings); + EXPECT_CALL(transport_adapter, Restore()).WillOnce(Return(true)); + transport_adapter.Init(); + + auto mockdev = utils::MakeShared<MockDevice>(dev_id, uniq_id); + transport_adapter.AddDevice(mockdev); + + EXPECT_CALL(transport_adapter, FindDevice(uniq_id)).WillOnce(Return(mockdev)); + EXPECT_CALL(*mockdev, Stop()); + + transport_adapter.StopDevice(uniq_id); +} + } // namespace transport_manager_test } // namespace components } // namespace test diff --git a/src/components/transport_manager/test/transport_manager_impl_test.cc b/src/components/transport_manager/test/transport_manager_impl_test.cc index c7cf3b2cb2..eebb247908 100644 --- a/src/components/transport_manager/test/transport_manager_impl_test.cc +++ b/src/components/transport_manager/test/transport_manager_impl_test.cc @@ -70,10 +70,15 @@ const uint32_t kAsyncExpectationsTimeout = 10000u; class TransportManagerImplTest : public ::testing::Test { protected: TransportManagerImplTest() - : device_handle_(1) + : mock_adapter_(NULL) + , tm_(mock_transport_manager_settings_) , mac_address_("MA:CA:DR:ES:S") - , dev_info_(device_handle_, mac_address_, "TestDeviceName", "BTMAC") - , tm_(settings) {} + , connection_type_("BTMAC") + , device_name_("TestDeviceName") + , device_handle_( + tm_.get_converter().UidToHandle(mac_address_, connection_type_)) + , dev_info_( + device_handle_, mac_address_, device_name_, connection_type_) {} void SetUp() OVERRIDE { resumption::LastStateImpl last_state_("app_storage_folder", @@ -101,11 +106,46 @@ class TransportManagerImplTest : public ::testing::Test { MakeShared<RawMessage>(connection_key_, version_protocol_, data, kSize); } - void HandleDeviceListUpdated() { - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_DEVICE_LIST_UPDATED); + DeviceInfo ConstructDeviceInfo(const std::string& mac_address, + const std::string& connection_type, + const std::string& device_name) { + const auto device_handle( + tm_.get_converter().UidToHandle(mac_address, connection_type)); + + return DeviceInfo(device_handle, mac_address, device_name, connection_type); + } + + void SetOnDeviceExpectations(const DeviceInfo& device_info) { + EXPECT_CALL(*tm_listener_, OnDeviceAdded(device_info)); + EXPECT_CALL(*tm_listener_, OnDeviceListUpdated(_)); + } + + void SetDeviceExpectations(MockTransportAdapter* mock_adapter, + const DeviceList& device_list, + const DeviceInfo& device_info) { + EXPECT_CALL(*mock_adapter, GetDeviceList()) + .WillRepeatedly(Return(device_list)); + + EXPECT_CALL(*mock_adapter, DeviceName(device_info.mac_address())) + .WillRepeatedly(Return(device_info.name())); + + EXPECT_CALL(*mock_adapter, GetConnectionType()) + .WillRepeatedly(Return(device_info.connection_type())); + } + + void SetAddDeviceExpectations(MockTransportAdapter* mock_adapter, + transport_adapter::DeviceType type, + const DeviceList& device_list, + const DeviceInfo& device_info) { + SetDeviceExpectations(mock_adapter, device_list, device_info); + + EXPECT_CALL(*mock_adapter, GetDeviceType()).WillRepeatedly(Return(type)); + + SetOnDeviceExpectations(device_info); + } - TransportAdapterEvent test_event(type, + void HandleDeviceListUpdated() { + TransportAdapterEvent test_event(EventTypeEnum::ON_DEVICE_LIST_UPDATED, mock_adapter_, dev_info_.mac_address(), application_id_, @@ -125,18 +165,15 @@ class TransportManagerImplTest : public ::testing::Test { .Times(AtLeast(1)) .WillRepeatedly(Return(dev_info_.connection_type())); - EXPECT_CALL(*tm_listener_, OnDeviceFound(dev_info_)); EXPECT_CALL(*tm_listener_, OnDeviceAdded(dev_info_)); + EXPECT_CALL(*tm_listener_, OnDeviceListUpdated(_)); tm_.TestHandle(test_event); device_list_.pop_back(); } void HandleConnection() { - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_CONNECT_DONE); - - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_CONNECT_DONE, mock_adapter_, dev_info_.mac_address(), application_id_, @@ -146,7 +183,7 @@ class TransportManagerImplTest : public ::testing::Test { EXPECT_CALL(*mock_adapter_, DeviceName(dev_info_.mac_address())) .WillOnce(Return(dev_info_.name())); EXPECT_CALL(*mock_adapter_, GetConnectionType()) - .WillOnce(Return(dev_info_.connection_type())); + .WillRepeatedly(Return(dev_info_.connection_type())); EXPECT_CALL(*tm_listener_, OnConnectionEstablished(dev_info_, connection_key_)); @@ -155,10 +192,7 @@ class TransportManagerImplTest : public ::testing::Test { } void HandleConnectionFailed() { - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_CONNECT_FAIL); - - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_CONNECT_FAIL, mock_adapter_, dev_info_.mac_address(), application_id_, @@ -168,7 +202,7 @@ class TransportManagerImplTest : public ::testing::Test { EXPECT_CALL(*mock_adapter_, DeviceName(dev_info_.mac_address())) .WillOnce(Return(dev_info_.name())); EXPECT_CALL(*mock_adapter_, GetConnectionType()) - .WillOnce(Return(dev_info_.connection_type())); + .WillRepeatedly(Return(dev_info_.connection_type())); EXPECT_CALL(*tm_listener_, OnConnectionFailed(dev_info_, _)); @@ -176,9 +210,7 @@ class TransportManagerImplTest : public ::testing::Test { } void HandleSendDone() { - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEND_DONE); - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_SEND_DONE, mock_adapter_, mac_address_, application_id_, @@ -193,9 +225,7 @@ class TransportManagerImplTest : public ::testing::Test { } void HandleReceiveDone() { - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_RECEIVED_DONE); - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_RECEIVED_DONE, mock_adapter_, mac_address_, application_id_, @@ -210,10 +240,7 @@ class TransportManagerImplTest : public ::testing::Test { } void HandleSendFailed() { - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEND_FAIL); - - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_SEND_FAIL, mock_adapter_, mac_address_, application_id_, @@ -226,10 +253,7 @@ class TransportManagerImplTest : public ::testing::Test { } void HandleSearchDone() { - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEARCH_DONE); - - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_SEARCH_DONE, mock_adapter_, mac_address_, application_id_, @@ -242,10 +266,7 @@ class TransportManagerImplTest : public ::testing::Test { } void HandleSearchFail() { - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEARCH_FAIL); - - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_SEARCH_FAIL, mock_adapter_, mac_address_, application_id_, @@ -258,16 +279,13 @@ class TransportManagerImplTest : public ::testing::Test { } void HandleFindNewApplicationsRequest() { - const int type = - static_cast<int>(TransportAdapterListenerImpl::EventTypeEnum:: - ON_FIND_NEW_APPLICATIONS_REQUEST); - - TransportAdapterEvent test_event(type, - mock_adapter_, - mac_address_, - application_id_, - test_message_, - error_); + TransportAdapterEvent test_event( + EventTypeEnum::ON_FIND_NEW_APPLICATIONS_REQUEST, + mock_adapter_, + mac_address_, + application_id_, + test_message_, + error_); EXPECT_CALL(*tm_listener_, OnFindNewApplicationsRequest()); @@ -275,10 +293,7 @@ class TransportManagerImplTest : public ::testing::Test { } void HandleConnectionClosed() { - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_DISCONNECT_DONE); - - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_DISCONNECT_DONE, mock_adapter_, mac_address_, application_id_, @@ -293,10 +308,7 @@ class TransportManagerImplTest : public ::testing::Test { } void HandleDisconnectionFailed() { - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_DISCONNECT_FAIL); - - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_DISCONNECT_FAIL, mock_adapter_, mac_address_, application_id_, @@ -312,23 +324,26 @@ class TransportManagerImplTest : public ::testing::Test { EXPECT_CALL(*mock_adapter_, Terminate()); ASSERT_EQ(E_SUCCESS, tm_.Stop()); } - MockTransportManagerSettings settings; + + MockTransportManagerSettings mock_transport_manager_settings_; #ifdef TELEMETRY_MONITOR MockTMTelemetryObserver mock_metric_observer_; #endif // TELEMETRY_MONITOR MockTransportAdapter* mock_adapter_; utils::SharedPtr<MockTransportManagerListener> tm_listener_; + MockTransportManagerImpl tm_; const ApplicationHandle application_id_ = 1; ConnectionUID connection_key_; RawMessagePtr test_message_; - DeviceHandle device_handle_; std::string mac_address_; + std::string connection_type_; + std::string device_name_; + DeviceHandle device_handle_; const DeviceInfo dev_info_; DeviceList device_list_; BaseErrorPtr error_; - MockTransportManagerImpl tm_; }; TEST_F(TransportManagerImplTest, SearchDevices_AdaptersNotAdded) { @@ -642,45 +657,39 @@ TEST_F(TransportManagerImplTest, Reinit_InitAdapterFailed) { TEST_F(TransportManagerImplTest, UpdateDeviceList_AddNewDevice) { device_list_.push_back(dev_info_.mac_address()); - EXPECT_CALL(*mock_adapter_, GetDeviceList()).WillOnce(Return(device_list_)); - EXPECT_CALL(*mock_adapter_, DeviceName(dev_info_.mac_address())) - .WillOnce(Return(dev_info_.name())); - EXPECT_CALL(*mock_adapter_, GetConnectionType()) - .WillOnce(Return(dev_info_.connection_type())); - EXPECT_CALL(*tm_listener_, OnDeviceAdded(dev_info_)); - - tm_.UpdateDeviceList(mock_adapter_); + SetDeviceExpectations(mock_adapter_, device_list_, dev_info_); + EXPECT_CALL(*tm_listener_, OnDeviceFound(dev_info_)); + SetOnDeviceExpectations(dev_info_); + tm_.OnDeviceListUpdated(mock_adapter_); device_list_.pop_back(); } TEST_F(TransportManagerImplTest, UpdateDeviceList_RemoveDevice) { device_list_.push_back(dev_info_.mac_address()); - - ::testing::InSequence seq; - EXPECT_CALL(*mock_adapter_, GetDeviceList()).WillOnce(Return(device_list_)); - EXPECT_CALL(*mock_adapter_, GetConnectionType()) - .WillOnce(Return(dev_info_.connection_type())); - EXPECT_CALL(*mock_adapter_, DeviceName(dev_info_.mac_address())) - .WillOnce(Return(dev_info_.name())); - EXPECT_CALL(*tm_listener_, OnDeviceAdded(dev_info_)); - tm_.UpdateDeviceList(mock_adapter_); + { + SetDeviceExpectations(mock_adapter_, device_list_, dev_info_); + ::testing::InSequence s; + EXPECT_CALL(*tm_listener_, OnDeviceFound(dev_info_)); + SetOnDeviceExpectations(dev_info_); + tm_.OnDeviceListUpdated(mock_adapter_); + } device_list_.pop_back(); + SetDeviceExpectations(mock_adapter_, device_list_, dev_info_); + // Device list is empty now - EXPECT_CALL(*mock_adapter_, GetDeviceList()).WillOnce(Return(device_list_)); + ::testing::InSequence s; EXPECT_CALL(*tm_listener_, OnDeviceRemoved(dev_info_)); - tm_.UpdateDeviceList(mock_adapter_); + EXPECT_CALL(*tm_listener_, OnDeviceListUpdated(_)); + tm_.OnDeviceListUpdated(mock_adapter_); } /* * Tests which check correct handling and receiving events */ TEST_F(TransportManagerImplTest, ReceiveEventFromDevice_OnSearchDeviceDone) { - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEARCH_DONE); - TestAsyncWaiter waiter; - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_SEARCH_DONE, mock_adapter_, mac_address_, application_id_, @@ -696,11 +705,8 @@ TEST_F(TransportManagerImplTest, ReceiveEventFromDevice_OnSearchDeviceDone) { } TEST_F(TransportManagerImplTest, ReceiveEventFromDevice_OnSearchDeviceFail) { - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEARCH_FAIL); - TestAsyncWaiter waiter; - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_SEARCH_FAIL, mock_adapter_, mac_address_, application_id_, @@ -716,10 +722,7 @@ TEST_F(TransportManagerImplTest, ReceiveEventFromDevice_OnSearchDeviceFail) { } TEST_F(TransportManagerImplTest, ReceiveEventFromDevice_DeviceListUpdated) { - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_DEVICE_LIST_UPDATED); - - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_DEVICE_LIST_UPDATED, mock_adapter_, dev_info_.mac_address(), application_id_, @@ -772,10 +775,7 @@ TEST_F(TransportManagerImplTest, CheckReceiveEvent) { TEST_F(TransportManagerImplTest, CheckReceiveFailedEvent) { // Arrange - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_RECEIVED_FAIL); - - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_RECEIVED_FAIL, mock_adapter_, mac_address_, application_id_, @@ -790,10 +790,7 @@ TEST_F(TransportManagerImplTest, CheckReceiveFailedEvent) { TEST_F(TransportManagerImplTest, CheckUnexpectedDisconnect) { // Arrange - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_UNEXPECTED_DISCONNECT); - - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_UNEXPECTED_DISCONNECT, mock_adapter_, mac_address_, application_id_, @@ -875,10 +872,12 @@ TEST_F(TransportManagerImplTest, SendMessageToDevice_ConnectionNotExist) { TEST_F(TransportManagerImplTest, ReceiveEventFromDevice_TMIsNotInitialized) { // Arrange - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEARCH_DONE); - TransportAdapterEvent test_event( - type, NULL, mac_address_, application_id_, test_message_, error_); + TransportAdapterEvent test_event(EventTypeEnum::ON_SEARCH_DONE, + NULL, + mac_address_, + application_id_, + test_message_, + error_); // Check before Act UninitializeTM(); // Act and Assert @@ -938,84 +937,10 @@ TEST_F(TransportManagerImplTest, } TEST_F(TransportManagerImplTest, - UpdateDeviceList_AddDevices_TwoTransportAdapters) { - // Arrange - MockTransportAdapter* second_mock_adapter = new MockTransportAdapter(); - device_list_.push_back(dev_info_.mac_address()); - // Check before Act - EXPECT_CALL(*second_mock_adapter, AddListener(_)); - EXPECT_CALL(*second_mock_adapter, IsInitialised()).WillOnce(Return(true)); - EXPECT_EQ(E_SUCCESS, tm_.AddTransportAdapter(second_mock_adapter)); - - // Act and Assert - EXPECT_CALL(*second_mock_adapter, GetDeviceList()) - .WillOnce(Return(device_list_)); - EXPECT_CALL(*second_mock_adapter, DeviceName(dev_info_.mac_address())) - .WillOnce(Return(dev_info_.name())); - EXPECT_CALL(*second_mock_adapter, GetConnectionType()) - .WillOnce(Return(dev_info_.connection_type())); - EXPECT_CALL(*tm_listener_, OnDeviceAdded(dev_info_)); - tm_.UpdateDeviceList(second_mock_adapter); - - EXPECT_CALL(*mock_adapter_, GetDeviceList()).WillOnce(Return(device_list_)); - EXPECT_CALL(*mock_adapter_, DeviceName(dev_info_.mac_address())) - .WillOnce(Return(dev_info_.name())); - EXPECT_CALL(*mock_adapter_, GetConnectionType()) - .WillOnce(Return(dev_info_.connection_type())); - EXPECT_CALL(*tm_listener_, OnDeviceAdded(dev_info_)); - tm_.UpdateDeviceList(mock_adapter_); - - device_list_.pop_back(); -} - -TEST_F(TransportManagerImplTest, - UpdateDeviceList_RemoveDevices_TwoTransportAdapters) { - // Arrange - MockTransportAdapter* second_mock_adapter = new MockTransportAdapter(); - device_list_.push_back(dev_info_.mac_address()); - // Check before Act - EXPECT_CALL(*second_mock_adapter, AddListener(_)); - EXPECT_CALL(*second_mock_adapter, IsInitialised()).WillOnce(Return(true)); - EXPECT_EQ(E_SUCCESS, tm_.AddTransportAdapter(second_mock_adapter)); - - // Act and Assert - EXPECT_CALL(*second_mock_adapter, GetDeviceList()) - .WillOnce(Return(device_list_)); - EXPECT_CALL(*second_mock_adapter, DeviceName(dev_info_.mac_address())) - .WillOnce(Return(dev_info_.name())); - EXPECT_CALL(*second_mock_adapter, GetConnectionType()) - .WillOnce(Return(dev_info_.connection_type())); - EXPECT_CALL(*tm_listener_, OnDeviceAdded(dev_info_)); - tm_.UpdateDeviceList(second_mock_adapter); - - EXPECT_CALL(*mock_adapter_, GetDeviceList()).WillOnce(Return(device_list_)); - EXPECT_CALL(*mock_adapter_, DeviceName(dev_info_.mac_address())) - .WillOnce(Return(dev_info_.name())); - EXPECT_CALL(*mock_adapter_, GetConnectionType()) - .WillOnce(Return(dev_info_.connection_type())); - EXPECT_CALL(*tm_listener_, OnDeviceAdded(dev_info_)); - tm_.UpdateDeviceList(mock_adapter_); - - device_list_.pop_back(); - - EXPECT_CALL(*second_mock_adapter, GetDeviceList()) - .WillOnce(Return(device_list_)); - EXPECT_CALL(*tm_listener_, OnDeviceRemoved(dev_info_)); - tm_.UpdateDeviceList(second_mock_adapter); - - EXPECT_CALL(*mock_adapter_, GetDeviceList()).WillOnce(Return(device_list_)); - EXPECT_CALL(*tm_listener_, OnDeviceRemoved(dev_info_)); - tm_.UpdateDeviceList(mock_adapter_); -} - -TEST_F(TransportManagerImplTest, CheckEventOnDisconnectDone_ConnectionNotExist) { // SetUp does not add connections // Arrange - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_DISCONNECT_DONE); - - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_DISCONNECT_DONE, mock_adapter_, mac_address_, application_id_, @@ -1031,10 +956,7 @@ TEST_F(TransportManagerImplTest, TEST_F(TransportManagerImplTest, CheckEventOnSendDone_ConnectionNotExist) { // SetUp does not add connections // Arrange - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEND_DONE); - - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_SEND_DONE, mock_adapter_, mac_address_, application_id_, @@ -1052,9 +974,7 @@ TEST_F(TransportManagerImplTest, CheckEventOnSendDone_ConnectionNotExist) { TEST_F(TransportManagerImplTest, CheckEventOnReceivedDone_ConnectionNotExist) { // SetUp does not add connections // Arrange - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_RECEIVED_DONE); - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_RECEIVED_DONE, mock_adapter_, mac_address_, application_id_, @@ -1071,9 +991,7 @@ TEST_F(TransportManagerImplTest, CheckEventOnReceivedDone_ConnectionNotExist) { TEST_F(TransportManagerImplTest, CheckEventOnReceivedFail_ConnectionNotExist) { // SetUp does not add connections // Arrange - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_RECEIVED_FAIL); - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_RECEIVED_FAIL, mock_adapter_, mac_address_, application_id_, @@ -1088,9 +1006,7 @@ TEST_F(TransportManagerImplTest, CheckEventOnUnexpectedDisconnect_ConnectionNotExist) { // SetUp does not add connections // Arrange - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_UNEXPECTED_DISCONNECT); - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_UNEXPECTED_DISCONNECT, mock_adapter_, mac_address_, application_id_, @@ -1108,6 +1024,305 @@ TEST_F(TransportManagerImplTest, RunAppOnDevice_TransportAdapterFound_SUCCESS) { tm_.RunAppOnDevice(device_handle_, bundle_id); } +TEST_F(TransportManagerImplTest, + UpdateDeviceList_AddDevices_TwoTransportAdapters_ExpectSuccess) { + // Arrange + MockTransportAdapter* second_mock_adapter = new MockTransportAdapter(); + device_list_.push_back(dev_info_.mac_address()); + // Check before Act + EXPECT_CALL(*second_mock_adapter, AddListener(_)); + EXPECT_CALL(*second_mock_adapter, IsInitialised()).WillOnce(Return(true)); + EXPECT_EQ(E_SUCCESS, tm_.AddTransportAdapter(second_mock_adapter)); + + // Act and Assert + SetDeviceExpectations(mock_adapter_, device_list_, dev_info_); + EXPECT_CALL(*tm_listener_, OnDeviceFound(dev_info_)); + SetOnDeviceExpectations(dev_info_); + tm_.OnDeviceListUpdated(mock_adapter_); + + const std::string mac_address("NE:WA:DR:ES:SS"); + const std::string connection_type("TCP"); + const std::string device_name("TestName"); + const transport_manager::DeviceHandle device_handle( + tm_.get_converter().UidToHandle(mac_address, connection_type)); + + DeviceInfo second_device( + device_handle, mac_address, device_name, connection_type); + DeviceList device_list_2; + device_list_2.push_back(second_device.mac_address()); + + SetDeviceExpectations(second_mock_adapter, device_list_2, second_device); + + EXPECT_CALL(*tm_listener_, OnDeviceFound(second_device)); + SetOnDeviceExpectations(second_device); + tm_.OnDeviceListUpdated(second_mock_adapter); + + device_list_.pop_back(); +} + +TEST_F( + TransportManagerImplTest, + UpdateDeviceList_AddSameUUIDNonSwitchableDevices_TwoTransportAdapters_ExpectNoSwitch) { + device_list_.push_back(dev_info_.mac_address()); + SetAddDeviceExpectations(mock_adapter_, + transport_adapter::DeviceType::TCP, + device_list_, + dev_info_); + + tm_.OnDeviceListUpdated(mock_adapter_); + + // Adapter will be removed by TM on destruction + MockTransportAdapter* second_mock_adapter = new MockTransportAdapter(); + EXPECT_CALL(*second_mock_adapter, AddListener(_)); + EXPECT_CALL(*second_mock_adapter, IsInitialised()).WillOnce(Return(true)); + EXPECT_EQ(E_SUCCESS, tm_.AddTransportAdapter(second_mock_adapter)); + + const auto usb_serial = "USB_serial"; + DeviceInfo second_device = + ConstructDeviceInfo(usb_serial, "USB_IOS", "SecondDeviceName"); + + DeviceList second_adapter_device_list; + second_adapter_device_list.push_back(usb_serial); + + SetAddDeviceExpectations(second_mock_adapter, + transport_adapter::DeviceType::IOS_USB, + second_adapter_device_list, + second_device); + + tm_.OnDeviceListUpdated(second_mock_adapter); + + // Act + EXPECT_CALL(*second_mock_adapter, StopDevice(_)).Times(0); + EXPECT_CALL(*second_mock_adapter, DeviceSwitched(_)).Times(0); + + tm_.TestHandle( + TransportAdapterEvent(EventTypeEnum::ON_TRANSPORT_SWITCH_REQUESTED, + second_mock_adapter, + mac_address_, + application_id_, + test_message_, + error_)); + + device_list_.pop_back(); +} + +TEST_F(TransportManagerImplTest, OnlyOneDeviceShouldNotTriggerSwitch) { + device_list_.push_back(dev_info_.mac_address()); + SetDeviceExpectations(mock_adapter_, device_list_, dev_info_); + SetOnDeviceExpectations(dev_info_); + + EXPECT_CALL(*mock_adapter_, StopDevice(_)).Times(0); + EXPECT_CALL(*mock_adapter_, DeviceSwitched(_)).Times(0); + EXPECT_CALL(*tm_listener_, OnDeviceSwitchingStart(_, _)).Times(0); + + tm_.TestHandle(TransportAdapterEvent(EventTypeEnum::ON_DEVICE_LIST_UPDATED, + mock_adapter_, + mac_address_, + application_id_, + test_message_, + error_)); + + device_list_.pop_back(); +} + +TEST_F(TransportManagerImplTest, + TwoTransportAdapterAddSameSwitchableDevice_ExpectSuccess) { + device_list_.push_back(dev_info_.mac_address()); + const uint32_t timeout = 0; + + SetAddDeviceExpectations(mock_adapter_, + transport_adapter::DeviceType::IOS_BT, + device_list_, + dev_info_); + + EXPECT_CALL(*tm_listener_, OnDeviceFound(dev_info_)); + + tm_.TestHandle(TransportAdapterEvent(EventTypeEnum::ON_DEVICE_LIST_UPDATED, + mock_adapter_, + mac_address_, + application_id_, + test_message_, + error_)); + + auto second_mock_adapter = utils::MakeShared<MockTransportAdapter>(); + + const auto usb_serial = "USB_serial"; + DeviceInfo second_device = + ConstructDeviceInfo(usb_serial, "USB_IOS", "SecondDeviceName"); + + DeviceList second_adapter_devices; + second_adapter_devices.push_back(second_device.mac_address()); + + SetAddDeviceExpectations(second_mock_adapter.get(), + transport_adapter::DeviceType::IOS_USB, + second_adapter_devices, + second_device); + + EXPECT_CALL(*tm_listener_, OnDeviceFound(second_device)); + EXPECT_CALL(*second_mock_adapter, DeviceSwitched(_)).Times(0); + + tm_.TestHandle(TransportAdapterEvent(EventTypeEnum::ON_DEVICE_LIST_UPDATED, + second_mock_adapter.get(), + mac_address_, + application_id_, + test_message_, + error_)); + + // Act + const auto uuid = "ABC-DEF-GHJ-KLM"; + SwitchableDevices bt_switchables; + bt_switchables.insert(std::make_pair(dev_info_.mac_address(), uuid)); + EXPECT_CALL(*mock_adapter_, GetSwitchableDevices()) + .WillOnce(Return(bt_switchables)); + + SwitchableDevices usb_switchables; + usb_switchables.insert(std::make_pair(second_device.mac_address(), uuid)); + EXPECT_CALL(*second_mock_adapter, GetSwitchableDevices()) + .WillOnce(Return(usb_switchables)); + + EXPECT_CALL(*mock_adapter_, StopDevice(mac_address_)); + EXPECT_CALL(*second_mock_adapter, DeviceSwitched(usb_serial)); + EXPECT_CALL(mock_transport_manager_settings_, app_transport_change_timer()) + .WillOnce(Return(timeout)); + EXPECT_CALL(mock_transport_manager_settings_, + app_transport_change_timer_addition()).WillOnce(Return(0)); + + EXPECT_CALL(*tm_listener_, OnDeviceSwitchingStart(mac_address_, usb_serial)); + + tm_.TestHandle( + TransportAdapterEvent(EventTypeEnum::ON_TRANSPORT_SWITCH_REQUESTED, + second_mock_adapter.get(), + mac_address_, + application_id_, + test_message_, + error_)); + + // There is internal timer started on switching. Need to wait for timeout. + sleep(1); + device_list_.pop_back(); +} + +TEST_F(TransportManagerImplTest, + TwoTransportAdapterAddSameDeviceSecondSkipped) { + device_list_.push_back(dev_info_.mac_address()); + + SetAddDeviceExpectations(mock_adapter_, + transport_adapter::DeviceType::IOS_BT, + device_list_, + dev_info_); + + EXPECT_CALL(*tm_listener_, OnDeviceFound(_)); + + tm_.TestHandle(TransportAdapterEvent(EventTypeEnum::ON_DEVICE_LIST_UPDATED, + mock_adapter_, + mac_address_, + application_id_, + test_message_, + error_)); + + auto second_mock_adapter = utils::MakeShared<MockTransportAdapter>(); + + DeviceInfo second_device = + ConstructDeviceInfo("MA:CA:DR:ES:S", "USB_IOS", "SecondDeviceName"); + + SetAddDeviceExpectations(second_mock_adapter.get(), + transport_adapter::DeviceType::IOS_USB, + device_list_, + second_device); + + EXPECT_CALL(*tm_listener_, OnDeviceFound(_)).Times(0); + + tm_.TestHandle(TransportAdapterEvent(EventTypeEnum::ON_DEVICE_LIST_UPDATED, + second_mock_adapter.get(), + mac_address_, + application_id_, + test_message_, + error_)); + + device_list_.pop_back(); +} + +TEST_F(TransportManagerImplTest, NoDeviceTransportSwitchRequest_Fail) { + device_list_.push_back(dev_info_.mac_address()); + SetAddDeviceExpectations(mock_adapter_, + transport_adapter::DeviceType::IOS_USB, + device_list_, + dev_info_); + + EXPECT_CALL(*tm_listener_, OnDeviceFound(_)); + + tm_.TestHandle(TransportAdapterEvent(EventTypeEnum::ON_DEVICE_LIST_UPDATED, + mock_adapter_, + mac_address_, + application_id_, + test_message_, + error_)); + + EXPECT_CALL(*mock_adapter_, StopDevice(mac_address_)).Times(0); + + EXPECT_CALL(*tm_listener_, OnDeviceSwitchingStart(mac_address_, mac_address_)) + .Times(0); + + tm_.TestHandle( + TransportAdapterEvent(EventTypeEnum::ON_TRANSPORT_SWITCH_REQUESTED, + mock_adapter_, + mac_address_, + application_id_, + test_message_, + error_)); + + device_list_.pop_back(); +} + +TEST_F(TransportManagerImplTest, + UpdateDeviceList_RemoveDevices_TwoTransportAdapters_ExpectSuccess) { + // Arrange + MockTransportAdapter* second_mock_adapter = new MockTransportAdapter(); + device_list_.push_back(dev_info_.mac_address()); + // Check before Act + EXPECT_CALL(*second_mock_adapter, AddListener(_)); + EXPECT_CALL(*second_mock_adapter, IsInitialised()).WillOnce(Return(true)); + EXPECT_EQ(E_SUCCESS, tm_.AddTransportAdapter(second_mock_adapter)); + + // Act and Assert + SetDeviceExpectations(mock_adapter_, device_list_, dev_info_); + + EXPECT_CALL(*tm_listener_, OnDeviceFound(dev_info_)); + SetOnDeviceExpectations(dev_info_); + tm_.OnDeviceListUpdated(mock_adapter_); + + const std::string mac_address("NE:WA:DR:ES:SS"); + const std::string connection_type("TCP"); + const std::string device_name("TestName"); + const transport_manager::DeviceHandle device_handle( + tm_.get_converter().UidToHandle(mac_address, connection_type)); + + DeviceInfo second_device( + device_handle, mac_address, device_name, connection_type); + DeviceList device_list_2; + device_list_2.push_back(second_device.mac_address()); + SetDeviceExpectations(second_mock_adapter, device_list_2, second_device); + + EXPECT_CALL(*tm_listener_, OnDeviceFound(second_device)); + SetOnDeviceExpectations(second_device); + tm_.OnDeviceListUpdated(second_mock_adapter); + + device_list_.pop_back(); + device_list_2.pop_back(); + + EXPECT_CALL(*second_mock_adapter, GetDeviceList()) + .WillRepeatedly(Return(device_list_2)); + EXPECT_CALL(*tm_listener_, OnDeviceRemoved(second_device)); + EXPECT_CALL(*tm_listener_, OnDeviceListUpdated(_)); + tm_.OnDeviceListUpdated(second_mock_adapter); + + EXPECT_CALL(*mock_adapter_, GetDeviceList()) + .WillRepeatedly(Return(device_list_)); + EXPECT_CALL(*tm_listener_, OnDeviceRemoved(dev_info_)); + EXPECT_CALL(*tm_listener_, OnDeviceListUpdated(_)); + tm_.OnDeviceListUpdated(mock_adapter_); +} + } // namespace transport_manager_test } // namespace components } // namespace test |