summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Keeler <jacob.keeler@livioradio.com>2019-03-07 20:09:08 -0500
committerjacobkeeler <jacob.keeler@livioradio.com>2019-03-07 20:48:03 -0500
commitda94380c916d22127da156bec2a753398f44b4db (patch)
tree7ae524f666ce2c341308fb4f95d41ae5488b5359
parent7a08eafdfe80eab35ac56d3694ddc993d73b871a (diff)
parentb49f662b54b5be8a67140fca1e8f55f87bef13d2 (diff)
downloadsdl_core-da94380c916d22127da156bec2a753398f44b4db.tar.gz
Merge pull request #2833 from smartdevicelink/feature/cloud_app_hybrid_preference
Handle hybrid app preference
-rw-r--r--src/components/application_manager/include/application_manager/application_manager_impl.h11
-rw-r--r--src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/register_app_interface_request.h7
-rw-r--r--src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_request.cc67
-rw-r--r--src/components/application_manager/src/application_impl.cc3
-rw-r--r--src/components/application_manager/src/application_manager_impl.cc65
-rw-r--r--src/components/include/application_manager/application_manager.h3
-rw-r--r--src/components/include/test/application_manager/mock_application_manager.h3
7 files changed, 128 insertions, 31 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..d72d03fa53 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;
@@ -402,7 +404,6 @@ class ApplicationManagerImpl
* @param app A cloud application
* @return The current CloudConnectionStatus of app
*/
-
hmi_apis::Common_CloudConnectionStatus::eType GetCloudAppConnectionStatus(
ApplicationConstSharedPtr app) const;
@@ -1002,6 +1003,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..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/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..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;
}
@@ -922,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];
@@ -938,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();
@@ -949,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;
}
}
@@ -961,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/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 36309fa2f9..61c0f41524 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.
@@ -923,11 +934,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
@@ -943,8 +954,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
@@ -960,7 +999,7 @@ void ApplicationManagerImpl::RefreshCloudAppInformation() {
enabled,
auth_token,
cloud_transport_type,
- hybrid_app_preference};
+ hybrid_app_preference_str};
// If the device was disconnected, this will reinitialize the device
connection_handler().AddCloudAppDevice(policy_id, properties);
@@ -1045,11 +1084,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();
@@ -1068,7 +1107,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));