diff options
105 files changed, 1958 insertions, 330 deletions
diff --git a/.travis.yml b/.travis.yml index 7f7df359b4..7060f4f33f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: cpp -dist: trusty +dist: xenial sudo: required only: - master diff --git a/src/appMain/life_cycle_impl.cc b/src/appMain/life_cycle_impl.cc index b87191d937..efc627f33a 100644 --- a/src/appMain/life_cycle_impl.cc +++ b/src/appMain/life_cycle_impl.cc @@ -111,6 +111,7 @@ bool LifeCycleImpl::StartComponents() { media_manager_ = new media_manager::MediaManagerImpl(*app_manager_, profile_); app_manager_->set_connection_handler(connection_handler_); + app_manager_->AddPolicyObserver(protocol_handler_); if (!app_manager_->Init(*last_state_, media_manager_)) { LOG4CXX_ERROR(logger_, "Application manager init failed."); return false; @@ -134,7 +135,6 @@ bool LifeCycleImpl::StartComponents() { security_manager_->AddListener(app_manager_); app_manager_->AddPolicyObserver(security_manager_); - app_manager_->AddPolicyObserver(protocol_handler_); if (!crypto_manager_->Init()) { LOG4CXX_ERROR(logger_, "CryptoManager initialization fail."); return false; diff --git a/src/appMain/sdl_preloaded_pt.json b/src/appMain/sdl_preloaded_pt.json index fcd92e6df5..f70fdfdf10 100644 --- a/src/appMain/sdl_preloaded_pt.json +++ b/src/appMain/sdl_preloaded_pt.json @@ -552,6 +552,11 @@ "FULL",
"LIMITED"]
},
+ "GetCloudAppProperties":{
+ "hmi_levels":["BACKGROUND",
+ "FULL",
+ "LIMITED"]
+ },
"GetVehicleData": {
"hmi_levels": ["BACKGROUND",
"FULL",
diff --git a/src/components/application_manager/include/application_manager/application.h b/src/components/application_manager/include/application_manager/application.h index 7a59263299..b4d8ca857e 100644 --- a/src/components/application_manager/include/application_manager/application.h +++ b/src/components/application_manager/include/application_manager/application.h @@ -957,10 +957,10 @@ class Application : public virtual InitialApplicationData, * websocket open. * @return cloud app auth token */ - virtual const std::string& cloud_app_auth_token() const = 0; + virtual const std::string& auth_token() const = 0; /** - * @brief Get cloud app tranpsport type. Defines the type of websocket + * @brief Get cloud app transport type. Defines the type of websocket * connection used. * @return cloud app transport type */ @@ -994,7 +994,7 @@ class Application : public virtual InitialApplicationData, /** * @brief Set cloud app auth token */ - virtual void set_cloud_app_auth_token(const std::string& auth_token) = 0; + virtual void set_auth_token(const std::string& auth_token) = 0; /** * @brief Set cloud app transport type 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 6d627d0c67..ff34d2a96a 100644 --- a/src/components/application_manager/include/application_manager/application_impl.h +++ b/src/components/application_manager/include/application_manager/application_impl.h @@ -420,10 +420,10 @@ class ApplicationImpl : public virtual Application, * websocket open. * @return cloud app auth token */ - const std::string& cloud_app_auth_token() const OVERRIDE; + const std::string& auth_token() const OVERRIDE; /** - * @brief Get cloud app tranpsport type. Defines the type of websocket + * @brief Get cloud app transport type. Defines the type of websocket * connection used. * @return cloud app transport type */ @@ -457,7 +457,7 @@ class ApplicationImpl : public virtual Application, /** * @brief Set cloud app auth token */ - void set_cloud_app_auth_token(const std::string& auth_token) OVERRIDE; + void set_auth_token(const std::string& auth_token) OVERRIDE; /** * @brief Set cloud app transport type 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 12f2310d36..27be913cd5 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 @@ -117,6 +117,14 @@ struct CommandParametersPermissions; typedef std::map<std::string, hmi_apis::Common_TransportType::eType> DeviceTypes; +struct AppIconInfo { + std::string endpoint; + bool pending_request; + AppIconInfo(); + AppIconInfo(std::string ws_endpoint, bool pending) + : endpoint(ws_endpoint), pending_request(pending) {} +}; + CREATE_LOGGERPTR_GLOBAL(logger_, "ApplicationManager") typedef std::shared_ptr<timer::Timer> TimerSPtr; @@ -156,6 +164,7 @@ class ApplicationManagerImpl bool Stop() OVERRIDE; DataAccessor<ApplicationSet> applications() const OVERRIDE; + DataAccessor<AppsWaitRegistrationSet> pending_applications() const OVERRIDE; ApplicationSharedPtr application(uint32_t app_id) const OVERRIDE; ApplicationSharedPtr active_application() const OVERRIDE; @@ -164,6 +173,10 @@ class ApplicationManagerImpl uint32_t hmi_app_id) const OVERRIDE; ApplicationSharedPtr application_by_policy_id( const std::string& policy_app_id) const OVERRIDE; + ApplicationSharedPtr application_by_name( + const std::string& app_name) const OVERRIDE; + ApplicationSharedPtr pending_application_by_policy_id( + const std::string& policy_app_id) const OVERRIDE; std::vector<ApplicationSharedPtr> applications_by_button( uint32_t button) OVERRIDE; @@ -194,6 +207,9 @@ class ApplicationManagerImpl void SendDriverDistractionState(ApplicationSharedPtr application); + void SendGetIconUrlNotifications(const uint32_t connection_key, + ApplicationSharedPtr application); + ApplicationSharedPtr application( const std::string& device_id, const std::string& policy_app_id) const OVERRIDE; @@ -365,6 +381,8 @@ class ApplicationManagerImpl void ConnectToDevice(const std::string& device_mac) OVERRIDE; void OnHMIStartedCooperation() OVERRIDE; + void DisconnectCloudApp(ApplicationSharedPtr app) OVERRIDE; + void RefreshCloudAppInformation() OVERRIDE; void CreatePendingApplication( @@ -372,6 +390,14 @@ class ApplicationManagerImpl const transport_manager::DeviceInfo& device_info, connection_handler::DeviceHandle device_id); + void SetPendingApplicationState( + const transport_manager::ConnectionUID connection_id, + const transport_manager::DeviceInfo& device_info); + + std::string PolicyIDByIconUrl(const std::string url) OVERRIDE; + + void SetIconFileFromSystemRequest(const std::string policy_id) OVERRIDE; + /** * @brief Notifies the applicaiton manager that a cloud connection status has * updated and should trigger an UpdateAppList RPC to the HMI @@ -383,7 +409,6 @@ class ApplicationManagerImpl * @param app A cloud application * @return The current CloudConnectionStatus of app */ - hmi_apis::Common_CloudConnectionStatus::eType GetCloudAppConnectionStatus( ApplicationConstSharedPtr app) const; @@ -510,9 +535,6 @@ class ApplicationManagerImpl // typedef for Applications list typedef std::set<ApplicationSharedPtr, ApplicationsAppIdSorter> ApplictionSet; - typedef std::set<ApplicationSharedPtr, ApplicationsPolicyAppIdSorter> - AppsWaitRegistrationSet; - // typedef for Applications list iterator typedef ApplictionSet::iterator ApplictionSetIt; @@ -1002,6 +1024,14 @@ class ApplicationManagerImpl } }; + struct AppNamePredicate { + std::string app_name_; + AppNamePredicate(const std::string& app_name) : app_name_(app_name) {} + bool operator()(const ApplicationSharedPtr app) const { + return app ? app->name() == app_name_ : false; + } + }; + /** * @brief Sends UpdateAppList notification to HMI */ @@ -1496,6 +1526,9 @@ class ApplicationManagerImpl pending_device_map_lock_ptr_; std::map<std::string, std::string> pending_device_map_; + sync_primitives::Lock app_icon_map_lock_ptr_; + std::map<std::string, AppIconInfo> app_icon_map_; + #ifdef TELEMETRY_MONITOR AMTelemetryObserver* metric_observer_; #endif // TELEMETRY_MONITOR 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 index 145bef659e..18267c9e7f 100644 --- a/src/components/application_manager/include/application_manager/helpers/application_helper.h +++ b/src/components/application_manager/include/application_manager/helpers/application_helper.h @@ -57,6 +57,18 @@ ApplicationSharedPtr FindApp(DataAccessor<ApplicationSet> accessor, return app; } +template <class UnaryPredicate> +ApplicationSharedPtr FindPendingApp( + DataAccessor<AppsWaitRegistrationSet> accessor, UnaryPredicate finder) { + AppsWaitRegistrationSet::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 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 07d9c8dc23..774376b249 100644 --- a/src/components/application_manager/include/application_manager/hmi_state.h +++ b/src/components/application_manager/include/application_manager/hmi_state.h @@ -207,7 +207,7 @@ class HmiState { } protected: - std::shared_ptr<Application> app_; + uint32_t hmi_app_id_; StateID state_id_; const ApplicationManager& app_mngr_; HmiStatePtr parent_; 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 8a8e50bf1c..ac84bcfaa5 100644 --- a/src/components/application_manager/include/application_manager/message_helper.h +++ b/src/components/application_manager/include/application_manager/message_helper.h @@ -786,6 +786,14 @@ class MessageHelper { static hmi_apis::Common_Language::eType CommonLanguageFromString( const std::string& language); + /** + * @brief CommonLightNameFromString convert string to LightName enum value + * @param lightName string to convert + * @return value LightName enum value + */ + static hmi_apis::Common_LightName::eType CommonLightNameFromString( + const std::string& lightName); + static smart_objects::SmartObjectSPtr GetOnAppInterfaceUnregisteredNotificationToMobile( int32_t connection_key, 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 df96ade313..abc98876a2 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 @@ -187,6 +187,8 @@ class PolicyHandler : public PolicyHandlerInterface, void GetUpdateUrls(const uint32_t service_type, EndpointUrls& out_end_points) OVERRIDE; virtual std::string GetLockScreenIconUrl() const OVERRIDE; + virtual std::string GetIconUrl( + const std::string& policy_app_id) const OVERRIDE; uint32_t NextRetryTimeout() OVERRIDE; /** @@ -431,7 +433,7 @@ class PolicyHandler : public PolicyHandlerInterface, * @param hybrid_app_preference Filled with the hybrid app preference for the * cloud application set by the user */ - void GetCloudAppParameters(const std::string& policy_app_id, + bool GetCloudAppParameters(const std::string& policy_app_id, bool& enabled, std::string& endpoint, std::string& certificate, @@ -480,6 +482,9 @@ class PolicyHandler : public PolicyHandlerInterface, #ifdef EXTERNAL_PROPRIETARY_MODE void OnCertificateDecrypted(bool is_succeeded) OVERRIDE; #endif // EXTERNAL_PROPRIETARY_MODE + void OnAuthTokenUpdated(const std::string& policy_app_id, + const std::string& auth_token); + virtual bool CanUpdate() OVERRIDE; virtual void OnDeviceConsentChanged(const std::string& device_id, diff --git a/src/components/application_manager/include/application_manager/policies/regular/policy_handler_observer.h b/src/components/application_manager/include/application_manager/policies/regular/policy_handler_observer.h index 07d234f036..68e7511b43 100644 --- a/src/components/application_manager/include/application_manager/policies/regular/policy_handler_observer.h +++ b/src/components/application_manager/include/application_manager/policies/regular/policy_handler_observer.h @@ -48,6 +48,9 @@ class PolicyHandlerObserver { return false; } + virtual void OnAuthTokenUpdated(const std::string& policy_app_id, + const std::string& auth_token) {} + virtual void OnPTUFinished(const bool ptu_result) {} virtual ~PolicyHandlerObserver() {} diff --git a/src/components/application_manager/include/application_manager/smart_object_keys.h b/src/components/application_manager/include/application_manager/smart_object_keys.h index 5d030dace6..67c849c8fc 100644 --- a/src/components/application_manager/include/application_manager/smart_object_keys.h +++ b/src/components/application_manager/include/application_manager/smart_object_keys.h @@ -190,12 +190,14 @@ extern const char* green; extern const char* blue; extern const char* display_layout; extern const char* icon_resumed; +extern const char* nicknames; extern const char* enabled; -extern const char* cloud_app_auth_token; +extern const char* auth_token; extern const char* cloud_transport_type; extern const char* hybrid_app_preference; extern const char* is_cloud_application; extern const char* cloud_connection_status; +extern const char* endpoint; // PutFile extern const char* sync_file_name; diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/get_cloud_app_properties_request.h b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/get_cloud_app_properties_request.h new file mode 100644 index 0000000000..3d74a80dc2 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/get_cloud_app_properties_request.h @@ -0,0 +1,31 @@ +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_SDL_RPC_PLUGIN_INCLUDE_SDL_RPC_PLUGIN_COMMANDS_MOBILE_GET_CLOUD_APP_PROPERTIES_REQUEST_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_SDL_RPC_PLUGIN_INCLUDE_SDL_RPC_PLUGIN_COMMANDS_MOBILE_GET_CLOUD_APP_PROPERTIES_REQUEST_H_ + +#include "application_manager/commands/command_request_impl.h" + +namespace sdl_rpc_plugin { +namespace app_mngr = application_manager; + +namespace commands { + +class GetCloudAppPropertiesRequest + : public app_mngr::commands::CommandRequestImpl { + public: + GetCloudAppPropertiesRequest( + const app_mngr::commands::MessageSharedPtr& message, + app_mngr::ApplicationManager& application_manager, + app_mngr::rpc_service::RPCService& rpc_service, + app_mngr::HMICapabilities& hmi_capabilities, + policy::PolicyHandlerInterface& policy_handler); + virtual ~GetCloudAppPropertiesRequest(); + virtual void Run(); + virtual void on_event(const app_mngr::event_engine::Event& event); + + private: + DISALLOW_COPY_AND_ASSIGN(GetCloudAppPropertiesRequest); +}; // GetCloudAppPropertiesRequest + +} // namespace commands +} // namespace sdl_rpc_plugin + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_SDL_RPC_PLUGIN_INCLUDE_SDL_RPC_PLUGIN_COMMANDS_MOBILE_GET_CLOUD_APP_PROPERTIES_REQUEST_H_ diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/get_cloud_app_properties_response.h b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/get_cloud_app_properties_response.h new file mode 100644 index 0000000000..f716c7dcb5 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/get_cloud_app_properties_response.h @@ -0,0 +1,31 @@ +#ifndef SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_SDL_RPC_PLUGIN_INCLUDE_SDL_RPC_PLUGIN_COMMANDS_MOBILE_GET_CLOUD_APP_PROPERTIES_RESPONSE_H_ +#define SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_SDL_RPC_PLUGIN_INCLUDE_SDL_RPC_PLUGIN_COMMANDS_MOBILE_GET_CLOUD_APP_PROPERTIES_RESPONSE_H_ + +#include "application_manager/commands/command_response_impl.h" + +namespace sdl_rpc_plugin { +namespace app_mngr = application_manager; + +namespace commands { + +class GetCloudAppPropertiesResponse + : public app_mngr::commands::CommandResponseImpl { + public: + GetCloudAppPropertiesResponse( + const app_mngr::commands::MessageSharedPtr& message, + app_mngr::ApplicationManager& application_manager, + app_mngr::rpc_service::RPCService& rpc_service, + app_mngr::HMICapabilities& hmi_capabilities, + policy::PolicyHandlerInterface& policy_handler); + virtual ~GetCloudAppPropertiesResponse(); + virtual void Run(); + + private: + DISALLOW_COPY_AND_ASSIGN(GetCloudAppPropertiesResponse); + +}; // GetCloudAppPropertiesResponse + +} // namespace commands +} // namespace sdl_rpc_plugin + +#endif // SRC_COMPONENTS_APPLICATION_MANAGER_RPC_PLUGINS_SDL_RPC_PLUGIN_INCLUDE_SDL_RPC_PLUGIN_COMMANDS_MOBILE_GET_CLOUD_APP_PROPERTIES_RESPONSE_H_ diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/register_app_interface_request.h b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/register_app_interface_request.h index f8be896996..91ee8ea813 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/register_app_interface_request.h +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/register_app_interface_request.h @@ -144,11 +144,14 @@ class RegisterAppInterfaceRequest /* * @brief Check new application parameters (name, tts, vr) for * coincidence with already known parameters of registered applications + * @param out_duplicate_apps In the case other apps was found with duplicate + * names, this field will be filled with a list of said apps * * return SUCCESS if there is no coincidence of app.name/TTS/VR synonyms, * otherwise appropriate error code returns - */ - mobile_apis::Result::eType CheckCoincidence(); + */ + mobile_apis::Result::eType CheckCoincidence( + std::vector<app_mngr::ApplicationSharedPtr>& out_duplicate_apps); /* * @brief Predicate for using with CheckCoincidence method to compare with VR diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/on_exit_application_notification.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/on_exit_application_notification.cc index 681390fbf4..b6d44a4511 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/on_exit_application_notification.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/on_exit_application_notification.cc @@ -106,6 +106,10 @@ void OnExitApplicationNotification::Run() { application_manager_.UnregisterApplication(app_id, Result::SUCCESS); return; } + case Common_ApplicationExitReason::CLOSE_CLOUD_CONNECTION: { + application_manager_.DisconnectCloudApp(app_impl); + break; + } default: { LOG4CXX_WARN(logger_, "Unhandled reason"); return; diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_cloud_app_properties_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_cloud_app_properties_request.cc new file mode 100644 index 0000000000..34ed30c243 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_cloud_app_properties_request.cc @@ -0,0 +1,98 @@ +#include "sdl_rpc_plugin/commands/mobile/get_cloud_app_properties_request.h" + +namespace sdl_rpc_plugin { +using namespace application_manager; + +namespace commands { + +GetCloudAppPropertiesRequest::GetCloudAppPropertiesRequest( + const app_mngr::commands::MessageSharedPtr& message, + app_mngr::ApplicationManager& application_manager, + app_mngr::rpc_service::RPCService& rpc_service, + app_mngr::HMICapabilities& hmi_capabilities, + policy::PolicyHandlerInterface& policy_handler) + : CommandRequestImpl(message, + application_manager, + rpc_service, + hmi_capabilities, + policy_handler) {} + +GetCloudAppPropertiesRequest::~GetCloudAppPropertiesRequest() {} + +void GetCloudAppPropertiesRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + ApplicationSharedPtr app = application_manager_.application(connection_key()); + + if (!app) { + LOG4CXX_ERROR(logger_, "Application is not registered"); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED); + return; + } + + std::string policy_app_id = + (*message_)[strings::msg_params][strings::app_id].asString(); + + bool enabled = true; + std::string endpoint; + std::string auth_token; + std::string certificate; + std::string cloud_transport_type; + std::string hybrid_app_preference; + + bool result = policy_handler_.GetCloudAppParameters(policy_app_id, + enabled, + endpoint, + certificate, + auth_token, + cloud_transport_type, + hybrid_app_preference); + + if (!result) { + SendResponse(false, + mobile_apis::Result::DATA_NOT_AVAILABLE, + "Cloud app does not exist on module"); + return; + } + + policy::StringArray nicknames; + policy::StringArray app_hmi_types; + + policy_handler_.GetInitialAppData(policy_app_id, &nicknames, &app_hmi_types); + + smart_objects::SmartObject response_params(smart_objects::SmartType_Map); + smart_objects::SmartObject properties(smart_objects::SmartType_Map); + smart_objects::SmartObject nicknames_array(smart_objects::SmartType_Array); + size_t i = 0; + for (std::string nickname : nicknames) { + nicknames_array[i] = nickname; + ++i; + } + properties[strings::nicknames] = nicknames_array; + properties[strings::app_id] = policy_app_id; + properties[strings::enabled] = enabled; + + if (!auth_token.empty()) { + properties[strings::auth_token] = auth_token; + } + if (!cloud_transport_type.empty()) { + properties[strings::cloud_transport_type] = cloud_transport_type; + } + if (!hybrid_app_preference.empty()) { + properties[strings::hybrid_app_preference] = hybrid_app_preference; + } + if (!endpoint.empty()) { + properties[strings::endpoint] = endpoint; + } + + response_params[strings::properties] = properties; + + SendResponse(true, mobile_apis::Result::SUCCESS, NULL, &response_params); +} + +void GetCloudAppPropertiesRequest::on_event( + const app_mngr::event_engine::Event& event) { + LOG4CXX_INFO(logger_, "GetCloudAppPropertiesRequest on_event"); +} + +} // namespace commands +} // namespace sdl_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_cloud_app_properties_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_cloud_app_properties_response.cc new file mode 100644 index 0000000000..813a9e7006 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/get_cloud_app_properties_response.cc @@ -0,0 +1,31 @@ +#include "application_manager/application_manager.h" +#include "application_manager/rpc_service.h" +#include "sdl_rpc_plugin/commands/mobile/get_cloud_app_properties_response.h" + +namespace sdl_rpc_plugin { +using namespace application_manager; + +namespace commands { + +GetCloudAppPropertiesResponse::GetCloudAppPropertiesResponse( + const app_mngr::commands::MessageSharedPtr& message, + app_mngr::ApplicationManager& application_manager, + app_mngr::rpc_service::RPCService& rpc_service, + app_mngr::HMICapabilities& hmi_capabilities, + policy::PolicyHandlerInterface& policy_handler) + : CommandResponseImpl(message, + application_manager, + rpc_service, + hmi_capabilities, + policy_handler) {} + +GetCloudAppPropertiesResponse::~GetCloudAppPropertiesResponse() {} + +void GetCloudAppPropertiesResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + rpc_service_.SendMessageToMobile(message_); +} + +} // namespace commands +} // namespace sdl_rpc_plugins diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_request.cc index b346ee5798..924705f82b 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_request.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_request.cc @@ -281,17 +281,51 @@ void RegisterAppInterfaceRequest::Run() { return; } - mobile_apis::Result::eType coincidence_result = CheckCoincidence(); + std::vector<ApplicationSharedPtr> duplicate_apps; + mobile_apis::Result::eType coincidence_result = + CheckCoincidence(duplicate_apps); + + if (mobile_apis::Result::DUPLICATE_NAME == coincidence_result && + duplicate_apps.size() == 1) { + ApplicationSharedPtr duplicate_app = duplicate_apps.front(); + bool error_response = true; + if (duplicate_app->is_cloud_app()) { + if (duplicate_app->hybrid_app_preference() == + mobile_apis::HybridAppPreference::MOBILE) { + // Unregister cloud application and allow mobile application to register + // in it's place + application_manager_.UnregisterApplication( + duplicate_app->app_id(), mobile_apis::Result::USER_DISALLOWED); + error_response = false; + } + } else { + ApplicationSharedPtr cloud_app = + application_manager_.pending_application_by_policy_id(policy_app_id); + // If the duplicate name was not because of a mobile/cloud app pair, go + // through the normal process for handling duplicate names + if (cloud_app.use_count() == 0 || !cloud_app->is_cloud_app()) { + usage_statistics::AppCounter count_of_rejections_duplicate_name( + GetPolicyHandler().GetStatisticManager(), + policy_app_id, + usage_statistics::REJECTIONS_DUPLICATE_NAME); + ++count_of_rejections_duplicate_name; + } else if (cloud_app->hybrid_app_preference() == + mobile_apis::HybridAppPreference::CLOUD) { + // Unregister mobile application and allow cloud application to + // register in it's place + application_manager_.UnregisterApplication( + duplicate_app->app_id(), mobile_apis::Result::USER_DISALLOWED); + error_response = false; + } + } - if (mobile_apis::Result::SUCCESS != coincidence_result) { - LOG4CXX_ERROR(logger_, "Coincidence check failed."); - if (mobile_apis::Result::DUPLICATE_NAME == coincidence_result) { - usage_statistics::AppCounter count_of_rejections_duplicate_name( - GetPolicyHandler().GetStatisticManager(), - policy_app_id, - usage_statistics::REJECTIONS_DUPLICATE_NAME); - ++count_of_rejections_duplicate_name; + if (error_response) { + LOG4CXX_ERROR(logger_, "Coincidence check failed."); + SendResponse(false, coincidence_result); + return; } + } else if (mobile_apis::Result::SUCCESS != coincidence_result) { + LOG4CXX_ERROR(logger_, "Coincidence check failed."); SendResponse(false, coincidence_result); return; } @@ -447,6 +481,9 @@ void RegisterAppInterfaceRequest::Run() { GetLockScreenIconUrlNotification(connection_key(), application); rpc_service_.ManageMobileCommand(so, SOURCE_SDL); application_manager_.SendDriverDistractionState(application); + // Create onSystemRequest to mobile to obtain cloud app icons + application_manager_.SendGetIconUrlNotifications(connection_key(), + application); } smart_objects::SmartObjectSPtr @@ -919,7 +956,8 @@ void RegisterAppInterfaceRequest::SendOnAppRegisteredNotificationToHMI( DCHECK(rpc_service_.ManageHMICommand(notification)); } -mobile_apis::Result::eType RegisterAppInterfaceRequest::CheckCoincidence() { +mobile_apis::Result::eType RegisterAppInterfaceRequest::CheckCoincidence( + std::vector<ApplicationSharedPtr>& out_duplicate_apps) { LOG4CXX_AUTO_TRACE(logger_); const smart_objects::SmartObject& msg_params = (*message_)[strings::msg_params]; @@ -935,7 +973,8 @@ mobile_apis::Result::eType RegisterAppInterfaceRequest::CheckCoincidence() { const custom_str::CustomString& cur_name = (*it)->name(); if (app_name.CompareIgnoreCase(cur_name)) { LOG4CXX_ERROR(logger_, "Application name is known already."); - return mobile_apis::Result::DUPLICATE_NAME; + out_duplicate_apps.push_back(*it); + continue; } const smart_objects::SmartObject* vr = (*it)->vr_synonyms(); @@ -946,7 +985,8 @@ mobile_apis::Result::eType RegisterAppInterfaceRequest::CheckCoincidence() { if (0 != std::count_if(curr_vr->begin(), curr_vr->end(), v)) { LOG4CXX_ERROR(logger_, "Application name is known already."); - return mobile_apis::Result::DUPLICATE_NAME; + out_duplicate_apps.push_back(*it); + continue; } } @@ -958,12 +998,16 @@ mobile_apis::Result::eType RegisterAppInterfaceRequest::CheckCoincidence() { CoincidencePredicateVR v(cur_name); if (0 != std::count_if(new_vr->begin(), new_vr->end(), v)) { LOG4CXX_ERROR(logger_, "vr_synonyms duplicated with app_name ."); - return mobile_apis::Result::DUPLICATE_NAME; + out_duplicate_apps.push_back(*it); + continue; } } // end vr check } // application for end + if (!out_duplicate_apps.empty()) { + return mobile_apis::Result::DUPLICATE_NAME; + } return mobile_apis::Result::SUCCESS; } // method end diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_cloud_app_properties_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_cloud_app_properties_request.cc index 663881a2ea..5173be56d6 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_cloud_app_properties_request.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_cloud_app_properties_request.cc @@ -29,12 +29,6 @@ void SetCloudAppPropertiesRequest::Run() { return; } - if ((*message_)[strings::msg_params].empty()) { - LOG4CXX_ERROR(logger_, strings::msg_params << " is empty."); - SendResponse(false, mobile_apis::Result::INVALID_DATA); - return; - } - policy_handler_.OnSetCloudAppProperties(*message_); SendResponse(true, mobile_apis::Result::SUCCESS); diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/system_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/system_request.cc index cea00a9d5e..da39aefd6a 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/system_request.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/system_request.cc @@ -511,7 +511,8 @@ void SystemRequest::Run() { return; } - if (!file_system::IsFileNameValid(file_name)) { + if (!file_system::IsFileNameValid(file_name) && + mobile_apis::RequestType::ICON_URL != request_type) { const std::string err_msg = "Sync file name contains forbidden symbols."; LOG4CXX_ERROR(logger_, err_msg); SendResponse(false, mobile_apis::Result::INVALID_DATA, err_msg.c_str()); @@ -533,8 +534,21 @@ void SystemRequest::Run() { std::string binary_data_folder; if ((*message_)[strings::params].keyExists(strings::binary_data)) { binary_data = (*message_)[strings::params][strings::binary_data].asBinary(); - binary_data_folder = - application_manager_.get_settings().system_files_path(); + if (mobile_apis::RequestType::ICON_URL == request_type) { + binary_data_folder = + application_manager_.get_settings().app_icons_folder(); + // Use the URL file name to identify the policy id. + // Save the icon file with the policy id as the name. + file_name = application_manager_.PolicyIDByIconUrl(file_name); + if (file_name.empty()) { + const std::string err_msg = "Invalid file name"; + SendResponse(false, mobile_apis::Result::INVALID_DATA, err_msg.c_str()); + } + LOG4CXX_DEBUG(logger_, "Got ICON_URL Request. File name: " << file_name); + } else { + binary_data_folder = + application_manager_.get_settings().system_files_path(); + } } else { binary_data_folder = application_manager_.get_settings().app_storage_folder(); @@ -581,6 +595,12 @@ void SystemRequest::Run() { LOG4CXX_DEBUG(logger_, "Binary data ok."); + if (mobile_apis::RequestType::ICON_URL == request_type) { + application_manager_.SetIconFileFromSystemRequest(file_name); + SendResponse(true, mobile_apis::Result::SUCCESS); + return; + } + if (mobile_apis::RequestType::HTTP == request_type && (*message_)[strings::msg_params].keyExists(strings::file_name)) { const std::string& file = diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/mobile_command_factory.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/mobile_command_factory.cc index f12dcbb485..554d004360 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/mobile_command_factory.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/mobile_command_factory.cc @@ -127,6 +127,8 @@ #include "sdl_rpc_plugin/commands/mobile/send_haptic_data_response.h" #include "sdl_rpc_plugin/commands/mobile/set_cloud_app_properties_request.h" #include "sdl_rpc_plugin/commands/mobile/set_cloud_app_properties_response.h" +#include "sdl_rpc_plugin/commands/mobile/get_cloud_app_properties_request.h" +#include "sdl_rpc_plugin/commands/mobile/get_cloud_app_properties_response.h" #include "sdl_rpc_plugin/commands/mobile/get_file_request.h" #include "sdl_rpc_plugin/commands/mobile/get_file_response.h" #include "interfaces/MOBILE_API.h" @@ -353,6 +355,12 @@ CommandCreator& MobileCommandFactory::get_creator_factory( : factory .GetCreator<commands::SetCloudAppPropertiesResponse>(); } + case mobile_apis::FunctionID::GetCloudAppPropertiesID: { + return mobile_api::messageType::request == message_type + ? factory.GetCreator<commands::GetCloudAppPropertiesRequest>() + : factory + .GetCreator<commands::GetCloudAppPropertiesResponse>(); + } case mobile_apis::FunctionID::OnButtonEventID: { return factory.GetCreator<commands::mobile::OnButtonEventNotification>(); } diff --git a/src/components/application_manager/src/application_impl.cc b/src/components/application_manager/src/application_impl.cc index 02bf5b49fe..3d17da51ce 100644 --- a/src/components/application_manager/src/application_impl.cc +++ b/src/components/application_manager/src/application_impl.cc @@ -1167,7 +1167,7 @@ const std::string& ApplicationImpl::cloud_app_endpoint() const { return endpoint_; } -const std::string& ApplicationImpl::cloud_app_auth_token() const { +const std::string& ApplicationImpl::auth_token() const { return auth_token_; } @@ -1185,15 +1185,14 @@ const std::string& ApplicationImpl::cloud_app_certificate() const { } bool ApplicationImpl::is_cloud_app() const { - return !endpoint_.empty() && - hybrid_app_preference_ != mobile_apis::HybridAppPreference::MOBILE; + return !endpoint_.empty(); } void ApplicationImpl::set_cloud_app_endpoint(const std::string& endpoint) { endpoint_ = endpoint; } -void ApplicationImpl::set_cloud_app_auth_token(const std::string& auth_token) { +void ApplicationImpl::set_auth_token(const std::string& auth_token) { auth_token_ = auth_token; } diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc index f9da143720..9d16c366d5 100644 --- a/src/components/application_manager/src/application_manager_impl.cc +++ b/src/components/application_manager/src/application_manager_impl.cc @@ -73,6 +73,7 @@ #include "policy/usage_statistics/counter.h" #include "utils/custom_string.h" #include <time.h> +#include <boost/filesystem.hpp> namespace { int get_rand_from_range(uint32_t from = 0, int to = RAND_MAX) { @@ -241,6 +242,13 @@ DataAccessor<ApplicationSet> ApplicationManagerImpl::applications() const { return accessor; } +DataAccessor<AppsWaitRegistrationSet> +ApplicationManagerImpl::pending_applications() const { + DataAccessor<AppsWaitRegistrationSet> accessor( + apps_to_register_, apps_to_register_list_lock_ptr_); + return accessor; +} + ApplicationSharedPtr ApplicationManagerImpl::application( uint32_t app_id) const { AppIdPredicate finder(app_id); @@ -262,6 +270,20 @@ ApplicationSharedPtr ApplicationManagerImpl::application_by_policy_id( return FindApp(accessor, finder); } +ApplicationSharedPtr ApplicationManagerImpl::application_by_name( + const std::string& app_name) const { + AppNamePredicate finder(app_name); + DataAccessor<ApplicationSet> accessor = applications(); + return FindApp(accessor, finder); +} + +ApplicationSharedPtr ApplicationManagerImpl::pending_application_by_policy_id( + const std::string& policy_app_id) const { + PolicyAppIdPredicate finder(policy_app_id); + DataAccessor<AppsWaitRegistrationSet> accessor = pending_applications(); + return FindPendingApp(accessor, finder); +} + bool ActiveAppPredicate(const ApplicationSharedPtr app) { return app ? app->IsFullscreen() : false; } @@ -618,7 +640,7 @@ ApplicationSharedPtr ApplicationManagerImpl::RegisterApplication( // Set cloud app parameters application->set_cloud_app_endpoint((*it)->cloud_app_endpoint()); application->set_cloud_app_certificate((*it)->cloud_app_certificate()); - application->set_cloud_app_auth_token((*it)->cloud_app_auth_token()); + application->set_auth_token((*it)->auth_token()); application->set_cloud_app_transport_type( (*it)->cloud_app_transport_type()); application->set_hybrid_app_preference((*it)->hybrid_app_preference()); @@ -676,6 +698,10 @@ ApplicationSharedPtr ApplicationManagerImpl::RegisterApplication( apps_size_ = applications_.size(); applications_list_lock_ptr_->Release(); + // Update cloud app information, in case any pending apps are unable to be + // registered due to a mobile app taking precedence + RefreshCloudAppInformation(); + // It is possible that secondary transport of this app has been already // established. Make sure that the information is reflected to application // instance. @@ -811,21 +837,116 @@ void ApplicationManagerImpl::OnHMIStartedCooperation() { RefreshCloudAppInformation(); } +std::string ApplicationManagerImpl::PolicyIDByIconUrl(const std::string url) { + sync_primitives::AutoLock lock(app_icon_map_lock_ptr_); + for (auto& x : app_icon_map_) { + auto policy_id = x.first; + std::string icon_url = GetPolicyHandler().GetIconUrl(policy_id); + if (icon_url == url) { + LOG4CXX_DEBUG(logger_, "Matched icon url: " << url); + x.second.pending_request = false; + return policy_id; + } + } + return std::string(""); +} + +void ApplicationManagerImpl::SetIconFileFromSystemRequest( + const std::string policy_id) { + app_icon_map_lock_ptr_.Acquire(); + auto app_icon_it = app_icon_map_.find(policy_id); + if (app_icon_it != app_icon_map_.end()) { + app_icon_map_.erase(app_icon_it); + } + app_icon_map_lock_ptr_.Release(); + + // Find pending application and set icon path + auto app = pending_application_by_policy_id(policy_id); + if (!app) { + return; + } + const std::string app_icon_dir(settings_.app_icons_folder()); + const std::string full_icon_path(app_icon_dir + "/" + policy_id); + if (file_system::FileExists(full_icon_path)) { + LOG4CXX_DEBUG(logger_, "Set Icon Path: " << full_icon_path); + AppFile file; + file.is_persistent = true; + file.is_download_complete = true; + file.file_name = full_icon_path; + + std::string icon_url = GetPolicyHandler().GetIconUrl(policy_id); + std::string extension = boost::filesystem::extension(icon_url); + if (extension == "bmp" || extension == "BMP") { + file.file_type = mobile_apis::FileType::GRAPHIC_BMP; + } else if (extension == "JPEG" || extension == "jpeg" || + extension == "JPG" || extension == "jpg") { + file.file_type = mobile_apis::FileType::GRAPHIC_JPEG; + } else { + file.file_type = mobile_apis::FileType::GRAPHIC_PNG; + } + + app->AddFile(file); + app->set_app_icon_path(full_icon_path); + } + SendUpdateAppList(); +} + +void ApplicationManagerImpl::DisconnectCloudApp(ApplicationSharedPtr app) { + std::string endpoint; + std::string certificate; + std::string auth_token; + std::string cloud_transport_type; + std::string hybrid_app_preference; + bool enabled = true; + std::string policy_app_id = app->policy_app_id(); + GetPolicyHandler().GetCloudAppParameters(policy_app_id, + enabled, + endpoint, + certificate, + auth_token, + cloud_transport_type, + hybrid_app_preference); + if (app->IsRegistered() && app->is_cloud_app()) { + LOG4CXX_DEBUG(logger_, "Disabled app is registered, unregistering now"); + GetRPCService().ManageMobileCommand( + MessageHelper::GetOnAppInterfaceUnregisteredNotificationToMobile( + app->app_id(), + mobile_api::AppInterfaceUnregisteredReason::APP_UNAUTHORIZED), + commands::Command::SOURCE_SDL); + + OnAppUnauthorized(app->app_id()); + } + // Delete the cloud device + connection_handler().RemoveCloudAppDevice(app->device()); + + transport_manager::transport_adapter::CloudAppProperties properties{ + endpoint, + certificate, + enabled, + auth_token, + cloud_transport_type, + hybrid_app_preference}; + // Create device in pending state + LOG4CXX_DEBUG(logger_, "Re-adding the cloud app device"); + connection_handler().AddCloudAppDevice(policy_app_id, properties); +} + void ApplicationManagerImpl::RefreshCloudAppInformation() { LOG4CXX_AUTO_TRACE(logger_); std::vector<std::string> enabled_apps; GetPolicyHandler().GetEnabledCloudApps(enabled_apps); std::vector<std::string>::iterator enabled_it = enabled_apps.begin(); std::vector<std::string>::iterator enabled_end = enabled_apps.end(); - std::string endpoint = ""; - std::string certificate = ""; - std::string auth_token = ""; - std::string cloud_transport_type = ""; - std::string hybrid_app_preference = ""; + std::string endpoint; + std::string certificate; + std::string auth_token; + std::string cloud_transport_type; + std::string hybrid_app_preference_str; bool enabled = true; // Store old device map and clear the current map pending_device_map_lock_ptr_->Acquire(); + app_icon_map_lock_ptr_.Acquire(); std::map<std::string, std::string> old_device_map = pending_device_map_; pending_device_map_ = std::map<std::string, std::string>(); // Create a device for each newly enabled cloud app @@ -836,21 +957,82 @@ void ApplicationManagerImpl::RefreshCloudAppInformation() { certificate, auth_token, cloud_transport_type, - hybrid_app_preference); + hybrid_app_preference_str); + + mobile_apis::HybridAppPreference::eType hybrid_app_preference = + mobile_apis::HybridAppPreference::INVALID_ENUM; + smart_objects::EnumConversionHelper< + mobile_apis::HybridAppPreference::eType>:: + StringToEnum(hybrid_app_preference_str, &hybrid_app_preference); + + auto policy_id = *enabled_it; + policy::StringArray nicknames; + policy::StringArray app_hmi_types; + GetPolicyHandler().GetInitialAppData(policy_id, &nicknames, &app_hmi_types); + + if (nicknames.empty()) { + LOG4CXX_ERROR(logger_, "Cloud App missing nickname"); + continue; + } else if (mobile_apis::HybridAppPreference::MOBILE == + hybrid_app_preference) { + auto nickname_it = nicknames.begin(); + for (; nickname_it != nicknames.end(); ++nickname_it) { + auto app = application_by_name(*nickname_it); + if (app.use_count() != 0) { + LOG4CXX_ERROR( + logger_, + "Mobile app already registered for cloud app: " << *nickname_it); + continue; + } + } + } pending_device_map_.insert( - std::pair<std::string, std::string>(endpoint, *enabled_it)); + std::pair<std::string, std::string>(endpoint, policy_id)); // Determine which endpoints were disabled by erasing all enabled apps from // the old device list auto old_device_it = old_device_map.find(endpoint); if (old_device_it != old_device_map.end()) { old_device_map.erase(old_device_it); + } + + transport_manager::transport_adapter::CloudAppProperties properties{ + endpoint, + certificate, + enabled, + auth_token, + cloud_transport_type, + hybrid_app_preference_str}; + + // If the device was disconnected, this will reinitialize the device + connection_handler().AddCloudAppDevice(policy_id, properties); + + // Look for app icon url data and add to app_icon_url_map + std::string url = GetPolicyHandler().GetIconUrl(policy_id); + + if (url.empty()) { + LOG4CXX_DEBUG(logger_, "No Icon Url for cloud app"); + continue; + } + + auto app_icon_it = app_icon_map_.find(policy_id); + if (app_icon_it != app_icon_map_.end()) { + LOG4CXX_DEBUG(logger_, "Cloud App Already Exists in Icon Map"); continue; } - connection_handler().AddCloudAppDevice( - *enabled_it, endpoint, cloud_transport_type); + const std::string app_icon_dir(settings_.app_icons_folder()); + const std::string full_icon_path(app_icon_dir + "/" + policy_id); + if (!file_system::FileExists(full_icon_path)) { + int icon_map_size = app_icon_map_.size(); + AppIconInfo icon_info(endpoint, false); + LOG4CXX_DEBUG(logger_, + "Inserting cloud app into icon map: " << icon_map_size); + app_icon_map_.insert( + std::pair<std::string, AppIconInfo>(policy_id, icon_info)); + } } + app_icon_map_lock_ptr_.Release(); pending_device_map_lock_ptr_->Release(); int removed_app_count = 0; @@ -905,16 +1087,17 @@ void ApplicationManagerImpl::CreatePendingApplication( connection_handler::DeviceHandle device_id) { LOG4CXX_AUTO_TRACE(logger_); - std::string endpoint = ""; - std::string certificate = ""; - std::string auth_token = ""; - std::string cloud_transport_type = ""; - std::string hybrid_app_preference_str = ""; + std::string endpoint; + std::string certificate; + std::string auth_token; + std::string cloud_transport_type; + std::string hybrid_app_preference_str; bool enabled = true; std::string name = device_info.name(); pending_device_map_lock_ptr_->Acquire(); auto it = pending_device_map_.find(name); if (it == pending_device_map_.end()) { + pending_device_map_lock_ptr_->Release(); return; } pending_device_map_lock_ptr_->Release(); @@ -927,7 +1110,7 @@ void ApplicationManagerImpl::CreatePendingApplication( GetPolicyHandler().GetInitialAppData( policy_app_id, &nicknames, &app_hmi_types); - if (!nicknames.size()) { + if (nicknames.empty()) { LOG4CXX_ERROR(logger_, "Cloud App missing nickname"); return; } @@ -968,7 +1151,7 @@ void ApplicationManagerImpl::CreatePendingApplication( mobile_apis::HybridAppPreference::eType>:: StringToEnum(hybrid_app_preference_str, &hybrid_app_preference_enum); - if (!convert_result) { + if (!hybrid_app_preference_str.empty() && !convert_result) { LOG4CXX_ERROR( logger_, "Could not convert string to enum: " << hybrid_app_preference_str); @@ -977,7 +1160,7 @@ void ApplicationManagerImpl::CreatePendingApplication( application->set_hmi_application_id(GenerateNewHMIAppID()); application->set_cloud_app_endpoint(endpoint); - application->set_cloud_app_auth_token(auth_token); + application->set_auth_token(auth_token); application->set_cloud_app_transport_type(cloud_transport_type); application->set_hybrid_app_preference(hybrid_app_preference_enum); application->set_cloud_app_certificate(certificate); @@ -992,6 +1175,36 @@ void ApplicationManagerImpl::CreatePendingApplication( SendUpdateAppList(); } +void ApplicationManagerImpl::SetPendingApplicationState( + const transport_manager::ConnectionUID connection_id, + const transport_manager::DeviceInfo& device_info) { + std::string name = device_info.name(); + pending_device_map_lock_ptr_->Acquire(); + auto it = pending_device_map_.find(name); + if (it == pending_device_map_.end()) { + pending_device_map_lock_ptr_->Release(); + return; + } + pending_device_map_lock_ptr_->Release(); + + const std::string policy_app_id = it->second; + auto app = application_by_policy_id(policy_app_id); + + if (!app) { + return; + } + LOG4CXX_DEBUG(logger_, + "Unregister application and move into apps_to_register"); + { + sync_primitives::AutoLock lock(apps_to_register_list_lock_ptr_); + apps_to_register_.insert(app); + } + + UnregisterApplication( + app->app_id(), mobile_apis::Result::INVALID_ENUM, true, true); + app->MarkUnregistered(); +} + void ApplicationManagerImpl::OnConnectionStatusUpdated() { SendUpdateAppList(); } @@ -1246,6 +1459,7 @@ void ApplicationManagerImpl::OnDeviceListUpdated( so_to_send[jhs::S_PARAMS][jhs::S_CORRELATION_ID] = GetNextHMICorrelationID(); so_to_send[jhs::S_MSG_PARAMS] = *msg_params; rpc_service_->ManageHMICommand(update_list); + RefreshCloudAppInformation(); } void ApplicationManagerImpl::OnFindNewApplicationsRequest() { @@ -2741,6 +2955,7 @@ void ApplicationManagerImpl::UnregisterApplication( logger_, "There is no more SDL4 apps with device handle: " << handle); RemoveAppsWaitingForRegistration(handle); + RefreshCloudAppInformation(); SendUpdateAppList(); } } @@ -3625,7 +3840,15 @@ void ApplicationManagerImpl::OnPTUFinished(const bool ptu_result) { if (!ptu_result) { return; } + RefreshCloudAppInformation(); + + auto app_id = policy_handler_->GetAppIdForSending(); + auto app = application(app_id); + if (app) { + SendGetIconUrlNotifications(app->app_id(), app); + } + auto on_app_policy_updated = [](plugin_manager::RPCPlugin& plugin) { plugin.OnPolicyEvent(plugin_manager::kApplicationPolicyUpdated); }; @@ -3668,6 +3891,58 @@ void ApplicationManagerImpl::SendDriverDistractionState( } } +void ApplicationManagerImpl::SendGetIconUrlNotifications( + const uint32_t connection_key, ApplicationSharedPtr application) { + LOG4CXX_AUTO_TRACE(logger_); + std::vector<std::string> enabled_apps; + GetPolicyHandler().GetEnabledCloudApps(enabled_apps); + std::vector<std::string>::iterator enabled_it = enabled_apps.begin(); + std::vector<std::string>::iterator enabled_end = enabled_apps.end(); + sync_primitives::AutoLock lock(app_icon_map_lock_ptr_); + for (; enabled_it != enabled_end; ++enabled_it) { + auto app_icon_it = app_icon_map_.find(*enabled_it); + if (app_icon_it == app_icon_map_.end()) { + LOG4CXX_WARN(logger_, "Could not find cloud app in icon map"); + continue; + } + + std::string endpoint = app_icon_it->second.endpoint; + bool pending_request = app_icon_it->second.pending_request; + + if (pending_request) { + LOG4CXX_DEBUG(logger_, "Cloud app has already sent request"); + continue; + } + + std::string url = GetPolicyHandler().GetIconUrl(*enabled_it); + + if (url.empty()) { + LOG4CXX_DEBUG(logger_, "No Icon Url for cloud app"); + continue; + } + + LOG4CXX_DEBUG(logger_, "Creating Get Icon Request"); + + smart_objects::SmartObjectSPtr message = + std::make_shared<smart_objects::SmartObject>( + smart_objects::SmartType_Map); + (*message)[strings::params][strings::function_id] = + mobile_apis::FunctionID::OnSystemRequestID; + (*message)[strings::params][strings::connection_key] = connection_key; + (*message)[strings::params][strings::message_type] = + mobile_apis::messageType::notification; + (*message)[strings::params][strings::protocol_version] = + application->protocol_version(); + (*message)[strings::msg_params][strings::request_type] = + mobile_apis::RequestType::ICON_URL; + (*message)[strings::msg_params][strings::url] = url; + + app_icon_it->second.pending_request = true; + + rpc_service_->ManageMobileCommand(message, commands::Command::SOURCE_SDL); + } +} + protocol_handler::MajorProtocolVersion ApplicationManagerImpl::SupportedSDLVersion() const { LOG4CXX_AUTO_TRACE(logger_); diff --git a/src/components/application_manager/src/hmi_capabilities_impl.cc b/src/components/application_manager/src/hmi_capabilities_impl.cc index f67590543d..6cd6747e99 100644 --- a/src/components/application_manager/src/hmi_capabilities_impl.cc +++ b/src/components/application_manager/src/hmi_capabilities_impl.cc @@ -1170,6 +1170,20 @@ bool HMICapabilitiesImpl::load_capabilities_from_file() { smart_objects::SmartObject rc_capability_so; formatters::CFormatterJsonBase::jsonValueToObj(rc_capability, rc_capability_so); + if (rc_capability_so.keyExists("lightControlCapabilities")) { + if (rc_capability_so["lightControlCapabilities"].keyExists( + "supportedLights")) { + auto& lights = rc_capability_so["lightControlCapabilities"] + ["supportedLights"]; + auto it = lights.asArray()->begin(); + for (; it != lights.asArray()->end(); ++it) { + smart_objects::SmartObject& light_name_so = (*it)["name"]; + auto light_name = MessageHelper::CommonLightNameFromString( + light_name_so.asString()); + light_name_so = light_name; + } + } + } set_rc_capability(rc_capability_so); if (!rc_capability_so.empty()) { set_rc_supported(true); diff --git a/src/components/application_manager/src/hmi_state.cc b/src/components/application_manager/src/hmi_state.cc index 7be9668543..e220988f0e 100644 --- a/src/components/application_manager/src/hmi_state.cc +++ b/src/components/application_manager/src/hmi_state.cc @@ -45,7 +45,7 @@ CREATE_LOGGERPTR_GLOBAL(logger_, "HmiState") HmiState::HmiState(std::shared_ptr<Application> app, const ApplicationManager& app_mngr, StateID state_id) - : app_(app) + : hmi_app_id_(app->hmi_app_id()) , state_id_(state_id) , app_mngr_(app_mngr) , hmi_level_(mobile_apis::HMILevel::INVALID_ENUM) @@ -57,7 +57,7 @@ HmiState::HmiState(std::shared_ptr<Application> app, HmiState::HmiState(std::shared_ptr<Application> app, const ApplicationManager& app_mngr) - : app_(app) + : hmi_app_id_(app->hmi_app_id()) , state_id_(STATE_ID_REGULAR) , app_mngr_(app_mngr) , hmi_level_(mobile_apis::HMILevel::INVALID_ENUM) @@ -73,19 +73,27 @@ void HmiState::set_parent(HmiStatePtr parent) { } bool HmiState::is_navi_app() const { - return app_->is_navi(); + const ApplicationSharedPtr app = + app_mngr_.application_by_hmi_app(hmi_app_id_); + return app ? app->is_navi() : false; } bool HmiState::is_media_app() const { - return app_->is_media_application(); + const ApplicationSharedPtr app = + app_mngr_.application_by_hmi_app(hmi_app_id_); + return app ? app->is_media_application() : false; } bool HmiState::is_voice_communication_app() const { - return app_->is_voice_communication_supported(); + const ApplicationSharedPtr app = + app_mngr_.application_by_hmi_app(hmi_app_id_); + return app ? app->is_voice_communication_supported() : false; } bool HmiState::is_mobile_projection_app() const { - return app_->mobile_projection_enabled(); + const ApplicationSharedPtr app = + app_mngr_.application_by_hmi_app(hmi_app_id_); + return app ? app->mobile_projection_enabled() : false; } mobile_apis::AudioStreamingState::eType VRHmiState::audio_streaming_state() @@ -123,7 +131,9 @@ VideoStreamingHmiState::VideoStreamingHmiState( mobile_apis::VideoStreamingState::eType VideoStreamingHmiState::video_streaming_state() const { - if (app_->IsVideoApplication()) { + const ApplicationSharedPtr app = + app_mngr_.application_by_hmi_app(hmi_app_id_); + if (app && app->IsVideoApplication()) { return parent()->video_streaming_state(); } @@ -201,7 +211,7 @@ AudioSource::AudioSource(std::shared_ptr<Application> app, const ApplicationManager& app_mngr) : HmiState(app, app_mngr, STATE_ID_AUDIO_SOURCE) , keep_context_(app->keep_context()) { - app_->set_keep_context(false); + app->set_keep_context(false); } mobile_apis::HMILevel::eType AudioSource::hmi_level() const { @@ -260,7 +270,15 @@ std::ostream& operator<<(std::ostream& os, const HmiState::StateID src) { } std::ostream& operator<<(std::ostream& os, const HmiState& src) { - os << "HMIState(app id:" << src.app_->app_id() << ", state:" << src.state_id() + const ApplicationSharedPtr app = + src.app_mngr_.application_by_hmi_app(src.hmi_app_id_); + os << "HMIState(app id:"; + if (app) { + os << app->app_id(); + } else { + os << "(none)"; + } + os << ", hmi app id:" << src.hmi_app_id_ << ", state:" << src.state_id() << ", hmi_level:" << src.hmi_level() << ", audio:" << src.audio_streaming_state() << ", video:" << src.video_streaming_state() 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 7db2308c2c..0e44a53c6f 100644 --- a/src/components/application_manager/src/message_helper/message_helper.cc +++ b/src/components/application_manager/src/message_helper/message_helper.cc @@ -290,6 +290,17 @@ hmi_apis::Common_Language::eType MessageHelper::CommonLanguageFromString( return hmi_apis::Common_Language::INVALID_ENUM; } +hmi_apis::Common_LightName::eType MessageHelper::CommonLightNameFromString( + const std::string& lightName) { + using namespace ns_smart_device_link::ns_smart_objects; + hmi_apis::Common_LightName::eType value; + if (EnumConversionHelper<hmi_apis::Common_LightName::eType>::StringToEnum( + lightName, &value)) { + return value; + } + return hmi_apis::Common_LightName::INVALID_ENUM; +} + std::string MessageHelper::GetDeviceMacAddressForHandle( const transport_manager::DeviceHandle device_handle, const ApplicationManager& app_mngr) { @@ -1592,6 +1603,7 @@ bool MessageHelper::CreateHMIApplicationStruct( message[hmi_response::policy_app_id] = policy_app_id; const std::string icon_path = app->app_icon_path(); + if (file_system::FileExists(app->app_icon_path())) { message[strings::icon] = icon_path; } diff --git a/src/components/application_manager/src/policies/policy_handler.cc b/src/components/application_manager/src/policies/policy_handler.cc index c267ac5de9..6a164d196a 100644 --- a/src/components/application_manager/src/policies/policy_handler.cc +++ b/src/components/application_manager/src/policies/policy_handler.cc @@ -91,7 +91,8 @@ RequestTypeMap TypeToString = { {mobile_apis::RequestType::EMERGENCY, "EMERGENCY"}, {mobile_apis::RequestType::MEDIA, "MEDIA"}, {mobile_apis::RequestType::FOTA, "FOTA"}, - {mobile_apis::RequestType::OEM_SPECIFIC, "OEM_SPECIFIC"}}; + {mobile_apis::RequestType::OEM_SPECIFIC, "OEM_SPECIFIC"}, + {mobile_apis::RequestType::ICON_URL, "ICON_URL"}}; const std::string RequestTypeToString(mobile_apis::RequestType::eType type) { RequestTypeMap::const_iterator it = TypeToString.find(type); @@ -1576,6 +1577,11 @@ std::string PolicyHandler::GetLockScreenIconUrl() const { return policy_manager_->GetLockScreenIconUrl(); } +std::string PolicyHandler::GetIconUrl(const std::string& policy_app_id) const { + POLICY_LIB_CHECK(std::string("")); + return policy_manager_->GetIconUrl(policy_app_id); +} + uint32_t PolicyHandler::NextRetryTimeout() { POLICY_LIB_CHECK(0); LOG4CXX_AUTO_TRACE(logger_); @@ -1771,6 +1777,17 @@ void PolicyHandler::OnCertificateUpdated(const std::string& certificate_data) { } #endif // EXTERNAL_PROPRIETARY_MODE +void PolicyHandler::OnAuthTokenUpdated(const std::string& policy_app_id, + const std::string& auth_token) { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock lock(listeners_lock_); + HandlersCollection::const_iterator it = listeners_.begin(); + for (; it != listeners_.end(); ++it) { + PolicyHandlerObserver* observer = *it; + observer->OnAuthTokenUpdated(policy_app_id, auth_token); + } +} + void PolicyHandler::OnPTUFinished(const bool ptu_result) { LOG4CXX_AUTO_TRACE(logger_); sync_primitives::AutoLock lock(listeners_lock_); @@ -1852,7 +1869,7 @@ void PolicyHandler::GetEnabledCloudApps( policy_manager_->GetEnabledCloudApps(enabled_apps); } -void PolicyHandler::GetCloudAppParameters( +bool PolicyHandler::GetCloudAppParameters( const std::string& policy_app_id, bool& enabled, std::string& endpoint, @@ -1860,14 +1877,14 @@ void PolicyHandler::GetCloudAppParameters( std::string& auth_token, std::string& cloud_transport_type, std::string& hybrid_app_preference) const { - POLICY_LIB_CHECK_VOID(); - policy_manager_->GetCloudAppParameters(policy_app_id, - enabled, - endpoint, - certificate, - auth_token, - cloud_transport_type, - hybrid_app_preference); + POLICY_LIB_CHECK(false); + return policy_manager_->GetCloudAppParameters(policy_app_id, + enabled, + endpoint, + certificate, + auth_token, + cloud_transport_type, + hybrid_app_preference); } const bool PolicyHandler::CheckCloudAppEnabled( @@ -1898,43 +1915,76 @@ void PolicyHandler::OnSetCloudAppProperties( << strings::msg_params); return; } - const smart_objects::SmartObject& msg_params = message[strings::msg_params]; - if (!msg_params.keyExists(strings::app_id)) { + if (!message[strings::msg_params].keyExists(strings::properties)) { + LOG4CXX_ERROR(logger_, + "Message does not contain app properties " + << strings::msg_params); + return; + } + + const smart_objects::SmartObject& properties = + message[strings::msg_params][strings::properties]; + if (!properties.keyExists(strings::app_id)) { LOG4CXX_ERROR(logger_, "Message does not contain mandatory parameter " << strings::app_id); return; } - std::string policy_app_id(msg_params[strings::app_id].asString()); + std::string policy_app_id(properties[strings::app_id].asString()); policy_manager_->InitCloudApp(policy_app_id); - if (msg_params.keyExists(strings::enabled)) { - policy_manager_->SetCloudAppEnabled(policy_app_id, - msg_params[strings::enabled].asBool()); - + bool auth_token_update = false; + if (properties.keyExists(strings::enabled)) { + bool enabled = properties[strings::enabled].asBool(); + policy_manager_->SetCloudAppEnabled(policy_app_id, enabled); + auth_token_update = enabled; application_manager_.RefreshCloudAppInformation(); } - if (msg_params.keyExists(strings::cloud_app_auth_token)) { - policy_manager_->SetAppAuthToken( - policy_app_id, msg_params[strings::cloud_app_auth_token].asString()); + if (properties.keyExists(strings::auth_token)) { + std::string auth_token = properties[strings::auth_token].asString(); + policy_manager_->SetAppAuthToken(policy_app_id, auth_token); + auth_token_update = true; } - if (msg_params.keyExists(strings::cloud_transport_type)) { + if (properties.keyExists(strings::cloud_transport_type)) { policy_manager_->SetAppCloudTransportType( - policy_app_id, msg_params[strings::cloud_transport_type].asString()); + policy_app_id, properties[strings::cloud_transport_type].asString()); + } + if (properties.keyExists(strings::endpoint)) { + policy_manager_->SetAppEndpoint(policy_app_id, + properties[strings::endpoint].asString()); + } + if (properties.keyExists(strings::nicknames)) { + StringArray nicknames; + const smart_objects::SmartObject& nicknames_array = + properties[strings::nicknames]; + for (size_t i = 0; i < nicknames_array.length(); ++i) { + nicknames.push_back(nicknames_array[i].asString()); + } + policy_manager_->SetAppNicknames(policy_app_id, nicknames); } - if (msg_params.keyExists(strings::hybrid_app_preference)) { + if (properties.keyExists(strings::hybrid_app_preference)) { std::string hybrid_app_preference; mobile_apis::HybridAppPreference::eType value = static_cast<mobile_apis::HybridAppPreference::eType>( - msg_params[strings::hybrid_app_preference].asUInt()); + properties[strings::hybrid_app_preference].asUInt()); smart_objects::EnumConversionHelper< mobile_apis::HybridAppPreference::eType>:: EnumToString(value, &hybrid_app_preference); policy_manager_->SetHybridAppPreference(policy_app_id, hybrid_app_preference); } + + if (auth_token_update) { + bool enabled; + std::string end, cert, ctt, hap; + std::string auth_token; + + policy_manager_->GetCloudAppParameters( + policy_app_id, enabled, end, cert, auth_token, ctt, hap); + OnAuthTokenUpdated(policy_app_id, auth_token); + } } void PolicyHandler::GetAppServiceParameters( diff --git a/src/components/application_manager/src/smart_object_keys.cc b/src/components/application_manager/src/smart_object_keys.cc index 402a15ae60..a1dedd1d64 100644 --- a/src/components/application_manager/src/smart_object_keys.cc +++ b/src/components/application_manager/src/smart_object_keys.cc @@ -157,12 +157,14 @@ const char* green = "green"; const char* blue = "blue"; const char* display_layout = "displayLayout"; const char* icon_resumed = "iconResumed"; +const char* nicknames = "nicknames"; const char* enabled = "enabled"; -const char* cloud_app_auth_token = "cloudAppAuthToken"; +const char* auth_token = "authToken"; const char* cloud_transport_type = "cloudTransportType"; const char* hybrid_app_preference = "hybridAppPreference"; const char* is_cloud_application = "isCloudApplication"; const char* cloud_connection_status = "cloudConnectionStatus"; +const char* endpoint = "endpoint"; // PutFile const char* sync_file_name = "syncFileName"; diff --git a/src/components/application_manager/test/application_impl_test.cc b/src/components/application_manager/test/application_impl_test.cc index 301ed227b8..437f567538 100644 --- a/src/components/application_manager/test/application_impl_test.cc +++ b/src/components/application_manager/test/application_impl_test.cc @@ -118,6 +118,13 @@ class ApplicationImplTest : public ::testing::Test { AddSet hmi_action); void CheckCurrentHMIState(); + // 'directory_name' has to be declared prior to 'app_impl' so that when + // deleting ApplicationImplTest class, 'directory_name' will be removed + // after 'app_impl' runs its destructor. + // (ApplicationImpl's destructor calls CleanupFiles(), which will call + // application_manager_.get_settings().app_storage_folder() and will + // access 'directory_name'.) + const std::string directory_name = "./test_storage"; MockApplicationManagerSettings mock_application_manager_settings_; MockApplicationManager mock_application_manager_; std::shared_ptr<ApplicationImpl> app_impl; @@ -126,7 +133,6 @@ class ApplicationImplTest : public ::testing::Test { 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; HmiStatePtr testHmiState; HMILevel::eType test_lvl; 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 389f092e50..f27e252142 100644 --- a/src/components/application_manager/test/application_manager_impl_test.cc +++ b/src/components/application_manager/test/application_manager_impl_test.cc @@ -1435,8 +1435,7 @@ TEST_F(ApplicationManagerImplTest, ON_CALL(*waiting_app, device()).WillByDefault(Return(kDeviceId)); EXPECT_CALL(*waiting_app, cloud_app_endpoint()) .WillOnce(ReturnRef(kEndpoint)); - EXPECT_CALL(*waiting_app, cloud_app_auth_token()) - .WillOnce(ReturnRef(kAuthToken)); + EXPECT_CALL(*waiting_app, auth_token()).WillOnce(ReturnRef(kAuthToken)); EXPECT_CALL(*waiting_app, cloud_app_certificate()) .WillOnce(ReturnRef(kCertificate)); EXPECT_CALL(*waiting_app, cloud_app_transport_type()) @@ -1489,7 +1488,7 @@ TEST_F(ApplicationManagerImplTest, EXPECT_EQ(APIVersion::kAPIV3, application->version().max_supported_api_version); EXPECT_EQ(kEndpoint, application->cloud_app_endpoint()); - EXPECT_EQ(kAuthToken, application->cloud_app_auth_token()); + EXPECT_EQ(kAuthToken, application->auth_token()); EXPECT_EQ(kCertificate, application->cloud_app_certificate()); EXPECT_EQ(kTransportType, application->cloud_app_transport_type()); EXPECT_EQ(kHybridAppPreference, application->hybrid_app_preference()); diff --git a/src/components/application_manager/test/help_prompt_manager_test.cc b/src/components/application_manager/test/help_prompt_manager_test.cc index f921eb1dde..dc6635b049 100644 --- a/src/components/application_manager/test/help_prompt_manager_test.cc +++ b/src/components/application_manager/test/help_prompt_manager_test.cc @@ -136,10 +136,12 @@ class HelpPromptManagerTest : public ::testing::Test { typedef CommandsTest<CommandsTestMocks::kIsNice>::MockAppManager MockAppManager; MockAppManager app_mngr_; + // put this before ApplicationImplTest instance, so that app_mngr_settings_ + // will still exist during app_impl_'s destructor. + NiceMock<MockApplicationManagerSettings> app_mngr_settings_; std::shared_ptr<ApplicationImplTest> app_impl_; MockHmiInterfaces mock_hmi_interfaces_; NiceMock<event_engine_test::MockEventDispatcher> mock_event_dispatcher_; - NiceMock<MockApplicationManagerSettings> app_mngr_settings_; std::shared_ptr<application_manager_test::MockApplication> mock_app_; sync_primitives::Lock app_lock_; MockRPCService mock_rpc_service_; @@ -175,11 +177,6 @@ void HelpPromptManagerTest::SetUp() { mock_help_prompt_manager_ = std::shared_ptr<MockHelpPromptManager>(new MockHelpPromptManager()); - HmiStatePtr state = std::make_shared<HmiState>( - static_cast<std::shared_ptr<Application> >(mock_app_), - app_mngr_, - HmiState::STATE_ID_REGULAR); - std::string path = file_system::CreateDirectory("storage"); file_system::CreateFile(path + "/" + "certificate"); 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 d5b3752936..36d20f227d 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 @@ -343,14 +343,14 @@ class MockApplication : public ::application_manager::Application { MOCK_CONST_METHOD0(is_remote_control_supported, bool()); MOCK_METHOD1(set_remote_control_supported, void(const bool allow)); MOCK_CONST_METHOD0(cloud_app_endpoint, const std::string&()); - MOCK_CONST_METHOD0(cloud_app_auth_token, const std::string&()); + MOCK_CONST_METHOD0(auth_token, const std::string&()); MOCK_CONST_METHOD0(cloud_app_transport_type, const std::string&()); MOCK_CONST_METHOD0(hybrid_app_preference, const mobile_apis::HybridAppPreference::eType&()); MOCK_CONST_METHOD0(cloud_app_certificate, const std::string&()); MOCK_CONST_METHOD0(is_cloud_app, bool()); MOCK_METHOD1(set_cloud_app_endpoint, void(const std::string& endpoint)); - MOCK_METHOD1(set_cloud_app_auth_token, void(const std::string& auth_token)); + MOCK_METHOD1(set_auth_token, void(const std::string& auth_token)); MOCK_METHOD1(set_cloud_app_transport_type, void(const std::string& transport_type)); MOCK_METHOD1(set_hybrid_app_preference, 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 7889774fae..ac39c39f22 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 @@ -164,6 +164,8 @@ class MockMessageHelper { ApplicationManager& app_mngr)); MOCK_METHOD1(CommonLanguageFromString, hmi_apis::Common_Language::eType(const std::string& language)); + MOCK_METHOD1(CommonLightNameFromString, + hmi_apis::Common_LightName::eType(const std::string& lightName)); MOCK_METHOD1(CommonLanguageToString, std::string(hmi_apis::Common_Language::eType)); MOCK_METHOD2(CreateModuleInfoSO, diff --git a/src/components/application_manager/test/mock_message_helper.cc b/src/components/application_manager/test/mock_message_helper.cc index b3b3327ca9..518761c315 100644 --- a/src/components/application_manager/test/mock_message_helper.cc +++ b/src/components/application_manager/test/mock_message_helper.cc @@ -277,6 +277,12 @@ hmi_apis::Common_Language::eType MessageHelper::CommonLanguageFromString( language); } +hmi_apis::Common_LightName::eType MessageHelper::CommonLightNameFromString( + const std::string& lightName) { + return MockMessageHelper::message_helper_mock()->CommonLightNameFromString( + lightName); +} + smart_objects::SmartObjectSPtr MessageHelper::CreateModuleInfoSO( uint32_t function_id, ApplicationManager& app_mngr) { return MockMessageHelper::message_helper_mock()->CreateModuleInfoSO( 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 58fea00f82..9574f8d00f 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 @@ -170,34 +170,42 @@ class StateControllerImplTest : public ::testing::Test { am::ApplicationSharedPtr simple_app_; NiceMock<application_manager_test::MockApplication>* simple_app_ptr_; uint32_t simple_app_id_ = 1721; + uint32_t simple_hmi_app_id_ = 22770; // random number am::ApplicationSharedPtr navi_app_; NiceMock<application_manager_test::MockApplication>* navi_app_ptr_; uint32_t navi_app_id_ = 1762; + uint32_t navi_hmi_app_id_ = 17559; am::ApplicationSharedPtr media_app_; NiceMock<application_manager_test::MockApplication>* media_app_ptr_; uint32_t media_app_id_ = 1801; + uint32_t media_hmi_app_id_ = 12751; am::ApplicationSharedPtr vc_app_; NiceMock<application_manager_test::MockApplication>* vc_app_ptr_; uint32_t vc_app_id_ = 1825; + uint32_t vc_hmi_app_id_ = 14986; am::ApplicationSharedPtr media_navi_app_; NiceMock<application_manager_test::MockApplication>* media_navi_app_ptr_; uint32_t media_navi_app_id_ = 1855; + uint32_t media_navi_hmi_app_id_ = 16194; am::ApplicationSharedPtr media_vc_app_; NiceMock<application_manager_test::MockApplication>* media_vc_app_ptr_; uint32_t media_vc_app_id_ = 1881; + uint32_t media_vc_hmi_app_id_ = 12798; am::ApplicationSharedPtr navi_vc_app_; NiceMock<application_manager_test::MockApplication>* navi_vc_app_ptr_; uint32_t navi_vc_app_id_ = 1894; + uint32_t navi_vc_hmi_app_id_ = 10807; am::ApplicationSharedPtr media_navi_vc_app_; NiceMock<application_manager_test::MockApplication>* media_navi_vc_app_ptr_; uint32_t media_navi_vc_app_id_ = 1922; + uint32_t media_navi_vc_hmi_app_id_ = 21419; std::vector<am::HmiStatePtr> valid_states_for_audio_app_; std::vector<am::HmiStatePtr> valid_states_for_not_audio_app_; @@ -661,6 +669,7 @@ class StateControllerImplTest : public ::testing::Test { am::ApplicationSharedPtr ConfigureApp( NiceMock<application_manager_test::MockApplication>** app_mock, uint32_t app_id, + uint32_t hmi_app_id, bool media, bool navi, bool vc) { @@ -670,6 +679,7 @@ class StateControllerImplTest : public ::testing::Test { am::ApplicationSharedPtr app(*app_mock); ON_CALL(**app_mock, app_id()).WillByDefault(Return(app_id)); + ON_CALL(**app_mock, hmi_app_id()).WillByDefault(Return(hmi_app_id)); ON_CALL(**app_mock, is_media_application()).WillByDefault(Return(media)); ON_CALL(**app_mock, is_navi()).WillByDefault(Return(navi)); ON_CALL(**app_mock, is_voice_communication_supported()) @@ -871,21 +881,50 @@ class StateControllerImplTest : public ::testing::Test { } void ConfigureApps() { - simple_app_ = ConfigureApp( - &simple_app_ptr_, simple_app_id_, NOT_MEDIA, NOT_NAVI, NOT_VC); - media_app_ = - ConfigureApp(&media_app_ptr_, media_app_id_, MEDIA, NOT_NAVI, NOT_VC); - navi_app_ = - ConfigureApp(&navi_app_ptr_, navi_app_id_, NOT_MEDIA, NAVI, NOT_VC); - vc_app_ = ConfigureApp(&vc_app_ptr_, vc_app_id_, NOT_MEDIA, NOT_NAVI, VC); - media_navi_app_ = ConfigureApp( - &media_navi_app_ptr_, media_navi_app_id_, MEDIA, NAVI, NOT_VC); - media_vc_app_ = - ConfigureApp(&media_vc_app_ptr_, media_vc_app_id_, MEDIA, NOT_NAVI, VC); - navi_vc_app_ = - ConfigureApp(&navi_vc_app_ptr_, navi_vc_app_id_, NOT_MEDIA, NAVI, VC); - media_navi_vc_app_ = ConfigureApp( - &media_navi_vc_app_ptr_, media_navi_vc_app_id_, MEDIA, NAVI, VC); + simple_app_ = ConfigureApp(&simple_app_ptr_, + simple_app_id_, + simple_hmi_app_id_, + NOT_MEDIA, + NOT_NAVI, + NOT_VC); + media_app_ = ConfigureApp(&media_app_ptr_, + media_app_id_, + media_hmi_app_id_, + MEDIA, + NOT_NAVI, + NOT_VC); + navi_app_ = ConfigureApp(&navi_app_ptr_, + navi_app_id_, + navi_hmi_app_id_, + NOT_MEDIA, + NAVI, + NOT_VC); + vc_app_ = ConfigureApp( + &vc_app_ptr_, vc_app_id_, vc_hmi_app_id_, NOT_MEDIA, NOT_NAVI, VC); + media_navi_app_ = ConfigureApp(&media_navi_app_ptr_, + media_navi_app_id_, + media_navi_hmi_app_id_, + MEDIA, + NAVI, + NOT_VC); + media_vc_app_ = ConfigureApp(&media_vc_app_ptr_, + media_vc_app_id_, + media_vc_hmi_app_id_, + MEDIA, + NOT_NAVI, + VC); + navi_vc_app_ = ConfigureApp(&navi_vc_app_ptr_, + navi_vc_app_id_, + navi_vc_hmi_app_id_, + NOT_MEDIA, + NAVI, + VC); + media_navi_vc_app_ = ConfigureApp(&media_navi_vc_app_ptr_, + media_navi_vc_app_id_, + media_navi_vc_hmi_app_id_, + MEDIA, + NAVI, + VC); applications_list_.push_back(simple_app_); applications_list_.push_back(media_app_); applications_list_.push_back(navi_app_); @@ -914,6 +953,15 @@ class StateControllerImplTest : public ::testing::Test { ASSERT_EQ(navi_vc_app_->app_id(), navi_vc_app_id_); ASSERT_EQ(media_navi_vc_app_->app_id(), media_navi_vc_app_id_); + ASSERT_EQ(simple_app_->hmi_app_id(), simple_hmi_app_id_); + ASSERT_EQ(media_app_->hmi_app_id(), media_hmi_app_id_); + ASSERT_EQ(navi_app_->hmi_app_id(), navi_hmi_app_id_); + ASSERT_EQ(vc_app_->hmi_app_id(), vc_hmi_app_id_); + ASSERT_EQ(media_navi_app_->hmi_app_id(), media_navi_hmi_app_id_); + ASSERT_EQ(media_vc_app_->hmi_app_id(), media_vc_hmi_app_id_); + ASSERT_EQ(navi_vc_app_->hmi_app_id(), navi_vc_hmi_app_id_); + ASSERT_EQ(media_navi_vc_app_->hmi_app_id(), media_navi_vc_hmi_app_id_); + ASSERT_FALSE(simple_app_->IsAudioApplication()); ASSERT_TRUE(media_app_->IsAudioApplication()); ASSERT_TRUE(navi_app_->IsAudioApplication()); @@ -1040,6 +1088,8 @@ class StateControllerImplTest : public ::testing::Test { application_set_.insert(app); ON_CALL(app_manager_mock_, application(app->app_id())) .WillByDefault(Return(app)); + ON_CALL(app_manager_mock_, application_by_hmi_app(app->hmi_app_id())) + .WillByDefault(Return(app)); } am::HmiStatePtr NoneNotAudibleState() { @@ -1475,9 +1525,9 @@ TEST_F(StateControllerImplTest, NiceMock<application_manager_test::MockApplication>* app_moved_to_full_mock; app_in_full = - ConfigureApp(&app_in_full_mock, 1761, NOT_MEDIA, NOT_NAVI, NOT_VC); - app_moved_to_full = - ConfigureApp(&app_moved_to_full_mock, 1796, NOT_MEDIA, NOT_NAVI, NOT_VC); + ConfigureApp(&app_in_full_mock, 1761, 15685, NOT_MEDIA, NOT_NAVI, NOT_VC); + app_moved_to_full = ConfigureApp( + &app_moved_to_full_mock, 1796, 30093, NOT_MEDIA, NOT_NAVI, NOT_VC); InsertApplication(app_in_full); InsertApplication(app_moved_to_full); @@ -1549,11 +1599,11 @@ TEST_F(StateControllerImplTest, namespace SystemContext = mobile_apis::SystemContext; NiceMock<application_manager_test::MockApplication>* app_in_full_mock; am::ApplicationSharedPtr app_in_full = - ConfigureApp(&app_in_full_mock, 1761, MEDIA, NOT_NAVI, NOT_VC); + ConfigureApp(&app_in_full_mock, 1761, 15685, MEDIA, NOT_NAVI, NOT_VC); NiceMock<application_manager_test::MockApplication>* app_moved_to_full_mock; - am::ApplicationSharedPtr app_moved_to_full = - ConfigureApp(&app_moved_to_full_mock, 1796, MEDIA, NOT_NAVI, NOT_VC); + am::ApplicationSharedPtr app_moved_to_full = ConfigureApp( + &app_moved_to_full_mock, 1796, 30093, MEDIA, NOT_NAVI, NOT_VC); InsertApplication(app_in_full); InsertApplication(app_moved_to_full); @@ -1575,11 +1625,11 @@ TEST_F(StateControllerImplTest, NiceMock<application_manager_test::MockApplication>* app_in_limited_mock; am::ApplicationSharedPtr app_in_limited = - ConfigureApp(&app_in_limited_mock, 1761, NOT_MEDIA, NAVI, NOT_VC); + ConfigureApp(&app_in_limited_mock, 1761, 15685, NOT_MEDIA, NAVI, NOT_VC); NiceMock<application_manager_test::MockApplication>* app_moved_to_full_mock; am::ApplicationSharedPtr app_moved_to_full = - ConfigureApp(&app_moved_to_full_mock, 1796, NOT_MEDIA, NAVI, VC); + ConfigureApp(&app_moved_to_full_mock, 1796, 30093, NOT_MEDIA, NAVI, VC); InsertApplication(app_in_limited); InsertApplication(app_moved_to_full); @@ -1600,12 +1650,12 @@ TEST_F(StateControllerImplTest, namespace SystemContext = mobile_apis::SystemContext; NiceMock<application_manager_test::MockApplication>* app_in_limited_mock; am::ApplicationSharedPtr app_in_limited = - ConfigureApp(&app_in_limited_mock, 1761, NOT_MEDIA, NOT_NAVI, VC); + ConfigureApp(&app_in_limited_mock, 1761, 15685, NOT_MEDIA, NOT_NAVI, VC); NiceMock<application_manager_test::MockApplication>* app_moved_to_limited_mock; - am::ApplicationSharedPtr app_moved_to_limited = - ConfigureApp(&app_moved_to_limited_mock, 1796, NOT_MEDIA, NOT_NAVI, VC); + am::ApplicationSharedPtr app_moved_to_limited = ConfigureApp( + &app_moved_to_limited_mock, 1796, 30093, NOT_MEDIA, NOT_NAVI, VC); InsertApplication(app_in_limited); InsertApplication(app_moved_to_limited); @@ -1749,8 +1799,8 @@ TEST_F(StateControllerImplTest, namespace SystemContext = mobile_apis::SystemContext; NiceMock<application_manager_test::MockApplication>* app_moved_to_full_mock; - am::ApplicationSharedPtr app_moved_to_full = - ConfigureApp(&app_moved_to_full_mock, 1761, NOT_MEDIA, NOT_NAVI, NOT_VC); + am::ApplicationSharedPtr app_moved_to_full = ConfigureApp( + &app_moved_to_full_mock, 1761, 15685, NOT_MEDIA, NOT_NAVI, NOT_VC); am::ApplicationSharedPtr limited_app = media_app_; NiceMock<application_manager_test::MockApplication>* limited_app_mock = @@ -1758,7 +1808,7 @@ TEST_F(StateControllerImplTest, NiceMock<application_manager_test::MockApplication>* full_app_mock; am::ApplicationSharedPtr full_app = - ConfigureApp(&full_app_mock, 1796, NOT_MEDIA, NOT_NAVI, NOT_VC); + ConfigureApp(&full_app_mock, 1796, 30093, NOT_MEDIA, NOT_NAVI, NOT_VC); InsertApplication(app_moved_to_full); InsertApplication(limited_app); @@ -1786,16 +1836,16 @@ TEST_F( namespace SystemContext = mobile_apis::SystemContext; NiceMock<application_manager_test::MockApplication>* app_moved_to_full_mock; - am::ApplicationSharedPtr app_moved_to_full = - ConfigureApp(&app_moved_to_full_mock, 1761, MEDIA, NOT_NAVI, NOT_VC); + am::ApplicationSharedPtr app_moved_to_full = ConfigureApp( + &app_moved_to_full_mock, 1761, 15685, MEDIA, NOT_NAVI, NOT_VC); NiceMock<application_manager_test::MockApplication>* limited_app_mock; am::ApplicationSharedPtr limited_app = - ConfigureApp(&limited_app_mock, 1762, MEDIA, NOT_NAVI, NOT_VC); + ConfigureApp(&limited_app_mock, 1762, 17559, MEDIA, NOT_NAVI, NOT_VC); NiceMock<application_manager_test::MockApplication>* full_app_mock; am::ApplicationSharedPtr full_app = - ConfigureApp(&full_app_mock, 1796, NOT_MEDIA, NOT_NAVI, NOT_VC); + ConfigureApp(&full_app_mock, 1796, 30093, NOT_MEDIA, NOT_NAVI, NOT_VC); InsertApplication(app_moved_to_full); InsertApplication(limited_app); @@ -1823,16 +1873,16 @@ TEST_F( namespace SystemContext = mobile_apis::SystemContext; NiceMock<application_manager_test::MockApplication>* app_moved_to_full_mock; - am::ApplicationSharedPtr app_moved_to_full = - ConfigureApp(&app_moved_to_full_mock, 1761, MEDIA, NOT_NAVI, NOT_VC); + am::ApplicationSharedPtr app_moved_to_full = ConfigureApp( + &app_moved_to_full_mock, 1761, 15685, MEDIA, NOT_NAVI, NOT_VC); NiceMock<application_manager_test::MockApplication>* limited_app_mock; am::ApplicationSharedPtr limited_app = - ConfigureApp(&limited_app_mock, 1762, MEDIA, NOT_NAVI, NOT_VC); + ConfigureApp(&limited_app_mock, 1762, 17559, MEDIA, NOT_NAVI, NOT_VC); NiceMock<application_manager_test::MockApplication>* full_app_mock; am::ApplicationSharedPtr full_app = - ConfigureApp(&full_app_mock, 1796, NOT_MEDIA, NAVI, NOT_VC); + ConfigureApp(&full_app_mock, 1796, 30093, NOT_MEDIA, NAVI, NOT_VC); InsertApplication(app_moved_to_full); InsertApplication(limited_app); @@ -2845,14 +2895,7 @@ TEST_F(StateControllerImplTest, am::event_engine::Event event(event_id); event.set_smart_object(msg); - const HmiStatePtr state = - createHmiState(mobile_apis::HMILevel::HMI_FULL, - mobile_apis::AudioStreamingState::AUDIBLE, - mobile_apis::VideoStreamingState::NOT_STREAMABLE, - mobile_apis::SystemContext::SYSCTXT_MAIN); - EXPECT_CALL(*simple_app_ptr_, keep_context()).WillOnce(Return(true)); - EXPECT_CALL(*simple_app_ptr_, RegularHmiState()).WillOnce(Return(state)); EXPECT_CALL(*simple_app_ptr_, IsAudioApplication()) .WillRepeatedly(Return(true)); EXPECT_CALL(*simple_app_ptr_, CurrentHmiState()) @@ -2884,12 +2927,6 @@ TEST_F(StateControllerImplTest, OnEventChangedAudioSourceAppToBackground) { am::event_engine::Event event(event_id); event.set_smart_object(msg); - const HmiStatePtr state = - createHmiState(mobile_apis::HMILevel::HMI_LIMITED, - mobile_apis::AudioStreamingState::AUDIBLE, - mobile_apis::VideoStreamingState::NOT_STREAMABLE, - mobile_apis::SystemContext::SYSCTXT_MAIN); - EXPECT_CALL(*simple_app_ptr_, RegularHmiState()).WillOnce(Return(state)); EXPECT_CALL(*simple_app_ptr_, IsAudioApplication()) .WillRepeatedly(Return(true)); EXPECT_CALL(*simple_app_ptr_, CurrentHmiState()) 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 e9e7ba47a3..06eb4f232d 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 @@ -81,7 +81,7 @@ class ConnectionHandlerImpl ConnectionHandlerImpl(const ConnectionHandlerSettings& settings, transport_manager::TransportManager& tm); /** - * \brief Destructor + * @brief Destructor */ ~ConnectionHandlerImpl(); @@ -130,9 +130,10 @@ class ConnectionHandlerImpl void ConnectToAllDevices() OVERRIDE; - void AddCloudAppDevice(const std::string& policy_app_id, - const std::string& endpoint, - const std::string& cloud_transport_type) OVERRIDE; + void AddCloudAppDevice( + const std::string& policy_app_id, + const transport_manager::transport_adapter::CloudAppProperties& + cloud_properties) OVERRIDE; void RemoveCloudAppDevice(const DeviceHandle device_id) OVERRIDE; @@ -378,6 +379,15 @@ class ConnectionHandlerImpl const protocol_handler::ServiceType& service_type) const OVERRIDE; /** + * @brief Get cloud app id by connection id + * @param connection_id unique connection id + * @return the policy app id of the cloud app if the connection is tied to a + * cloud app, an empty string otherwise. + */ + std::string GetCloudAppID( + const transport_manager::ConnectionUID connection_id) const OVERRIDE; + + /** * \brief Get device handle by mac address * \param mac_address uniq address * \param device_handle @@ -655,6 +665,12 @@ class ConnectionHandlerImpl std::map<uint32_t, protocol_handler::SessionContext> start_service_context_map_; + // Map app id -> (cloud_app_endpoint, connection_uid) + mutable sync_primitives::Lock cloud_app_id_map_lock_; + std::map<std::string, + std::pair<std::string, transport_manager::ConnectionUID> > + cloud_app_id_map_; + /** * @brief connection object as it's being closed */ diff --git a/src/components/connection_handler/src/connection_handler_impl.cc b/src/components/connection_handler/src/connection_handler_impl.cc index 679cbd1af0..7e93e04047 100644 --- a/src/components/connection_handler/src/connection_handler_impl.cc +++ b/src/components/connection_handler/src/connection_handler_impl.cc @@ -270,6 +270,17 @@ void ConnectionHandlerImpl::OnConnectionPending( LOG4CXX_DEBUG(logger_, "Add Pending Connection #" << connection_id << " to the list."); + std::string endpoint = device_info.mac_address(); + cloud_app_id_map_lock_.Acquire(); + for (auto it = cloud_app_id_map_.begin(); it != cloud_app_id_map_.end(); + ++it) { + if (endpoint == it->second.first) { + it->second.second = connection_id; + break; + } + } + cloud_app_id_map_lock_.Release(); + sync_primitives::AutoWriteLock lock(connection_list_lock_); if (connection_list_.find(connection_id) == connection_list_.end()) { Connection* connection = @@ -286,6 +297,9 @@ void ConnectionHandlerImpl::OnConnectionPending( connection_handler_observer_->CreatePendingApplication( connection_id, device_info, device_id); + } else { + connection_handler_observer_->SetPendingApplicationState(connection_id, + device_info); } } @@ -1108,6 +1122,18 @@ const uint8_t ConnectionHandlerImpl::GetSessionIdFromSecondaryTransport( return 0; } +std::string ConnectionHandlerImpl::GetCloudAppID( + const transport_manager::ConnectionUID connection_id) const { + sync_primitives::AutoLock auto_lock(cloud_app_id_map_lock_); + for (auto it = cloud_app_id_map_.begin(); it != cloud_app_id_map_.end(); + ++it) { + if (connection_id == it->second.second) { + return it->first; + } + } + return std::string(); +} + struct CompareMAC { explicit CompareMAC(const std::string& mac) : mac_(mac) {} bool operator()(const DeviceMap::value_type& device) { @@ -1325,9 +1351,13 @@ void ConnectionHandlerImpl::ConnectToAllDevices() { void ConnectionHandlerImpl::AddCloudAppDevice( const std::string& policy_app_id, - const std::string& endpoint, - const std::string& cloud_transport_type) { - transport_manager_.AddCloudDevice(endpoint, cloud_transport_type); + const transport_manager::transport_adapter::CloudAppProperties& + cloud_properties) { + cloud_app_id_map_lock_.Acquire(); + cloud_app_id_map_[policy_app_id] = + std::make_pair(cloud_properties.endpoint, 0); + cloud_app_id_map_lock_.Release(); + transport_manager_.AddCloudDevice(cloud_properties); } void ConnectionHandlerImpl::RemoveCloudAppDevice(const DeviceHandle device_id) { diff --git a/src/components/include/application_manager/application_manager.h b/src/components/include/application_manager/application_manager.h index 863ec093f0..97140a18f1 100644 --- a/src/components/include/application_manager/application_manager.h +++ b/src/components/include/application_manager/application_manager.h @@ -153,6 +153,8 @@ class ApplicationManager { connection_handler::ConnectionHandler* handler) = 0; virtual DataAccessor<ApplicationSet> applications() const = 0; + virtual DataAccessor<AppsWaitRegistrationSet> pending_applications() + const = 0; virtual ApplicationSharedPtr application(uint32_t app_id) const = 0; virtual ApplicationSharedPtr active_application() const = 0; @@ -168,6 +170,12 @@ class ApplicationManager { virtual ApplicationSharedPtr application_by_policy_id( const std::string& policy_app_id) const = 0; + virtual ApplicationSharedPtr application_by_name( + const std::string& app_name) const = 0; + + virtual ApplicationSharedPtr pending_application_by_policy_id( + const std::string& policy_app_id) const = 0; + virtual AppSharedPtrs applications_by_button(uint32_t button) = 0; virtual AppSharedPtrs applications_with_navi() = 0; @@ -286,6 +294,9 @@ class ApplicationManager { */ virtual void SendDriverDistractionState(ApplicationSharedPtr application) = 0; + virtual void SendGetIconUrlNotifications( + const uint32_t connection_key, ApplicationSharedPtr application) = 0; + /** * @brief Checks if Application is subscribed for way points * @param Application pointer @@ -431,8 +442,14 @@ class ApplicationManager { virtual void OnHMIStartedCooperation() = 0; + virtual void DisconnectCloudApp(ApplicationSharedPtr app) = 0; + virtual void RefreshCloudAppInformation() = 0; + virtual std::string PolicyIDByIconUrl(const std::string url) = 0; + + virtual void SetIconFileFromSystemRequest(const std::string policy_id) = 0; + /** * @brief Retrieve the current connection status of a cloud app * @param app A cloud application 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 64f0b893b2..7003e11473 100644 --- a/src/components/include/application_manager/policies/policy_handler_interface.h +++ b/src/components/include/application_manager/policies/policy_handler_interface.h @@ -105,6 +105,7 @@ class PolicyHandlerInterface { virtual void GetUpdateUrls(const uint32_t service_type, EndpointUrls& out_end_points) = 0; virtual std::string GetLockScreenIconUrl() const = 0; + virtual std::string GetIconUrl(const std::string& policy_app_id) const = 0; virtual uint32_t NextRetryTimeout() = 0; /** @@ -471,7 +472,7 @@ class PolicyHandlerInterface { * @param hybrid_app_preference Filled with the hybrid app preference for the * cloud application set by the user */ - virtual void GetCloudAppParameters( + virtual bool GetCloudAppParameters( const std::string& policy_app_id, bool& enabled, std::string& endpoint, diff --git a/src/components/include/application_manager/policies/policy_handler_observer.h b/src/components/include/application_manager/policies/policy_handler_observer.h index 1c32102184..c13846dff2 100644 --- a/src/components/include/application_manager/policies/policy_handler_observer.h +++ b/src/components/include/application_manager/policies/policy_handler_observer.h @@ -48,6 +48,9 @@ class PolicyHandlerObserver { return false; } + virtual void OnAuthTokenUpdated(const std::string& policy_app_id, + const std::string& auth_token) {} + virtual void OnPTUFinished(const bool ptu_result) {} virtual ~PolicyHandlerObserver() {} diff --git a/src/components/include/connection_handler/connection_handler.h b/src/components/include/connection_handler/connection_handler.h index a4058c7078..ea9cc6c039 100644 --- a/src/components/include/connection_handler/connection_handler.h +++ b/src/components/include/connection_handler/connection_handler.h @@ -103,9 +103,10 @@ class ConnectionHandler { virtual void ConnectToAllDevices() = 0; - virtual void AddCloudAppDevice(const std::string& policy_app_id, - const std::string& endpoint, - const std::string& cloud_transport_type) = 0; + virtual void AddCloudAppDevice( + const std::string& policy_app_id, + const transport_manager::transport_adapter::CloudAppProperties& + cloud_properties) = 0; virtual void RemoveCloudAppDevice(const DeviceHandle device_id) = 0; @@ -128,6 +129,15 @@ class ConnectionHandler { virtual uint32_t GetConnectionSessionsCount(uint32_t connection_key) = 0; /** + * @brief Get cloud app id by connection id + * @param connection_id unique connection id + * @return the policy app id of the cloud app if the connection is tied to a + * cloud app, an empty string otherwise. + */ + virtual std::string GetCloudAppID( + const transport_manager::ConnectionUID connection_id) const = 0; + + /** * Gets device id by mac address * @param mac_address * @return true if successfully diff --git a/src/components/include/connection_handler/connection_handler_observer.h b/src/components/include/connection_handler/connection_handler_observer.h index f683318ada..b9d6a18926 100644 --- a/src/components/include/connection_handler/connection_handler_observer.h +++ b/src/components/include/connection_handler/connection_handler_observer.h @@ -168,6 +168,10 @@ class ConnectionHandlerObserver { const transport_manager::DeviceInfo& device_info, connection_handler::DeviceHandle device_id) = 0; + virtual void SetPendingApplicationState( + const transport_manager::ConnectionUID connection_id, + const transport_manager::DeviceInfo& device_info) = 0; + protected: /** * \brief Destructor diff --git a/src/components/include/policy/policy_external/policy/policy_listener.h b/src/components/include/policy/policy_external/policy/policy_listener.h index c446c87d1b..8299d019f5 100644 --- a/src/components/include/policy/policy_external/policy/policy_listener.h +++ b/src/components/include/policy/policy_external/policy/policy_listener.h @@ -115,6 +115,16 @@ class PolicyListener { virtual void OnCertificateUpdated(const std::string& certificate_data) = 0; /** + * @brief OnAuthTokenUpdated the callback which signals if an app's auth token + * field has been updated during a PTU + * + * @param policy_app_id the policy app id tied to the updated field. + * @param auth_token the value of the updated field. + */ + virtual void OnAuthTokenUpdated(const std::string& policy_app_id, + const std::string& auth_token) = 0; + + /** * @brief OnPTUFinishedd the callback which signals PTU has finished * * @param ptu_result the result from the PTU - true if successful, 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 e7aefe9f6c..80365f10ab 100644 --- a/src/components/include/policy/policy_external/policy/policy_manager.h +++ b/src/components/include/policy/policy_external/policy/policy_manager.h @@ -109,12 +109,21 @@ class PolicyManager : public usage_statistics::StatisticsManager { /** * @brief GetLockScreenIcon allows to obtain lock screen icon url; - * @return url which point to the resourse where lock screen icon could be + * @return url which point to the resource where lock screen icon could be *obtained. */ virtual std::string GetLockScreenIconUrl() const = 0; /** + * @brief Get Icon Url used for showing a cloud apps icon before the initial + *registration + * + * @return url which point to the resource where icon could be + *obtained. + */ + virtual std::string GetIconUrl(const std::string& policy_app_id) const = 0; + + /** * @brief PTU is needed, for this PTS has to be formed and sent. */ virtual void RequestPTUpdate() = 0; @@ -546,7 +555,7 @@ class PolicyManager : public usage_statistics::StatisticsManager { * @param hybrid_app_preference Filled with the hybrid app preference for the * cloud application set by the user */ - virtual void GetCloudAppParameters( + virtual bool GetCloudAppParameters( const std::string& policy_app_id, bool& enabled, std::string& endpoint, @@ -584,6 +593,20 @@ class PolicyManager : public usage_statistics::StatisticsManager { const std::string& cloud_transport_type) = 0; /** + * @brief Set a cloud app's endpoint url + * @param endpoint URL for websocket connection + */ + virtual void SetAppEndpoint(const std::string& policy_app_id, + const std::string& endpoint) = 0; + + /** + * @brief Set a cloud app's nicknames + * @param nicknames Nicknames for cloud app + */ + virtual void SetAppNicknames(const std::string& policy_app_id, + const StringArray& nicknames) = 0; + + /** * @brief Set the user preference for how a hybrid (cloud and mobile) app * should be used * @param hybrid_app_preference Hybrid app user preference diff --git a/src/components/include/policy/policy_regular/policy/policy_listener.h b/src/components/include/policy/policy_regular/policy/policy_listener.h index 3f6f555bcc..56e674e81b 100644 --- a/src/components/include/policy/policy_regular/policy/policy_listener.h +++ b/src/components/include/policy/policy_regular/policy/policy_listener.h @@ -113,6 +113,16 @@ class PolicyListener { virtual void OnCertificateUpdated(const std::string& certificate_data) = 0; /** + * @brief OnAuthTokenUpdated the callback which signals if an app's auth token + * field has been updated during a PTU + * + * @param policy_app_id the policy app id tied to the updated field. + * @param auth_token the value of the updated field. + */ + virtual void OnAuthTokenUpdated(const std::string& policy_app_id, + const std::string& auth_token) = 0; + + /** * Gets devices ids by policy application id * @param policy_app_id * @return list devices ids 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 e4ee95fda0..bcb55ed681 100644 --- a/src/components/include/policy/policy_regular/policy/policy_manager.h +++ b/src/components/include/policy/policy_regular/policy/policy_manager.h @@ -87,12 +87,21 @@ class PolicyManager : public usage_statistics::StatisticsManager { /** * @brief GetLockScreenIcon allows to obtain lock screen icon url; - * @return url which point to the resourse where lock screen icon could be + * @return url which point to the resource where lock screen icon could be *obtained. */ virtual std::string GetLockScreenIconUrl() const = 0; /** + * @brief Get Icon Url used for showing a cloud apps icon before the initial + *registration + * + * @return url which point to the resource where icon could be + *obtained. + */ + virtual std::string GetIconUrl(const std::string& policy_app_id) const = 0; + + /** * @brief Gets all URLs for sending PTS to from PT itself. * @param service_type Service specifies user of URL * @param out_end_points output vector of urls @@ -526,7 +535,7 @@ class PolicyManager : public usage_statistics::StatisticsManager { * @param hybrid_app_preference Filled with the hybrid app preference for the * cloud application set by the user */ - virtual void GetCloudAppParameters( + virtual bool GetCloudAppParameters( const std::string& policy_app_id, bool& enabled, std::string& endpoint, @@ -565,6 +574,20 @@ class PolicyManager : public usage_statistics::StatisticsManager { const std::string& cloud_transport_type) = 0; /** + * @brief Set a cloud app's endpoint url + * @param endpoint URL for websocket connection + */ + virtual void SetAppEndpoint(const std::string& policy_app_id, + const std::string& endpoint) = 0; + + /** + * @brief Set a cloud app's nicknames + * @param nicknames Nicknames for cloud app + */ + virtual void SetAppNicknames(const std::string& policy_app_id, + const StringArray& nicknames) = 0; + + /** * @brief Set the user preference for how a hybrid (cloud and mobile) app * should be used * @param hybrid_app_preference Hybrid app user preference diff --git a/src/components/include/protocol/bson_object_keys.h b/src/components/include/protocol/bson_object_keys.h index 56bd5cebd6..f81de4cc81 100644 --- a/src/components/include/protocol/bson_object_keys.h +++ b/src/components/include/protocol/bson_object_keys.h @@ -48,6 +48,7 @@ extern const char* video_service_transports; extern const char* tcp_ip_address; extern const char* tcp_port; extern const char* reason; +extern const char* auth_token; } // namespace strings 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 1b9fe5ed1c..4f09d2c2f9 100644 --- a/src/components/include/test/application_manager/mock_application_manager.h +++ b/src/components/include/test/application_manager/mock_application_manager.h @@ -74,6 +74,9 @@ class MockApplicationManager : public application_manager::ApplicationManager { void(connection_handler::ConnectionHandler* handler)); MOCK_CONST_METHOD0(applications, DataAccessor<application_manager::ApplicationSet>()); + MOCK_CONST_METHOD0( + pending_applications, + DataAccessor<application_manager::AppsWaitRegistrationSet>()); MOCK_CONST_METHOD1( application, application_manager::ApplicationSharedPtr(uint32_t app_id)); MOCK_CONST_METHOD0(active_application, @@ -99,6 +102,12 @@ class MockApplicationManager : public application_manager::ApplicationManager { MOCK_CONST_METHOD1(application_by_policy_id, application_manager::ApplicationSharedPtr( const std::string& policy_app_id)); + MOCK_CONST_METHOD1( + application_by_name, + application_manager::ApplicationSharedPtr(const std::string& app_name)); + MOCK_CONST_METHOD1(pending_application_by_policy_id, + application_manager::ApplicationSharedPtr( + const std::string& policy_app_id)); MOCK_METHOD1( applications_by_button, std::vector<application_manager::ApplicationSharedPtr>(uint32_t button)); @@ -126,6 +135,9 @@ class MockApplicationManager : public application_manager::ApplicationManager { void(const std::shared_ptr<application_manager::Application> app)); MOCK_METHOD1(SendDriverDistractionState, void(application_manager::ApplicationSharedPtr app)); + MOCK_METHOD2(SendGetIconUrlNotifications, + void(const uint32_t connection_key, + application_manager::ApplicationSharedPtr application)); MOCK_METHOD2(RemoveHMIFakeParameters, void(application_manager::commands::MessageSharedPtr& message, const hmi_apis::FunctionID::eType& function_id)); @@ -169,10 +181,14 @@ class MockApplicationManager : public application_manager::ApplicationManager { MOCK_METHOD1(EndAudioPassThru, bool(uint32_t app_id)); MOCK_METHOD1(ConnectToDevice, void(const std::string& device_mac)); MOCK_METHOD0(OnHMIStartedCooperation, void()); + MOCK_METHOD1(DisconnectCloudApp, + void(application_manager::ApplicationSharedPtr app)); MOCK_METHOD0(RefreshCloudAppInformation, void()); MOCK_CONST_METHOD1(GetCloudAppConnectionStatus, hmi_apis::Common_CloudConnectionStatus::eType( application_manager::ApplicationConstSharedPtr app)); + MOCK_METHOD1(PolicyIDByIconUrl, std::string(const std::string url)); + MOCK_METHOD1(SetIconFileFromSystemRequest, void(const std::string policy_id)); MOCK_CONST_METHOD0(IsHMICooperating, bool()); MOCK_METHOD2(IviInfoUpdated, void(mobile_apis::VehicleDataType::eType vehicle_info, 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 1db0338caf..b6d8ab4cfa 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 @@ -102,6 +102,7 @@ class MockPolicyHandlerInterface : public policy::PolicyHandlerInterface { void(const uint32_t service_type, policy::EndpointUrls& end_points)); MOCK_CONST_METHOD0(GetLockScreenIconUrl, std::string()); + MOCK_CONST_METHOD1(GetIconUrl, std::string(const std::string& policy_app_id)); MOCK_METHOD0(ResetRetrySequence, void()); MOCK_METHOD0(NextRetryTimeout, uint32_t()); MOCK_CONST_METHOD0(TimeoutExchangeSec, uint32_t()); @@ -218,7 +219,7 @@ class MockPolicyHandlerInterface : public policy::PolicyHandlerInterface { MOCK_CONST_METHOD1(CheckCloudAppEnabled, const bool(const std::string& policy_app_id)); MOCK_CONST_METHOD7(GetCloudAppParameters, - void(const std::string& policy_app_id, + bool(const std::string& policy_app_id, bool& enabled, std::string& endpoint, std::string& certificate, 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 219ee7b561..8cc439c78a 100644 --- a/src/components/include/test/connection_handler/mock_connection_handler.h +++ b/src/components/include/test/connection_handler/mock_connection_handler.h @@ -66,14 +66,17 @@ class MockConnectionHandler : public connection_handler::ConnectionHandler { MOCK_CONST_METHOD2(RunAppOnDevice, void(const std::string&, const std::string&)); MOCK_METHOD0(ConnectToAllDevices, void()); - MOCK_METHOD3(AddCloudAppDevice, - void(const std::string& policy_app_id, - const std::string& endpoint, - const std::string& cloud_transport_type)); + MOCK_METHOD2( + AddCloudAppDevice, + void(const std::string& policy_app_id, + const transport_manager::transport_adapter::CloudAppProperties&)); MOCK_METHOD1(RemoveCloudAppDevice, void(const DeviceHandle device_id)); MOCK_METHOD1(CloseRevokedConnection, void(uint32_t connection_key)); MOCK_METHOD1(CloseConnection, void(ConnectionHandle connection_handle)); MOCK_METHOD1(GetConnectionSessionsCount, uint32_t(uint32_t connection_key)); + MOCK_CONST_METHOD1( + GetCloudAppID, + std::string(const transport_manager::ConnectionUID connection_id)); MOCK_METHOD2(GetDeviceID, bool(const std::string& mac_address, DeviceHandle* device_handle)); 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 0a8e71c085..552be4bee0 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 @@ -79,6 +79,9 @@ class MockConnectionHandlerObserver void(const transport_manager::ConnectionUID connection_id, const transport_manager::DeviceInfo& device_info, connection_handler::DeviceHandle device_id)); + MOCK_METHOD2(SetPendingApplicationState, + void(const transport_manager::ConnectionUID connection_id, + const transport_manager::DeviceInfo& device_info)); }; } // 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 25c391205d..ee8a111100 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 @@ -79,7 +79,7 @@ class MockCacheManagerInterface : public ::policy::CacheManagerInterface { MOCK_CONST_METHOD1(GetEnabledCloudApps, void(std::vector<std::string>& enabled_apps)); MOCK_CONST_METHOD7(GetCloudAppParameters, - void(const std::string& policy_app_id, + bool(const std::string& policy_app_id, bool& enabled, std::string& endpoint, std::string& certificate, @@ -95,6 +95,12 @@ class MockCacheManagerInterface : public ::policy::CacheManagerInterface { MOCK_METHOD2(SetAppCloudTransportType, void(const std::string& policy_app_id, const std::string& cloud_transport_type)); + MOCK_METHOD2(SetAppEndpoint, + void(const std::string& policy_app_id, + const std::string& endpoint)); + MOCK_METHOD2(SetAppNicknames, + void(const std::string& policy_app_id, + const StringArray& nicknames)); MOCK_METHOD2(SetHybridAppPreference, void(const std::string& policy_app_id, const std::string& hybrid_app_preference)); @@ -123,6 +129,7 @@ class MockCacheManagerInterface : public ::policy::CacheManagerInterface { MOCK_METHOD2(GetUpdateUrls, void(const uint32_t service_type, EndpointUrls& out_end_points)); MOCK_CONST_METHOD0(GetLockScreenIconUrl, std::string()); + MOCK_CONST_METHOD1(GetIconUrl, std::string(const std::string& policy_app_id)); MOCK_METHOD1( GetNotificationsNumber, policy_table::NumberOfNotificationsType(const std::string& priority)); diff --git a/src/components/include/test/policy/policy_external/policy/mock_policy_listener.h b/src/components/include/test/policy/policy_external/policy/mock_policy_listener.h index 1f570d8699..720a81862a 100644 --- a/src/components/include/test/policy/policy_external/policy/mock_policy_listener.h +++ b/src/components/include/test/policy/policy_external/policy/mock_policy_listener.h @@ -81,6 +81,9 @@ class MockPolicyListener : public ::policy::PolicyListener { uint32_t timeout_exceed)); MOCK_METHOD0(CanUpdate, bool()); MOCK_METHOD1(OnCertificateUpdated, void(const std::string&)); + MOCK_METHOD2(OnAuthTokenUpdated, + void(const std::string& policy_app_id, + const std::string& auth_token)); MOCK_METHOD1(OnPTUFinished, void(const bool ptu_result)); MOCK_CONST_METHOD2(SendOnAppPermissionsChanged, void(const policy::AppPermissions&, const std::string&)); 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 7c47202496..3f594ff6df 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 @@ -180,6 +180,7 @@ class MockPolicyManager : public PolicyManager { MOCK_METHOD1(OnAppRegisteredOnMobile, void(const std::string& application_id)); MOCK_CONST_METHOD0(GetLockScreenIconUrl, std::string()); + MOCK_CONST_METHOD1(GetIconUrl, std::string(const std::string& policy_app_id)); MOCK_CONST_METHOD1( GetAppRequestTypes, const std::vector<std::string>(const std::string policy_app_id)); @@ -203,6 +204,12 @@ class MockPolicyManager : public PolicyManager { MOCK_METHOD2(SetAppCloudTransportType, void(const std::string& policy_app_id, const std::string& cloud_transport_type)); + MOCK_METHOD2(SetAppEndpoint, + void(const std::string& policy_app_id, + const std::string& endpoint)); + MOCK_METHOD2(SetAppNicknames, + void(const std::string& policy_app_id, + const StringArray& nicknames)); MOCK_METHOD2(SetHybridAppPreference, void(const std::string& policy_app_id, const std::string& hybrid_app_preference)); 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 c8bff0bbc0..c92b310fcd 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 @@ -66,7 +66,7 @@ class MockCacheManagerInterface : public CacheManagerInterface { MOCK_CONST_METHOD1(GetEnabledCloudApps, void(std::vector<std::string>& enabled_apps)); MOCK_CONST_METHOD7(GetCloudAppParameters, - void(const std::string& policy_app_id, + bool(const std::string& policy_app_id, bool& enabled, std::string& endpoint, std::string& certificate, @@ -82,6 +82,12 @@ class MockCacheManagerInterface : public CacheManagerInterface { MOCK_METHOD2(SetAppCloudTransportType, void(const std::string& policy_app_id, const std::string& cloud_transport_type)); + MOCK_METHOD2(SetAppEndpoint, + void(const std::string& policy_app_id, + const std::string& endpoint)); + MOCK_METHOD2(SetAppNicknames, + void(const std::string& policy_app_id, + const StringArray& nicknames)); MOCK_METHOD2(SetHybridAppPreference, void(const std::string& policy_app_id, const std::string& hybrid_app_preference)); @@ -107,6 +113,7 @@ class MockCacheManagerInterface : public CacheManagerInterface { MOCK_METHOD2(GetUpdateUrls, void(const uint32_t service_type, EndpointUrls& out_end_points)); MOCK_CONST_METHOD0(GetLockScreenIconUrl, std::string()); + MOCK_CONST_METHOD1(GetIconUrl, std::string(const std::string& policy_app_id)); MOCK_METHOD2(Init, bool(const std::string& file_name, const PolicySettings* settings)); diff --git a/src/components/include/test/policy/policy_regular/policy/mock_policy_listener.h b/src/components/include/test/policy/policy_regular/policy/mock_policy_listener.h index 3b0c1a925e..045d4f4e4f 100644 --- a/src/components/include/test/policy/policy_regular/policy/mock_policy_listener.h +++ b/src/components/include/test/policy/policy_regular/policy/mock_policy_listener.h @@ -75,6 +75,9 @@ class MockPolicyListener : public ::policy::PolicyListener { MOCK_METHOD1(OnSnapshotCreated, void(const policy::BinaryMessage& pt_string)); MOCK_METHOD0(CanUpdate, bool()); MOCK_METHOD1(OnCertificateUpdated, void(const std::string&)); + MOCK_METHOD2(OnAuthTokenUpdated, + void(const std::string& policy_app_id, + const std::string& auth_token)); MOCK_CONST_METHOD2(SendOnAppPermissionsChanged, void(const policy::AppPermissions&, const std::string&)); MOCK_METHOD3(OnUpdateHMILevel, 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 fe0a301a58..ab49a6caae 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 @@ -184,7 +184,7 @@ class MockPolicyManager : public PolicyManager { MOCK_CONST_METHOD1(GetEnabledCloudApps, void(std::vector<std::string>& enabled_apps)); MOCK_CONST_METHOD7(GetCloudAppParameters, - void(const std::string& policy_app_id, + bool(const std::string& policy_app_id, bool& enabled, std::string& endpoint, std::string& certificate, @@ -200,6 +200,12 @@ class MockPolicyManager : public PolicyManager { MOCK_METHOD2(SetAppCloudTransportType, void(const std::string& policy_app_id, const std::string& cloud_transport_type)); + MOCK_METHOD2(SetAppEndpoint, + void(const std::string& policy_app_id, + const std::string& endpoint)); + MOCK_METHOD2(SetAppNicknames, + void(const std::string& policy_app_id, + const StringArray& nicknames)); MOCK_METHOD2(SetHybridAppPreference, void(const std::string& policy_app_id, const std::string& hybrid_app_preference)); @@ -230,6 +236,7 @@ class MockPolicyManager : public PolicyManager { MOCK_CONST_METHOD0(get_settings, const PolicySettings&()); MOCK_METHOD1(set_settings, void(const PolicySettings* get_settings)); MOCK_CONST_METHOD0(GetLockScreenIconUrl, std::string()); + MOCK_CONST_METHOD1(GetIconUrl, std::string(const std::string& policy_app_id)); MOCK_METHOD1(GetNextUpdateUrl, AppIdURL(const EndpointUrls& urls)); MOCK_CONST_METHOD2(RetrySequenceUrl, AppIdURL(const struct RetrySequenceURL&, diff --git a/src/components/include/test/transport_manager/mock_transport_manager.h b/src/components/include/test/transport_manager/mock_transport_manager.h index 40168c9c37..0581d4f375 100644 --- a/src/components/include/test/transport_manager/mock_transport_manager.h +++ b/src/components/include/test/transport_manager/mock_transport_manager.h @@ -59,9 +59,9 @@ class MockTransportManager : public ::transport_manager::TransportManager, MOCK_METHOD1(Init, int(resumption::LastState& last_state)); MOCK_METHOD0(Reinit, int()); MOCK_METHOD0(SearchDevices, int()); - MOCK_METHOD2(AddCloudDevice, - void(const std::string& endpoint, - const std::string& cloud_transport_type)); + MOCK_METHOD1( + AddCloudDevice, + void(const transport_manager::transport_adapter::CloudAppProperties)); MOCK_METHOD1(RemoveCloudDevice, void(const DeviceHandle device_id)); MOCK_METHOD1(ConnectDevice, int(const DeviceHandle)); MOCK_CONST_METHOD1( 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 2b3efd3624..eaa1fa9955 100644 --- a/src/components/include/transport_manager/transport_adapter/transport_adapter.h +++ b/src/components/include/transport_manager/transport_adapter/transport_adapter.h @@ -71,6 +71,15 @@ enum DeviceType { UNKNOWN }; +struct CloudAppProperties { + std::string endpoint; + std::string certificate; + bool enabled; + std::string auth_token; + std::string cloud_transport_type; + std::string hybrid_app_preference; +}; + typedef std::map<DeviceType, std::string> DeviceTypes; /** @@ -89,6 +98,7 @@ typedef std::list<TransportAdapterListener*> TransportAdapterListenerList; */ typedef std::map<std::string, std::string> TransportConfig; +typedef std::map<std::string, CloudAppProperties> CloudAppTransportConfig; /** * @brief TransportConfig keys */ diff --git a/src/components/include/transport_manager/transport_manager.h b/src/components/include/transport_manager/transport_manager.h index 2596ba1b77..4ccc78cd1b 100644 --- a/src/components/include/transport_manager/transport_manager.h +++ b/src/components/include/transport_manager/transport_manager.h @@ -75,8 +75,9 @@ class TransportManager { **/ virtual int SearchDevices() = 0; - virtual void AddCloudDevice(const std::string& endpoint, - const std::string& cloud_transport_type) = 0; + virtual void AddCloudDevice( + const transport_manager::transport_adapter::CloudAppProperties + cloud_properties) = 0; virtual void RemoveCloudDevice(const DeviceHandle device_id) = 0; diff --git a/src/components/interfaces/HMI_API.xml b/src/components/interfaces/HMI_API.xml index e927280718..004e0301c7 100644 --- a/src/components/interfaces/HMI_API.xml +++ b/src/components/interfaces/HMI_API.xml @@ -487,6 +487,9 @@ <element name="UNSUPPORTED_HMI_RESOURCE"> <description>By getting this value, SDL unregisters the named application</description> </element> + <element name="CLOSE_CLOUD_CONNECTION"> + <description>By getting this value, SDL puts the named app to NONE HMILevel. Used by the HMI to close a cloud app connection.</description> + </element> </enum> <enum name="TextFieldName"> @@ -1268,6 +1271,7 @@ <element name="MEDIA" /> <element name="FOTA" /> <element name="OEM_SPECIFIC"/> + <element name="ICON_URL"/> </enum> <enum name="ECallConfirmationStatus"> diff --git a/src/components/interfaces/MOBILE_API.xml b/src/components/interfaces/MOBILE_API.xml index 1d910e29bf..3b9614ab76 100644 --- a/src/components/interfaces/MOBILE_API.xml +++ b/src/components/interfaces/MOBILE_API.xml @@ -552,6 +552,26 @@ <element name="BOTH" /> </enum> + <struct name="CloudAppProperties" since="5.1"> + <param name="nicknames" type="String" minlength="0" maxlength="100" array="true" minsize="0" maxsize="100" mandatory="false"> + <description>An array of app names a cloud app is allowed to register with. If included in a SetCloudAppProperties request, this value will overwrite the existing "nicknames" field in the app policies section of the policy table.</description> + </param> + <param name="appID" type="String" maxlength="100" mandatory="true"></param> + <param name="enabled" type="Boolean" mandatory="false"> + <description>If true, cloud app will be included in HMI RPC UpdateAppList</description> + </param> + <param name="authToken" type="String" maxlength="65535" mandatory="false"> + <description>Used to authenticate websocket connection on app activation</description> + </param> + <param name="cloudTransportType" type="String" maxlength="100" mandatory="false"> + <description>Specifies the connection type Core should use</description> + </param> + <param name="hybridAppPreference" type="HybridAppPreference" mandatory="false"> + <description>Specifies the user preference to use the cloud app version or mobile app version when both are available</description> + </param> + <param name="endpoint" type="String" maxlength="65535" mandatory="false"></param> + </struct> + <enum name="ButtonName" since="1.0"> <description>Defines the hard (physical) and soft (touchscreen) buttons available from the module</description> <element name="OK" /> @@ -2419,6 +2439,7 @@ <element name="MEDIA" /> <element name="FOTA" /> <element name="OEM_SPECIFIC" since="5.0" /> + <element name="ICON_URL" since="5.1" /> </enum> <enum name="AppHMIType" since="2.0"> @@ -2617,10 +2638,11 @@ <element name="GetSystemCapabilityID" value="48" hexvalue="30" since="4.5" /> <element name="SendHapticDataID" value="49" hexvalue="31" since="4.5" /> <element name="SetCloudAppPropertiesID" value="50" hexvalue="32" since="5.1" /> + <element name="GetCloudAppPropertiesID" value="51" hexvalue="33" since="5.1" /> <element name="PublishAppServiceID" value="52" hexvalue="34" since="5.1" /> <element name="GetAppServiceDataID" value="53" hexvalue="35" since="5.1" /> - <element name="PerformAppServiceInteractionID" value="55" hexvalue="37" since="5.1" /> <element name="GetFileID" value="54" hexvalue="36" since="5.1" /> + <element name="PerformAppServiceInteractionID" value="55" hexvalue="37" since="5.1" /> <!-- Base Notifications @@ -7107,19 +7129,8 @@ <description> RPC used to enable/disable a cloud application and set authentication data </description> - <param name="appName" type="String" maxlength="100" mandatory="true"></param> - <param name="appID" type="String" maxlength="100" mandatory="true"></param> - <param name="enabled" type="Boolean" mandatory="false"> - <description>If true, cloud app will be included in HMI RPC UpdateAppList</description> - </param> - <param name="cloudAppAuthToken" type="String" maxlength="100" mandatory="false"> - <description>Used to authenticate websocket connection on app activation</description> - </param> - <param name="cloudTransportType" type="String" maxlength="100" mandatory="false"> - <description>Specifies the connection type Core should use</description> - </param> - <param name="hybridAppPreference" type="HybridAppPreference" mandatory="false"> - <description>Specifies the user preference to use the cloud app version or mobile app version when both are available</description> + <param name="properties" type="CloudAppProperties" mandatory="true"> + <description> The requested cloud application properties </description> </param> </function> @@ -7132,19 +7143,40 @@ </param> <param name="resultCode" type="Result" platform="documentation" mandatory="true"> <description>See Result</description> - <element name="SUCCESS" /> - <element name="INVALID_DATA" /> - <element name="OUT_OF_MEMORY" /> - <element name="TOO_MANY_PENDING_REQUESTS" /> - <element name="GENERIC_ERROR" /> - <element name="DUPLICATE_NAME" /> - <element name="TOO_MANY_APPLICATIONS" /> - <element name="APPLICATION_REGISTERED_ALREADY" /> - <element name="UNSUPPORTED_VERSION" /> - <element name="WRONG_LANGUAGE" /> - <element name="DISALLOWED" /> - <element name="WARNINGS" /> - <element name="RESUME_FAILED" /> + <element name="SUCCESS"/> + <element name="INVALID_DATA"/> + <element name="OUT_OF_MEMORY"/> + <element name="TOO_MANY_PENDING_REQUESTS"/> + <element name="GENERIC_ERROR"/> + <element name="DISALLOWED"/> + <element name="WARNINGS"/> + </param> + </function> + + <function name="GetCloudAppProperties" functionID="GetCloudAppPropertiesID" messagetype="request" since="5.1"> + <description> + RPC used to get the current properties of a cloud application + </description> + <param name="appID" type="String" maxlength="100" mandatory="true"></param> + </function> + + <function name="GetCloudAppProperties" functionID="GetCloudAppPropertiesID" messagetype="response" since="5.1"> + <description>The response to GetCloudAppProperties</description> + <param name="properties" type="CloudAppProperties" mandatory="false"> + <description> The requested cloud application properties </description> + </param> + <param name="success" type="Boolean" platform="documentation" mandatory="true"> + <description> true if successful; false if failed </description> + </param> + <param name="resultCode" type="Result" platform="documentation" mandatory="true"> + <description>See Result</description> + <element name="SUCCESS"/> + <element name="INVALID_DATA"/> + <element name="OUT_OF_MEMORY"/> + <element name="TOO_MANY_PENDING_REQUESTS"/> + <element name="GENERIC_ERROR"/> + <element name="DISALLOWED"/> + <element name="WARNINGS"/> </param> </function> 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 3813b58ca3..8dd8c3a9b9 100644 --- a/src/components/policy/policy_external/include/policy/cache_manager.h +++ b/src/components/policy/policy_external/include/policy/cache_manager.h @@ -182,7 +182,7 @@ class CacheManager : public CacheManagerInterface { * @param hybrid_app_preference Filled with the hybrid app preference for the * cloud application set by the user */ - virtual void GetCloudAppParameters(const std::string& policy_app_id, + virtual bool GetCloudAppParameters(const std::string& policy_app_id, bool& enabled, std::string& endpoint, std::string& certificate, @@ -221,6 +221,20 @@ class CacheManager : public CacheManagerInterface { const std::string& cloud_transport_type); /** + * @brief Set a cloud app's endpoint url + * @param endpoint URL for websocket connection + */ + virtual void SetAppEndpoint(const std::string& policy_app_id, + const std::string& endpoint); + + /** + * @brief Set a cloud app's nicknames + * @param nicknames Nicknames for cloud app + */ + virtual void SetAppNicknames(const std::string& policy_app_id, + const StringArray& nicknames); + + /** * @brief Set the user preference for how a hybrid (cloud and mobile) app * should be used * @param hybrid_app_preference Hybrid app user preference @@ -272,6 +286,15 @@ class CacheManager : public CacheManagerInterface { virtual std::string GetLockScreenIconUrl() const; /** + * @brief Get Icon Url used for showing a cloud apps icon before the intial + *registration + * + * @return url which point to the resourse where icon could be + *obtained. + */ + virtual std::string GetIconUrl(const std::string& policy_app_id) const; + + /** * @brief Gets list of URL to send PTS to * @param service_type If URLs for specific service are preset, * return them otherwise default URLs. 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 21c8a947cc..e5185ed1d3 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 @@ -189,7 +189,7 @@ class CacheManagerInterface { * @param hybrid_app_preference Filled with the hybrid app preference for the * cloud application set by the user */ - virtual void GetCloudAppParameters( + virtual bool GetCloudAppParameters( const std::string& policy_app_id, bool& enabled, std::string& endpoint, @@ -229,6 +229,20 @@ class CacheManagerInterface { const std::string& cloud_transport_type) = 0; /** + * @brief Set a cloud app's endpoint url + * @param endpoint URL for websocket connection + */ + virtual void SetAppEndpoint(const std::string& policy_app_id, + const std::string& endpoint) = 0; + + /** + * @brief Set a cloud app's nicknames + * @param nicknames Nicknames for cloud app + */ + virtual void SetAppNicknames(const std::string& policy_app_id, + const StringArray& nicknames) = 0; + + /** * @brief Set the user preference for how a hybrid (cloud and mobile) app * should be used * @param hybrid_app_preference Hybrid app user preference @@ -290,6 +304,15 @@ class CacheManagerInterface { virtual std::string GetLockScreenIconUrl() const = 0; /** + * @brief Get Icon Url used for showing a cloud apps icon before the intial + *registration + * + * @return url which point to the resourse where icon could be + *obtained. + */ + virtual std::string GetIconUrl(const std::string& policy_app_id) const = 0; + + /** * @brief Get allowed number of notifications * depending on application priority. * @param priority Priority of application 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 9cf067c0ec..09da4d6c9f 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 @@ -209,6 +209,15 @@ class PolicyManagerImpl : public PolicyManager { std::string GetLockScreenIconUrl() const OVERRIDE; /** + * @brief Get Icon Url used for showing a cloud apps icon before the intial + *registration + * + * @return url which point to the resourse where icon could be + *obtained. + */ + std::string GetIconUrl(const std::string& policy_app_id) const OVERRIDE; + + /** * @brief Handler of PTS sending out */ void OnUpdateStarted() OVERRIDE; @@ -594,7 +603,7 @@ class PolicyManagerImpl : public PolicyManager { * @param hybrid_app_preference Filled with the hybrid app preference for the * cloud application set by the user */ - void GetCloudAppParameters(const std::string& policy_app_id, + bool GetCloudAppParameters(const std::string& policy_app_id, bool& enabled, std::string& endpoint, std::string& certificate, @@ -631,6 +640,20 @@ class PolicyManagerImpl : public PolicyManager { const std::string& cloud_transport_type) OVERRIDE; /** + * @brief Set a cloud app's endpoint url + * @param endpoint URL for websocket connection + */ + void SetAppEndpoint(const std::string& policy_app_id, + const std::string& endpoint) OVERRIDE; + + /** + * @brief Set a cloud app's nicknames + * @param nicknames Nicknames for cloud app + */ + void SetAppNicknames(const std::string& policy_app_id, + const StringArray& nicknames) OVERRIDE; + + /** * @brief Set the user preference for how a hybrid (cloud and mobile) app * should be used * @param hybrid_app_preference Hybrid app user preference @@ -971,6 +994,12 @@ class PolicyManagerImpl : public PolicyManager { const std::string& application_id) OVERRIDE; /** + * @brief notify listener of updated auth token for a given policy id + * @param policy_app_id the app id that has an updated auth token + */ + void SendAuthTokenUpdated(const std::string policy_app_id); + + /** * @brief Gets all allowed module types * @param policy_app_id unique identifier of application * @param modules list of allowed module types diff --git a/src/components/policy/policy_external/include/policy/policy_table/enums.h b/src/components/policy/policy_external/include/policy/policy_table/enums.h index d2cf995e95..28b0caf95b 100644 --- a/src/components/policy/policy_external/include/policy/policy_table/enums.h +++ b/src/components/policy/policy_external/include/policy/policy_table/enums.h @@ -154,6 +154,7 @@ enum RequestType { RT_MEDIA, RT_FOTA, RT_OEM_SPECIFIC, + RT_ICON_URL, RT_EMPTY // Added to allow empty Request Types handling }; @@ -446,6 +447,11 @@ enum FunctionID { SetCloudAppPropertiesID = 50, /** + * @brief GetCloudAppPropertiesID. + */ + GetCloudAppPropertiesID = 51, + + /** * @brief PublishAppServiceID. */ PublishAppServiceID = 52, diff --git a/src/components/policy/policy_external/include/policy/policy_table/types.h b/src/components/policy/policy_external/include/policy/policy_table/types.h index 0edfa55ab8..f354a3176f 100644 --- a/src/components/policy/policy_external/include/policy/policy_table/types.h +++ b/src/components/policy/policy_external/include/policy/policy_table/types.h @@ -232,6 +232,7 @@ struct ApplicationParams : PolicyBase { Optional<Boolean> enabled; Optional<String<0, 65535> > auth_token; Optional<String<0, 255> > cloud_transport_type; + Optional<String<0, 65535> > icon_url; // App Service Params Optional<AppServiceParameters> app_service_parameters; diff --git a/src/components/policy/policy_external/include/policy/policy_table_interface_ext.xml b/src/components/policy/policy_external/include/policy/policy_table_interface_ext.xml index 7749c4ee8f..d2ce9f1022 100644 --- a/src/components/policy/policy_external/include/policy/policy_table_interface_ext.xml +++ b/src/components/policy/policy_external/include/policy/policy_table_interface_ext.xml @@ -108,9 +108,11 @@ <param name="cloud_transport_type" type="String" minlength="0" maxlength="255" mandatory="false" /> <param name="hybrid_app_preference" type="HybridAppPreference" mandatory="false" /> + <param name="icon_url" type="String" minlength="0" maxlength="65535" + mandatory="false" /> <param name="service_name" type="String" mandatory="false" /> <param name="service_type" type="String" mandatory="false" /> - <param name="handled_rpcs" array="true" mandatory="false"> + <param name="handled_rpcs" array="true" mandatory="false" /> </struct> <typedef name="HmiLevels" type="HmiLevel" array="true" diff --git a/src/components/policy/policy_external/src/cache_manager.cc b/src/components/policy/policy_external/src/cache_manager.cc index 6d400cd0b4..bfc0825d65 100644 --- a/src/components/policy/policy_external/src/cache_manager.cc +++ b/src/components/policy/policy_external/src/cache_manager.cc @@ -1403,7 +1403,7 @@ void CacheManager::GetEnabledCloudApps( } } -void CacheManager::GetCloudAppParameters( +bool CacheManager::GetCloudAppParameters( const std::string& policy_app_id, bool& enabled, std::string& endpoint, @@ -1432,7 +1432,9 @@ void CacheManager::GetCloudAppParameters( ? EnumToJsonString(*app_policy.hybrid_app_preference) : std::string(); enabled = app_policy.enabled.is_initialized() && *app_policy.enabled; + return true; } + return false; } void CacheManager::InitCloudApp(const std::string& policy_app_id) { @@ -1487,6 +1489,28 @@ void CacheManager::SetAppCloudTransportType( } } +void CacheManager::SetAppEndpoint(const std::string& policy_app_id, + const std::string& endpoint) { + policy_table::ApplicationPolicies& policies = + pt_->policy_table.app_policies_section.apps; + policy_table::ApplicationPolicies::iterator policy_iter = + policies.find(policy_app_id); + if (policies.end() != policy_iter) { + *(*policy_iter).second.endpoint = endpoint; + } +} + +void CacheManager::SetAppNicknames(const std::string& policy_app_id, + const StringArray& nicknames) { + policy_table::ApplicationPolicies& policies = + pt_->policy_table.app_policies_section.apps; + policy_table::ApplicationPolicies::iterator policy_iter = + policies.find(policy_app_id); + if (policies.end() != policy_iter) { + (*(*policy_iter).second.nicknames) = nicknames; + } +} + void CacheManager::SetHybridAppPreference( const std::string& policy_app_id, const std::string& hybrid_app_preference) { @@ -1619,6 +1643,21 @@ std::string CacheManager::GetLockScreenIconUrl() const { return std::string(""); } +std::string CacheManager::GetIconUrl(const std::string& policy_app_id) const { + CACHE_MANAGER_CHECK(std::string()); + std::string url; + const policy_table::ApplicationPolicies& policies = + pt_->policy_table.app_policies_section.apps; + policy_table::ApplicationPolicies::const_iterator policy_iter = + policies.find(policy_app_id); + if (policies.end() != policy_iter) { + auto app_policy = (*policy_iter).second; + url = app_policy.icon_url.is_initialized() ? *app_policy.icon_url + : std::string(); + } + return url; +} + rpc::policy_table_interface_base::NumberOfNotificationsType CacheManager::GetNotificationsNumber(const std::string& priority) { CACHE_MANAGER_CHECK(0); 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 404c48d2e4..4858611ba1 100644 --- a/src/components/policy/policy_external/src/policy_manager_impl.cc +++ b/src/components/policy/policy_external/src/policy_manager_impl.cc @@ -271,6 +271,11 @@ std::string PolicyManagerImpl::GetLockScreenIconUrl() const { return cache_->GetLockScreenIconUrl(); } +std::string PolicyManagerImpl::GetIconUrl( + const std::string& policy_app_id) const { + return cache_->GetIconUrl(policy_app_id); +} + /** * @brief FilterInvalidFunctions filter functions that are absent in schema * @param rpcs list of functions to filter @@ -497,6 +502,12 @@ bool PolicyManagerImpl::LoadPT(const std::string& file, } else { LOG4CXX_INFO(logger_, "app_hmi_types empty"); } + + std::vector<std::string> enabled_apps; + cache_->GetEnabledCloudApps(enabled_apps); + for (auto it = enabled_apps.begin(); it != enabled_apps.end(); ++it) { + SendAuthTokenUpdated(*it); + } } // If there was a user request for policy table update, it should be started @@ -730,7 +741,7 @@ void PolicyManagerImpl::GetEnabledCloudApps( cache_->GetEnabledCloudApps(enabled_apps); } -void PolicyManagerImpl::GetCloudAppParameters( +bool PolicyManagerImpl::GetCloudAppParameters( const std::string& policy_app_id, bool& enabled, std::string& endpoint, @@ -738,13 +749,13 @@ void PolicyManagerImpl::GetCloudAppParameters( std::string& auth_token, std::string& cloud_transport_type, std::string& hybrid_app_preference) const { - cache_->GetCloudAppParameters(policy_app_id, - enabled, - endpoint, - certificate, - auth_token, - cloud_transport_type, - hybrid_app_preference); + return cache_->GetCloudAppParameters(policy_app_id, + enabled, + endpoint, + certificate, + auth_token, + cloud_transport_type, + hybrid_app_preference); } void PolicyManagerImpl::InitCloudApp(const std::string& policy_app_id) { @@ -766,6 +777,16 @@ void PolicyManagerImpl::SetAppCloudTransportType( cache_->SetAppCloudTransportType(policy_app_id, cloud_transport_type); } +void PolicyManagerImpl::SetAppEndpoint(const std::string& policy_app_id, + const std::string& endpoint) { + cache_->SetAppEndpoint(policy_app_id, endpoint); +} + +void PolicyManagerImpl::SetAppNicknames(const std::string& policy_app_id, + const StringArray& nicknames) { + cache_->SetAppNicknames(policy_app_id, nicknames); +} + void PolicyManagerImpl::SetHybridAppPreference( const std::string& policy_app_id, const std::string& hybrid_app_preference) { @@ -2086,6 +2107,11 @@ bool PolicyManagerImpl::InitPT(const std::string& file_name, const bool ret = cache_->Init(file_name, settings); if (ret) { RefreshRetrySequence(); + std::vector<std::string> enabled_apps; + cache_->GetEnabledCloudApps(enabled_apps); + for (auto it = enabled_apps.begin(); it != enabled_apps.end(); ++it) { + SendAuthTokenUpdated(*it); + } } return ret; } @@ -2194,6 +2220,15 @@ void PolicyManagerImpl::SendAppPermissionsChanged( listener()->OnPermissionsUpdated(application_id, notification_data); } +void PolicyManagerImpl::SendAuthTokenUpdated(const std::string policy_app_id) { + bool enabled = false; + std::string end, cert, ctt, hap; + std::string auth_token; + cache_->GetCloudAppParameters( + policy_app_id, enabled, end, cert, auth_token, ctt, hap); + listener_->OnAuthTokenUpdated(policy_app_id, auth_token); +} + void PolicyManagerImpl::OnPrimaryGroupsChanged( const std::string& application_id) { const std::vector<std::string> devices = diff --git a/src/components/policy/policy_external/src/policy_table/enums.cc b/src/components/policy/policy_external/src/policy_table/enums.cc index 2a3d944f33..bb25623b35 100644 --- a/src/components/policy/policy_external/src/policy_table/enums.cc +++ b/src/components/policy/policy_external/src/policy_table/enums.cc @@ -629,6 +629,8 @@ bool IsValidEnum(RequestType val) { return true; case RT_OEM_SPECIFIC: return true; + case RT_ICON_URL: + return true; case RT_EMPTY: return true; default: @@ -680,6 +682,8 @@ const char* EnumToJsonString(RequestType val) { return "FOTA"; case RT_OEM_SPECIFIC: return "OEM_SPECIFIC"; + case RT_ICON_URL: + return "ICON_URL"; case RT_EMPTY: return "EMPTY"; default: @@ -772,6 +776,10 @@ bool EnumFromJsonString(const std::string& literal, RequestType* result) { *result = RT_OEM_SPECIFIC; return true; } + if ("ICON_URL" == literal) { + *result = RT_ICON_URL; + return true; + } if ("EMPTY" == literal) { *result = RT_EMPTY; return true; @@ -1126,6 +1134,11 @@ bool EnumFromJsonString(const std::string& literal, FunctionID* result) { return true; } + if ("GetCloudAppProperties" == literal) { + *result = GetCloudAppPropertiesID; + return true; + } + if ("PublishAppService" == literal) { *result = PublishAppServiceID; return true; diff --git a/src/components/policy/policy_external/src/policy_table/types.cc b/src/components/policy/policy_external/src/policy_table/types.cc index db28b5b4fb..ca14b20987 100644 --- a/src/components/policy/policy_external/src/policy_table/types.cc +++ b/src/components/policy/policy_external/src/policy_table/types.cc @@ -346,12 +346,13 @@ ApplicationParams::ApplicationParams(const Json::Value* value__) , memory_kb(impl::ValueMember(value__, "memory_kb"), 0) , heart_beat_timeout_ms(impl::ValueMember(value__, "heart_beat_timeout_ms")) , moduleType(impl::ValueMember(value__, "moduleType")) - , certificate(impl::ValueMember(value__, "certificate"), "not_specified") + , certificate(impl::ValueMember(value__, "certificate")) , hybrid_app_preference(impl::ValueMember(value__, "hybrid_app_preference")) , endpoint(impl::ValueMember(value__, "endpoint")) , enabled(impl::ValueMember(value__, "enabled")) , auth_token(impl::ValueMember(value__, "auth_token")) , cloud_transport_type(impl::ValueMember(value__, "cloud_transport_type")) + , icon_url(impl::ValueMember(value__, "icon_url")) , app_service_parameters(impl::ValueMember(value__, "app_services")) {} Json::Value ApplicationParams::ToJsonValue() const { @@ -371,6 +372,7 @@ Json::Value ApplicationParams::ToJsonValue() const { impl::WriteJsonField("enabled", enabled, &result__); impl::WriteJsonField("auth_token", auth_token, &result__); impl::WriteJsonField("cloud_transport_type", cloud_transport_type, &result__); + impl::WriteJsonField("icon_url", auth_token, &result__); impl::WriteJsonField("app_services", app_service_parameters, &result__); return result__; } @@ -414,6 +416,9 @@ bool ApplicationParams::is_valid() const { if (!hybrid_app_preference.is_valid()) { return false; } + if (!icon_url.is_valid()) { + return false; + } if (!app_service_parameters.is_valid()) { return false; } @@ -467,6 +472,9 @@ bool ApplicationParams::struct_empty() const { if (hybrid_app_preference.is_initialized()) { return false; } + if (icon_url.is_initialized()) { + return false; + } if (app_service_parameters.is_initialized()) { return false; } @@ -537,6 +545,9 @@ void ApplicationParams::ReportErrors(rpc::ValidationReport* report__) const { moduleType.ReportErrors( &report__->ReportSubobject("hybrid_app_preference")); } + if (!icon_url.is_valid()) { + moduleType.ReportErrors(&report__->ReportSubobject("icon_url")); + } if (!app_service_parameters.is_valid()) { app_service_parameters.ReportErrors( &report__->ReportSubobject("app_services")); @@ -556,6 +567,7 @@ void ApplicationParams::SetPolicyTableType(PolicyTableType pt_type) { enabled.SetPolicyTableType(pt_type); cloud_transport_type.SetPolicyTableType(pt_type); hybrid_app_preference.SetPolicyTableType(pt_type); + icon_url.SetPolicyTableType(pt_type); app_service_parameters.SetPolicyTableType(pt_type); } diff --git a/src/components/policy/policy_external/src/sql_pt_ext_queries.cc b/src/components/policy/policy_external/src/sql_pt_ext_queries.cc index 32320b6d6c..58206e2c69 100644 --- a/src/components/policy/policy_external/src/sql_pt_ext_queries.cc +++ b/src/components/policy/policy_external/src/sql_pt_ext_queries.cc @@ -207,8 +207,8 @@ const std::string kInsertApplication = " `default_hmi`, `priority_value`, `is_revoked`, `memory_kb`, " " `heart_beat_timeout_ms`, `certificate`, `hybrid_app_preference_value`, " " `endpoint`, `enabled`, `auth_token`, " - " `cloud_transport_type`) VALUES " - "(?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + " `cloud_transport_type`, `icon_url`) VALUES " + "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; const std::string kCollectFriendlyMsg = "SELECT * FROM `message`"; @@ -237,7 +237,7 @@ const std::string kSelectAppPolicies = "SELECT `id`, `priority_value`, `default_hmi`, `keep_context`, " " `steal_focus`, `memory_kb`, `heart_beat_timeout_ms`, `certificate`, " " `hybrid_app_preference_value`, `endpoint`, `enabled`, `auth_token` " - " `cloud_transport_type` FROM `application`"; + " `cloud_transport_type`, `icon_url` FROM `application`"; const std::string kSelectFunctionalGroupNames = "SELECT `id`, `user_consent_prompt`, `name`" diff --git a/src/components/policy/policy_external/src/sql_pt_ext_representation.cc b/src/components/policy/policy_external/src/sql_pt_ext_representation.cc index 6e0da9e5de..29970a4424 100644 --- a/src/components/policy/policy_external/src/sql_pt_ext_representation.cc +++ b/src/components/policy/policy_external/src/sql_pt_ext_representation.cc @@ -790,6 +790,9 @@ bool SQLPTExtRepresentation::SaveSpecificAppPolicy( app.second.cloud_transport_type.is_initialized() ? app_query.Bind(13, *app.second.cloud_transport_type) : app_query.Bind(13); + app.second.icon_url.is_initialized() + ? app_query.Bind(14, *app.second.icon_url) + : app_query.Bind(14); if (!app_query.Exec() || !app_query.Reset()) { LOG4CXX_WARN(logger_, "Incorrect insert into application."); @@ -932,6 +935,7 @@ bool SQLPTExtRepresentation::GatherApplicationPoliciesSection( } *params.auth_token = query.GetString(11); *params.cloud_transport_type = query.GetString(12); + *params.icon_url = query.GetString(13); const auto& gather_app_id = ((*policies).apps[app_id].is_string()) ? (*policies).apps[app_id].get_string() diff --git a/src/components/policy/policy_external/src/sql_pt_queries.cc b/src/components/policy/policy_external/src/sql_pt_queries.cc index 51f4e4c13e..dea0fb4166 100644 --- a/src/components/policy/policy_external/src/sql_pt_queries.cc +++ b/src/components/policy/policy_external/src/sql_pt_queries.cc @@ -156,6 +156,7 @@ const std::string kCreateSchema = " `enabled` BOOLEAN, " " `auth_token` VARCHAR(65535), " " `cloud_transport_type` VARCHAR(255), " + " `icon_url` VARCHAR(65535), " " `remote_control_denied` BOOLEAN NOT NULL DEFAULT 0, " " CONSTRAINT `fk_application_hmi_level1` " " FOREIGN KEY(`default_hmi`) " @@ -676,8 +677,8 @@ const std::string kInsertApplication = "INSERT OR IGNORE INTO `application` (`id`, `priority_value`, " "`is_revoked`, `memory_kb`, `heart_beat_timeout_ms`, `certificate`, " "`hybrid_app_preference_value`, `endpoint`, `enabled`, `auth_token`, " - "`cloud_transport_type`) VALUES " - "(?,?,?,?,?,?,?,?,?,?,?)"; + "`cloud_transport_type`, `icon_url`) VALUES " + "(?,?,?,?,?,?,?,?,?,?,?,?)"; const std::string kInsertAppGroup = "INSERT INTO `app_group` (`application_id`, `functional_group_id`)" @@ -816,7 +817,8 @@ const std::string kSelectUserMsgsVersion = const std::string kSelectAppPolicies = "SELECT `id`, `priority_value`, `memory_kb`, " " `heart_beat_timeout_ms`, `certificate`, `hybrid_app_preference_value`, " - " `endpoint`, `enabled`, `auth_token`, `cloud_transport_type` FROM " + " `endpoint`, `enabled`, `auth_token`, `cloud_transport_type`, `icon_url` " + "FROM " " `application`"; const std::string kCollectFriendlyMsg = "SELECT * FROM `message`"; @@ -939,14 +941,14 @@ const std::string kInsertApplicationFull = " `default_hmi`, `priority_value`, `is_revoked`, `is_default`, " " `is_predata`, `memory_kb`, `heart_beat_timeout_ms`, " " `certificate`, `hybrid_app_preference_value`, `endpoint`, `enabled`, " - " `auth_token`, `cloud_transport_type`) " - " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + " `auth_token`, `cloud_transport_type`, `icon_url`) " + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; const std::string kSelectApplicationFull = "SELECT `keep_context`, `steal_focus`, `default_hmi`, `priority_value`, " " `is_revoked`, `is_default`, `is_predata`, `memory_kb`," " `heart_beat_timeout_ms`, `certificate`, `hybrid_app_preference_value`, " - " `endpoint`, `enabled`, `auth_token`, `cloud_transport_type`" + " `endpoint`, `enabled`, `auth_token`, `cloud_transport_type`, `icon_url` " "FROM `application` " "WHERE `id` = ?"; diff --git a/src/components/policy/policy_external/src/sql_pt_representation.cc b/src/components/policy/policy_external/src/sql_pt_representation.cc index 0b60daa0e1..6b2996f2fd 100644 --- a/src/components/policy/policy_external/src/sql_pt_representation.cc +++ b/src/components/policy/policy_external/src/sql_pt_representation.cc @@ -777,6 +777,7 @@ bool SQLPTRepresentation::GatherApplicationPoliciesSection( } *params.auth_token = query.GetString(8); *params.cloud_transport_type = query.GetString(9); + *params.icon_url = query.GetString(10); const auto& gather_app_id = ((*policies).apps[app_id].is_string()) ? (*policies).apps[app_id].get_string() @@ -1089,6 +1090,9 @@ bool SQLPTRepresentation::SaveSpecificAppPolicy( app.second.cloud_transport_type.is_initialized() ? app_query.Bind(10, *app.second.cloud_transport_type) : app_query.Bind(10); + app.second.icon_url.is_initialized() + ? app_query.Bind(11, *app.second.icon_url) + : app_query.Bind(11); if (!app_query.Exec() || !app_query.Reset()) { LOG4CXX_WARN(logger_, "Incorrect insert into application."); @@ -2331,6 +2335,8 @@ bool SQLPTRepresentation::CopyApplication(const std::string& source, : query.Bind(14, source_app.GetString(13)); source_app.IsNull(14) ? query.Bind(15) : query.Bind(15, source_app.GetString(14)); + source_app.IsNull(15) ? query.Bind(16) + : query.Bind(16, source_app.GetString(15)); if (!query.Exec()) { LOG4CXX_WARN(logger_, "Failed inserting into application."); 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 354a979287..72a6aae4ad 100644 --- a/src/components/policy/policy_regular/include/policy/cache_manager.h +++ b/src/components/policy/policy_regular/include/policy/cache_manager.h @@ -170,7 +170,7 @@ class CacheManager : public CacheManagerInterface { * @param hybrid_app_preference Filled with the hybrid app preference for the * cloud application set by the user */ - virtual void GetCloudAppParameters(const std::string& policy_app_id, + virtual bool GetCloudAppParameters(const std::string& policy_app_id, bool& enabled, std::string& endpoint, std::string& certificate, @@ -209,6 +209,20 @@ class CacheManager : public CacheManagerInterface { const std::string& cloud_transport_type); /** + * @brief Set a cloud app's endpoint url + * @param endpoint URL for websocket connection + */ + virtual void SetAppEndpoint(const std::string& policy_app_id, + const std::string& endpoint); + + /** + * @brief Set a cloud app's nicknames + * @param nicknames Nicknames for cloud app + */ + virtual void SetAppNicknames(const std::string& policy_app_id, + const StringArray& nicknames); + + /** * @brief Set the user preference for how a hybrid (cloud and mobile) app * should be used * @param hybrid_app_preference Hybrid app user preference @@ -266,6 +280,15 @@ class CacheManager : public CacheManagerInterface { virtual std::string GetLockScreenIconUrl() const; /** + * @brief Get Icon Url used for showing a cloud apps icon before the intial + *registration + * + * @return url which point to the resourse where icon could be + *obtained. + */ + virtual std::string GetIconUrl(const std::string& policy_app_id) const; + + /** * @brief Get allowed number of notifications * depending on application priority. * @param priority Priority of application 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 639a9f9c18..6f6c8f97ab 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 @@ -175,7 +175,7 @@ class CacheManagerInterface { * @param hybrid_app_preference Filled with the hybrid app preference for the * cloud application set by the user */ - virtual void GetCloudAppParameters( + virtual bool GetCloudAppParameters( const std::string& policy_app_id, bool& enabled, std::string& endpoint, @@ -215,6 +215,19 @@ class CacheManagerInterface { const std::string& cloud_transport_type) = 0; /** + * @brief Set a cloud app's endpoint url + * @param endpoint URL for websocket connection + */ + virtual void SetAppEndpoint(const std::string& policy_app_id, + const std::string& endpoint) = 0; + + /** + * @brief Set a cloud app's nicknames + * @param nicknames Nicknames for cloud app + */ + virtual void SetAppNicknames(const std::string& policy_app_id, + const StringArray& nicknames) = 0; + /** * @brief Set the user preference for how a hybrid (cloud and mobile) app * should be used * @param hybrid_app_preference Hybrid app user preference @@ -274,6 +287,15 @@ class CacheManagerInterface { virtual std::string GetLockScreenIconUrl() const = 0; /** + * @brief Get Icon Url used for showing a cloud apps icon before the intial + *registration + * + * @return url which point to the resourse where icon could be + *obtained. + */ + virtual std::string GetIconUrl(const std::string& policy_app_id) const = 0; + + /** * @brief Get allowed number of notifications * depending on application priority. * @param priority Priority of application 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 4ed8903b00..df2b44ba9a 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 @@ -117,6 +117,15 @@ class PolicyManagerImpl : public PolicyManager { std::string GetLockScreenIconUrl() const OVERRIDE; /** + * @brief Get Icon Url used for showing a cloud apps icon before the intial + *registration + * + * @return url which point to the resourse where icon could be + *obtained. + */ + std::string GetIconUrl(const std::string& policy_app_id) const OVERRIDE; + + /** * @brief PTU is needed, for this PTS has to be formed and sent. */ bool RequestPTUpdate() OVERRIDE; @@ -588,7 +597,7 @@ class PolicyManagerImpl : public PolicyManager { * @param hybrid_app_preference Filled with the hybrid app preference for the * cloud application set by the user */ - void GetCloudAppParameters(const std::string& policy_app_id, + bool GetCloudAppParameters(const std::string& policy_app_id, bool& enabled, std::string& endpoint, std::string& certificate, @@ -626,6 +635,20 @@ class PolicyManagerImpl : public PolicyManager { const std::string& cloud_transport_type) OVERRIDE; /** + * @brief Set a cloud app's endpoint url + * @param endpoint URL for websocket connection + */ + void SetAppEndpoint(const std::string& policy_app_id, + const std::string& endpoint) OVERRIDE; + + /** + * @brief Set a cloud app's nicknames + * @param nicknames Nicknames for cloud app + */ + void SetAppNicknames(const std::string& policy_app_id, + const StringArray& nicknames) OVERRIDE; + + /** * @brief Set the user preference for how a hybrid (cloud and mobile) app * should be used * @param hybrid_app_preference Hybrid app user preference @@ -920,6 +943,12 @@ class PolicyManagerImpl : public PolicyManager { const std::string& application_id) OVERRIDE; /** + * @brief notify listener of updated auth token for a given policy id + * @param policy_app_id the app id that has an updated auth token + */ + void SendAuthTokenUpdated(const std::string policy_app_id); + + /** * @brief Gets all allowed module types * @param policy_app_id unique identifier of application * @param modules list of allowed module types diff --git a/src/components/policy/policy_regular/include/policy/policy_table/enums.h b/src/components/policy/policy_regular/include/policy/policy_table/enums.h index 5b496a4fbd..679950277d 100644 --- a/src/components/policy/policy_regular/include/policy/policy_table/enums.h +++ b/src/components/policy/policy_regular/include/policy/policy_table/enums.h @@ -432,6 +432,11 @@ enum FunctionID { SetCloudAppPropertiesID = 50, /** + * @brief GetCloudAppPropertiesID. + */ + GetCloudAppPropertiesID = 51, + + /** * @brief PublishAppServiceID. */ PublishAppServiceID = 52, diff --git a/src/components/policy/policy_regular/include/policy/policy_table/types.h b/src/components/policy/policy_regular/include/policy/policy_table/types.h index 118f98677a..65a489ef27 100644 --- a/src/components/policy/policy_regular/include/policy/policy_table/types.h +++ b/src/components/policy/policy_regular/include/policy/policy_table/types.h @@ -190,7 +190,7 @@ struct ApplicationParams : PolicyBase { Optional<RequestSubTypes> RequestSubType; Optional<Integer<uint16_t, 0, 65225> > memory_kb; Optional<Integer<uint32_t, 0, UINT_MAX> > heart_beat_timeout_ms; - Optional<String<0, 255> > certificate; + Optional<String<0, 65535> > certificate; mutable Optional<ModuleTypes> moduleType; // Cloud application params Optional<Enum<HybridAppPreference> > hybrid_app_preference; @@ -198,6 +198,7 @@ struct ApplicationParams : PolicyBase { Optional<Boolean> enabled; Optional<String<0, 65535> > auth_token; Optional<String<0, 255> > cloud_transport_type; + Optional<String<0, 65535> > icon_url; // App Service Params Optional<AppServiceParameters> app_service_parameters; diff --git a/src/components/policy/policy_regular/src/cache_manager.cc b/src/components/policy/policy_regular/src/cache_manager.cc index 5abe4158f1..42e2af5804 100644 --- a/src/components/policy/policy_regular/src/cache_manager.cc +++ b/src/components/policy/policy_regular/src/cache_manager.cc @@ -696,7 +696,7 @@ void CacheManager::GetEnabledCloudApps( } } -void CacheManager::GetCloudAppParameters( +bool CacheManager::GetCloudAppParameters( const std::string& policy_app_id, bool& enabled, std::string& endpoint, @@ -725,7 +725,9 @@ void CacheManager::GetCloudAppParameters( ? EnumToJsonString(*app_policy.hybrid_app_preference) : std::string(); enabled = app_policy.enabled.is_initialized() && *app_policy.enabled; + return true; } + return false; } void CacheManager::InitCloudApp(const std::string& policy_app_id) { @@ -782,6 +784,28 @@ void CacheManager::SetAppCloudTransportType( } } +void CacheManager::SetAppEndpoint(const std::string& policy_app_id, + const std::string& endpoint) { + policy_table::ApplicationPolicies& policies = + pt_->policy_table.app_policies_section.apps; + policy_table::ApplicationPolicies::iterator policy_iter = + policies.find(policy_app_id); + if (policies.end() != policy_iter) { + *(*policy_iter).second.endpoint = endpoint; + } +} + +void CacheManager::SetAppNicknames(const std::string& policy_app_id, + const StringArray& nicknames) { + policy_table::ApplicationPolicies& policies = + pt_->policy_table.app_policies_section.apps; + policy_table::ApplicationPolicies::iterator policy_iter = + policies.find(policy_app_id); + if (policies.end() != policy_iter) { + (*(*policy_iter).second.nicknames) = nicknames; + } +} + void CacheManager::SetHybridAppPreference( const std::string& policy_app_id, const std::string& hybrid_app_preference) { @@ -908,6 +932,21 @@ std::string CacheManager::GetLockScreenIconUrl() const { return std::string(""); } +std::string CacheManager::GetIconUrl(const std::string& policy_app_id) const { + CACHE_MANAGER_CHECK(std::string()); + std::string url; + const policy_table::ApplicationPolicies& policies = + pt_->policy_table.app_policies_section.apps; + policy_table::ApplicationPolicies::const_iterator policy_iter = + policies.find(policy_app_id); + if (policies.end() != policy_iter) { + auto app_policy = (*policy_iter).second; + url = app_policy.icon_url.is_initialized() ? *app_policy.icon_url + : std::string(); + } + return url; +} + rpc::policy_table_interface_base::NumberOfNotificationsType CacheManager::GetNotificationsNumber(const std::string& priority) { CACHE_MANAGER_CHECK(0); 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 5f09d166b1..62e40433aa 100644 --- a/src/components/policy/policy_regular/src/policy_manager_impl.cc +++ b/src/components/policy/policy_regular/src/policy_manager_impl.cc @@ -368,6 +368,12 @@ bool PolicyManagerImpl::LoadPT(const std::string& file, } else { LOG4CXX_INFO(logger_, "app_hmi_types empty" << pt_content.size()); } + + std::vector<std::string> enabled_apps; + cache_->GetEnabledCloudApps(enabled_apps); + for (auto it = enabled_apps.begin(); it != enabled_apps.end(); ++it) { + SendAuthTokenUpdated(*it); + } } // If there was a user request for policy table update, it should be started @@ -443,6 +449,11 @@ std::string PolicyManagerImpl::GetLockScreenIconUrl() const { return cache_->GetLockScreenIconUrl(); } +std::string PolicyManagerImpl::GetIconUrl( + const std::string& policy_app_id) const { + return cache_->GetIconUrl(policy_app_id); +} + void PolicyManagerImpl::StartPTExchange() { LOG4CXX_AUTO_TRACE(logger_); @@ -549,7 +560,7 @@ void PolicyManagerImpl::GetEnabledCloudApps( cache_->GetEnabledCloudApps(enabled_apps); } -void PolicyManagerImpl::GetCloudAppParameters( +bool PolicyManagerImpl::GetCloudAppParameters( const std::string& policy_app_id, bool& enabled, std::string& endpoint, @@ -557,13 +568,13 @@ void PolicyManagerImpl::GetCloudAppParameters( std::string& auth_token, std::string& cloud_transport_type, std::string& hybrid_app_preference) const { - cache_->GetCloudAppParameters(policy_app_id, - enabled, - endpoint, - certificate, - auth_token, - cloud_transport_type, - hybrid_app_preference); + return cache_->GetCloudAppParameters(policy_app_id, + enabled, + endpoint, + certificate, + auth_token, + cloud_transport_type, + hybrid_app_preference); } void PolicyManagerImpl::InitCloudApp(const std::string& policy_app_id) { @@ -585,6 +596,16 @@ void PolicyManagerImpl::SetAppCloudTransportType( cache_->SetAppCloudTransportType(policy_app_id, cloud_transport_type); } +void PolicyManagerImpl::SetAppEndpoint(const std::string& policy_app_id, + const std::string& endpoint) { + cache_->SetAppEndpoint(policy_app_id, endpoint); +} + +void PolicyManagerImpl::SetAppNicknames(const std::string& policy_app_id, + const StringArray& nicknames) { + cache_->SetAppNicknames(policy_app_id, nicknames); +} + void PolicyManagerImpl::SetHybridAppPreference( const std::string& policy_app_id, const std::string& hybrid_app_preference) { @@ -1347,6 +1368,11 @@ bool PolicyManagerImpl::InitPT(const std::string& file_name, if (!certificate_data.empty()) { listener_->OnCertificateUpdated(certificate_data); } + std::vector<std::string> enabled_apps; + cache_->GetEnabledCloudApps(enabled_apps); + for (auto it = enabled_apps.begin(); it != enabled_apps.end(); ++it) { + SendAuthTokenUpdated(*it); + } } return ret; } @@ -1462,6 +1488,15 @@ void PolicyManagerImpl::SendAppPermissionsChanged( listener()->OnPermissionsUpdated(application_id, notification_data); } +void PolicyManagerImpl::SendAuthTokenUpdated(const std::string policy_app_id) { + bool enabled = false; + std::string end, cert, ctt, hap; + std::string auth_token; + cache_->GetCloudAppParameters( + policy_app_id, enabled, end, cert, auth_token, ctt, hap); + listener_->OnAuthTokenUpdated(policy_app_id, auth_token); +} + void PolicyManagerImpl::OnPrimaryGroupsChanged( const std::string& application_id) { const std::vector<std::string> devices = diff --git a/src/components/policy/policy_regular/src/policy_table/enums.cc b/src/components/policy/policy_regular/src/policy_table/enums.cc index 113ba8c527..421ccacded 100644 --- a/src/components/policy/policy_regular/src/policy_table/enums.cc +++ b/src/components/policy/policy_regular/src/policy_table/enums.cc @@ -849,6 +849,8 @@ bool IsValidEnum(FunctionID val) { return true; case SetCloudAppPropertiesID: return true; + case GetCloudAppPropertiesID: + return true; case PublishAppServiceID: return true; case GetFileID: @@ -1010,6 +1012,8 @@ const char* EnumToJsonString(FunctionID val) { return "SendHapticData"; case SetCloudAppPropertiesID: return "SetCloudAppProperties"; + case GetCloudAppPropertiesID: + return "GetCloudAppProperties"; case PublishAppServiceID: return "PublishAppService"; case GetFileID: @@ -1317,6 +1321,11 @@ bool EnumFromJsonString(const std::string& literal, FunctionID* result) { return true; } + if ("GetCloudAppProperties" == literal) { + *result = GetCloudAppPropertiesID; + return true; + } + if ("PublishAppService" == literal) { *result = PublishAppServiceID; return true; diff --git a/src/components/policy/policy_regular/src/policy_table/types.cc b/src/components/policy/policy_regular/src/policy_table/types.cc index 5f7d2e57bf..ac100984da 100644 --- a/src/components/policy/policy_regular/src/policy_table/types.cc +++ b/src/components/policy/policy_regular/src/policy_table/types.cc @@ -270,13 +270,14 @@ ApplicationParams::ApplicationParams(const Json::Value* value__) , RequestSubType(impl::ValueMember(value__, "RequestSubType")) , memory_kb(impl::ValueMember(value__, "memory_kb"), 0) , heart_beat_timeout_ms(impl::ValueMember(value__, "heart_beat_timeout_ms")) - , certificate(impl::ValueMember(value__, "certificate"), "not_specified") + , certificate(impl::ValueMember(value__, "certificate")) , moduleType(impl::ValueMember(value__, "moduleType")) , hybrid_app_preference(impl::ValueMember(value__, "hybrid_app_preference")) , endpoint(impl::ValueMember(value__, "endpoint")) , enabled(impl::ValueMember(value__, "enabled")) , auth_token(impl::ValueMember(value__, "auth_token")) , cloud_transport_type(impl::ValueMember(value__, "cloud_transport_type")) + , icon_url(impl::ValueMember(value__, "icon_url")) , app_service_parameters(impl::ValueMember(value__, "app_services")) {} Json::Value ApplicationParams::ToJsonValue() const { @@ -297,6 +298,7 @@ Json::Value ApplicationParams::ToJsonValue() const { impl::WriteJsonField("enabled", enabled, &result__); impl::WriteJsonField("auth_token", auth_token, &result__); impl::WriteJsonField("cloud_transport_type", cloud_transport_type, &result__); + impl::WriteJsonField("icon_url", auth_token, &result__); impl::WriteJsonField("app_services", app_service_parameters, &result__); return result__; } @@ -344,6 +346,9 @@ bool ApplicationParams::is_valid() const { if (!hybrid_app_preference.is_valid()) { return false; } + if (!icon_url.is_valid()) { + return false; + } if (!app_service_parameters.is_valid()) { return false; } @@ -400,6 +405,9 @@ bool ApplicationParams::struct_empty() const { if (hybrid_app_preference.is_initialized()) { return false; } + if (icon_url.is_initialized()) { + return false; + } if (app_service_parameters.is_initialized()) { return false; } @@ -457,6 +465,9 @@ void ApplicationParams::ReportErrors(rpc::ValidationReport* report__) const { moduleType.ReportErrors( &report__->ReportSubobject("hybrid_app_preference")); } + if (!icon_url.is_valid()) { + moduleType.ReportErrors(&report__->ReportSubobject("icon_url")); + } if (!app_service_parameters.is_valid()) { app_service_parameters.ReportErrors( &report__->ReportSubobject("app_services")); @@ -477,6 +488,7 @@ void ApplicationParams::SetPolicyTableType(PolicyTableType pt_type) { enabled.SetPolicyTableType(pt_type); cloud_transport_type.SetPolicyTableType(pt_type); hybrid_app_preference.SetPolicyTableType(pt_type); + icon_url.SetPolicyTableType(pt_type); app_service_parameters.SetPolicyTableType(pt_type); } diff --git a/src/components/policy/policy_regular/src/sql_pt_queries.cc b/src/components/policy/policy_regular/src/sql_pt_queries.cc index 610a24eb19..708a29c34a 100644 --- a/src/components/policy/policy_regular/src/sql_pt_queries.cc +++ b/src/components/policy/policy_regular/src/sql_pt_queries.cc @@ -142,6 +142,7 @@ const std::string kCreateSchema = " `enabled` BOOLEAN, " " `auth_token` VARCHAR(65535), " " `cloud_transport_type` VARCHAR(255), " + " `icon_url` VARCHAR(65535), " " `remote_control_denied` BOOLEAN NOT NULL DEFAULT 0, " " CONSTRAINT `fk_application_hmi_level1` " " FOREIGN KEY(`default_hmi`) " @@ -625,8 +626,8 @@ const std::string kInsertApplication = "INSERT OR IGNORE INTO `application` (`id`, `priority_value`, " "`is_revoked`, `memory_kb`, `heart_beat_timeout_ms`, `certificate`, " "`hybrid_app_preference_value`, `endpoint`, `enabled`, `auth_token`, " - "`cloud_transport_type`) VALUES " - "(?,?,?,?,?,?,?,?,?,?,?)"; + "`cloud_transport_type`, `icon_url`) VALUES " + "(?,?,?,?,?,?,?,?,?,?,?,?)"; const std::string kInsertAppGroup = "INSERT INTO `app_group` (`application_id`, `functional_group_id`)" @@ -751,7 +752,8 @@ const std::string kSelectUserMsgsVersion = const std::string kSelectAppPolicies = "SELECT `id`, `priority_value`, `memory_kb`, " " `heart_beat_timeout_ms`, `certificate`, `hybrid_app_preference_value`, " - " `endpoint`, `enabled`, `auth_token`, `cloud_transport_type` FROM " + " `endpoint`, `enabled`, `auth_token`, `cloud_transport_type`, `icon_url` " + "FROM " " `application`"; const std::string kCollectFriendlyMsg = "SELECT * FROM `message`"; @@ -874,14 +876,14 @@ const std::string kInsertApplicationFull = " `default_hmi`, `priority_value`, `is_revoked`, `is_default`, " " `is_predata`, `memory_kb`, `heart_beat_timeout_ms`, " " `certificate`, `hybrid_app_preference_value`, `endpoint`, `enabled`, " - " `auth_token`, `cloud_transport_type`) " - " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + " `auth_token`, `cloud_transport_type`, `icon_url`) " + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; const std::string kSelectApplicationFull = "SELECT `keep_context`, `steal_focus`, `default_hmi`, `priority_value`, " " `is_revoked`, `is_default`, `is_predata`, `memory_kb`," " `heart_beat_timeout_ms`, `certificate`, `hybrid_app_preference_value`, " - " `endpoint`, `enabled`, `auth_token`, `cloud_transport_type` " + " `endpoint`, `enabled`, `auth_token`, `cloud_transport_type`, `icon_url` " "FROM `application` " "WHERE `id` = " "?"; diff --git a/src/components/policy/policy_regular/src/sql_pt_representation.cc b/src/components/policy/policy_regular/src/sql_pt_representation.cc index 661be436f0..19133a45f8 100644 --- a/src/components/policy/policy_regular/src/sql_pt_representation.cc +++ b/src/components/policy/policy_regular/src/sql_pt_representation.cc @@ -733,6 +733,7 @@ bool SQLPTRepresentation::GatherApplicationPoliciesSection( } *params.auth_token = query.GetString(8); *params.cloud_transport_type = query.GetString(9); + *params.icon_url = query.GetString(10); const auto& gather_app_id = ((*policies).apps[app_id].is_string()) ? (*policies).apps[app_id].get_string() @@ -1031,6 +1032,9 @@ bool SQLPTRepresentation::SaveSpecificAppPolicy( app.second.cloud_transport_type.is_initialized() ? app_query.Bind(10, *app.second.cloud_transport_type) : app_query.Bind(10); + app.second.icon_url.is_initialized() + ? app_query.Bind(11, *app.second.icon_url) + : app_query.Bind(11); if (!app_query.Exec() || !app_query.Reset()) { LOG4CXX_WARN(logger_, "Incorrect insert into application."); @@ -2284,6 +2288,8 @@ bool SQLPTRepresentation::CopyApplication(const std::string& source, : query.Bind(14, source_app.GetString(13)); source_app.IsNull(14) ? query.Bind(15) : query.Bind(15, source_app.GetString(14)); + source_app.IsNull(15) ? query.Bind(16) + : query.Bind(16, source_app.GetString(15)); if (!query.Exec()) { LOG4CXX_WARN(logger_, "Failed inserting into application."); diff --git a/src/components/protocol/src/bson_object_keys.cc b/src/components/protocol/src/bson_object_keys.cc index 11160d7082..acafd3dbd2 100644 --- a/src/components/protocol/src/bson_object_keys.cc +++ b/src/components/protocol/src/bson_object_keys.cc @@ -18,6 +18,7 @@ const char* video_service_transports = "videoServiceTransports"; const char* tcp_ip_address = "tcpIpAddress"; const char* tcp_port = "tcpPort"; const char* reason = "reason"; +const char* auth_token = "authToken"; } // namespace strings diff --git a/src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h b/src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h index ccf6082a18..89800037b5 100644 --- a/src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h +++ b/src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h @@ -428,6 +428,9 @@ class ProtocolHandlerImpl void NotifySessionStarted(const SessionContext& context, std::vector<std::string>& rejected_params) OVERRIDE; + void OnAuthTokenUpdated(const std::string& policy_app_id, + const std::string& auth_token) OVERRIDE; + #ifdef BUILD_TESTS const impl::FromMobileQueue& get_from_mobile_queue() const { return raw_ford_messages_from_mobile_; @@ -777,6 +780,10 @@ class ProtocolHandlerImpl sync_primitives::Lock start_session_frame_map_lock_; StartSessionFrameMap start_session_frame_map_; + // Map policy app id -> auth token + sync_primitives::Lock auth_token_map_lock_; + std::map<std::string, std::string> auth_token_map_; + bool tcp_enabled_; std::string tcp_port_; std::string tcp_ip_address_; diff --git a/src/components/protocol_handler/src/protocol_handler_impl.cc b/src/components/protocol_handler/src/protocol_handler_impl.cc index ee2dc73780..27b06af424 100644 --- a/src/components/protocol_handler/src/protocol_handler_impl.cc +++ b/src/components/protocol_handler/src/protocol_handler_impl.cc @@ -59,10 +59,11 @@ CREATE_LOGGERPTR_GLOBAL(logger_, "ProtocolHandler") std::string ConvertPacketDataToString(const uint8_t* data, const size_t data_size); -const size_t kStackSize = 65536; +const size_t kStackSize = 131072; -utils::SemanticVersion defaultProtocolVersion(5, 1, 0); -utils::SemanticVersion minMultipleTransportsVersion(5, 1, 0); +utils::SemanticVersion default_protocol_version(5, 2, 0); +utils::SemanticVersion min_multiple_transports_version(5, 1, 0); +utils::SemanticVersion min_cloud_app_version(5, 2, 0); ProtocolHandlerImpl::ProtocolHandlerImpl( const ProtocolHandlerSettings& settings, @@ -309,16 +310,16 @@ void ProtocolHandlerImpl::SendStartSessionAck( ¶ms, strings::hash_id))); // Minimum protocol version supported by both - utils::SemanticVersion* minVersion = + utils::SemanticVersion* min_version = (full_version.major_version_ < PROTOCOL_VERSION_5) - ? &defaultProtocolVersion + ? &default_protocol_version : utils::SemanticVersion::min(full_version, - defaultProtocolVersion); - char protocolVersionString[256]; - strncpy(protocolVersionString, (*minVersion).toString().c_str(), 255); + default_protocol_version); + char protocol_version_string[256]; + strncpy(protocol_version_string, (*min_version).toString().c_str(), 255); const bool protocol_ver_written = bson_object_put_string( - ¶ms, strings::protocol_version, protocolVersionString); + ¶ms, strings::protocol_version, protocol_version_string); UNUSED(protocol_ver_written); LOG4CXX_DEBUG( logger_, @@ -327,12 +328,12 @@ void ProtocolHandlerImpl::SendStartSessionAck( << bson_object_get_string(¶ms, strings::protocol_version)); LOG4CXX_INFO(logger_, - "Protocol Version String " << protocolVersionString); + "Protocol Version String " << protocol_version_string); std::vector<std::string> secondaryTransports; std::vector<int32_t> audioServiceTransports; std::vector<int32_t> videoServiceTransports; - if (*minVersion >= minMultipleTransportsVersion) { + if (*min_version >= min_multiple_transports_version) { if (ParseSecondaryTransportConfiguration(connection_id, secondaryTransports, audioServiceTransports, @@ -410,10 +411,23 @@ void ProtocolHandlerImpl::SendStartSessionAck( connection_handler_.SetSecondaryTransportID(session_id, kDisabledSecondary); } + + std::string policy_app_id = + connection_handler_.GetCloudAppID(connection_id); + if (*min_version >= min_cloud_app_version && !policy_app_id.empty()) { + sync_primitives::AutoLock lock(auth_token_map_lock_); + auto it = auth_token_map_.find(policy_app_id); + if (it != auth_token_map_.end()) { + char auth_token[65536]; + strncpy(auth_token, it->second.c_str(), 65535); + auth_token[sizeof(auth_token) - 1] = '\0'; + bson_object_put_string(¶ms, strings::auth_token, auth_token); + } + } } - uint8_t* payloadBytes = bson_object_to_bytes(¶ms); - ptr->set_data(payloadBytes, bson_object_size(¶ms)); - free(payloadBytes); + uint8_t* payload_bytes = bson_object_to_bytes(¶ms); + ptr->set_data(payload_bytes, bson_object_size(¶ms)); + free(payload_bytes); } else { set_hash_id(hash_id, *ptr); } @@ -1185,6 +1199,17 @@ void ProtocolHandlerImpl::OnTransportConfigUpdated( } } +void ProtocolHandlerImpl::OnAuthTokenUpdated(const std::string& policy_app_id, + const std::string& auth_token) { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock lock(auth_token_map_lock_); + if (auth_token.empty()) { + auth_token_map_.erase(policy_app_id); + } else { + auth_token_map_[policy_app_id] = auth_token; + } +} + RESULT_CODE ProtocolHandlerImpl::SendFrame(const ProtocolFramePtr packet) { LOG4CXX_AUTO_TRACE(logger_); if (!packet) { diff --git a/src/components/rpc_base/include/rpc_base/rpc_base_json_inl.h b/src/components/rpc_base/include/rpc_base/rpc_base_json_inl.h index 6c8bb359af..960ca10e21 100644 --- a/src/components/rpc_base/include/rpc_base/rpc_base_json_inl.h +++ b/src/components/rpc_base/include/rpc_base/rpc_base_json_inl.h @@ -206,6 +206,7 @@ String<minlen, maxlen>::String(const Json::Value* value, if (!is_initialized()) { value_state_ = kValid; } else if (is_valid()) { + value_ = value->asString(); value_state_ = length_range_.Includes(value_.length()) ? kValid : kInvalid; } } diff --git a/src/components/transport_manager/include/transport_manager/cloud/cloud_websocket_transport_adapter.h b/src/components/transport_manager/include/transport_manager/cloud/cloud_websocket_transport_adapter.h index d52e4b307d..138f9ca895 100644 --- a/src/components/transport_manager/include/transport_manager/cloud/cloud_websocket_transport_adapter.h +++ b/src/components/transport_manager/include/transport_manager/cloud/cloud_websocket_transport_adapter.h @@ -58,6 +58,23 @@ class CloudWebsocketTransportAdapter : public TransportAdapterImpl { */ virtual ~CloudWebsocketTransportAdapter(); + /** + * @brief Set CloudTransportConfig for specified app_id + * + * @param app_id app ID string + * @param properties New cloud app properties for the app + */ + void SetAppCloudTransportConfig(std::string app_id, + CloudAppProperties properties); + + /** + * @brief Get CloudTransportConfig for specified app_id + * + * @param app_id app ID string + * @return CloudAppProperties for the app + */ + const CloudAppProperties& GetAppCloudTransportConfig(std::string app_id); + protected: /** * @brief Return type of device. @@ -81,6 +98,7 @@ class CloudWebsocketTransportAdapter : public TransportAdapterImpl { void CreateDevice(const std::string& uid) OVERRIDE; private: + CloudAppTransportConfig transport_config_; }; } // namespace transport_adapter diff --git a/src/components/transport_manager/include/transport_manager/cloud/websocket_client_connection.h b/src/components/transport_manager/include/transport_manager/cloud/websocket_client_connection.h index da3a80e1b2..aa608312a0 100644 --- a/src/components/transport_manager/include/transport_manager/cloud/websocket_client_connection.h +++ b/src/components/transport_manager/include/transport_manager/cloud/websocket_client_connection.h @@ -42,6 +42,7 @@ #include <boost/asio/connect.hpp> #include <boost/asio/ip/tcp.hpp> #include <boost/asio/ssl/stream.hpp> +#include <boost/asio/thread_pool.hpp> #include <cstdlib> #include <functional> #include <iostream> @@ -49,6 +50,7 @@ #include <string> #include <thread> #include "transport_manager/transport_adapter/connection.h" +#include "transport_manager/cloud/cloud_websocket_transport_adapter.h" #include "utils/threads/thread.h" #include "utils/threads/message_loop_thread.h" #include "utils/message_queue.h" @@ -61,6 +63,8 @@ using ::utils::MessageQueue; typedef std::queue<protocol_handler::RawMessagePtr> AsyncQueue; typedef protocol_handler::RawMessagePtr Message; +typedef websocket::stream<tcp::socket> WS; +typedef websocket::stream<ssl::stream<tcp::socket> > WSS; namespace transport_manager { namespace transport_adapter { @@ -117,6 +121,13 @@ class WebsocketClientConnection */ TransportAdapter::Error Disconnect(); + /** + * @brief Attempt to add provided certificate to the ssl::context + * + * @param cert Certificate string from policy table + */ + void AddCertificateAuthority(std::string cert, boost::system::error_code& ec); + void Shutdown(); void Recv(boost::system::error_code ec); @@ -126,14 +137,17 @@ class WebsocketClientConnection private: TransportAdapterController* controller_; boost::asio::io_context ioc_; + ssl::context ctx_; tcp::resolver resolver_; - websocket::stream<tcp::socket> ws_; boost::beast::flat_buffer buffer_; std::string host_; std::string text_; + WS ws_; + WSS wss_; std::atomic_bool shutdown_; + CloudAppProperties cloud_properties; typedef std::queue<protocol_handler::RawMessagePtr> FrameQueue; FrameQueue frames_to_send_; mutable sync_primitives::Lock frames_to_send_mutex_; @@ -170,6 +184,8 @@ class WebsocketClientConnection const DeviceUID device_uid_; const ApplicationHandle app_handle_; + + boost::asio::thread_pool io_pool_; }; } // namespace transport_adapter diff --git a/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_controller.h b/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_controller.h index 6d97a55a70..7a0a37758c 100644 --- a/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_controller.h +++ b/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_controller.h @@ -88,6 +88,10 @@ class TransportAdapterController { */ virtual DeviceSptr FindDevice(const DeviceUID& device_handle) const = 0; + virtual ConnectionSPtr FindPendingConnection( + const DeviceUID& device_handle, + const ApplicationHandle& app_handle) const = 0; + /** * @brief Create connection and fill its parameters. * 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 68d5ba3067..b30f1e35b2 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 @@ -264,6 +264,10 @@ class TransportAdapterImpl : public TransportAdapter, */ DeviceSptr FindDevice(const DeviceUID& device_handle) const OVERRIDE; + ConnectionSPtr FindPendingConnection( + const DeviceUID& device_handle, + const ApplicationHandle& app_handle) const OVERRIDE; + /** * @brief Search for device in container of devices, if it is not there - adds *it. 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 4b75f4aaa8..118439bd4a 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 @@ -139,8 +139,9 @@ class TransportManagerImpl **/ int SearchDevices() OVERRIDE; - void AddCloudDevice(const std::string& endpoint, - const std::string& cloud_transport_type) OVERRIDE; + void AddCloudDevice( + const transport_manager::transport_adapter::CloudAppProperties + cloud_properties) OVERRIDE; void RemoveCloudDevice(const DeviceHandle device_id) OVERRIDE; diff --git a/src/components/transport_manager/src/cloud/cloud_websocket_connection_factory.cc b/src/components/transport_manager/src/cloud/cloud_websocket_connection_factory.cc index cdc27ed8ef..0d9fda6fe5 100644 --- a/src/components/transport_manager/src/cloud/cloud_websocket_connection_factory.cc +++ b/src/components/transport_manager/src/cloud/cloud_websocket_connection_factory.cc @@ -56,11 +56,15 @@ TransportAdapter::Error CloudWebsocketConnectionFactory::Init() { TransportAdapter::Error CloudWebsocketConnectionFactory::CreateConnection( const DeviceUID& device_uid, const ApplicationHandle& app_handle) { LOG4CXX_AUTO_TRACE(logger_); - std::shared_ptr<WebsocketClientConnection> connection = - std::make_shared<WebsocketClientConnection>( - device_uid, app_handle, controller_); - controller_->ConnectionCreated(connection, device_uid, app_handle); - TransportAdapter::Error error = connection->Start(); + auto connection = controller_->FindPendingConnection(device_uid, app_handle); + + std::shared_ptr<WebsocketClientConnection> ws_connection = + std::dynamic_pointer_cast<WebsocketClientConnection>(connection); + if (ws_connection.use_count() == 0) { + return TransportAdapter::Error::BAD_PARAM; + } + + TransportAdapter::Error error = ws_connection->Start(); if (TransportAdapter::OK != error) { LOG4CXX_ERROR( logger_, diff --git a/src/components/transport_manager/src/cloud/cloud_websocket_transport_adapter.cc b/src/components/transport_manager/src/cloud/cloud_websocket_transport_adapter.cc index 5093e6c2af..dd575979b2 100644 --- a/src/components/transport_manager/src/cloud/cloud_websocket_transport_adapter.cc +++ b/src/components/transport_manager/src/cloud/cloud_websocket_transport_adapter.cc @@ -53,6 +53,16 @@ CloudWebsocketTransportAdapter::CloudWebsocketTransportAdapter( CloudWebsocketTransportAdapter::~CloudWebsocketTransportAdapter() {} +void CloudWebsocketTransportAdapter::SetAppCloudTransportConfig( + std::string app_id, CloudAppProperties properties) { + transport_config_[app_id] = properties; +} + +const CloudAppProperties& +CloudWebsocketTransportAdapter::GetAppCloudTransportConfig(std::string app_id) { + return transport_config_[app_id]; +} + DeviceType CloudWebsocketTransportAdapter::GetDeviceType() const { return CLOUD_WEBSOCKET; } @@ -64,6 +74,12 @@ bool CloudWebsocketTransportAdapter::Restore() { } void CloudWebsocketTransportAdapter::CreateDevice(const std::string& uid) { + // If the device has already been created, just ignore the request + DeviceSptr device = FindDevice(uid); + if (device.use_count() != 0) { + return; + } + boost::regex pattern( "(wss?):\\/\\/([A-Z\\d\\.-]{2,})\\.?([A-Z]{2,})?(:\\d{2,4})\\/", boost::regex::icase); @@ -81,7 +97,8 @@ void CloudWebsocketTransportAdapter::CreateDevice(const std::string& uid) { // Extract host and port from endpoint string boost::regex group_pattern( - "(wss?:\\/\\/)([A-Z\\d\\.-]{2,}\\.?([A-Z]{2,})?)(:)(\\d{2,4})(\\/)"); + "(wss?:\\/\\/)([A-Z\\d\\.-]{2,}\\.?([A-Z]{2,})?)(:)(\\d{2,5})(\\/" + "[A-Z\\d\\.-]+)*\\/?"); boost::smatch results; std::string host = ""; diff --git a/src/components/transport_manager/src/cloud/websocket_client_connection.cc b/src/components/transport_manager/src/cloud/websocket_client_connection.cc index e001e8877d..5c9553a970 100644 --- a/src/components/transport_manager/src/cloud/websocket_client_connection.cc +++ b/src/components/transport_manager/src/cloud/websocket_client_connection.cc @@ -47,75 +47,150 @@ WebsocketClientConnection::WebsocketClientConnection( const ApplicationHandle& app_handle, TransportAdapterController* controller) : controller_(controller) + , ctx_(ssl::context::sslv23_client) , resolver_(ioc_) , ws_(ioc_) + , wss_(ioc_, ctx_) , shutdown_(false) , thread_delegate_(new LoopThreadDelegate(&message_queue_, this)) , write_thread_(threads::CreateThread("WS Async Send", thread_delegate_)) , device_uid_(device_uid) - , app_handle_(app_handle) {} + , app_handle_(app_handle) + , io_pool_(1) {} WebsocketClientConnection::~WebsocketClientConnection() { ioc_.stop(); - if (io_service_thread_.joinable()) { - io_service_thread_.join(); + io_pool_.join(); +} + +void WebsocketClientConnection::AddCertificateAuthority( + const std::string cert, boost::system::error_code& ec) { + ctx_.add_certificate_authority(boost::asio::buffer(cert.data(), cert.size()), + ec); + if (ec) { + return; } + + wss_.next_layer().set_verify_mode(ssl::verify_peer); } TransportAdapter::Error WebsocketClientConnection::Start() { LOG4CXX_AUTO_TRACE(logger_); DeviceSptr device = controller_->FindDevice(device_uid_); CloudDevice* cloud_device = static_cast<CloudDevice*>(device.get()); + CloudWebsocketTransportAdapter* cloud_ta = + static_cast<CloudWebsocketTransportAdapter*>(controller_); + cloud_properties = cloud_ta->GetAppCloudTransportConfig(device_uid_); auto const host = cloud_device->GetHost(); auto const port = cloud_device->GetPort(); boost::system::error_code ec; + + LOG4CXX_DEBUG(logger_, "Cloud app endpoint: " << cloud_properties.endpoint); + LOG4CXX_DEBUG(logger_, + "Cloud app certificate: " << cloud_properties.certificate); + LOG4CXX_DEBUG( + logger_, + "Cloud app authentication token: " << cloud_properties.auth_token); + LOG4CXX_DEBUG( + logger_, + "Cloud app transport type: " << cloud_properties.cloud_transport_type); + LOG4CXX_DEBUG(logger_, + "Cloud app hybrid app preference: " + << cloud_properties.hybrid_app_preference); + auto const results = resolver_.resolve(host, port, ec); if (ec) { std::string str_err = "ErrorMessage: " + ec.message(); LOG4CXX_ERROR(logger_, "Could not resolve host/port: " << str_err); - Shutdown(); return TransportAdapter::FAIL; } - boost::asio::connect(ws_.next_layer(), results.begin(), results.end(), ec); + + // Make Connection to host IP Address over TCP + if (cloud_properties.cloud_transport_type == "WSS") { + boost::asio::connect( + wss_.next_layer().next_layer(), results.begin(), results.end(), ec); + } else { + boost::asio::connect(ws_.next_layer(), results.begin(), results.end(), ec); + } if (ec) { std::string str_err = "ErrorMessage: " + ec.message(); LOG4CXX_ERROR(logger_, "Could not connect to websocket: " << host << ":" << port); LOG4CXX_ERROR(logger_, str_err); - Shutdown(); return TransportAdapter::FAIL; } - ws_.handshake(host, "/", ec); + + if (cloud_properties.cloud_transport_type == "WSS") { + AddCertificateAuthority(cloud_properties.certificate, ec); + + if (ec) { + std::string str_err = "ErrorMessage: " + ec.message(); + LOG4CXX_ERROR(logger_, + "Failed to add certificate authority: " + << cloud_properties.certificate); + LOG4CXX_ERROR(logger_, str_err); + Shutdown(); + return TransportAdapter::FAIL; + } + + // Perform SSL Handshake + wss_.next_layer().handshake(ssl::stream_base::client, ec); + + if (ec) { + std::string str_err = "ErrorMessage: " + ec.message(); + LOG4CXX_ERROR(logger_, + "Could not complete SSL Handshake failed with host/port: " + << host << ":" << port); + LOG4CXX_ERROR(logger_, str_err); + Shutdown(); + return TransportAdapter::FAIL; + } + } + + // Perform websocket handshake + if (cloud_properties.cloud_transport_type == "WSS") { + wss_.handshake(host, "/", ec); + } else { + ws_.handshake(host, "/", ec); + } if (ec) { std::string str_err = "ErrorMessage: " + ec.message(); LOG4CXX_ERROR(logger_, "Could not complete handshake with host/port: " << host << ":" << port); LOG4CXX_ERROR(logger_, str_err); - Shutdown(); return TransportAdapter::FAIL; } - ws_.binary(true); + + // Set the binary message write option + if (cloud_properties.cloud_transport_type == "WSS") { + wss_.binary(true); + } else { + ws_.binary(true); + } write_thread_->start(threads::ThreadOptions()); controller_->ConnectDone(device_uid_, app_handle_); // Start async read - ws_.async_read(buffer_, - std::bind(&WebsocketClientConnection::OnRead, - this, - std::placeholders::_1, - std::placeholders::_2)); - - // Start IO Service thread. Allows for async reads without blocking. - io_service_thread_ = std::thread([&]() { - ioc_.run(); - LOG4CXX_DEBUG(logger_, "Ending Boost IO Thread"); - }); + if (cloud_properties.cloud_transport_type == "WSS") { + wss_.async_read(buffer_, + std::bind(&WebsocketClientConnection::OnRead, + this, + std::placeholders::_1, + std::placeholders::_2)); + } else { + ws_.async_read(buffer_, + std::bind(&WebsocketClientConnection::OnRead, + this, + std::placeholders::_1, + std::placeholders::_2)); + } + + boost::asio::post(io_pool_, [&]() { ioc_.run(); }); LOG4CXX_DEBUG(logger_, "Successfully started websocket connection @: " << host << ":" << port); - return TransportAdapter::OK; } @@ -130,12 +205,19 @@ void WebsocketClientConnection::Recv(boost::system::error_code ec) { Shutdown(); return; } - - ws_.async_read(buffer_, - std::bind(&WebsocketClientConnection::OnRead, - this, - std::placeholders::_1, - std::placeholders::_2)); + if (cloud_properties.cloud_transport_type == "WSS") { + wss_.async_read(buffer_, + std::bind(&WebsocketClientConnection::OnRead, + this, + std::placeholders::_1, + std::placeholders::_2)); + } else { + ws_.async_read(buffer_, + std::bind(&WebsocketClientConnection::OnRead, + this, + std::placeholders::_1, + std::placeholders::_2)); + } } void WebsocketClientConnection::OnRead(boost::system::error_code ec, @@ -144,14 +226,12 @@ void WebsocketClientConnection::OnRead(boost::system::error_code ec, if (ec) { std::string str_err = "ErrorMessage: " + ec.message(); LOG4CXX_ERROR(logger_, str_err); + ws_.lowest_layer().close(); + ioc_.stop(); Shutdown(); - controller_->ConnectionAborted( - device_uid_, app_handle_, CommunicationError()); return; } - std::string data_str = boost::beast::buffers_to_string(buffer_.data()); - LOG4CXX_DEBUG(logger_, "Cloud Transport Received: " << data_str); ssize_t size = (ssize_t)buffer_.size(); const uint8_t* data = boost::asio::buffer_cast<const uint8_t*>( @@ -220,11 +300,15 @@ void WebsocketClientConnection::LoopThreadDelegate::DrainQueue() { message_queue_.pop(message_ptr); if (!shutdown_) { boost::system::error_code ec; - handler_.ws_.write( - boost::asio::buffer(message_ptr->data(), message_ptr->data_size())); + if (handler_.cloud_properties.cloud_transport_type == "WSS") { + handler_.wss_.write( + boost::asio::buffer(message_ptr->data(), message_ptr->data_size())); + } else { + handler_.ws_.write( + boost::asio::buffer(message_ptr->data(), message_ptr->data_size())); + } if (ec) { LOG4CXX_ERROR(logger_, "Error writing to websocket"); - handler_.Shutdown(); handler_.controller_->DataSendFailed(handler_.device_uid_, handler_.app_handle_, message_ptr, 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 34d5a29abd..865e8d6aa8 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 @@ -233,7 +233,9 @@ TransportAdapter::Error TransportAdapterImpl::Connect( server_connection_factory_->CreateConnection(device_id, app_handle); if (TransportAdapter::OK != err) { connections_lock_.AcquireForWriting(); - connections_.erase(std::make_pair(device_id, app_handle)); + if (!pending_app) { + connections_.erase(std::make_pair(device_id, app_handle)); + } connections_lock_.Release(); } LOG4CXX_TRACE(logger_, "exit with error: " << err); @@ -819,6 +821,26 @@ void TransportAdapterImpl::DeviceSwitched(const DeviceUID& device_handle) { UNUSED(device_handle); } +ConnectionSPtr TransportAdapterImpl::FindPendingConnection( + const DeviceUID& device_id, const ApplicationHandle& app_handle) const { + LOG4CXX_TRACE(logger_, + "enter. device_id: " << &device_id + << ", app_handle: " << &app_handle); + ConnectionSPtr connection; + connections_lock_.AcquireForReading(); + ConnectionMap::const_iterator it = + connections_.find(std::make_pair(device_id, app_handle)); + if (it != connections_.end()) { + const ConnectionInfo& info = it->second; + if (info.state == ConnectionInfo::PENDING) { + connection = info.connection; + } + } + connections_lock_.Release(); + LOG4CXX_TRACE(logger_, "exit with Connection: " << connection); + return connection; +} + DeviceSptr TransportAdapterImpl::FindDevice(const DeviceUID& device_id) const { LOG4CXX_TRACE(logger_, "enter. device_id: " << &device_id); DeviceSptr ret; @@ -836,7 +858,8 @@ DeviceSptr TransportAdapterImpl::FindDevice(const DeviceUID& device_id) const { void TransportAdapterImpl::ConnectPending(const DeviceUID& device_id, const ApplicationHandle& app_handle) { - connections_lock_.AcquireForReading(); + LOG4CXX_AUTO_TRACE(logger_); + connections_lock_.AcquireForWriting(); ConnectionMap::iterator it_conn = connections_.find(std::make_pair(device_id, app_handle)); if (it_conn != connections_.end()) { @@ -845,6 +868,15 @@ void TransportAdapterImpl::ConnectPending(const DeviceUID& device_id, } connections_lock_.Release(); + DeviceSptr device = FindDevice(device_id); + if (device.use_count() == 0) { + LOG4CXX_ERROR( + logger_, "Unable to find device, cannot set connection pending status"); + return; + } else { + device->set_connection_status(ConnectionStatus::PENDING); + } + for (TransportAdapterListenerList::iterator it = listeners_.begin(); it != listeners_.end(); ++it) { @@ -1145,12 +1177,13 @@ void TransportAdapterImpl::RunAppOnDevice(const DeviceUID& device_uid, void TransportAdapterImpl::RemoveDevice(const DeviceUID& device_handle) { LOG4CXX_AUTO_TRACE(logger_); - LOG4CXX_DEBUG(logger_, "Device_handle: " << &device_handle); + LOG4CXX_DEBUG(logger_, "Remove Device_handle: " << &device_handle); sync_primitives::AutoLock locker(devices_mutex_); DeviceMap::iterator i = devices_.find(device_handle); if (i != devices_.end()) { DeviceSptr device = i->second; - if (!device->keep_on_disconnect()) { + bool is_cloud_device = (GetDeviceType() == DeviceType::CLOUD_WEBSOCKET); + if (!device->keep_on_disconnect() || is_cloud_device) { devices_.erase(i); for (TransportAdapterListenerList::iterator it = listeners_.begin(); it != listeners_.end(); diff --git a/src/components/transport_manager/src/transport_manager_default.cc b/src/components/transport_manager/src/transport_manager_default.cc index bf692de24c..41487b054b 100644 --- a/src/components/transport_manager/src/transport_manager_default.cc +++ b/src/components/transport_manager/src/transport_manager_default.cc @@ -107,9 +107,8 @@ int TransportManagerDefault::Init(resumption::LastState& last_state) { #if defined CLOUD_APP_WEBSOCKET_TRANSPORT_SUPPORT transport_adapter::TransportAdapterImpl* ta_cloud = - new transport_adapter::CloudWebsocketTransportAdapter( - last_state, get_settings()); // Todo add retry connection logic from - // ini to initializer. + new transport_adapter::CloudWebsocketTransportAdapter(last_state, + get_settings()); #ifdef TELEMETRY_MONITOR if (metric_observer_) { ta_cloud->SetTelemetryObserver(metric_observer_); diff --git a/src/components/transport_manager/src/transport_manager_impl.cc b/src/components/transport_manager/src/transport_manager_impl.cc index 301132d26f..d197882120 100644 --- a/src/components/transport_manager/src/transport_manager_impl.cc +++ b/src/components/transport_manager/src/transport_manager_impl.cc @@ -50,6 +50,7 @@ #include "transport_manager/transport_manager_listener.h" #include "transport_manager/transport_manager_listener_empty.h" #include "transport_manager/transport_adapter/transport_adapter.h" +#include "transport_manager/cloud/cloud_websocket_transport_adapter.h" #include "transport_manager/transport_adapter/transport_adapter_event.h" #include "config_profile/profile.h" @@ -130,10 +131,11 @@ void TransportManagerImpl::ReconnectionTimeout() { } void TransportManagerImpl::AddCloudDevice( - const std::string& endpoint, const std::string& cloud_transport_type) { - // todo put conversion into own function + const transport_manager::transport_adapter::CloudAppProperties + cloud_properties) { transport_adapter::DeviceType type = transport_adapter::DeviceType::UNKNOWN; - if (cloud_transport_type == "WS") { + if ((cloud_properties.cloud_transport_type == "WS") || + (cloud_properties.cloud_transport_type == "WSS")) { type = transport_adapter::DeviceType::CLOUD_WEBSOCKET; } else { return; @@ -142,7 +144,11 @@ void TransportManagerImpl::AddCloudDevice( std::vector<TransportAdapter*>::iterator ta = transport_adapters_.begin(); for (; ta != transport_adapters_.end(); ++ta) { if ((*ta)->GetDeviceType() == type) { - (*ta)->CreateDevice(endpoint); + (*ta)->CreateDevice(cloud_properties.endpoint); + transport_adapter::CloudWebsocketTransportAdapter* cta = + static_cast<transport_adapter::CloudWebsocketTransportAdapter*>(*ta); + cta->SetAppCloudTransportConfig(cloud_properties.endpoint, + cloud_properties); } } @@ -1002,19 +1008,42 @@ void TransportManagerImpl::Handle(TransportAdapterEvent event) { case EventTypeEnum::ON_CONNECT_PENDING: { const DeviceHandle device_handle = converter_.UidToHandle( event.device_uid, event.transport_adapter->GetConnectionType()); - AddConnection(ConnectionInternal(this, - event.transport_adapter, - ++connection_id_counter_, - event.device_uid, - event.application_id, - device_handle)); + int connection_id = 0; + std::vector<ConnectionInternal>::iterator it = connections_.begin(); + std::vector<ConnectionInternal>::iterator end = connections_.end(); + for (; it != end; ++it) { + if (it->transport_adapter != event.transport_adapter) { + continue; + } else if (it->Connection::device != event.device_uid) { + continue; + } else if (it->Connection::application != event.application_id) { + continue; + } else if (it->device_handle_ != device_handle) { + continue; + } else { + LOG4CXX_DEBUG(logger_, "Connection Object Already Exists"); + connection_id = it->Connection::id; + break; + } + } + + if (it == end) { + AddConnection(ConnectionInternal(this, + event.transport_adapter, + ++connection_id_counter_, + event.device_uid, + event.application_id, + device_handle)); + connection_id = connection_id_counter_; + } + RaiseEvent( &TransportManagerListener::OnConnectionPending, DeviceInfo(device_handle, event.device_uid, event.transport_adapter->DeviceName(event.device_uid), event.transport_adapter->GetConnectionType()), - connection_id_counter_); + connection_id); LOG4CXX_DEBUG(logger_, "event_type = ON_CONNECT_PENDING"); break; } diff --git a/src/components/transport_manager/test/include/transport_manager/transport_adapter/mock_transport_adapter_controller.h b/src/components/transport_manager/test/include/transport_manager/transport_adapter/mock_transport_adapter_controller.h index 642c193d63..1de5eac702 100644 --- a/src/components/transport_manager/test/include/transport_manager/transport_adapter/mock_transport_adapter_controller.h +++ b/src/components/transport_manager/test/include/transport_manager/transport_adapter/mock_transport_adapter_controller.h @@ -55,6 +55,9 @@ class MockTransportAdapterController : public TransportAdapterController { void(ConnectionSPtr connection, const DeviceUID& device_handle, const ApplicationHandle& app_handle)); + MOCK_CONST_METHOD2(FindPendingConnection, + ConnectionSPtr(const DeviceUID& device_handle, + const ApplicationHandle& app_handle)); MOCK_METHOD2(ConnectDone, void(const DeviceUID& device_handle, const ApplicationHandle& app_handle)); diff --git a/src/components/transport_manager/test/tcp_client_listener_test.cc b/src/components/transport_manager/test/tcp_client_listener_test.cc index f44f8785aa..1f4a17cf6c 100644 --- a/src/components/transport_manager/test/tcp_client_listener_test.cc +++ b/src/components/transport_manager/test/tcp_client_listener_test.cc @@ -69,6 +69,9 @@ class MockTransportAdapterController : public TransportAdapterController { MOCK_METHOD1(SearchDeviceDone, void(const DeviceVector& devices)); MOCK_METHOD1(SearchDeviceFailed, void(const SearchDeviceError& error)); MOCK_CONST_METHOD1(FindDevice, DeviceSptr(const DeviceUID& device_handle)); + MOCK_CONST_METHOD2(FindPendingConnection, + ConnectionSPtr(const DeviceUID& device_handle, + const ApplicationHandle& app_handle)); MOCK_METHOD3(ConnectionCreated, void(ConnectionSPtr connection, const DeviceUID& device_handle, |