diff options
author | jacobkeeler <jacob.keeler@livioradio.com> | 2019-03-05 14:32:47 -0500 |
---|---|---|
committer | jacobkeeler <jacob.keeler@livioradio.com> | 2019-03-05 14:37:21 -0500 |
commit | 3d3178c0d78dc2c0c1f515bb955eadff78a83e59 (patch) | |
tree | fa43e2e94d01dffecefd39b8d2224fce4e637210 | |
parent | 7083c88030f15af77dc9a1c9a40a8a5bf73d8c73 (diff) | |
download | sdl_core-3d3178c0d78dc2c0c1f515bb955eadff78a83e59.tar.gz |
Handle hybrid app preference
If both a cloud app and mobile app attempt to register with the same name, the hybrid app preference of the cloud app is used to determine which app should be registered
7 files changed, 116 insertions, 25 deletions
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 ae00108591..32d3a521e3 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 @@ -173,6 +173,8 @@ 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; @@ -1002,6 +1004,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 */ 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..a6bfdec209 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 @@ -148,7 +148,8 @@ class RegisterAppInterfaceRequest * 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( + app_mngr::ApplicationSharedPtr& app); /* * @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/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 6317d9b068..e4540fe888 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,49 @@ void RegisterAppInterfaceRequest::Run() { return; } - mobile_apis::Result::eType coincidence_result = CheckCoincidence(); + ApplicationSharedPtr duplicate_app; + mobile_apis::Result::eType coincidence_result = + CheckCoincidence(duplicate_app); + + if (mobile_apis::Result::DUPLICATE_NAME == coincidence_result) { + 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; } @@ -922,7 +954,8 @@ void RegisterAppInterfaceRequest::SendOnAppRegisteredNotificationToHMI( DCHECK(rpc_service_.ManageHMICommand(notification)); } -mobile_apis::Result::eType RegisterAppInterfaceRequest::CheckCoincidence() { +mobile_apis::Result::eType RegisterAppInterfaceRequest::CheckCoincidence( + ApplicationSharedPtr& out_app) { LOG4CXX_AUTO_TRACE(logger_); const smart_objects::SmartObject& msg_params = (*message_)[strings::msg_params]; @@ -938,6 +971,7 @@ 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."); + out_app = *it; return mobile_apis::Result::DUPLICATE_NAME; } @@ -949,6 +983,7 @@ 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."); + out_app = *it; return mobile_apis::Result::DUPLICATE_NAME; } } @@ -961,6 +996,7 @@ 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 ."); + out_app = *it; return mobile_apis::Result::DUPLICATE_NAME; } } // end vr check diff --git a/src/components/application_manager/src/application_impl.cc b/src/components/application_manager/src/application_impl.cc index 63bc9be8c6..3d17da51ce 100644 --- a/src/components/application_manager/src/application_impl.cc +++ b/src/components/application_manager/src/application_impl.cc @@ -1185,8 +1185,7 @@ 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) { diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc index 364887ad3f..5dd9291c0d 100644 --- a/src/components/application_manager/src/application_manager_impl.cc +++ b/src/components/application_manager/src/application_manager_impl.cc @@ -269,6 +269,13 @@ 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); @@ -690,6 +697,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. @@ -917,11 +928,11 @@ void ApplicationManagerImpl::RefreshCloudAppInformation() { 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 @@ -937,8 +948,36 @@ 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, policy_id)); // Determine which endpoints were disabled by erasing all enabled apps from @@ -1032,11 +1071,11 @@ 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(); @@ -1055,7 +1094,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; } diff --git a/src/components/include/application_manager/application_manager.h b/src/components/include/application_manager/application_manager.h index cfd6cbe61c..67be49a224 100644 --- a/src/components/include/application_manager/application_manager.h +++ b/src/components/include/application_manager/application_manager.h @@ -169,6 +169,9 @@ 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; 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 7cae217371..daf4a23925 100644 --- a/src/components/include/test/application_manager/mock_application_manager.h +++ b/src/components/include/test/application_manager/mock_application_manager.h @@ -100,6 +100,9 @@ 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)); |