diff options
author | Andrey Oleynik <aoleynik@luxoft.com> | 2016-01-19 17:33:14 +0200 |
---|---|---|
committer | Herasym Oleh <oolleehh@gmail.com> | 2016-02-02 18:25:23 +0200 |
commit | b41c76e656a3164ec40182ca3fff28f5b451eed0 (patch) | |
tree | 71b97de9da8b5d389997546f80f4194efa477318 /src | |
parent | 770372f4c5f3bc5f1e01995b76fa77e3ebb63bb7 (diff) | |
download | sdl_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')
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); } } |