diff options
9 files changed, 166 insertions, 115 deletions
diff --git a/src/components/application_manager/include/application_manager/commands/mobile/system_request.h b/src/components/application_manager/include/application_manager/commands/mobile/system_request.h index 76447b4753..de87512e92 100644 --- a/src/components/application_manager/include/application_manager/commands/mobile/system_request.h +++ b/src/components/application_manager/include/application_manager/commands/mobile/system_request.h @@ -86,7 +86,7 @@ class SystemRequest : public CommandRequestImpl { * @param data Data * @return true, if data is valid, otherwise - false */ - bool ValidateQueryAppData(const smart_objects::SmartObject& data) const; + bool ValidateQueryAppData(smart_objects::SmartObject& data) const; private: static uint32_t index; diff --git a/src/components/application_manager/include/application_manager/hmi_capabilities.h b/src/components/application_manager/include/application_manager/hmi_capabilities.h index 98b9099384..f94c8125c8 100644 --- a/src/components/application_manager/include/application_manager/hmi_capabilities.h +++ b/src/components/application_manager/include/application_manager/hmi_capabilities.h @@ -416,6 +416,15 @@ class HMICapabilities { void Init(resumption::LastState* last_state); + /** + * @brief return component which follows for correctness of + * languages + * @return HMI language handler + */ + HMILanguageHandler& get_hmi_language_handler() { + return hmi_language_handler_; + } + protected: /* * @brief Loads capabilities from local file in case SDL was launched 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 6e4d9785f6..e8af02c189 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 @@ -98,6 +98,13 @@ class HMILanguageHandler : public event_engine::EventObserver { hmi_apis::Common_Language::eType tts); void Init(resumption::LastState* value); + /** + * @brief Removes application from container after + * removing application from core + * @param app_id id application for removing + */ + void OnUnregisterApplication(uint32_t app_id); + private: void SendOnLanguageChangeToMobile(uint32_t connection_key); 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 93784e9671..31da7647fa 100644 --- a/src/components/application_manager/include/application_manager/hmi_state.h +++ b/src/components/application_manager/include/application_manager/hmi_state.h @@ -151,7 +151,7 @@ class HmiState { /** * @brief state_id state type - * @return reutrn state type + * @return return state type */ StateID state_id() const { return state_id_; diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc index 9b97736e76..f525165827 100644 --- a/src/components/application_manager/src/application_manager_impl.cc +++ b/src/components/application_manager/src/application_manager_impl.cc @@ -320,6 +320,7 @@ std::vector<ApplicationSharedPtr> ApplicationManagerImpl::IviInfoUpdated( } void ApplicationManagerImpl::OnApplicationRegistered(ApplicationSharedPtr app) { + LOG4CXX_AUTO_TRACE(logger_); DCHECK_OR_RETURN_VOID(app); sync_primitives::AutoLock lock(applications_list_lock_); const mobile_apis::HMILevel::eType default_level = GetDefaultHmiLevel(app); @@ -2607,6 +2608,8 @@ void ApplicationManagerImpl::UnregisterApplication( resume_ctrl_.RemoveApplicationFromSaved(app_to_remove); } applications_.erase(app_to_remove); + (hmi_capabilities_.get_hmi_language_handler()) + .OnUnregisterApplication(app_id); AppV4DevicePredicate finder(handle); ApplicationSharedPtr app = FindApp(accessor, finder); if (!app) { diff --git a/src/components/application_manager/src/commands/mobile/register_app_interface_request.cc b/src/components/application_manager/src/commands/mobile/register_app_interface_request.cc index 526ce6e672..412827f7c8 100644 --- a/src/components/application_manager/src/commands/mobile/register_app_interface_request.cc +++ b/src/components/application_manager/src/commands/mobile/register_app_interface_request.cc @@ -542,16 +542,25 @@ void RegisterAppInterfaceRequest::SendRegisterAppInterfaceResponseToMobile() { *(application.get()), resumption, need_restore_vr); SendResponse(true, result_code, add_info.c_str(), &response_params); - if (result_code != mobile_apis::Result::RESUME_FAILED) { - resumer.StartResumption(application, hash_id); + // Check if application exists, because application might be unregestered + // during sending reponse to mobile. + application = application_manager_.application(key); + if (application) { + LOG4CXX_DEBUG(logger_, "Application with app_id = " << key << " exists."); + if (result_code != mobile_apis::Result::RESUME_FAILED) { + resumer.StartResumption(application, hash_id); + } else { + resumer.StartResumptionOnlyHMILevel(application); + } + + // By default app subscribed to CUSTOM_BUTTON + SendSubscribeCustomButtonNotification(); + MessageHelper::SendChangeRegistrationRequestToHMI(application, + application_manager_); } else { - resumer.StartResumptionOnlyHMILevel(application); + LOG4CXX_DEBUG(logger_, + "Application with app_id = " << key << " doesn't exist."); } - - // By default app subscribed to CUSTOM_BUTTON - SendSubscribeCustomButtonNotification(); - MessageHelper::SendChangeRegistrationRequestToHMI(application, - application_manager_); } void RegisterAppInterfaceRequest::SendOnAppRegisteredNotificationToHMI( diff --git a/src/components/application_manager/src/commands/mobile/system_request.cc b/src/components/application_manager/src/commands/mobile/system_request.cc index cd2418f52e..b9acf5e930 100644 --- a/src/components/application_manager/src/commands/mobile/system_request.cc +++ b/src/components/application_manager/src/commands/mobile/system_request.cc @@ -72,11 +72,11 @@ class QueryAppsDataValidator { typedef std::set<std::string> SynonymsSet; typedef std::map<std::string, SynonymsSet> SynonymsMap; - QueryAppsDataValidator(const smart_objects::SmartObject& object, + QueryAppsDataValidator(smart_objects::SmartObject& object, const ApplicationManager& manager) : data_(object), manager_(manager) {} - bool Validate() const { + bool Validate() { LOG4CXX_AUTO_TRACE(logger_); if (!data_.isValid()) { LOG4CXX_ERROR(logger_, @@ -102,19 +102,25 @@ class QueryAppsDataValidator { return true; } - bool ValidateAppDataAndOsAndLanguagesData() const { - const smart_objects::SmartArray* objects_array = - data_[json::response].asArray(); + bool ValidateAppDataAndOsAndLanguagesData() { + smart_objects::SmartArray* objects_array = data_[json::response].asArray(); + if (!objects_array) { LOG4CXX_WARN(logger_, kQueryAppsValidationFailedPrefix << "QueryApps response is not array."); return false; } - const std::size_t arr_size(objects_array->size()); + SynonymsMap synonyms_map; - for (std::size_t idx = 0; idx < arr_size; ++idx) { - const smart_objects::SmartObject& app_data = (*objects_array)[idx]; + bool has_response_valid_application = false; + + smart_objects::SmartArray::iterator applications_iterator = + objects_array->begin(); + + for (; applications_iterator != objects_array->end(); + ++applications_iterator) { + const smart_objects::SmartObject& app_data = *applications_iterator; if (!app_data.isValid()) { LOG4CXX_WARN(logger_, @@ -122,59 +128,50 @@ class QueryAppsDataValidator { << "Wrong application data in json file."); return false; } - std::set<std::string> app_ids_set; - if (!ValidateAppIdAndAppName(app_data, app_ids_set)) { + + if (!CheckMandatoryParametersPresent(app_data)) { + LOG4CXX_WARN(logger_, + "Application hasn`t some of mandatory parameters. " + "Application will be skipped."); + objects_array->erase(applications_iterator); + continue; + } + + if (!ValidateAppIdAndAppName(app_data)) { return false; } + + // If we dont have any of android/ios field + // we skip this json in CheckMandatoryParametersPresent + const std::string os_type = + (app_data.keyExists(json::android)) ? json::android : json::ios; + // Verify os and dependent languages data - std::string os_type; - if (app_data.keyExists(json::ios)) { - os_type = json::ios; - if (!app_data[os_type].keyExists(json::urlScheme)) { - LOG4CXX_WARN(logger_, - kQueryAppsValidationFailedPrefix - << "Can't find URL scheme in json file."); - return false; - } - if (app_data[os_type][json::urlScheme].asString().length() > + if (json::ios == os_type) { + if (app_data[json::ios][json::urlScheme].asString().length() > kUrlSchemaLengthMax) { LOG4CXX_WARN( logger_, kQueryAppsValidationFailedPrefix << "An urlscheme length exceeds maximum allowed [" - << app_data[os_type][json::urlScheme].asString().length() + << app_data[json::ios][json::urlScheme].asString().length() << "]>[" << kUrlSchemaLengthMax << "]"); return false; } } - if (os_type.empty()) { - if (app_data.keyExists(json::android)) { - os_type = json::android; - if (!app_data[os_type].keyExists(json::packageName)) { - LOG4CXX_WARN(logger_, - kQueryAppsValidationFailedPrefix - << "Can't find package name in json file."); - return false; - } - if (app_data[json::android][json::packageName].asString().length() > - kPackageNameLengthMax) { - LOG4CXX_WARN(logger_, - kQueryAppsValidationFailedPrefix - << "Package name length [" - << app_data[json::android][json::packageName] - .asString() - .length() << "] exceeds max length [" - << kPackageNameLengthMax << "]in json file."); - return false; - } - } - } - if (os_type.empty()) { - LOG4CXX_WARN(logger_, - kQueryAppsValidationFailedPrefix - << "Can't find mobile OS type in json file."); - return false; + if (json::android == os_type) { + if (app_data[json::android][json::packageName].asString().length() > + kPackageNameLengthMax) { + LOG4CXX_WARN(logger_, + kQueryAppsValidationFailedPrefix + << "Package name length [" + << app_data[json::android][json::packageName] + .asString() + .length() << "] exceeds max length [" + << kPackageNameLengthMax << "]in json file."); + return false; + } } // Languages verification @@ -188,19 +185,12 @@ class QueryAppsDataValidator { synonyms_map)) { return false; } + has_response_valid_application = true; } - return true; + return has_response_valid_application; } - bool ValidateAppIdAndAppName(const smart_objects::SmartObject& app_data, - std::set<std::string>& app_ids_set) const { - // Verify appid - if (!app_data.keyExists(json::appId)) { - LOG4CXX_WARN(logger_, - kQueryAppsValidationFailedPrefix - << "Can't find app ID in json file."); - return false; - } + bool ValidateAppIdAndAppName(const smart_objects::SmartObject& app_data) { // Verify appid length const std::string app_id(app_data[json::appId].asString()); if (app_id.length() > kAppIdLengthMax) { @@ -212,30 +202,21 @@ class QueryAppsDataValidator { } // Verify that appid is unique - if (app_ids_set.find(app_id) != app_ids_set.end()) { + if (applications_id_set_.find(app_id) != applications_id_set_.end()) { LOG4CXX_WARN(logger_, kQueryAppsValidationFailedPrefix << "An Object ID is not unigue [" << app_id << "]"); return false; } - app_ids_set.insert(app_id); + applications_id_set_.insert(app_id); // Verify that app is not registered yet ApplicationSharedPtr registered_app = manager_.application_by_policy_id(app_id); if (registered_app) { - LOG4CXX_WARN(logger_, - kQueryAppsValidationFailedPrefix - << "Application with the same id: " << app_id - << " is registered already."); - return false; - } - // Verify app name exist - if (!app_data.keyExists(json::name)) { - LOG4CXX_WARN(logger_, - kQueryAppsValidationFailedPrefix - << "Can't find app name in json file."); - return false; + LOG4CXX_INFO(logger_, + "Application with the id: " << app_id + << " is already registered."); } // And app name length const std::string appName(app_data[json::name].asString()); @@ -404,7 +385,35 @@ class QueryAppsDataValidator { return true; } - const smart_objects::SmartObject& data_; + bool CheckMandatoryParametersPresent( + const smart_objects::SmartObject& app_data) const { + if (!app_data.keyExists(json::android) && !app_data.keyExists(json::ios)) { + return false; + } + + if (app_data.keyExists(json::android) && + !app_data[json::android].keyExists(json::packageName)) { + return false; + } + + if (app_data.keyExists(json::ios) && + !app_data[json::ios].keyExists(json::urlScheme)) { + return false; + } + + if (!app_data.keyExists(json::appId)) { + return false; + } + + if (!app_data.keyExists(json::name)) { + return false; + } + + return true; + } + + smart_objects::SmartObject& data_; + std::set<std::string> applications_id_set_; const ApplicationManager& manager_; DISALLOW_COPY_AND_ASSIGN(QueryAppsDataValidator); @@ -620,7 +629,7 @@ void SystemRequest::on_event(const event_engine::Event& event) { } bool SystemRequest::ValidateQueryAppData( - const smart_objects::SmartObject& data) const { + smart_objects::SmartObject& data) const { if (!data.isValid()) { LOG4CXX_ERROR(logger_, kQueryAppsValidationFailedPrefix diff --git a/src/components/application_manager/src/hmi_language_handler.cc b/src/components/application_manager/src/hmi_language_handler.cc index 72ab60eb3a..d37467ee76 100644 --- a/src/components/application_manager/src/hmi_language_handler.cc +++ b/src/components/application_manager/src/hmi_language_handler.cc @@ -131,6 +131,10 @@ void HMILanguageHandler::on_event(const event_engine::Event& event) { is_tts_language_received_ = true; break; case hmi_apis::FunctionID::BasicCommunication_OnAppRegistered: + if (!(msg[strings::params].keyExists(strings::app_id))) { + LOG4CXX_ERROR(logger_, "Message doesn't contain parameter app_id"); + return; + } CheckApplication( std::make_pair(msg[strings::params][strings::app_id].asUInt(), true)); return; @@ -273,26 +277,31 @@ void HMILanguageHandler::VerifyWithPersistedLanguages() { sync_primitives::AutoLock lock(apps_lock_); if (0 == apps_.size()) { LOG4CXX_DEBUG(logger_, - "No registered apps found. Unsubscribing from all events."); + "No registered apps found. HMILanguageHandler unsubscribed " + "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; + { + sync_primitives::AutoLock lock(apps_lock_); + 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; + } + apps_.erase(it); + if (0 == apps_.size()) { + LOG4CXX_DEBUG(logger_, + "HMILanguageHandler unsubscribed from all events."); + unsubscribe_from_all_events(); + } } - - LOG4CXX_INFO(logger_, - "Unregistering application with app_id " - << app.first << " because of HMI language(s) mismatch."); - SendOnLanguageChangeToMobile(app.first); application_manager_.ManageMobileCommand( MessageHelper::GetOnAppInterfaceUnregisteredNotificationToMobile( @@ -301,26 +310,28 @@ void HMILanguageHandler::HandleWrongLanguageApp(const Apps::value_type& app) { commands::Command::ORIGIN_SDL); application_manager_.UnregisterApplication( app.first, mobile_apis::Result::SUCCESS, false); - apps_.erase(it); - if (0 == apps_.size()) { - LOG4CXX_DEBUG(logger_, - "All apps processed. Unsubscribing from all events."); - unsubscribe_from_all_events(); - } + LOG4CXX_INFO(logger_, + "Unregistering application with app_id " + << app.first << " because of HMI language(s) mismatch."); } 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; + bool is_need_handle_wrong_language = false; + { + 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; + } + is_need_handle_wrong_language = apps_[app.first]; } - if (apps_[app.first]) { + if (is_need_handle_wrong_language) { HandleWrongLanguageApp(app); } } @@ -332,4 +343,10 @@ void HMILanguageHandler::Init(resumption::LastState* value) { persisted_tts_language_ = get_language_for(INTERFACE_TTS); } +void HMILanguageHandler::OnUnregisterApplication(uint32_t app_id) { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock lock(apps_lock_); + apps_.erase(app_id); +} + } // namespace application_manager diff --git a/src/components/application_manager/src/hmi_state.cc b/src/components/application_manager/src/hmi_state.cc index bad2d8661b..80628f9f33 100644 --- a/src/components/application_manager/src/hmi_state.cc +++ b/src/components/application_manager/src/hmi_state.cc @@ -61,19 +61,16 @@ void HmiState::set_parent(HmiStatePtr parent) { bool HmiState::is_navi_app(const uint32_t app_id) const { const ApplicationSharedPtr app = app_mngr_.application(app_id); - DCHECK_OR_RETURN(app, false); return app ? app->is_navi() : false; } bool HmiState::is_media_app(const uint32_t app_id) const { const ApplicationSharedPtr app = app_mngr_.application(app_id); - DCHECK_OR_RETURN(app, false); return app ? app->is_media_application() : false; } bool HmiState::is_voice_communication_app(const uint32_t app_id) const { const ApplicationSharedPtr app = app_mngr_.application(app_id); - DCHECK_OR_RETURN(app, false); return app ? app->is_voice_communication_supported() : false; } |