summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrey Oleynik <aoleynik@luxoft.com>2016-01-19 17:33:14 +0200
committerHerasym Oleh <oolleehh@gmail.com>2016-02-02 18:25:23 +0200
commitb41c76e656a3164ec40182ca3fff28f5b451eed0 (patch)
tree71b97de9da8b5d389997546f80f4194efa477318 /src
parent770372f4c5f3bc5f1e01995b76fa77e3ebb63bb7 (diff)
downloadsdl_core-b41c76e656a3164ec40182ca3fff28f5b451eed0.tar.gz
Fixes language comparison logic and adds event race handling.
Since it is unknow what will occur earlier - languages responses or applications registration - it is necessary to meet all conditions. Also this logic should be invoked only in case of some apps registered before responsed have been received. Impements: APPLINK-20560 Conflicts: src/components/application_manager/src/hmi_capabilities.cc
Diffstat (limited to 'src')
-rw-r--r--src/components/application_manager/include/application_manager/hmi_language_handler.h80
-rw-r--r--src/components/application_manager/src/application_manager_impl.cc15
-rw-r--r--src/components/application_manager/src/hmi_capabilities.cc15
-rw-r--r--src/components/application_manager/src/hmi_language_handler.cc145
4 files changed, 214 insertions, 41 deletions
diff --git a/src/components/application_manager/include/application_manager/hmi_language_handler.h b/src/components/application_manager/include/application_manager/hmi_language_handler.h
index d85f7d1a8b..60560a7d48 100644
--- a/src/components/application_manager/include/application_manager/hmi_language_handler.h
+++ b/src/components/application_manager/include/application_manager/hmi_language_handler.h
@@ -47,6 +47,8 @@ namespace application_manager {
**/
class HMILanguageHandler: public event_engine::EventObserver {
public:
+ typedef std::map<uint32_t, bool> Apps;
+
/**
* @brief Class constructor
*/
@@ -97,16 +99,88 @@ public:
void set_handle_response_for(
const event_engine::smart_objects::SmartObject& request);
+ /**
+ * @brief Sets default languages from HMI capabilities
+ * @param ui UI language
+ * @param vr VR language
+ * @param tts TTS language
+ */
+ void set_default_capabilities_languages(
+ hmi_apis::Common_Language::eType ui,
+ hmi_apis::Common_Language::eType vr,
+ hmi_apis::Common_Language::eType tts);
+
private:
/**
- * @brief Verifies already registered apps for language mismatch with
- * current HMI language(s).
+ * @brief Verifies languages gotten from HMI with persisted languages
+ */
+ void VerifyWithPersistedLanguages();
+
+ /**
+ * @brief Handles applications registered before actual HMI languages
+ * have been received
+ * @param app_id Application id
+ */
+ void HandleWrongLanguageApp(const Apps::value_type app_id);
+
+ /**
+ * @brief Checks if application needs to be handled because of language(s)
+ * mismatch
+ * @param app Application
+ */
+ void CheckApplication(const Apps::value_type app);
+
+ sync_primitives::Lock apps_lock_;
+
+ /**
+ * @brief Applications, which needs to be handled
+ */
+ Apps apps_;
+
+ /**
+ * @brief UI language persisted from previous ignition cycle
+ */
+ hmi_apis::Common_Language::eType persisted_ui_language_;
+
+ /**
+ * @brief VR language persisted from previous ignition cycle
*/
- void VerifyRegisteredApps() const;
+ hmi_apis::Common_Language::eType persisted_vr_language_;
+ /**
+ * @brief TTS language persisted from previous ignition cycle
+ */
+ hmi_apis::Common_Language::eType persisted_tts_language_;
+
+ /**
+ * @brief Default UI language from HMI capabilitites
+ */
+ hmi_apis::Common_Language::eType capabilities_ui_language_;
+
+ /**
+ * @brief Default VR language from HMI capabilitites
+ */
+ hmi_apis::Common_Language::eType capabilities_vr_language_;
+
+ /**
+ * @brief Default TTS language from HMI capabilitites
+ */
+ hmi_apis::Common_Language::eType capabilities_tts_language_;
+
+ /**
+ * @brief Indicates if current UI language has been received from HMI
+ */
bool is_ui_language_received_;
+
+ /**
+ * @brief Indicates if current VR language has been received from HMI
+ */
bool is_vr_language_received_;
+
+ /**
+ * @brief Indicates if current TTS language has been received from HMI
+ */
bool is_tts_language_received_;
};
diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc
index b0edd9ad40..b2b2a98d33 100644
--- a/src/components/application_manager/src/application_manager_impl.cc
+++ b/src/components/application_manager/src/application_manager_impl.cc
@@ -333,6 +333,21 @@ void ApplicationManagerImpl::OnApplicationRegistered(ApplicationSharedPtr app) {
sync_primitives::AutoLock lock(applications_list_lock_);
const mobile_apis::HMILevel::eType default_level = GetDefaultHmiLevel(app);
state_ctrl_.OnApplicationRegistered(app, default_level);
+
+ // TODO(AOleynik): Is neccessary to be able to know that registration process
+ // has been completed and default HMI level is set, otherwise policy will
+ // block all the requests/notifications to mobile
+ // APPLINK-20764 - introduce usage of internal events or re-implement
+ event_engine::Event event(
+ hmi_apis::FunctionID::BasicCommunication_OnAppRegistered);
+
+ smart_objects::SmartObject msg;
+ msg[strings::params][strings::message_type] =
+ hmi_apis::messageType::notification;
+ msg[strings::params][strings::app_id] = app->app_id();
+
+ event.set_smart_object(msg);
+ event.raise();
}
bool ApplicationManagerImpl::IsAppTypeExistsInFullOrLimited(
diff --git a/src/components/application_manager/src/hmi_capabilities.cc b/src/components/application_manager/src/hmi_capabilities.cc
index 7c7664f9e3..be73aa23c2 100644
--- a/src/components/application_manager/src/hmi_capabilities.cc
+++ b/src/components/application_manager/src/hmi_capabilities.cc
@@ -247,6 +247,9 @@ HMICapabilities::HMICapabilities(ApplicationManagerImpl* const app_mngr)
is_navi_cooperating_ = true;
is_ivi_cooperating_ = true;
}
+
+ hmi_language_handler_.set_default_capabilities_languages(
+ ui_language_, vr_language_, tts_language_);
}
HMICapabilities::~HMICapabilities() {
@@ -592,8 +595,8 @@ bool HMICapabilities::load_capabilities_from_file() {
Json::Value ui = root_json.get("UI", Json::Value::null);
if (check_existing_json_member(ui, "language")) {
- const std::string lang = ui.get("language", "EN_US").asString();
- set_active_ui_language(MessageHelper::CommonLanguageFromString(lang));
+ const std::string lang = ui.get("language", "EN-US").asString();
+ ui_language_ = (MessageHelper::CommonLanguageFromString(lang));
}
if (check_existing_json_member(ui, "languages")) {
@@ -794,8 +797,8 @@ bool HMICapabilities::load_capabilities_from_file() {
if (check_existing_json_member(root_json, "VR")) {
Json::Value vr = root_json.get("VR", "");
if (check_existing_json_member(vr, "language")) {
- const std::string lang = vr.get("language", "").asString();
- set_active_vr_language(MessageHelper::CommonLanguageFromString(lang));
+ const std::string lang = vr.get("language", "EN-US").asString();
+ vr_language_ = MessageHelper::CommonLanguageFromString(lang);
}
if (check_existing_json_member(vr, "languages")) {
@@ -823,8 +826,8 @@ bool HMICapabilities::load_capabilities_from_file() {
Json::Value tts = root_json.get("TTS", "");
if (check_existing_json_member(tts, "language")) {
- const std::string lang = tts.get("language", "").asString();
- set_active_tts_language(MessageHelper::CommonLanguageFromString(lang));
+ const std::string lang = tts.get("language", "EN-US").asString();
+ tts_language_ = MessageHelper::CommonLanguageFromString(lang);
}
if (check_existing_json_member(tts, "languages")) {
diff --git a/src/components/application_manager/src/hmi_language_handler.cc b/src/components/application_manager/src/hmi_language_handler.cc
index 2c6b156d61..31a235728f 100644
--- a/src/components/application_manager/src/hmi_language_handler.cc
+++ b/src/components/application_manager/src/hmi_language_handler.cc
@@ -30,8 +30,8 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include "application_manager/application_manager_impl.h"
#include "application_manager/hmi_language_handler.h"
+#include "application_manager/application_manager_impl.h"
#include "application_manager/message_helper.h"
#include "application_manager/hmi_capabilities.h"
#include "utils/helpers.h"
@@ -46,10 +46,20 @@ namespace application_manager {
CREATE_LOGGERPTR_GLOBAL(logger_, "ApplicationManager")
-HMILanguageHandler::HMILanguageHandler()
- : is_ui_language_received_(false),
+HMILanguageHandler::HMILanguageHandler() :
+ capabilities_ui_language_(hmi_apis::Common_Language::INVALID_ENUM),
+ capabilities_vr_language_(hmi_apis::Common_Language::INVALID_ENUM),
+ capabilities_tts_language_(hmi_apis::Common_Language::INVALID_ENUM),
+ is_ui_language_received_(false),
is_vr_language_received_(false),
is_tts_language_received_(false) {
+
+ persisted_ui_language_ = get_ui_language();
+ persisted_vr_language_ = get_vr_language();
+ persisted_tts_language_ = get_tts_language();
+
+ subscribe_on_event(
+ hmi_apis::FunctionID::BasicCommunication_OnAppRegistered);
}
void HMILanguageHandler::set_ui_language(
@@ -78,7 +88,7 @@ hmi_apis::Common_Language::eType HMILanguageHandler::get_ui_language() const {
if (LastState::instance()->dictionary[LanguagesKey].isMember(UIKey)) {
Common_Language::eType ui_language =
static_cast<Common_Language::eType>(
- LastState::instance()->dictionary[LanguagesKey][UIKey].asUInt());
+ LastState::instance()->dictionary[LanguagesKey][UIKey].asInt());
return ui_language;
}
@@ -94,7 +104,7 @@ hmi_apis::Common_Language::eType HMILanguageHandler::get_vr_language() const {
if (LastState::instance()->dictionary[LanguagesKey].isMember(VRKey)) {
Common_Language::eType vr_language =
static_cast<Common_Language::eType>(
- LastState::instance()->dictionary[LanguagesKey][VRKey].asUInt());
+ LastState::instance()->dictionary[LanguagesKey][VRKey].asInt());
return vr_language;
}
@@ -108,10 +118,9 @@ hmi_apis::Common_Language::eType HMILanguageHandler::get_tts_language() const {
using namespace hmi_apis;
if (LastState::instance()->dictionary.isMember(LanguagesKey)) {
if (LastState::instance()->dictionary[LanguagesKey].isMember(TTSKey)) {
- // Web HMI returns -1 which causes assert for debug
- Common_Language::eType tts_language = //Common_Language::EN_US;
+ Common_Language::eType tts_language =
static_cast<Common_Language::eType>(
- LastState::instance()->dictionary[LanguagesKey][TTSKey].asUInt());
+ LastState::instance()->dictionary[LanguagesKey][TTSKey].asInt());
return tts_language;
}
@@ -121,6 +130,7 @@ hmi_apis::Common_Language::eType HMILanguageHandler::get_tts_language() const {
void HMILanguageHandler::on_event(const event_engine::Event& event) {
LOG4CXX_AUTO_TRACE(logger_);
+ smart_objects::SmartObject msg = event.smart_object();
switch (event.id()) {
case hmi_apis::FunctionID::UI_GetLanguage:
LOG4CXX_DEBUG(logger_, "Got UI language response.");
@@ -134,13 +144,19 @@ void HMILanguageHandler::on_event(const event_engine::Event& event) {
LOG4CXX_DEBUG(logger_, "Got TTS language response.");
is_tts_language_received_ = true;
break;
+ case hmi_apis::FunctionID::BasicCommunication_OnAppRegistered:
+ CheckApplication(std::make_pair(
+ msg[strings::params][strings::app_id].asUInt(),
+ true));
+ return;
default:
return;
}
if (is_ui_language_received_ && is_vr_language_received_ &&
is_tts_language_received_) {
- VerifyRegisteredApps();
+ LOG4CXX_DEBUG(logger_, "All GetLanguages responses gotten.");
+ VerifyWithPersistedLanguages();
}
}
@@ -189,38 +205,103 @@ void HMILanguageHandler::set_handle_response_for(
" and correlation_id " << correlation_id);
}
-void HMILanguageHandler::VerifyRegisteredApps() const {
+void HMILanguageHandler::set_default_capabilities_languages(
+ hmi_apis::Common_Language::eType ui,
+ hmi_apis::Common_Language::eType vr,
+ hmi_apis::Common_Language::eType tts) {
+ capabilities_ui_language_ = ui;
+ if (hmi_apis::Common_Language::INVALID_ENUM == persisted_ui_language_) {
+ persisted_ui_language_ = ui;
+ }
+
+ capabilities_vr_language_ = vr;
+ if (hmi_apis::Common_Language::INVALID_ENUM == persisted_vr_language_) {
+ persisted_vr_language_ = vr;
+ }
+
+ capabilities_tts_language_ = tts;
+ if (hmi_apis::Common_Language::INVALID_ENUM == persisted_tts_language_) {
+ persisted_tts_language_ = tts;
+ }
+}
+
+void HMILanguageHandler::VerifyWithPersistedLanguages() {
LOG4CXX_AUTO_TRACE(logger_);
using namespace helpers;
HMICapabilities& hmi_capabilities =
ApplicationManagerImpl::instance()->hmi_capabilities();
- hmi_apis::Common_Language::eType ui_language =
- hmi_capabilities.active_ui_language();
- hmi_apis::Common_Language::eType vr_language =
- hmi_capabilities.active_vr_language();
- hmi_apis::Common_Language::eType tts_language =
- hmi_capabilities.active_tts_language();
+ // Updated values compared with persisted
+ if (hmi_capabilities.active_ui_language() == persisted_ui_language_ &&
+ hmi_capabilities.active_vr_language() == persisted_vr_language_ &&
+ hmi_capabilities.active_tts_language() == persisted_tts_language_) {
+ LOG4CXX_INFO(logger_,
+ "All languages gotten from HMI match to persisted values.");
+ return;
+ }
+
+ LOG4CXX_INFO(logger_, "Some languages gotten from HMI have "
+ "mismatch with persisted values.");
+
ApplicationManagerImpl::ApplicationListAccessor accessor;
ApplicationSetIt it = accessor.begin();
for (; accessor.end() != it;) {
ApplicationSharedPtr app = *it++;
- if (app->ui_language() !=
- MessageHelper::CommonToMobileLanguage(ui_language) ||
- !Compare<mobile_apis::Language::eType, EQ, ALL>(
- app->language(),
- MessageHelper::CommonToMobileLanguage(vr_language),
- MessageHelper::CommonToMobileLanguage(tts_language))) {
- LOG4CXX_INFO(logger_, "Application with app_id " << app->app_id()
- << " will be unregistered because of "
- "HMI language(s) mismatch.");
- MessageHelper::SendOnLanguageChangeToMobile(app->app_id());
- MessageHelper::SendOnAppInterfaceUnregisteredNotificationToMobile(
- app->app_id(),
- mobile_api::AppInterfaceUnregisteredReason::LANGUAGE_CHANGE);
- ApplicationManagerImpl::instance()->UnregisterApplication(
- app->app_id(), mobile_apis::Result::SUCCESS, false);
- }
+
+ LOG4CXX_INFO(logger_, "Application with app_id " << app->app_id()
+ << " will be unregistered because of "
+ "HMI language(s) mismatch.");
+
+ CheckApplication(std::make_pair(app->app_id(), false));
+ }
+
+ sync_primitives::AutoLock lock(apps_lock_);
+ if (!apps_.size()) {
+ LOG4CXX_DEBUG(logger_,
+ "No registered apps found. Unsubscribing from all events.");
+ unsubscribe_from_all_events();
+ }
+}
+
+void HMILanguageHandler::HandleWrongLanguageApp(
+ const Apps::value_type app) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ Apps::iterator it = apps_.find(app.first);
+ if (apps_.end() == it) {
+ LOG4CXX_DEBUG(logger_, "Application id " << app.first <<
+ " is not found within apps with wrong language.");
+ return;
+ }
+
+ LOG4CXX_INFO(logger_, "Unregistering application with app_id "
+ << app.first << " because of HMI language(s) mismatch.");
+
+ MessageHelper::SendOnLanguageChangeToMobile(app.first);
+ MessageHelper::SendOnAppInterfaceUnregisteredNotificationToMobile(
+ app.first,
+ mobile_api::AppInterfaceUnregisteredReason::LANGUAGE_CHANGE);
+ ApplicationManagerImpl::instance()->
+ UnregisterApplication(app.first, mobile_apis::Result::SUCCESS, false);
+ apps_.erase(it);
+ if (!apps_.size()) {
+ LOG4CXX_DEBUG(logger_,
+ "All apps processed. Unsubscribing from all events.");
+ unsubscribe_from_all_events();
+ }
+}
+
+void HMILanguageHandler::CheckApplication(const Apps::value_type app) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock lock(apps_lock_);
+ Apps::iterator it = apps_.find(app.first);
+ if (apps_.end() == it) {
+ LOG4CXX_INFO(logger_, "Adding application id " << app.first <<
+ " Application registered: " << app.second);
+ apps_.insert(app);
+ return;
+ }
+ if (apps_[app.first]) {
+ HandleWrongLanguageApp(app);
}
}