diff options
45 files changed, 729 insertions, 386 deletions
diff --git a/src/appMain/sdl_preloaded_pt.json b/src/appMain/sdl_preloaded_pt.json index bdd7b4e8c8..4f97d90b09 100644 --- a/src/appMain/sdl_preloaded_pt.json +++ b/src/appMain/sdl_preloaded_pt.json @@ -3160,20 +3160,20 @@ "name": "hdop", "key": "OEM_REF_HDOP", "type": "Float", - "mandatory": true, + "mandatory": false, "minvalue": 0, "maxvalue": 1000, - "since": "2.0", - "until": "5.0" + "since": "5.0" }, { "name": "hdop", "key": "OEM_REF_HDOP", "type": "Float", - "mandatory": false, + "mandatory": true, "minvalue": 0, - "maxvalue": 1000, - "since": "5.0" + "maxvalue": 10, + "since": "2.0", + "until": "5.0" }, { "name": "vdop", @@ -3181,7 +3181,7 @@ "type": "Float", "mandatory": false, "minvalue": 0, - "maxvalue": 10, + "maxvalue": 1000, "since": "5.0" }, { @@ -3216,7 +3216,7 @@ "mandatory": false, "minvalue": 0, "maxvalue": 31, - "until": "5.0" + "since": "5.0" }, { "name": "satellites", @@ -3269,7 +3269,7 @@ "mandatory": false, "minvalue": 0, "maxvalue": 359.99, - "until": "5.0" + "since": "5.0" }, { "name": "heading", @@ -3288,7 +3288,7 @@ "mandatory": false, "minvalue": 0, "maxvalue": 500, - "until": "5.0" + "since": "5.0" }, { "name": "speed", @@ -3305,8 +3305,6 @@ "key": "OEM_REF_SHIFT", "type": "Boolean", "mandatory": false, - "minvalue": 0, - "maxvalue": 500, "since": "6.0" } ], @@ -3358,16 +3356,16 @@ { "name": "type", "key": "OEM_REF_FUEL_RAN_TYPE", - "type": "Float", - "mandatory": false, - "minvalue": 0, - "maxvalue": 10000 + "type": "FuelType", + "mandatory": false }, { "name": "range", "key": "OEM_REF_FUEL_RAN_RANG", - "type": "FuelType", - "mandatory": false + "type": "Float", + "mandatory": false, + "minvalue": 0, + "maxvalue": 10000 } ], "key": "OEM_REF_FUEL_RAN", diff --git a/src/components/application_manager/include/application_manager/application_impl.h b/src/components/application_manager/include/application_manager/application_impl.h index 27b6c8123e..185d700d58 100644 --- a/src/components/application_manager/include/application_manager/application_impl.h +++ b/src/components/application_manager/include/application_manager/application_impl.h @@ -601,6 +601,7 @@ class ApplicationImpl : public virtual Application, std::atomic_bool is_resuming_; mobile_api::HMILevel::eType deferred_resumption_hmi_level_; bool is_hash_changed_during_suspend_; + smart_objects::SmartObject user_location_; uint32_t video_stream_retry_number_; uint32_t audio_stream_retry_number_; @@ -617,7 +618,6 @@ class ApplicationImpl : public virtual Application, std::string cloud_transport_type_; mobile_apis::HybridAppPreference::eType hybrid_app_preference_; std::string certificate_; - smart_objects::SmartObject user_location_; /** * @brief Defines number per time in seconds limits 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 e88c954c18..438b62c797 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 @@ -175,17 +175,21 @@ class ApplicationManagerImpl ApplicationSharedPtr active_application() const OVERRIDE; + ApplicationSharedPtr get_full_or_limited_application() const OVERRIDE; + ApplicationSharedPtr application_by_hmi_app( 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; + DEPRECATED 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; ApplicationSharedPtr reregister_application_by_policy_id( const std::string& policy_app_id) const OVERRIDE; + std::vector<ApplicationSharedPtr> applications_by_name( + const std::string& app_name) const OVERRIDE; std::vector<ApplicationSharedPtr> applications_by_button( uint32_t button) OVERRIDE; std::vector<ApplicationSharedPtr> applications_with_navi() OVERRIDE; @@ -647,6 +651,9 @@ class ApplicationManagerImpl const uint32_t corr_id, const int32_t function_id) OVERRIDE; + void OnQueryAppsRequest( + const connection_handler::DeviceHandle device) OVERRIDE; + // Overriden ConnectionHandlerObserver method void OnDeviceListUpdated( const connection_handler::DeviceMap& device_list) OVERRIDE; @@ -1136,8 +1143,19 @@ class ApplicationManagerImpl */ protocol_handler::MajorProtocolVersion SupportedSDLVersion() const OVERRIDE; + void ApplyFunctorForEachPlugin( + std::function<void(plugin_manager::RPCPlugin&)> functor) OVERRIDE; + private: /** + * @brief Adds application to registered applications list and marks it as + * registered + * @param application Application that should be added to registered + * applications list. + */ + void AddAppToRegisteredAppList(const ApplicationSharedPtr application); + + /** * @brief Removes service status record for service that failed to start * @param app Application whose service status record should be removed * @param Service type which status record should be removed @@ -1472,11 +1490,12 @@ class ApplicationManagerImpl * will send TTS global properties to HMI after timeout */ std::map<uint32_t, date_time::TimeDuration> tts_global_properties_app_list_; - + std::set<connection_handler::DeviceHandle> query_apps_devices_; bool audio_pass_thru_active_; uint32_t audio_pass_thru_app_id_; sync_primitives::Lock audio_pass_thru_lock_; sync_primitives::Lock tts_global_properties_app_list_lock_; + mutable sync_primitives::Lock query_apps_devices_lock_; hmi_apis::Common_DriverDistractionState::eType driver_distraction_state_; bool is_vr_session_strated_; bool hmi_cooperating_; diff --git a/src/components/application_manager/include/application_manager/hmi_capabilities_impl.h b/src/components/application_manager/include/application_manager/hmi_capabilities_impl.h index b4610f0375..2c4212c888 100644 --- a/src/components/application_manager/include/application_manager/hmi_capabilities_impl.h +++ b/src/components/application_manager/include/application_manager/hmi_capabilities_impl.h @@ -219,7 +219,7 @@ class HMICapabilitiesImpl : public HMICapabilities { * * @return Currently supported display capabilities */ - const smart_objects::SmartObject* display_capabilities() const OVERRIDE; + const smart_objects::SmartObjectSPtr display_capabilities() const OVERRIDE; /* * @brief Sets supported display capabilities @@ -248,7 +248,7 @@ class HMICapabilitiesImpl : public HMICapabilities { * * @return Currently supported HMI zone capabilities */ - const smart_objects::SmartObject* hmi_zone_capabilities() const OVERRIDE; + const smart_objects::SmartObjectSPtr hmi_zone_capabilities() const OVERRIDE; /* * @brief Sets supported HMI zone capabilities @@ -263,7 +263,8 @@ class HMICapabilitiesImpl : public HMICapabilities { * * @return Currently supported SoftButton's capabilities */ - const smart_objects::SmartObject* soft_button_capabilities() const OVERRIDE; + const smart_objects::SmartObjectSPtr soft_button_capabilities() + const OVERRIDE; /* * @brief Sets supported SoftButton's capabilities @@ -278,7 +279,7 @@ class HMICapabilitiesImpl : public HMICapabilities { * * @return Currently supported Button's capabilities */ - const smart_objects::SmartObject* button_capabilities() const OVERRIDE; + const smart_objects::SmartObjectSPtr button_capabilities() const OVERRIDE; /* * @brief Sets supported Button's capabilities @@ -301,7 +302,7 @@ class HMICapabilitiesImpl : public HMICapabilities { * * @return Currently supported speech capabilities */ - const smart_objects::SmartObject* speech_capabilities() const OVERRIDE; + const smart_objects::SmartObjectSPtr speech_capabilities() const OVERRIDE; /* * @brief Sets supported VR capabilities @@ -316,7 +317,7 @@ class HMICapabilitiesImpl : public HMICapabilities { * * @return Currently supported VR capabilities */ - const smart_objects::SmartObject* vr_capabilities() const OVERRIDE; + const smart_objects::SmartObjectSPtr vr_capabilities() const OVERRIDE; /* * @brief Sets supported audio_pass_thru capabilities @@ -331,7 +332,7 @@ class HMICapabilitiesImpl : public HMICapabilities { * * @return Currently supported audio_pass_thru capabilities */ - const smart_objects::SmartObject* audio_pass_thru_capabilities() + const smart_objects::SmartObjectSPtr audio_pass_thru_capabilities() const OVERRIDE; /* @@ -347,14 +348,15 @@ class HMICapabilitiesImpl : public HMICapabilities { * * @return Currently supported pcm_streaming capabilities */ - const smart_objects::SmartObject* pcm_stream_capabilities() const OVERRIDE; + const smart_objects::SmartObjectSPtr pcm_stream_capabilities() const OVERRIDE; /* * @brief Retrieves information about the preset bank capabilities * * @return Currently supported preset bank capabilities */ - const smart_objects::SmartObject* preset_bank_capabilities() const OVERRIDE; + const smart_objects::SmartObjectSPtr preset_bank_capabilities() + const OVERRIDE; /* * @brief Sets supported preset bank capabilities @@ -377,14 +379,14 @@ class HMICapabilitiesImpl : public HMICapabilities { * * @param vehicle_type Cuurent vehicle information */ - const smart_objects::SmartObject* vehicle_type() const OVERRIDE; + const smart_objects::SmartObjectSPtr vehicle_type() const OVERRIDE; /* * @brief Retrieves information about the prerecorded speech * * @return Currently supported prerecorded speech */ - const smart_objects::SmartObject* prerecorded_speech() const OVERRIDE; + const smart_objects::SmartObjectSPtr prerecorded_speech() const OVERRIDE; /* * @brief Sets supported prerecorded speech @@ -585,7 +587,7 @@ class HMICapabilitiesImpl : public HMICapabilities { hmi_apis::Common_Language::eType ui_language_; hmi_apis::Common_Language::eType vr_language_; hmi_apis::Common_Language::eType tts_language_; - smart_objects::SmartObject* vehicle_type_; + smart_objects::SmartObjectSPtr vehicle_type_; smart_objects::SmartObject* ui_supported_languages_; smart_objects::SmartObject* tts_supported_languages_; smart_objects::SmartObject* vr_supported_languages_; @@ -594,17 +596,17 @@ class HMICapabilitiesImpl : public HMICapabilities { * system_display_capabilities_. For backward compatibility * display_capabilities_ is not removed. */ - smart_objects::SmartObject* display_capabilities_; + smart_objects::SmartObjectSPtr display_capabilities_; smart_objects::SmartObjectSPtr system_display_capabilities_; - smart_objects::SmartObject* hmi_zone_capabilities_; - smart_objects::SmartObject* soft_buttons_capabilities_; - smart_objects::SmartObject* button_capabilities_; - smart_objects::SmartObject* preset_bank_capabilities_; - smart_objects::SmartObject* vr_capabilities_; - smart_objects::SmartObject* speech_capabilities_; - smart_objects::SmartObject* audio_pass_thru_capabilities_; - smart_objects::SmartObject* pcm_stream_capabilities_; - smart_objects::SmartObject* prerecorded_speech_; + smart_objects::SmartObjectSPtr hmi_zone_capabilities_; + smart_objects::SmartObjectSPtr soft_buttons_capabilities_; + smart_objects::SmartObjectSPtr button_capabilities_; + smart_objects::SmartObjectSPtr preset_bank_capabilities_; + smart_objects::SmartObjectSPtr vr_capabilities_; + smart_objects::SmartObjectSPtr speech_capabilities_; + smart_objects::SmartObjectSPtr audio_pass_thru_capabilities_; + smart_objects::SmartObjectSPtr pcm_stream_capabilities_; + smart_objects::SmartObjectSPtr prerecorded_speech_; bool is_navigation_supported_; bool is_phone_call_supported_; bool is_video_streaming_supported_; diff --git a/src/components/application_manager/include/application_manager/plugin_manager/rpc_plugin.h b/src/components/application_manager/include/application_manager/plugin_manager/rpc_plugin.h index 61b146f024..3af87a0c9e 100644 --- a/src/components/application_manager/include/application_manager/plugin_manager/rpc_plugin.h +++ b/src/components/application_manager/include/application_manager/plugin_manager/rpc_plugin.h @@ -65,7 +65,8 @@ enum ApplicationEvent { kApplicationRegistered, kApplicationUnregistered, kDeleteApplicationData, - kGlobalPropertiesUpdated + kGlobalPropertiesUpdated, + kRCStatusChanged }; class RPCPlugin { diff --git a/src/components/application_manager/include/application_manager/resumption/resume_ctrl.h b/src/components/application_manager/include/application_manager/resumption/resume_ctrl.h index 11b1bcf926..78366ea96a 100644 --- a/src/components/application_manager/include/application_manager/resumption/resume_ctrl.h +++ b/src/components/application_manager/include/application_manager/resumption/resume_ctrl.h @@ -113,9 +113,9 @@ class ResumeCtrl { * @brief RestoreAppWidgets add widgets for the application * @param application application which will be resumed * @param saved_app application specific section from backup file - * @return true if widgets resumed successfully otherwise - false + * @return the number of widget windows to be resumed */ - virtual void RestoreAppWidgets( + virtual size_t RestoreAppWidgets( application_manager::ApplicationSharedPtr application, const smart_objects::SmartObject& saved_app) = 0; diff --git a/src/components/application_manager/include/application_manager/resumption/resume_ctrl_impl.h b/src/components/application_manager/include/application_manager/resumption/resume_ctrl_impl.h index 5e6fb58671..f0d5dc39e4 100644 --- a/src/components/application_manager/include/application_manager/resumption/resume_ctrl_impl.h +++ b/src/components/application_manager/include/application_manager/resumption/resume_ctrl_impl.h @@ -124,8 +124,9 @@ class ResumeCtrlImpl : public ResumeCtrl, * @param application application which will be resumed * @param saved_app application specific section from backup file */ - void RestoreAppWidgets(application_manager::ApplicationSharedPtr application, - const smart_objects::SmartObject& saved_app) OVERRIDE; + size_t RestoreAppWidgets( + application_manager::ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app) OVERRIDE; /** * @brief Remove application from list of saved applications diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_helpers.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_helpers.cc index ca0edc90b1..f344dd15a7 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_helpers.cc +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_helpers.cc @@ -175,6 +175,7 @@ const std::vector<std::string> RCHelpers::GetModuleTypesList() { RCAppExtensionPtr RCHelpers::GetRCExtension( application_manager::Application& app) { + LOG4CXX_AUTO_TRACE(logger_); auto extension_interface = app.QueryInterface(RCRPCPlugin::kRCPluginID); auto extension = std::static_pointer_cast<RCAppExtension>(extension_interface); diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_rpc_plugin.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_rpc_plugin.cc index 9005eb7fd0..4e43cff58d 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_rpc_plugin.cc +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/rc_rpc_plugin.cc @@ -107,7 +107,12 @@ void RCRPCPlugin::OnPolicyEvent( void RCRPCPlugin::OnApplicationEvent( application_manager::plugin_manager::ApplicationEvent event, application_manager::ApplicationSharedPtr application) { + LOG4CXX_AUTO_TRACE(logger_); if (!application->is_remote_control_supported()) { + LOG4CXX_DEBUG( + logger_, + "Remote control is not supported for application with app_id: " + << application->app_id()); return; } switch (event) { @@ -119,8 +124,6 @@ void RCRPCPlugin::OnApplicationEvent( rc_capabilities_manager_ ->GetDriverLocationFromSeatLocationCapability(); extension->SetUserLocation(driver_location); - resource_allocation_manager_->SendOnRCStatusNotifications( - NotificationTrigger::APP_REGISTRATION, application); break; } case plugins::kApplicationExit: { @@ -139,6 +142,11 @@ void RCRPCPlugin::OnApplicationEvent( extension->SetUserLocation(user_location); break; } + case plugins::kRCStatusChanged: { + resource_allocation_manager_->SendOnRCStatusNotifications( + NotificationTrigger::APP_REGISTRATION, application); + break; + } default: break; } diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/resource_allocation_manager_impl.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/resource_allocation_manager_impl.cc index 97ff2b23da..049f9a3cf3 100644 --- a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/resource_allocation_manager_impl.cc +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/resource_allocation_manager_impl.cc @@ -156,6 +156,7 @@ bool ResourceAllocationManagerImpl::IsUserLocationValid( ModuleUid& module, application_manager::ApplicationSharedPtr app) { LOG4CXX_AUTO_TRACE(logger_); const auto extension = RCHelpers::GetRCExtension(*app); + DCHECK_OR_RETURN(extension, false); const auto user_location = extension->GetUserLocation(); const auto module_service_area = rc_capabilities_manager_.GetModuleServiceArea(module); 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 c55dcb65fc..d59964bbc7 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 @@ -134,30 +134,39 @@ class RegisterAppInterfaceRequest app_mngr::ApplicationConstSharedPtr app, bool resumption = false, bool need_restore_vr = false); - /* + + /** * @brief Check new ID along with known mobile application ID * * return TRUE if ID is known already, otherwise - FALSE */ bool IsApplicationWithSameAppIdRegistered(); - /* + /** * @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, + * @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(); + + /** + * @brief Search for any apps with the same appName as the one being + * registered + * @param out_duplicate_apps To be filled with a list of all of the apps which + * have duplicate appNames to the app being registered (registered or pending) + * + * @return TRUE if at least one duplicate app was found, otherwise FALSE + */ + bool GetDuplicateNames( std::vector<app_mngr::ApplicationSharedPtr>& out_duplicate_apps); - /* + /** * @brief Predicate for using with CheckCoincidence method to compare with VR * synonym SO * - * return TRUE if there is coincidence of VR, otherwise FALSE + * @return TRUE if there is coincidence of VR, otherwise FALSE */ struct CoincidencePredicateVR { CoincidencePredicateVR(const custom_str::CustomString& newItem) diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_button_event_notification.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_button_event_notification.cc index 0bf9b40cb6..bca3b20fe0 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_button_event_notification.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_button_event_notification.cc @@ -105,11 +105,10 @@ void OnButtonEventNotification::Run() { const auto window_id = app->GetSoftButtonWindowID(custom_btn_id); (*message_)[strings::msg_params][strings::window_id] = window_id; const auto window_hmi_level = app->hmi_level(window_id); - if ((mobile_api::HMILevel::HMI_FULL != window_hmi_level) && - (mobile_api::HMILevel::HMI_LIMITED != window_hmi_level)) { + if ((mobile_api::HMILevel::HMI_NONE == window_hmi_level)) { LOG4CXX_WARN(logger_, - "CUSTOM_BUTTON OnButtonEvent notification is allowed only " - << "in FULL or LIMITED hmi level"); + "CUSTOM_BUTTON OnButtonEvent notification is not allowed in " + "NONE hmi level"); return; } diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_button_press_notification.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_button_press_notification.cc index 8c22844865..c51991742d 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_button_press_notification.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/on_button_press_notification.cc @@ -108,11 +108,10 @@ void OnButtonPressNotification::Run() { app->hmi_level(mobile_apis::PredefinedWindows::DEFAULT_WINDOW); (*message_)[strings::msg_params][strings::window_id] = window_id; const auto window_hmi_level = app->hmi_level(window_id); - if ((mobile_api::HMILevel::HMI_FULL != window_hmi_level) && - (mobile_api::HMILevel::HMI_LIMITED != window_hmi_level)) { + if ((mobile_api::HMILevel::HMI_NONE == window_hmi_level)) { LOG4CXX_WARN(logger_, - "CUSTOM_BUTTON OnButtonPress notification is allowed only " - << "in FULL or LIMITED hmi level"); + "CUSTOM_BUTTON OnButtonPress notification is not allowed in " + "NONE hmi level"); return; } 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 14a94fd1a2..cbdaa713b8 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 @@ -43,6 +43,7 @@ #include "application_manager/application_manager.h" #include "application_manager/helpers/application_helper.h" #include "application_manager/message_helper.h" +#include "application_manager/plugin_manager/plugin_keys.h" #include "application_manager/policies/policy_handler.h" #include "application_manager/policies/policy_handler_interface.h" #include "application_manager/resumption/resume_ctrl.h" @@ -296,50 +297,77 @@ 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; - } + if (GetDuplicateNames(duplicate_apps)) { + LOG4CXX_ERROR(logger_, + "Found duplicate app names, checking for hybrid apps."); + // Default preference to BOTH + mobile_apis::HybridAppPreference::eType preference = + mobile_apis::HybridAppPreference::BOTH; + ApplicationSharedPtr app = + application_manager_.pending_application_by_policy_id(policy_app_id); + bool is_cloud_app = app.use_count() != 0 && app->is_cloud_app(); + if (is_cloud_app) { + // Retrieve hybrid app preference from registering app + preference = app->hybrid_app_preference(); } 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()) { + 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; - } 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; + } + // Search for the hybrid app preference in the duplicate app list + for (auto duplicate_app : duplicate_apps) { + if (duplicate_app->is_cloud_app()) { + preference = duplicate_app->hybrid_app_preference(); + break; + } } } - if (error_response) { - LOG4CXX_ERROR(logger_, "Coincidence check failed."); - SendResponse(false, coincidence_result); - return; + if (preference == mobile_apis::HybridAppPreference::MOBILE || + preference == mobile_apis::HybridAppPreference::CLOUD) { + bool cloud_app_exists = is_cloud_app; + bool mobile_app_exists = !is_cloud_app; + for (auto duplicate_app : duplicate_apps) { + cloud_app_exists = cloud_app_exists || (duplicate_app->IsRegistered() && + duplicate_app->is_cloud_app()); + mobile_app_exists = mobile_app_exists || !duplicate_app->is_cloud_app(); + if (is_cloud_app && !duplicate_app->is_cloud_app() && + preference == mobile_apis::HybridAppPreference::CLOUD) { + // Unregister mobile application and allow cloud application to + // register in it's place + LOG4CXX_ERROR( + logger_, + "Unregistering app because a preferred version is registered."); + application_manager_.UnregisterApplication( + duplicate_app->app_id(), + mobile_apis::Result::USER_DISALLOWED, + "App is disabled by user preferences"); + } + } + + bool mobile_app_matches = + !is_cloud_app && + preference == mobile_apis::HybridAppPreference::MOBILE; + bool cloud_app_matches = + is_cloud_app && preference == mobile_apis::HybridAppPreference::CLOUD; + + bool is_preferred_application = mobile_app_matches || cloud_app_matches; + if (mobile_app_exists && cloud_app_exists && !is_preferred_application) { + SendResponse(false, + mobile_apis::Result::USER_DISALLOWED, + "App is disabled by user preferences"); + return; + } } - } else if (mobile_apis::Result::SUCCESS != coincidence_result) { + } + + if (mobile_apis::Result::SUCCESS != coincidence_result) { LOG4CXX_ERROR(logger_, "Coincidence check failed."); SendResponse(false, coincidence_result); return; @@ -458,6 +486,12 @@ void RegisterAppInterfaceRequest::Run() { } } + auto on_app_registered = [application](plugin_manager::RPCPlugin& plugin) { + plugin.OnApplicationEvent(plugin_manager::kApplicationRegistered, + application); + }; + application_manager_.ApplyFunctorForEachPlugin(on_app_registered); + if (msg_params.keyExists(strings::day_color_scheme)) { application->set_day_color_scheme(msg_params[strings::day_color_scheme]); } @@ -524,30 +558,30 @@ RegisterAppInterfaceRequest::GetLockScreenIconUrlNotification( void FillVRRelatedFields(smart_objects::SmartObject& response_params, const HMICapabilities& hmi_capabilities) { response_params[strings::language] = hmi_capabilities.active_vr_language(); - if (hmi_capabilities.vr_capabilities()) { - response_params[strings::vr_capabilities] = - *hmi_capabilities.vr_capabilities(); + auto vr_capabilities = hmi_capabilities.vr_capabilities(); + if (vr_capabilities) { + response_params[strings::vr_capabilities] = *vr_capabilities; } } void FillVIRelatedFields(smart_objects::SmartObject& response_params, const HMICapabilities& hmi_capabilities) { - if (hmi_capabilities.vehicle_type()) { - response_params[hmi_response::vehicle_type] = - *hmi_capabilities.vehicle_type(); + auto vehicle_type = hmi_capabilities.vehicle_type(); + if (vehicle_type) { + response_params[hmi_response::vehicle_type] = *vehicle_type; } } void FillTTSRelatedFields(smart_objects::SmartObject& response_params, const HMICapabilities& hmi_capabilities) { response_params[strings::language] = hmi_capabilities.active_tts_language(); - if (hmi_capabilities.speech_capabilities()) { - response_params[strings::speech_capabilities] = - *hmi_capabilities.speech_capabilities(); + auto speech_capabilities = hmi_capabilities.speech_capabilities(); + if (speech_capabilities) { + response_params[strings::speech_capabilities] = *speech_capabilities; } - if (hmi_capabilities.prerecorded_speech()) { - response_params[strings::prerecorded_speech] = - *(hmi_capabilities.prerecorded_speech()); + auto prerecorded_speech = hmi_capabilities.prerecorded_speech(); + if (prerecorded_speech) { + response_params[strings::prerecorded_speech] = *prerecorded_speech; } } @@ -555,82 +589,70 @@ void FillUIRelatedFields(smart_objects::SmartObject& response_params, const HMICapabilities& hmi_capabilities) { response_params[strings::hmi_display_language] = hmi_capabilities.active_ui_language(); - if (hmi_capabilities.display_capabilities()) { + + auto display_capabilities = hmi_capabilities.display_capabilities(); + if (display_capabilities) { response_params[hmi_response::display_capabilities] = smart_objects::SmartObject(smart_objects::SmartType_Map); smart_objects::SmartObject& display_caps = response_params[hmi_response::display_capabilities]; - if (hmi_capabilities.display_capabilities()->keyExists( - hmi_response::display_type)) { + if (display_capabilities->keyExists(hmi_response::display_type)) { display_caps[hmi_response::display_type] = - hmi_capabilities.display_capabilities()->getElement( - hmi_response::display_type); + display_capabilities->getElement(hmi_response::display_type); } - if (hmi_capabilities.display_capabilities()->keyExists( - hmi_response::display_name)) { + if (display_capabilities->keyExists(hmi_response::display_name)) { display_caps[hmi_response::display_name] = - hmi_capabilities.display_capabilities()->getElement( - hmi_response::display_name); + display_capabilities->getElement(hmi_response::display_name); } - if (hmi_capabilities.display_capabilities()->keyExists( - hmi_response::text_fields)) { + if (display_capabilities->keyExists(hmi_response::text_fields)) { display_caps[hmi_response::text_fields] = - hmi_capabilities.display_capabilities()->getElement( - hmi_response::text_fields); + display_capabilities->getElement(hmi_response::text_fields); } - if (hmi_capabilities.display_capabilities()->keyExists( - hmi_response::image_fields)) { + if (display_capabilities->keyExists(hmi_response::image_fields)) { display_caps[hmi_response::image_fields] = - hmi_capabilities.display_capabilities()->getElement( - hmi_response::image_fields); + display_capabilities->getElement(hmi_response::image_fields); } - if (hmi_capabilities.display_capabilities()->keyExists( - hmi_response::media_clock_formats)) { + if (display_capabilities->keyExists(hmi_response::media_clock_formats)) { display_caps[hmi_response::media_clock_formats] = - hmi_capabilities.display_capabilities()->getElement( - hmi_response::media_clock_formats); + display_capabilities->getElement(hmi_response::media_clock_formats); } - if (hmi_capabilities.display_capabilities()->keyExists( - hmi_response::templates_available)) { + if (display_capabilities->keyExists(hmi_response::templates_available)) { display_caps[hmi_response::templates_available] = - hmi_capabilities.display_capabilities()->getElement( - hmi_response::templates_available); + display_capabilities->getElement(hmi_response::templates_available); } - if (hmi_capabilities.display_capabilities()->keyExists( - hmi_response::screen_params)) { + if (display_capabilities->keyExists(hmi_response::screen_params)) { display_caps[hmi_response::screen_params] = - hmi_capabilities.display_capabilities()->getElement( - hmi_response::screen_params); + display_capabilities->getElement(hmi_response::screen_params); } - if (hmi_capabilities.display_capabilities()->keyExists( + if (display_capabilities->keyExists( hmi_response::num_custom_presets_available)) { display_caps[hmi_response::num_custom_presets_available] = - hmi_capabilities.display_capabilities()->getElement( + display_capabilities->getElement( hmi_response::num_custom_presets_available); } - if (hmi_capabilities.display_capabilities()->keyExists( - hmi_response::image_capabilities)) { + if (display_capabilities->keyExists(hmi_response::image_capabilities)) { display_caps[hmi_response::graphic_supported] = - (hmi_capabilities.display_capabilities() - ->getElement(hmi_response::image_capabilities) + (display_capabilities->getElement(hmi_response::image_capabilities) .length() > 0); } } - if (hmi_capabilities.audio_pass_thru_capabilities()) { + auto audio_pass_thru_capabilities = + hmi_capabilities.audio_pass_thru_capabilities(); + if (audio_pass_thru_capabilities) { // hmi_capabilities json contains array and HMI response object response_params[strings::audio_pass_thru_capabilities] = - *hmi_capabilities.audio_pass_thru_capabilities(); + *audio_pass_thru_capabilities; } response_params[strings::hmi_capabilities] = smart_objects::SmartObject(smart_objects::SmartType_Map); @@ -728,36 +750,39 @@ void RegisterAppInterfaceRequest::SendRegisterAppInterfaceResponseToMobile( FillVIRelatedFields(response_params, hmi_capabilities); } - if (hmi_capabilities.button_capabilities()) { - response_params[hmi_response::button_capabilities] = - *hmi_capabilities.button_capabilities(); + auto button_capabilities = hmi_capabilities.button_capabilities(); + if (button_capabilities) { + response_params[hmi_response::button_capabilities] = *button_capabilities; } - if (hmi_capabilities.soft_button_capabilities()) { + auto soft_button_capabilities = hmi_capabilities.soft_button_capabilities(); + if (soft_button_capabilities) { response_params[hmi_response::soft_button_capabilities] = - *hmi_capabilities.soft_button_capabilities(); + *soft_button_capabilities; } - if (hmi_capabilities.preset_bank_capabilities()) { + auto preset_bank_capabilities = hmi_capabilities.preset_bank_capabilities(); + if (preset_bank_capabilities) { response_params[hmi_response::preset_bank_capabilities] = - *hmi_capabilities.preset_bank_capabilities(); + *preset_bank_capabilities; } - if (hmi_capabilities.hmi_zone_capabilities()) { - if (smart_objects::SmartType_Array == - hmi_capabilities.hmi_zone_capabilities()->getType()) { + auto hmi_zone_capabilities = hmi_capabilities.hmi_zone_capabilities(); + if (hmi_zone_capabilities) { + if (smart_objects::SmartType_Array == hmi_zone_capabilities->getType()) { // hmi_capabilities json contains array and HMI response object response_params[hmi_response::hmi_zone_capabilities] = - *hmi_capabilities.hmi_zone_capabilities(); + *hmi_zone_capabilities; } else { response_params[hmi_response::hmi_zone_capabilities][0] = - *hmi_capabilities.hmi_zone_capabilities(); + *hmi_zone_capabilities; } } - if (hmi_capabilities.pcm_stream_capabilities()) { + auto pcm_stream_capabilities = hmi_capabilities.pcm_stream_capabilities(); + if (pcm_stream_capabilities) { response_params[strings::pcm_stream_capabilities] = - *hmi_capabilities.pcm_stream_capabilities(); + *pcm_stream_capabilities; } const std::vector<uint32_t>& diag_modes = @@ -875,6 +900,12 @@ void RegisterAppInterfaceRequest::SendRegisterAppInterfaceResponseToMobile( // Default HMI level should be set before any permissions validation, since it // relies on HMI level. application_manager_.OnApplicationRegistered(application); + + auto send_rc_status = [application](plugin_manager::RPCPlugin& plugin) { + plugin.OnApplicationEvent(plugin_manager::kRCStatusChanged, application); + }; + application_manager_.ApplyFunctorForEachPlugin(send_rc_status); + SendOnAppRegisteredNotificationToHMI( application, resumption, need_restore_vr); (*notify_upd_manager)(); @@ -983,8 +1014,7 @@ void RegisterAppInterfaceRequest::SendOnAppRegisteredNotificationToHMI( DCHECK(rpc_service_.ManageHMICommand(notification)); } -mobile_apis::Result::eType RegisterAppInterfaceRequest::CheckCoincidence( - std::vector<ApplicationSharedPtr>& out_duplicate_apps) { +mobile_apis::Result::eType RegisterAppInterfaceRequest::CheckCoincidence() { LOG4CXX_AUTO_TRACE(logger_); const smart_objects::SmartObject& msg_params = (*message_)[strings::msg_params]; @@ -1008,8 +1038,7 @@ mobile_apis::Result::eType RegisterAppInterfaceRequest::CheckCoincidence( const auto& cur_name = app->name(); if (app_name.CompareIgnoreCase(cur_name)) { LOG4CXX_ERROR(logger_, "Application name is known already."); - out_duplicate_apps.push_back(app); - continue; + return mobile_apis::Result::DUPLICATE_NAME; } const auto vr = app->vr_synonyms(); if (vr) { @@ -1018,8 +1047,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_duplicate_apps.push_back(app); - continue; + return mobile_apis::Result::DUPLICATE_NAME; } } @@ -1030,8 +1058,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_duplicate_apps.push_back(app); - continue; + return mobile_apis::Result::DUPLICATE_NAME; } } // End vr check @@ -1056,12 +1083,44 @@ mobile_apis::Result::eType RegisterAppInterfaceRequest::CheckCoincidence( } // Application for end - if (!out_duplicate_apps.empty()) { - return mobile_apis::Result::DUPLICATE_NAME; - } return mobile_apis::Result::SUCCESS; } // method end +bool RegisterAppInterfaceRequest::GetDuplicateNames( + std::vector<ApplicationSharedPtr>& out_duplicate_apps) { + LOG4CXX_AUTO_TRACE(logger_); + const smart_objects::SmartObject& msg_params = + (*message_)[strings::msg_params]; + + const auto& app_name = msg_params[strings::app_name].asCustomString(); + { + const auto& accessor = application_manager_.applications().GetData(); + + for (const auto& app : accessor) { + const auto& cur_name = app->name(); + if (app_name.CompareIgnoreCase(cur_name)) { + out_duplicate_apps.push_back(app); + } + } + } + + const std::string policy_app_id = + application_manager_.GetCorrectMobileIDFromMessage(message_); + { + const auto& accessor = + application_manager_.pending_applications().GetData(); + + for (const auto& app : accessor) { + const auto& cur_name = app->name(); + if (app_name.CompareIgnoreCase(cur_name) && + policy_app_id != app->policy_app_id()) { + out_duplicate_apps.push_back(app); + } + } + } + return !out_duplicate_apps.empty(); +} + mobile_apis::Result::eType RegisterAppInterfaceRequest::CheckWithPolicyData() { LOG4CXX_AUTO_TRACE(logger_); // TODO(AOleynik): Check is necessary to allow register application in case diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/send_location_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/send_location_request.cc index 1df4d788d2..805c0f0e41 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/send_location_request.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/send_location_request.cc @@ -254,10 +254,10 @@ bool SendLocationRequest::CheckHMICapabilities( return false; } - if (hmi_capabilities.display_capabilities()) { - const SmartObject disp_cap = (*hmi_capabilities.display_capabilities()); + auto display_capabilities = hmi_capabilities.display_capabilities(); + if (display_capabilities) { const SmartObject& text_fields = - disp_cap.getElement(hmi_response::text_fields); + display_capabilities->getElement(hmi_response::text_fields); const size_t len = text_fields.length(); for (size_t i = 0; i < len; ++i) { const SmartObject& text_field = text_fields[i]; diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_display_layout_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_display_layout_request.cc index 5ba1076084..0cd9f6635c 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_display_layout_request.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/set_display_layout_request.cc @@ -154,10 +154,13 @@ void SetDisplayLayoutRequest::on_event(const event_engine::Event& event) { if (0 == msg_params[hmi_response::display_capabilities] [hmi_response::templates_available] .length()) { - msg_params[hmi_response::display_capabilities] - [hmi_response::templates_available] = - hmi_capabilities.display_capabilities()->getElement( - hmi_response::templates_available); + auto display_capabilities = hmi_capabilities.display_capabilities(); + if (display_capabilities) { + msg_params[hmi_response::display_capabilities] + [hmi_response::templates_available] = + display_capabilities->getElement( + hmi_response::templates_available); + } } } const Version& app_version = app->version(); diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/system_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/system_request.cc index 9be5a270f5..030db82881 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/system_request.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/system_request.cc @@ -612,7 +612,7 @@ void SystemRequest::Run() { return; } else if (mobile_apis::RequestType::QUERY_APPS == request_type) { using namespace ns_smart_device_link::ns_json_handler::formatters; - + application_manager_.OnQueryAppsRequest(application->device()); smart_objects::SmartObject sm_object; Json::Reader reader; std::string json(binary_data.begin(), binary_data.end()); @@ -623,6 +623,7 @@ void SystemRequest::Run() { } CFormatterJsonBase::jsonValueToObj(root, sm_object); + if (!ValidateQueryAppData(sm_object)) { SendResponse(false, mobile_apis::Result::GENERIC_ERROR); return; diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/on_button_notification_commands_test.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/on_button_notification_commands_test.cc index c0305a15ca..aa48e8916b 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/on_button_notification_commands_test.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/on_button_notification_commands_test.cc @@ -231,6 +231,35 @@ TYPED_TEST(OnButtonNotificationCommandsTest, Run_CustomButton_SUCCESS) { command->Run(); } +TYPED_TEST(OnButtonNotificationCommandsTest, + Run_CustomButton_SUCCESS_BACKGROUND) { + typedef typename TestFixture::Notification Notification; + + MessageSharedPtr notification_msg( + this->CreateMessage(smart_objects::SmartType_Map)); + + (*notification_msg)[am::strings::msg_params][am::hmi_response::button_name] = + mobile_apis::ButtonName::CUSTOM_BUTTON; + (*notification_msg)[am::strings::msg_params][am::strings::app_id] = kAppId; + (*notification_msg)[am::strings::msg_params] + [am::hmi_response::custom_button_id] = kCustomButtonId; + + std::shared_ptr<Notification> command( + this->template CreateCommand<Notification>(notification_msg)); + + typename TestFixture::MockAppPtr mock_app = this->CreateMockApp(); + ON_CALL(*mock_app, hmi_level(kDefaultWindowId)) + .WillByDefault(Return(mobile_apis::HMILevel::HMI_BACKGROUND)); + EXPECT_CALL(this->app_mngr_, application(kAppId)).WillOnce(Return(mock_app)); + EXPECT_CALL(*mock_app, IsSubscribedToSoftButton(kCustomButtonId)) + .WillOnce(Return(true)); + EXPECT_CALL(this->mock_rpc_service_, + SendMessageToMobile( + CheckNotificationMessage(TestFixture::kFunctionId), _)); + + command->Run(); +} + TYPED_TEST(OnButtonNotificationCommandsTest, Run_NoSubscribedApps_UNSUCCESS) { typedef typename TestFixture::Notification Notification; diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/register_app_interface_request_test.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/register_app_interface_request_test.cc index 636175c56f..6376570106 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/register_app_interface_request_test.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/register_app_interface_request_test.cc @@ -83,6 +83,8 @@ const hmi_apis::Common_Language::eType kHmiLanguage = hmi_apis::Common_Language::EN_US; const mobile_apis::Language::eType kMobileLanguage = mobile_apis::Language::EN_US; +const mobile_apis::HybridAppPreference::eType kHybridAppPreference = + mobile_apis::HybridAppPreference::INVALID_ENUM; const std::string kMacAddress1 = "test_mac_address1"; const std::string kMacAddress2 = "test_mac_address2"; const std::string kAppId1 = "test_app1_id"; @@ -102,6 +104,7 @@ class RegisterAppInterfaceRequestTest , app_name_("test_app_name_") , app2_name_("test_app2_name_") , lock_ptr_(std::make_shared<sync_primitives::Lock>()) + , pending_lock_ptr_(std::make_shared<sync_primitives::Lock>()) , mock_application_helper_( application_manager_test::MockApplicationHelper:: application_helper_mock()) { @@ -141,6 +144,9 @@ class RegisterAppInterfaceRequestTest ON_CALL(*mock_app, app_icon_path()).WillByDefault(ReturnRef(kDummyString)); ON_CALL(*mock_app, language()).WillByDefault(ReturnRef(kMobileLanguage)); ON_CALL(*mock_app, ui_language()).WillByDefault(ReturnRef(kMobileLanguage)); + ON_CALL(*mock_app, is_cloud_app()).WillByDefault(Return(false)); + ON_CALL(*mock_app, hybrid_app_preference()) + .WillByDefault(ReturnRef(kHybridAppPreference)); ON_CALL(*mock_app, policy_app_id()).WillByDefault(Return(kAppId1)); ON_CALL(*mock_app, msg_version()) .WillByDefault(ReturnRef(mock_semantic_version)); @@ -173,6 +179,28 @@ class RegisterAppInterfaceRequestTest .WillByDefault(ReturnRef(kDummyString)); ON_CALL(mock_hmi_capabilities_, ccpu_version()) .WillByDefault(ReturnRef(kDummyString)); + ON_CALL(mock_hmi_capabilities_, speech_capabilities()) + .WillByDefault(Return(smart_objects::SmartObjectSPtr())); + ON_CALL(mock_hmi_capabilities_, prerecorded_speech()) + .WillByDefault(Return(smart_objects::SmartObjectSPtr())); + ON_CALL(mock_hmi_capabilities_, vr_capabilities()) + .WillByDefault(Return(smart_objects::SmartObjectSPtr())); + ON_CALL(mock_hmi_capabilities_, display_capabilities()) + .WillByDefault(Return(smart_objects::SmartObjectSPtr())); + ON_CALL(mock_hmi_capabilities_, audio_pass_thru_capabilities()) + .WillByDefault(Return(smart_objects::SmartObjectSPtr())); + ON_CALL(mock_hmi_capabilities_, vehicle_type()) + .WillByDefault(Return(smart_objects::SmartObjectSPtr())); + ON_CALL(mock_hmi_capabilities_, button_capabilities()) + .WillByDefault(Return(smart_objects::SmartObjectSPtr())); + ON_CALL(mock_hmi_capabilities_, soft_button_capabilities()) + .WillByDefault(Return(smart_objects::SmartObjectSPtr())); + ON_CALL(mock_hmi_capabilities_, preset_bank_capabilities()) + .WillByDefault(Return(smart_objects::SmartObjectSPtr())); + ON_CALL(mock_hmi_capabilities_, hmi_zone_capabilities()) + .WillByDefault(Return(smart_objects::SmartObjectSPtr())); + ON_CALL(mock_hmi_capabilities_, pcm_stream_capabilities()) + .WillByDefault(Return(smart_objects::SmartObjectSPtr())); ON_CALL(app_mngr_settings_, supported_diag_modes()) .WillByDefault(ReturnRef(kDummyDiagModes)); ON_CALL(mock_policy_handler_, GetAppRequestTypes(_, _)) @@ -190,6 +218,8 @@ class RegisterAppInterfaceRequestTest ON_CALL(app_mngr_, IsAppInReconnectMode(_, _)).WillByDefault(Return(false)); ON_CALL(app_mngr_, application_by_policy_id(_)) .WillByDefault(Return(ApplicationSharedPtr())); + ON_CALL(app_mngr_, pending_application_by_policy_id(_)) + .WillByDefault(Return(ApplicationSharedPtr())); ON_CALL(mock_hmi_interfaces_, GetInterfaceState(_)) .WillByDefault(Return(am::HmiInterfaces::STATE_NOT_AVAILABLE)); ON_CALL( @@ -260,6 +290,8 @@ class RegisterAppInterfaceRequestTest const utils::custom_string::CustomString app2_name_; std::shared_ptr<sync_primitives::Lock> lock_ptr_; am::ApplicationSet app_set_; + std::shared_ptr<sync_primitives::Lock> pending_lock_ptr_; + am::AppsWaitRegistrationSet pending_app_set_; typedef IsNiceMock<policy_test::MockPolicyHandlerInterface, kMocksAreNice>::Result MockPolicyHandlerInterface; @@ -313,6 +345,9 @@ TEST_F(RegisterAppInterfaceRequestTest, Run_MinimalData_SUCCESS) { ON_CALL(app_mngr_, applications()) .WillByDefault( Return(DataAccessor<am::ApplicationSet>(app_set_, lock_ptr_))); + ON_CALL(app_mngr_, pending_applications()) + .WillByDefault(Return(DataAccessor<am::AppsWaitRegistrationSet>( + pending_app_set_, pending_lock_ptr_))); EXPECT_CALL(app_mngr_, application(kConnectionKey)) .WillOnce(Return(mock_app)); @@ -419,19 +454,27 @@ TEST_F(RegisterAppInterfaceRequestTest, "test_templates_available"; display_capabilities[am::hmi_response::screen_params] = "test_screen_params"; + auto vehicle_type_ptr = std::make_shared<smart_objects::SmartObject>( + (*expected_message)[am::hmi_response::vehicle_type]); ON_CALL(mock_hmi_capabilities_, vehicle_type()) - .WillByDefault( - Return(&(*expected_message)[am::hmi_response::vehicle_type])); + .WillByDefault(Return(vehicle_type_ptr)); + + auto vr_capabilities_ptr = std::make_shared<smart_objects::SmartObject>( + (*expected_message)[am::strings::vr_capabilities]); ON_CALL(mock_hmi_capabilities_, vr_capabilities()) - .WillByDefault( - Return(&(*expected_message)[am::strings::vr_capabilities])); + .WillByDefault(Return(vr_capabilities_ptr)); + + auto display_capabilities_ptr = std::make_shared<smart_objects::SmartObject>( + (*expected_message)[am::hmi_response::display_capabilities]); ON_CALL(mock_hmi_capabilities_, display_capabilities()) - .WillByDefault( - Return(&(*expected_message)[am::hmi_response::display_capabilities])); + .WillByDefault(Return(display_capabilities_ptr)); ON_CALL(app_mngr_, applications()) .WillByDefault( Return(DataAccessor<am::ApplicationSet>(app_set_, lock_ptr_))); + ON_CALL(app_mngr_, pending_applications()) + .WillByDefault(Return(DataAccessor<am::AppsWaitRegistrationSet>( + pending_app_set_, pending_lock_ptr_))); ON_CALL(mock_policy_handler_, PolicyEnabled()).WillByDefault(Return(true)); ON_CALL(mock_policy_handler_, GetInitialAppData(kAppId1, _, _)) .WillByDefault(Return(true)); @@ -622,6 +665,9 @@ TEST_F(RegisterAppInterfaceRequestTest, ON_CALL(app_mngr_, applications()) .WillByDefault( Return(DataAccessor<am::ApplicationSet>(app_set_, lock_ptr_))); + ON_CALL(app_mngr_, pending_applications()) + .WillByDefault(Return(DataAccessor<am::AppsWaitRegistrationSet>( + pending_app_set_, pending_lock_ptr_))); MockAppPtr mock_app2 = CreateBasicMockedApp(); @@ -659,6 +705,9 @@ TEST_F(RegisterAppInterfaceRequestTest, ON_CALL(app_mngr_, applications()) .WillByDefault( Return(DataAccessor<am::ApplicationSet>(app_set_, lock_ptr_))); + ON_CALL(app_mngr_, pending_applications()) + .WillByDefault(Return(DataAccessor<am::AppsWaitRegistrationSet>( + pending_app_set_, pending_lock_ptr_))); InitBasicMessage(); (*msg_)[am::strings::params][am::strings::connection_key] = kConnectionKey2; diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/send_location_request_test.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/send_location_request_test.cc index 5d90453278..968c91b5ce 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/send_location_request_test.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/send_location_request_test.cc @@ -110,6 +110,8 @@ class SendLocationRequestTest (*message_)[strings::msg_params] = SmartObject(smart_objects::SmartType_Map); (*message_)[strings::msg_params][strings::address] = kCorrectAddress; + ON_CALL(mock_hmi_capabilities_, display_capabilities()) + .WillByDefault(Return(smart_objects::SmartObjectSPtr())); EXPECT_CALL(app_mngr_, application(kConnectionKey)) .WillOnce(Return(mock_app_)); @@ -130,8 +132,7 @@ class SendLocationRequestTest SmartObject(smart_objects::SmartType_Map); (*disp_cap_)[hmi_response::text_fields][0][strings::name] = field_name; EXPECT_CALL(mock_hmi_capabilities_, display_capabilities()) - .Times(2) - .WillRepeatedly(Return(disp_cap_.get())); + .WillOnce(Return(disp_cap_)); } void FinishSetup() { diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/set_display_layout_test.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/set_display_layout_test.cc index cde15a2318..cc3b5925ce 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/set_display_layout_test.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/set_display_layout_test.cc @@ -240,7 +240,7 @@ TEST_F(SetDisplayLayoutRequestTest, OnEvent_AppVersion_v6_WARNING) { "templates_available"; EXPECT_CALL(mock_hmi_capabilities_, display_capabilities()) - .WillOnce(Return(dispaly_capabilities_msg.get())); + .WillOnce(Return(dispaly_capabilities_msg)); EXPECT_CALL( mock_rpc_service_, ManageMobileCommand(MobileResultCodeIs(mobile_result::WARNINGS), @@ -274,7 +274,7 @@ TEST_F(SetDisplayLayoutRequestTest, OnEvent_AppVersion_v5_SUCCESS) { "templates_available"; EXPECT_CALL(mock_hmi_capabilities_, display_capabilities()) - .WillOnce(Return(dispaly_capabilities_msg.get())); + .WillOnce(Return(dispaly_capabilities_msg)); EXPECT_CALL( mock_rpc_service_, ManageMobileCommand(MobileResultCodeIs(mobile_result::SUCCESS), diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/subscribe_button_request_test.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/subscribe_button_request_test.cc index 786f2b6bd1..f3bfe12ab1 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/subscribe_button_request_test.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/subscribe_button_request_test.cc @@ -162,7 +162,7 @@ TEST_F(SubscribeButtonRequestTest, Run_IsSubscribedToButton_UNSUCCESS) { (*button_caps_ptr)[0][am::hmi_response::button_name] = kButtonName; ON_CALL(mock_hmi_capabilities_, button_capabilities()) - .WillByDefault(Return(button_caps_ptr.get())); + .WillByDefault(Return(button_caps_ptr)); ON_CALL(*app, IsSubscribedToButton(_)).WillByDefault(Return(true)); @@ -193,7 +193,7 @@ TEST_F(SubscribeButtonRequestTest, Run_SUCCESS) { (*button_caps_ptr)[0][am::hmi_response::button_name] = kButtonName; ON_CALL(mock_hmi_capabilities_, button_capabilities()) - .WillByDefault(Return(button_caps_ptr.get())); + .WillByDefault(Return(button_caps_ptr)); ON_CALL(*app, IsSubscribedToButton(_)).WillByDefault(Return(false)); @@ -240,7 +240,7 @@ TEST_F(SubscribeButtonRequestTest, Run_NAV_SUCCESS) { (*button_caps_ptr)[0][am::hmi_response::button_name] = kButtonName; ON_CALL(mock_hmi_capabilities_, button_capabilities()) - .WillByDefault(Return(button_caps_ptr.get())); + .WillByDefault(Return(button_caps_ptr)); ON_CALL(*app, IsSubscribedToButton(_)).WillByDefault(Return(false)); @@ -289,7 +289,7 @@ TEST_F(SubscribeButtonRequestTest, Run_SUCCESS_App_Base_RPC_Version) { mobile_apis::ButtonName::PLAY_PAUSE; ON_CALL(mock_hmi_capabilities_, button_capabilities()) - .WillByDefault(Return(button_caps_ptr.get())); + .WillByDefault(Return(button_caps_ptr)); ON_CALL(*app, IsSubscribedToButton(_)).WillByDefault(Return(false)); diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/unsubscribe_button_request_test.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/unsubscribe_button_request_test.cc index 98d20dbbc4..5735610051 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/unsubscribe_button_request_test.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/unsubscribe_button_request_test.cc @@ -70,7 +70,7 @@ TEST_F(UnsubscribeButtonRequestTest, MessageSharedPtr button_caps_ptr(CreateMessage(smart_objects::SmartType_Map)); (*button_caps_ptr)[0][am::hmi_response::button_name] = kButtonId; EXPECT_CALL(mock_hmi_capabilities_, button_capabilities()) - .WillOnce(Return(button_caps_ptr.get())); + .WillOnce(Return(button_caps_ptr)); MockAppPtr mock_app(CreateMockApp()); EXPECT_CALL(app_mngr_, application(kConnectionKey)) @@ -106,7 +106,7 @@ TEST_F(UnsubscribeButtonRequestTest, MessageSharedPtr button_caps_ptr(CreateMessage(smart_objects::SmartType_Map)); EXPECT_CALL(mock_hmi_capabilities_, button_capabilities()) - .WillOnce(Return(button_caps_ptr.get())); + .WillOnce(Return(button_caps_ptr)); EXPECT_CALL(mock_rpc_service_, ManageMobileCommand( @@ -129,7 +129,7 @@ TEST_F(UnsubscribeButtonRequestTest, Run_SUCCESS) { MessageSharedPtr button_caps_ptr(CreateMessage(smart_objects::SmartType_Map)); (*button_caps_ptr)[0][am::hmi_response::button_name] = kButtonId; EXPECT_CALL(mock_hmi_capabilities_, button_capabilities()) - .WillOnce(Return(button_caps_ptr.get())); + .WillOnce(Return(button_caps_ptr)); MockAppPtr mock_app(CreateMockApp()); EXPECT_CALL(app_mngr_, application(kConnectionKey)) @@ -172,7 +172,7 @@ TEST_F(UnsubscribeButtonRequestTest, Run_SUCCESS_Base_RPC_Version) { mobile_apis::ButtonName::PLAY_PAUSE; EXPECT_CALL(mock_hmi_capabilities_, button_capabilities()) - .WillRepeatedly(Return(button_caps_ptr.get())); + .WillRepeatedly(Return(button_caps_ptr)); MockAppPtr mock_app(CreateMockApp()); EXPECT_CALL(app_mngr_, application(kConnectionKey)) diff --git a/src/components/application_manager/rpc_plugins/vehicle_info_plugin/src/vehicle_info_plugin.cc b/src/components/application_manager/rpc_plugins/vehicle_info_plugin/src/vehicle_info_plugin.cc index 40da7501c1..3017b6712f 100644 --- a/src/components/application_manager/rpc_plugins/vehicle_info_plugin/src/vehicle_info_plugin.cc +++ b/src/components/application_manager/rpc_plugins/vehicle_info_plugin/src/vehicle_info_plugin.cc @@ -98,6 +98,7 @@ void VehicleInfoPlugin::OnApplicationEvent( } void VehicleInfoPlugin::UnsubscribeFromRemovedVDItems() { + LOG4CXX_AUTO_TRACE(logger_); typedef std::vector<std::string> StringsVector; auto get_items_to_unsubscribe = [this]() -> StringsVector { diff --git a/src/components/application_manager/src/application_impl.cc b/src/components/application_manager/src/application_impl.cc index 2b328ae9a1..f66c87b47b 100644 --- a/src/components/application_manager/src/application_impl.cc +++ b/src/components/application_manager/src/application_impl.cc @@ -132,7 +132,7 @@ ApplicationImpl::ApplicationImpl( protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_3) , is_voice_communication_application_(false) , is_resuming_(false) - , deferred_resumption_hmi_level_(mobile_api::HMILevel::eType::INVALID_ENUM) + , deferred_resumption_hmi_level_(mobile_api::HMILevel::INVALID_ENUM) , is_hash_changed_during_suspend_(false) , video_stream_retry_number_(0) , audio_stream_retry_number_(0) @@ -144,6 +144,7 @@ ApplicationImpl::ApplicationImpl( "AudioStreamSuspend", new ::timer::TimerTaskImpl<ApplicationImpl>( this, &ApplicationImpl::OnAudioStreamSuspend)) + , hybrid_app_preference_(mobile_api::HybridAppPreference::INVALID_ENUM) , vi_lock_ptr_(std::make_shared<sync_primitives::Lock>()) , button_lock_ptr_(std::make_shared<sync_primitives::Lock>()) , application_manager_(application_manager) { diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc index 8044e8b6cd..d51d4c9d06 100644 --- a/src/components/application_manager/src/application_manager_impl.cc +++ b/src/components/application_manager/src/application_manager_impl.cc @@ -295,13 +295,6 @@ 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); @@ -309,6 +302,13 @@ ApplicationSharedPtr ApplicationManagerImpl::pending_application_by_policy_id( return FindPendingApp(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::reregister_application_by_policy_id( const std::string& policy_app_id) const { @@ -327,6 +327,20 @@ ApplicationSharedPtr ApplicationManagerImpl::active_application() const { return FindApp(accessor, ActiveAppPredicate); } +bool FullOrLimitedAppPredicate(const ApplicationSharedPtr app) { + return app ? app->IsFullscreen() || + app->hmi_level( + mobile_api::PredefinedWindows::DEFAULT_WINDOW) == + mobile_api::HMILevel::HMI_LIMITED + : false; +} + +ApplicationSharedPtr ApplicationManagerImpl::get_full_or_limited_application() + const { + DataAccessor<ApplicationSet> accessor = applications(); + return FindApp(accessor, FullOrLimitedAppPredicate); +} + bool LimitedAppPredicate(const ApplicationSharedPtr app) { return app ? app->hmi_level(mobile_api::PredefinedWindows::DEFAULT_WINDOW) == mobile_api::HMILevel::HMI_LIMITED @@ -406,6 +420,13 @@ ApplicationManagerImpl::applications_by_button(uint32_t button) { return FindAllApps(accessor, finder); } +std::vector<ApplicationSharedPtr> ApplicationManagerImpl::applications_by_name( + const std::string& app_name) const { + AppNamePredicate finder(app_name); + DataAccessor<ApplicationSet> accessor = applications(); + return FindAllApps(accessor, finder); +} + struct IsApplication { IsApplication(connection_handler::DeviceHandle device_handle, const std::string& policy_app_id) @@ -434,12 +455,6 @@ void ApplicationManagerImpl::OnApplicationRegistered(ApplicationSharedPtr app) { sync_primitives::AutoLock lock(applications_list_lock_ptr_); const mobile_apis::HMILevel::eType default_level = GetDefaultHmiLevel(app); state_ctrl_.OnApplicationRegistered(app, default_level); - - std::function<void(plugin_manager::RPCPlugin&)> on_app_registered = - [app](plugin_manager::RPCPlugin& plugin) { - plugin.OnApplicationEvent(plugin_manager::kApplicationRegistered, app); - }; - plugin_manager_->ForEachPlugin(on_app_registered); } void ApplicationManagerImpl::OnApplicationSwitched(ApplicationSharedPtr app) { @@ -729,14 +744,7 @@ ApplicationSharedPtr ApplicationManagerImpl::RegisterApplication( // Timer will be started after hmi level resumption. resume_controller().OnAppRegistrationStart(policy_app_id, device_mac); - // Add application to registered app list and set appropriate mark. - // Lock has to be released before adding app to policy DB to avoid possible - // deadlock with simultaneous PTU processing - applications_list_lock_ptr_->Acquire(); - application->MarkRegistered(); - applications_.insert(application); - apps_size_ = applications_.size(); - applications_list_lock_ptr_->Release(); + AddAppToRegisteredAppList(application); // Update cloud app information, in case any pending apps are unable to be // registered due to a mobile app taking precedence @@ -1025,15 +1033,23 @@ void ApplicationManagerImpl::RefreshCloudAppInformation() { } else if (mobile_apis::HybridAppPreference::MOBILE == hybrid_app_preference) { auto nickname_it = nicknames.begin(); + bool duplicate_found = false; 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; + auto apps = applications_by_name(*nickname_it); + for (auto app : apps) { + if (app.use_count() != 0 && !app->is_cloud_app()) { + LOG4CXX_ERROR(logger_, + "Mobile app already registered for cloud app: " + << *nickname_it); + duplicate_found = true; + break; + } } } + + if (duplicate_found) { + continue; + } } pending_device_map_.insert( @@ -1427,15 +1443,8 @@ ApplicationManagerImpl::AppsWaitingForRegistration() const { bool ApplicationManagerImpl::IsAppsQueriedFrom( const connection_handler::DeviceHandle handle) const { - sync_primitives::AutoLock lock(apps_to_register_list_lock_ptr_); - AppsWaitRegistrationSet::iterator it = apps_to_register_.begin(); - AppsWaitRegistrationSet::const_iterator it_end = apps_to_register_.end(); - for (; it != it_end; ++it) { - if (handle == (*it)->device()) { - return true; - } - } - return false; + sync_primitives::AutoLock lock(query_apps_devices_lock_); + return query_apps_devices_.find(handle) != query_apps_devices_.end(); } StateController& ApplicationManagerImpl::state_controller() { @@ -1527,6 +1536,13 @@ void ApplicationManagerImpl::OnFindNewApplicationsRequest() { GetPolicyHandler().OnAppsSearchStarted(); } +void ApplicationManagerImpl::OnQueryAppsRequest( + const connection_handler::DeviceHandle device) { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock lock(query_apps_devices_lock_); + query_apps_devices_.insert(device); +} + void ApplicationManagerImpl::SendUpdateAppList() { LOG4CXX_AUTO_TRACE(logger_); @@ -1551,6 +1567,8 @@ void ApplicationManagerImpl::SendUpdateAppList() { void ApplicationManagerImpl::RemoveDevice( const connection_handler::DeviceHandle& device_handle) { LOG4CXX_DEBUG(logger_, "device_handle " << device_handle); + sync_primitives::AutoLock lock(query_apps_devices_lock_); + query_apps_devices_.erase(device_handle); } void ApplicationManagerImpl::OnDeviceSwitchingStart( @@ -3129,13 +3147,10 @@ void ApplicationManagerImpl::UnregisterApplication( "There is no more SDL4 apps with device handle: " << handle); RemoveAppsWaitingForRegistration(handle); - RefreshCloudAppInformation(); - SendUpdateAppList(); - } else if (app_to_remove->is_cloud_app()) { - RefreshCloudAppInformation(); - SendUpdateAppList(); } } + RefreshCloudAppInformation(); + SendUpdateAppList(); } commands_holder_->Clear(app_to_remove); @@ -4176,6 +4191,28 @@ ApplicationManagerImpl::SupportedSDLVersion() const { get_settings().max_supported_protocol_version()); } +void ApplicationManagerImpl::AddAppToRegisteredAppList( + const ApplicationSharedPtr application) { + LOG4CXX_AUTO_TRACE(logger_); + DCHECK_OR_RETURN_VOID(application); + sync_primitives::AutoLock lock(applications_list_lock_ptr_); + + // Add application to registered app list and set appropriate mark. + application->MarkRegistered(); + applications_.insert(application); + LOG4CXX_DEBUG( + logger_, + "App with app_id: " << application->app_id() + << " has been added to registered applications list"); + apps_size_ = static_cast<uint32_t>(applications_.size()); +} + +void ApplicationManagerImpl::ApplyFunctorForEachPlugin( + std::function<void(plugin_manager::RPCPlugin&)> functor) { + LOG4CXX_AUTO_TRACE(logger_); + plugin_manager_->ForEachPlugin(functor); +} + event_engine::EventDispatcher& ApplicationManagerImpl::event_dispatcher() { return event_dispatcher_; } diff --git a/src/components/application_manager/src/commands/command_request_impl.cc b/src/components/application_manager/src/commands/command_request_impl.cc index 257ccfd9c3..e9dcd6e4b0 100644 --- a/src/components/application_manager/src/commands/command_request_impl.cc +++ b/src/components/application_manager/src/commands/command_request_impl.cc @@ -772,16 +772,14 @@ bool CommandRequestImpl::CheckHMICapabilities( return false; } - const SmartObject* button_capabilities_so = - hmi_capabilities_.button_capabilities(); - if (!button_capabilities_so) { + auto button_capabilities = hmi_capabilities_.button_capabilities(); + if (!button_capabilities) { LOG4CXX_ERROR(logger_, "Invalid button capabilities object"); return false; } - const SmartObject& button_capabilities = *button_capabilities_so; - for (size_t i = 0; i < button_capabilities.length(); ++i) { - const SmartObject& capabilities = button_capabilities[i]; + for (size_t i = 0; i < button_capabilities->length(); ++i) { + const SmartObject& capabilities = (*button_capabilities)[i]; const ButtonName::eType current_button = static_cast<ButtonName::eType>( capabilities.getElement(hmi_response::button_name).asInt()); if (current_button == button) { @@ -900,7 +898,8 @@ bool CommandRequestImpl::IsMobileResultSuccess( mobile_apis::Result::WARNINGS, mobile_apis::Result::WRONG_LANGUAGE, mobile_apis::Result::RETRY, - mobile_apis::Result::SAVED); + mobile_apis::Result::SAVED, + mobile_apis::Result::TRUNCATED_DATA); } bool CommandRequestImpl::IsHMIResultSuccess( @@ -913,7 +912,8 @@ bool CommandRequestImpl::IsHMIResultSuccess( hmi_apis::Common_Result::WARNINGS, hmi_apis::Common_Result::WRONG_LANGUAGE, hmi_apis::Common_Result::RETRY, - hmi_apis::Common_Result::SAVED); + hmi_apis::Common_Result::SAVED, + hmi_apis::Common_Result::TRUNCATED_DATA); } bool CommandRequestImpl::PrepareResultForMobileResponse( diff --git a/src/components/application_manager/src/hmi_capabilities_impl.cc b/src/components/application_manager/src/hmi_capabilities_impl.cc index 6f95e43545..2642651d28 100644 --- a/src/components/application_manager/src/hmi_capabilities_impl.cc +++ b/src/components/application_manager/src/hmi_capabilities_impl.cc @@ -339,6 +339,8 @@ void InitCapabilities() { image_field_name_enum.insert( std::make_pair(std::string("locationImage"), hmi_apis::Common_ImageFieldName::locationImage)); + image_field_name_enum.insert(std::make_pair( + std::string("alertIcon"), hmi_apis::Common_ImageFieldName::alertIcon)); file_type_enum.insert(std::make_pair(std::string("GRAPHIC_BMP"), hmi_apis::Common_FileType::GRAPHIC_BMP)); @@ -462,20 +464,9 @@ HMICapabilitiesImpl::HMICapabilitiesImpl(ApplicationManager& app_mngr) } HMICapabilitiesImpl::~HMICapabilitiesImpl() { - delete vehicle_type_; delete ui_supported_languages_; delete tts_supported_languages_; delete vr_supported_languages_; - delete display_capabilities_; - delete hmi_zone_capabilities_; - delete soft_buttons_capabilities_; - delete button_capabilities_; - delete preset_bank_capabilities_; - delete vr_capabilities_; - delete speech_capabilities_; - delete audio_pass_thru_capabilities_; - delete pcm_stream_capabilities_; - delete prerecorded_speech_; delete navigation_capability_; delete phone_capability_; delete video_streaming_capability_; @@ -483,13 +474,14 @@ HMICapabilitiesImpl::~HMICapabilitiesImpl() { } bool HMICapabilitiesImpl::VerifyImageType(const int32_t image_type) const { - if (!display_capabilities_) { + auto capabilities = display_capabilities(); + if (!capabilities) { return false; } - if (display_capabilities_->keyExists(hmi_response::image_capabilities)) { + if (capabilities->keyExists(hmi_response::image_capabilities)) { const smart_objects::SmartObject& image_caps = - display_capabilities_->getElement(hmi_response::image_capabilities); + capabilities->getElement(hmi_response::image_capabilities); for (uint32_t i = 0; i < image_caps.length(); ++i) { if (image_caps.getElement(i).asInt() == image_type) { return true; @@ -603,11 +595,9 @@ void HMICapabilitiesImpl::set_display_capabilities( if (app_mngr_.IsSOStructValid( hmi_apis::StructIdentifiers::Common_DisplayCapabilities, display_capabilities)) { - if (display_capabilities_) { - delete display_capabilities_; - } - display_capabilities_ = - new smart_objects::SmartObject(display_capabilities); + smart_objects::SmartObjectSPtr new_value = + std::make_shared<smart_objects::SmartObject>(display_capabilities); + display_capabilities_.swap(new_value); } } @@ -619,88 +609,73 @@ void HMICapabilitiesImpl::set_system_display_capabilities( void HMICapabilitiesImpl::set_hmi_zone_capabilities( const smart_objects::SmartObject& hmi_zone_capabilities) { - if (hmi_zone_capabilities_) { - delete hmi_zone_capabilities_; - } - hmi_zone_capabilities_ = - new smart_objects::SmartObject(hmi_zone_capabilities); + smart_objects::SmartObjectSPtr new_value = + std::make_shared<smart_objects::SmartObject>(hmi_zone_capabilities); + hmi_zone_capabilities_.swap(new_value); } void HMICapabilitiesImpl::set_soft_button_capabilities( const smart_objects::SmartObject& soft_button_capabilities) { - if (soft_buttons_capabilities_) { - delete soft_buttons_capabilities_; - } - soft_buttons_capabilities_ = - new smart_objects::SmartObject(soft_button_capabilities); + smart_objects::SmartObjectSPtr new_value = + std::make_shared<smart_objects::SmartObject>(soft_button_capabilities); + soft_buttons_capabilities_.swap(new_value); } void HMICapabilitiesImpl::set_button_capabilities( const smart_objects::SmartObject& button_capabilities) { - if (button_capabilities_) { - delete button_capabilities_; - } - button_capabilities_ = new smart_objects::SmartObject(button_capabilities); + smart_objects::SmartObjectSPtr new_value = + std::make_shared<smart_objects::SmartObject>(button_capabilities); + button_capabilities_.swap(new_value); } void HMICapabilitiesImpl::set_vr_capabilities( const smart_objects::SmartObject& vr_capabilities) { - if (vr_capabilities_) { - delete vr_capabilities_; - } - vr_capabilities_ = new smart_objects::SmartObject(vr_capabilities); + smart_objects::SmartObjectSPtr new_value = + std::make_shared<smart_objects::SmartObject>(vr_capabilities); + vr_capabilities_.swap(new_value); } void HMICapabilitiesImpl::set_speech_capabilities( const smart_objects::SmartObject& speech_capabilities) { - if (speech_capabilities_) { - delete speech_capabilities_; - } - speech_capabilities_ = new smart_objects::SmartObject(speech_capabilities); + smart_objects::SmartObjectSPtr new_value = + std::make_shared<smart_objects::SmartObject>(speech_capabilities); + speech_capabilities_.swap(new_value); } void HMICapabilitiesImpl::set_audio_pass_thru_capabilities( const smart_objects::SmartObject& audio_pass_thru_capabilities) { - if (audio_pass_thru_capabilities_) { - delete audio_pass_thru_capabilities_; - } - audio_pass_thru_capabilities_ = - new smart_objects::SmartObject(audio_pass_thru_capabilities); + smart_objects::SmartObjectSPtr new_value = + std::make_shared<smart_objects::SmartObject>( + audio_pass_thru_capabilities); + audio_pass_thru_capabilities_.swap(new_value); } void HMICapabilitiesImpl::set_pcm_stream_capabilities( const smart_objects::SmartObject& pcm_stream_capabilities) { - if (pcm_stream_capabilities_) { - delete pcm_stream_capabilities_; - } - pcm_stream_capabilities_ = - new smart_objects::SmartObject(pcm_stream_capabilities); + smart_objects::SmartObjectSPtr new_value = + std::make_shared<smart_objects::SmartObject>(pcm_stream_capabilities); + pcm_stream_capabilities_.swap(new_value); } void HMICapabilitiesImpl::set_preset_bank_capabilities( const smart_objects::SmartObject& preset_bank_capabilities) { - if (preset_bank_capabilities_) { - delete preset_bank_capabilities_; - } - preset_bank_capabilities_ = - new smart_objects::SmartObject(preset_bank_capabilities); + smart_objects::SmartObjectSPtr new_value = + std::make_shared<smart_objects::SmartObject>(preset_bank_capabilities); + preset_bank_capabilities_.swap(new_value); } void HMICapabilitiesImpl::set_vehicle_type( const smart_objects::SmartObject& vehicle_type) { - if (vehicle_type_) { - delete vehicle_type_; - } - vehicle_type_ = new smart_objects::SmartObject(vehicle_type); + smart_objects::SmartObjectSPtr new_value = + std::make_shared<smart_objects::SmartObject>(vehicle_type); + vehicle_type_.swap(new_value); } void HMICapabilitiesImpl::set_prerecorded_speech( const smart_objects::SmartObject& prerecorded_speech) { - if (prerecorded_speech_) { - delete prerecorded_speech_; - prerecorded_speech_ = NULL; - } - prerecorded_speech_ = new smart_objects::SmartObject(prerecorded_speech); + smart_objects::SmartObjectSPtr new_value = + std::make_shared<smart_objects::SmartObject>(prerecorded_speech); + prerecorded_speech_.swap(new_value); } void HMICapabilitiesImpl::set_navigation_supported(const bool supported) { @@ -811,7 +786,7 @@ const smart_objects::SmartObject* HMICapabilitiesImpl::tts_supported_languages() return tts_supported_languages_; } -const smart_objects::SmartObject* HMICapabilitiesImpl::display_capabilities() +const smart_objects::SmartObjectSPtr HMICapabilitiesImpl::display_capabilities() const { return display_capabilities_; } @@ -821,41 +796,42 @@ HMICapabilitiesImpl::system_display_capabilities() const { return system_display_capabilities_; } -const smart_objects::SmartObject* HMICapabilitiesImpl::hmi_zone_capabilities() - const { +const smart_objects::SmartObjectSPtr +HMICapabilitiesImpl::hmi_zone_capabilities() const { return hmi_zone_capabilities_; } -const smart_objects::SmartObject* +const smart_objects::SmartObjectSPtr HMICapabilitiesImpl::soft_button_capabilities() const { return soft_buttons_capabilities_; } -const smart_objects::SmartObject* HMICapabilitiesImpl::button_capabilities() +const smart_objects::SmartObjectSPtr HMICapabilitiesImpl::button_capabilities() const { return button_capabilities_; } -const smart_objects::SmartObject* HMICapabilitiesImpl::speech_capabilities() +const smart_objects::SmartObjectSPtr HMICapabilitiesImpl::speech_capabilities() const { return speech_capabilities_; } -const smart_objects::SmartObject* HMICapabilitiesImpl::vr_capabilities() const { +const smart_objects::SmartObjectSPtr HMICapabilitiesImpl::vr_capabilities() + const { return vr_capabilities_; } -const smart_objects::SmartObject* +const smart_objects::SmartObjectSPtr HMICapabilitiesImpl::audio_pass_thru_capabilities() const { return audio_pass_thru_capabilities_; } -const smart_objects::SmartObject* HMICapabilitiesImpl::pcm_stream_capabilities() - const { +const smart_objects::SmartObjectSPtr +HMICapabilitiesImpl::pcm_stream_capabilities() const { return pcm_stream_capabilities_; } -const smart_objects::SmartObject* +const smart_objects::SmartObjectSPtr HMICapabilitiesImpl::preset_bank_capabilities() const { return preset_bank_capabilities_; } @@ -864,11 +840,11 @@ bool HMICapabilitiesImpl::attenuated_supported() const { return attenuated_supported_; } -const smart_objects::SmartObject* HMICapabilitiesImpl::vehicle_type() const { +const smart_objects::SmartObjectSPtr HMICapabilitiesImpl::vehicle_type() const { return vehicle_type_; } -const smart_objects::SmartObject* HMICapabilitiesImpl::prerecorded_speech() +const smart_objects::SmartObjectSPtr HMICapabilitiesImpl::prerecorded_speech() const { return prerecorded_speech_; } diff --git a/src/components/application_manager/src/resumption/resume_ctrl_impl.cc b/src/components/application_manager/src/resumption/resume_ctrl_impl.cc index 0e1840e867..1be336c685 100644 --- a/src/components/application_manager/src/resumption/resume_ctrl_impl.cc +++ b/src/components/application_manager/src/resumption/resume_ctrl_impl.cc @@ -214,12 +214,19 @@ bool ResumeCtrlImpl::RestoreAppHMIState(ApplicationSharedPtr application) { "High-bandwidth transport not available, app will resume into : " << saved_hmi_level); } - + const bool app_exists_in_full_or_limited = + application_manager_.get_full_or_limited_application().use_count() != + 0; const bool app_hmi_state_is_set = SetAppHMIState(application, saved_hmi_level, true); + size_t restored_widgets = 0; if (app_hmi_state_is_set && application->is_app_data_resumption_allowed()) { - RestoreAppWidgets(application, saved_app); + restored_widgets = RestoreAppWidgets(application, saved_app); + } + if (0 == restored_widgets && app_exists_in_full_or_limited) { + LOG4CXX_DEBUG(logger_, "App exists in full or limited. Do not resume"); + return false; } } else { result = false; @@ -399,7 +406,7 @@ bool ResumeCtrlImpl::SetAppHMIState( return true; } -void ResumeCtrlImpl::RestoreAppWidgets( +size_t ResumeCtrlImpl::RestoreAppWidgets( application_manager::ApplicationSharedPtr application, const smart_objects::SmartObject& saved_app) { using namespace mobile_apis; @@ -407,7 +414,7 @@ void ResumeCtrlImpl::RestoreAppWidgets( DCHECK(application); if (!saved_app.keyExists(strings::windows_info)) { LOG4CXX_ERROR(logger_, "windows_info section does not exist"); - return; + return 0; } const auto& windows_info = saved_app[strings::windows_info]; auto request_list = MessageHelper::CreateUICreateWindowRequestsToHMI( @@ -419,6 +426,7 @@ void ResumeCtrlImpl::RestoreAppWidgets( (*request)[strings::params][strings::correlation_id].asInt(), request)); } ProcessHMIRequests(request_list); + return request_list.size(); } bool ResumeCtrlImpl::IsHMIApplicationIdExist(uint32_t hmi_app_id) { diff --git a/src/components/application_manager/test/application_manager_impl_test.cc b/src/components/application_manager/test/application_manager_impl_test.cc index 152d577cda..aa82c6b86b 100644 --- a/src/components/application_manager/test/application_manager_impl_test.cc +++ b/src/components/application_manager/test/application_manager_impl_test.cc @@ -90,6 +90,7 @@ using ::testing::SaveArg; using ::testing::SetArgPointee; using ::testing::SetArgReferee; +using application_manager::plugin_manager::MockRPCPluginManager; using test::components::application_manager_test::MockStateController; using test::components::policy_test::MockPolicyHandlerInterface; @@ -1607,6 +1608,9 @@ TEST_F(ApplicationManagerImplTest, smart_objects::SmartObjectSPtr request_for_registration_ptr = std::make_shared<smart_objects::SmartObject>(request_for_registration); + std::unique_ptr<plugin_manager::RPCPluginManager> rpc_plugin_manager( + new MockRPCPluginManager()); + app_manager_impl_->SetPluginManager(rpc_plugin_manager); ApplicationSharedPtr application = app_manager_impl_->RegisterApplication(request_for_registration_ptr); EXPECT_STREQ(kAppName.c_str(), application->name().c_str()); @@ -1774,6 +1778,9 @@ TEST_F(ApplicationManagerImplTest, smart_objects::SmartObjectSPtr request_for_registration_ptr = std::make_shared<smart_objects::SmartObject>(request_for_registration); + std::unique_ptr<plugin_manager::RPCPluginManager> rpc_plugin_manager( + new MockRPCPluginManager()); + app_manager_impl_->SetPluginManager(rpc_plugin_manager); ApplicationSharedPtr application = app_manager_impl_->RegisterApplication(request_for_registration_ptr); diff --git a/src/components/application_manager/test/hmi_capabilities_test.cc b/src/components/application_manager/test/hmi_capabilities_test.cc index 3d47c717e1..5c7cd238df 100644 --- a/src/components/application_manager/test/hmi_capabilities_test.cc +++ b/src/components/application_manager/test/hmi_capabilities_test.cc @@ -604,23 +604,25 @@ TEST_F(HMICapabilitiesTest, // with old audio pass thru format, the object is an array containing a single // object - smart_objects::SmartObject audio_pass_thru_capabilities_so = - *(hmi_capabilities->audio_pass_thru_capabilities()); + smart_objects::SmartObjectSPtr audio_pass_thru_capabilities_so = + hmi_capabilities->audio_pass_thru_capabilities(); EXPECT_EQ(smart_objects::SmartType_Array, - audio_pass_thru_capabilities_so.getType()); - EXPECT_EQ(1u, audio_pass_thru_capabilities_so.length()); - EXPECT_TRUE(audio_pass_thru_capabilities_so[0].keyExists("samplingRate")); + audio_pass_thru_capabilities_so->getType()); + EXPECT_EQ(1u, audio_pass_thru_capabilities_so->length()); + smart_objects::SmartObject& first_element = + (*audio_pass_thru_capabilities_so)[0]; + EXPECT_TRUE(first_element.keyExists("samplingRate")); EXPECT_EQ(hmi_apis::Common_SamplingRate::RATE_22KHZ, static_cast<hmi_apis::Common_SamplingRate::eType>( - audio_pass_thru_capabilities_so[0]["samplingRate"].asInt())); - EXPECT_TRUE(audio_pass_thru_capabilities_so[0].keyExists("bitsPerSample")); + first_element["samplingRate"].asInt())); + EXPECT_TRUE(first_element.keyExists("bitsPerSample")); EXPECT_EQ(hmi_apis::Common_BitsPerSample::RATE_16_BIT, static_cast<hmi_apis::Common_BitsPerSample::eType>( - audio_pass_thru_capabilities_so[0]["bitsPerSample"].asInt())); - EXPECT_TRUE(audio_pass_thru_capabilities_so[0].keyExists("audioType")); + first_element["bitsPerSample"].asInt())); + EXPECT_TRUE(first_element.keyExists("audioType")); EXPECT_EQ(hmi_apis::Common_AudioType::PCM, static_cast<hmi_apis::Common_AudioType::eType>( - audio_pass_thru_capabilities_so[0]["audioType"].asInt())); + first_element["audioType"].asInt())); } TEST_F(HMICapabilitiesTest, VerifyImageType) { diff --git a/src/components/application_manager/test/include/application_manager/mock_hmi_capabilities.h b/src/components/application_manager/test/include/application_manager/mock_hmi_capabilities.h index 5e5f2eb4a4..c08ad146ee 100644 --- a/src/components/application_manager/test/include/application_manager/mock_hmi_capabilities.h +++ b/src/components/application_manager/test/include/application_manager/mock_hmi_capabilities.h @@ -99,7 +99,8 @@ class MockHMICapabilities : public ::application_manager::HMICapabilities { MOCK_METHOD1(set_tts_supported_languages, void(const smart_objects::SmartObject& supported_languages)); - MOCK_CONST_METHOD0(display_capabilities, const smart_objects::SmartObject*()); + MOCK_CONST_METHOD0(display_capabilities, + const smart_objects::SmartObjectSPtr()); MOCK_METHOD1(set_display_capabilities, void(const smart_objects::SmartObject& display_capabilities)); @@ -109,50 +110,53 @@ class MockHMICapabilities : public ::application_manager::HMICapabilities { void(const smart_objects::SmartObject& display_capabilities)); MOCK_CONST_METHOD0(hmi_zone_capabilities, - const smart_objects::SmartObject*()); + const smart_objects::SmartObjectSPtr()); MOCK_METHOD1(set_hmi_zone_capabilities, void(const smart_objects::SmartObject& hmi_zone_capabilities)); MOCK_CONST_METHOD0(soft_button_capabilities, - const smart_objects::SmartObject*()); + const smart_objects::SmartObjectSPtr()); MOCK_METHOD1( set_soft_button_capabilities, void(const smart_objects::SmartObject& soft_button_capabilities)); - MOCK_CONST_METHOD0(button_capabilities, const smart_objects::SmartObject*()); + MOCK_CONST_METHOD0(button_capabilities, + const smart_objects::SmartObjectSPtr()); MOCK_METHOD1(set_button_capabilities, void(const smart_objects::SmartObject& button_capabilities)); - MOCK_CONST_METHOD0(speech_capabilities, const smart_objects::SmartObject*()); + MOCK_CONST_METHOD0(speech_capabilities, + const smart_objects::SmartObjectSPtr()); MOCK_METHOD1(set_speech_capabilities, void(const smart_objects::SmartObject& speech_capabilities)); - MOCK_CONST_METHOD0(vr_capabilities, const smart_objects::SmartObject*()); + MOCK_CONST_METHOD0(vr_capabilities, const smart_objects::SmartObjectSPtr()); MOCK_METHOD1(set_vr_capabilities, void(const smart_objects::SmartObject& vr_capabilities)); MOCK_CONST_METHOD0(audio_pass_thru_capabilities, - const smart_objects::SmartObject*()); + const smart_objects::SmartObjectSPtr()); MOCK_METHOD1( set_audio_pass_thru_capabilities, void(const smart_objects::SmartObject& audio_pass_thru_capabilities)); MOCK_CONST_METHOD0(pcm_stream_capabilities, - const smart_objects::SmartObject*()); + const smart_objects::SmartObjectSPtr()); MOCK_METHOD1(set_pcm_stream_capabilities, void(const smart_objects::SmartObject& pcm_stream_capabilities)); MOCK_CONST_METHOD0(preset_bank_capabilities, - const smart_objects::SmartObject*()); + const smart_objects::SmartObjectSPtr()); MOCK_METHOD1( set_preset_bank_capabilities, void(const smart_objects::SmartObject& preset_bank_capabilities)); - MOCK_CONST_METHOD0(vehicle_type, const smart_objects::SmartObject*()); + MOCK_CONST_METHOD0(vehicle_type, const smart_objects::SmartObjectSPtr()); MOCK_METHOD1(set_vehicle_type, void(const smart_objects::SmartObject& vehicle_type)); - MOCK_CONST_METHOD0(prerecorded_speech, const smart_objects::SmartObject*()); + MOCK_CONST_METHOD0(prerecorded_speech, + const smart_objects::SmartObjectSPtr()); MOCK_METHOD1(set_prerecorded_speech, void(const smart_objects::SmartObject& prerecorded_speech)); diff --git a/src/components/application_manager/test/include/application_manager/mock_resume_ctrl.h b/src/components/application_manager/test/include/application_manager/mock_resume_ctrl.h index 56c2ae3cd4..b657f0e86b 100644 --- a/src/components/application_manager/test/include/application_manager/mock_resume_ctrl.h +++ b/src/components/application_manager/test/include/application_manager/mock_resume_ctrl.h @@ -102,8 +102,8 @@ class MockResumeCtrl : public resumption::ResumeCtrl { MOCK_CONST_METHOD0(LaunchTime, time_t()); MOCK_METHOD2(RestoreAppWidgets, - void(app_mngr::ApplicationSharedPtr application, - const smart_objects::SmartObject& saved_app)); + size_t(app_mngr::ApplicationSharedPtr application, + const smart_objects::SmartObject& saved_app)); MOCK_METHOD1(RestoreWidgetsHMIState, void(const smart_objects::SmartObject& response_message)); diff --git a/src/components/application_manager/test/resumption/resume_ctrl_test.cc b/src/components/application_manager/test/resumption/resume_ctrl_test.cc index 9f0430a937..909ebbbb92 100644 --- a/src/components/application_manager/test/resumption/resume_ctrl_test.cc +++ b/src/components/application_manager/test/resumption/resume_ctrl_test.cc @@ -128,6 +128,8 @@ class ResumeCtrlTest : public ::testing::Test { EXPECT_CALL(mock_app_mngr_, CheckResumptionRequiredTransportAvailable(_)) .Times(AtLeast(0)) .WillRepeatedly(Return(true)); + ON_CALL(mock_app_mngr_, get_full_or_limited_application()) + .WillByDefault(Return(ApplicationSharedPtr())); ON_CALL(mock_application_manager_settings_, use_db_for_resumption()) .WillByDefault(Return(false)); diff --git a/src/components/connection_handler/src/connection_handler_impl.cc b/src/components/connection_handler/src/connection_handler_impl.cc index db1ee2dce5..1bb1ecbde3 100644 --- a/src/components/connection_handler/src/connection_handler_impl.cc +++ b/src/components/connection_handler/src/connection_handler_impl.cc @@ -258,10 +258,10 @@ void ConnectionHandlerImpl::OnConnectionPending( const transport_manager::ConnectionUID connection_id) { LOG4CXX_AUTO_TRACE(logger_); LOG4CXX_DEBUG(logger_, - "OnConnectionEstablished!!!: " - << device_info.device_handle() << " " << device_info.name() - << " " << device_info.mac_address() << " " - << device_info.connection_type()); + "OnConnectionPending!!!: " << device_info.device_handle() << " " + << device_info.name() << " " + << device_info.mac_address() << " " + << device_info.connection_type()); DeviceMap::iterator it = device_list_.find(device_info.device_handle()); if (device_list_.end() == it) { LOG4CXX_ERROR(logger_, "Unknown device!"); diff --git a/src/components/hmi_message_handler/src/websocket_session.cc b/src/components/hmi_message_handler/src/websocket_session.cc index 3d18da19d2..ad9d5273e4 100644 --- a/src/components/hmi_message_handler/src/websocket_session.cc +++ b/src/components/hmi_message_handler/src/websocket_session.cc @@ -304,12 +304,14 @@ void WebsocketSession::LoopThreadDelegate::exitThreadMain() { } void WebsocketSession::LoopThreadDelegate::DrainQueue() { - while (!message_queue_.empty()) { - Message message_ptr; - message_queue_.pop(message_ptr); - if (!shutdown_) { - handler_.ws_.write(boost::asio::buffer(*message_ptr)); - }; + Message message_ptr; + while (!shutdown_ && message_queue_.pop(message_ptr)) { + boost::system::error_code ec; + handler_.ws_.write(boost::asio::buffer(*message_ptr), ec); + if (ec) { + LOG4CXX_ERROR(ws_logger_, + "A system error has occurred: " << ec.message()); + } } } diff --git a/src/components/hmi_message_handler/test/hmi_message_handler_impl_test.cc b/src/components/hmi_message_handler/test/hmi_message_handler_impl_test.cc index eaa274d0f4..f38eb019e2 100644 --- a/src/components/hmi_message_handler/test/hmi_message_handler_impl_test.cc +++ b/src/components/hmi_message_handler/test/hmi_message_handler_impl_test.cc @@ -189,6 +189,46 @@ TEST_F(HMIMessageHandlerImplTest, SendMessageToHMI_Success) { EXPECT_TRUE(waiter.WaitFor(1, 100)); } +TEST(WebsocketSessionTest, SendMessage_UnpreparedConnection_WithoutFall) { + ::testing::FLAGS_gtest_death_test_style = "threadsafe"; + + auto send_message = []() { + auto message = + "{\"id\" : 1,\"jsonrpc\" : \"2.0\",\"method\" : " + "\"BasicCommunication.GetSystemInfo\"}"; + + Json::Reader reader; + Json::Value json_value; + + ASSERT_TRUE(reader.parse(message, json_value, false)); + + // Make unprepared connection + boost::asio::io_context ioc{1}; + boost::asio::ip::tcp::acceptor acceptor{ + ioc, {boost::asio::ip::make_address("127.0.0.1"), 8087}}; + boost::asio::ip::tcp::socket socket{ioc}; + + std::unique_ptr<hmi_message_handler::WebsocketSession> session( + new hmi_message_handler::WebsocketSession(std::move(socket), nullptr)); + + // Send message to unprepared connection + session->sendJsonMessage(json_value); + + // Wait for the message to be processed + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + // Stopping connection thread + session->Shutdown(); + session = nullptr; + + exit(0); + }; + + // Expected exit code 0, if test terminate by other signal(SIGABRT or + // SIGSEGV), we will get failed test + EXPECT_EXIT(send_message(), ::testing::ExitedWithCode(0), ""); +} + } // namespace hmi_message_handler_test } // namespace components } // namespace test diff --git a/src/components/include/application_manager/application_manager.h b/src/components/include/application_manager/application_manager.h index fa2e8941b8..e96101e7f1 100644 --- a/src/components/include/application_manager/application_manager.h +++ b/src/components/include/application_manager/application_manager.h @@ -170,6 +170,10 @@ class ApplicationManager { virtual ApplicationSharedPtr application(uint32_t app_id) const = 0; virtual ApplicationSharedPtr active_application() const = 0; + virtual void OnQueryAppsRequest( + const connection_handler::DeviceHandle device) = 0; + + virtual ApplicationSharedPtr get_full_or_limited_application() const = 0; /** * Function used only by HMI request/response/notification base classes @@ -182,7 +186,7 @@ class ApplicationManager { virtual ApplicationSharedPtr application_by_policy_id( const std::string& policy_app_id) const = 0; - virtual ApplicationSharedPtr application_by_name( + DEPRECATED virtual ApplicationSharedPtr application_by_name( const std::string& app_name) const = 0; virtual ApplicationSharedPtr pending_application_by_policy_id( @@ -191,6 +195,8 @@ class ApplicationManager { virtual ApplicationSharedPtr reregister_application_by_policy_id( const std::string& policy_app_id) const = 0; + virtual AppSharedPtrs applications_by_name( + const std::string& app_name) const = 0; virtual AppSharedPtrs applications_by_button(uint32_t button) = 0; virtual AppSharedPtrs applications_with_navi() = 0; @@ -664,6 +670,13 @@ class ApplicationManager { virtual protocol_handler::MajorProtocolVersion SupportedSDLVersion() const = 0; + /** + * @brief Applies functor for each plugin + * @param functor Functor that will be applied to each plugin + */ + virtual void ApplyFunctorForEachPlugin( + std::function<void(plugin_manager::RPCPlugin&)> functor) = 0; + /* * @brief Converts connection string transport type representation * to HMI Common_TransportType diff --git a/src/components/include/application_manager/hmi_capabilities.h b/src/components/include/application_manager/hmi_capabilities.h index 8e59bcc74d..535ab0409d 100644 --- a/src/components/include/application_manager/hmi_capabilities.h +++ b/src/components/include/application_manager/hmi_capabilities.h @@ -219,7 +219,7 @@ class HMICapabilities { * * @return Currently supported display capabilities */ - virtual const smart_objects::SmartObject* display_capabilities() const = 0; + virtual const smart_objects::SmartObjectSPtr display_capabilities() const = 0; /* * @brief Sets supported display capabilities @@ -248,7 +248,8 @@ class HMICapabilities { * * @return Currently supported HMI zone capabilities */ - virtual const smart_objects::SmartObject* hmi_zone_capabilities() const = 0; + virtual const smart_objects::SmartObjectSPtr hmi_zone_capabilities() + const = 0; /* * @brief Sets supported HMI zone capabilities @@ -263,7 +264,7 @@ class HMICapabilities { * * @return Currently supported SoftButton's capabilities */ - virtual const smart_objects::SmartObject* soft_button_capabilities() + virtual const smart_objects::SmartObjectSPtr soft_button_capabilities() const = 0; /* @@ -279,7 +280,7 @@ class HMICapabilities { * * @return Currently supported Button's capabilities */ - virtual const smart_objects::SmartObject* button_capabilities() const = 0; + virtual const smart_objects::SmartObjectSPtr button_capabilities() const = 0; /* * @brief Sets supported Button's capabilities @@ -302,7 +303,7 @@ class HMICapabilities { * * @return Currently supported speech capabilities */ - virtual const smart_objects::SmartObject* speech_capabilities() const = 0; + virtual const smart_objects::SmartObjectSPtr speech_capabilities() const = 0; /* * @brief Sets supported VR capabilities @@ -317,7 +318,7 @@ class HMICapabilities { * * @return Currently supported VR capabilities */ - virtual const smart_objects::SmartObject* vr_capabilities() const = 0; + virtual const smart_objects::SmartObjectSPtr vr_capabilities() const = 0; /* * @brief Sets supported audio_pass_thru capabilities @@ -332,7 +333,7 @@ class HMICapabilities { * * @return Currently supported audio_pass_thru capabilities */ - virtual const smart_objects::SmartObject* audio_pass_thru_capabilities() + virtual const smart_objects::SmartObjectSPtr audio_pass_thru_capabilities() const = 0; /* @@ -348,14 +349,15 @@ class HMICapabilities { * * @return Currently supported pcm_streaming capabilities */ - virtual const smart_objects::SmartObject* pcm_stream_capabilities() const = 0; + virtual const smart_objects::SmartObjectSPtr pcm_stream_capabilities() + const = 0; /* * @brief Retrieves information about the preset bank capabilities * * @return Currently supported preset bank capabilities */ - virtual const smart_objects::SmartObject* preset_bank_capabilities() + virtual const smart_objects::SmartObjectSPtr preset_bank_capabilities() const = 0; /* @@ -379,14 +381,14 @@ class HMICapabilities { * * @param vehicle_type Cuurent vehicle information */ - virtual const smart_objects::SmartObject* vehicle_type() const = 0; + virtual const smart_objects::SmartObjectSPtr vehicle_type() const = 0; /* * @brief Retrieves information about the prerecorded speech * * @return Currently supported prerecorded speech */ - virtual const smart_objects::SmartObject* prerecorded_speech() const = 0; + virtual const smart_objects::SmartObjectSPtr prerecorded_speech() const = 0; /* * @brief Sets supported prerecorded speech 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 e533228656..2e0269cefd 100644 --- a/src/components/include/test/application_manager/mock_application_manager.h +++ b/src/components/include/test/application_manager/mock_application_manager.h @@ -86,6 +86,8 @@ class MockApplicationManager : public application_manager::ApplicationManager { application, application_manager::ApplicationSharedPtr(uint32_t app_id)); MOCK_CONST_METHOD0(active_application, application_manager::ApplicationSharedPtr()); + MOCK_CONST_METHOD0(get_full_or_limited_application, + application_manager::ApplicationSharedPtr()); MOCK_CONST_METHOD2(application, application_manager::ApplicationSharedPtr( const std::string& device_id, @@ -116,6 +118,9 @@ class MockApplicationManager : public application_manager::ApplicationManager { MOCK_CONST_METHOD1(reregister_application_by_policy_id, application_manager::ApplicationSharedPtr( const std::string& policy_app_id)); + MOCK_CONST_METHOD1(applications_by_name, + std::vector<application_manager::ApplicationSharedPtr>( + const std::string& app_name)); MOCK_METHOD1( applications_by_button, std::vector<application_manager::ApplicationSharedPtr>(uint32_t button)); @@ -236,6 +241,8 @@ class MockApplicationManager : public application_manager::ApplicationManager { void(const uint32_t connection_key, const uint32_t corr_id, const int32_t function_id)); + MOCK_METHOD1(OnQueryAppsRequest, + void(const connection_handler::DeviceHandle)); MOCK_METHOD4(UnregisterApplication, void(const uint32_t&, mobile_apis::Result::eType, bool, bool)); MOCK_METHOD3(updateRequestTimeout, @@ -269,6 +276,10 @@ class MockApplicationManager : public application_manager::ApplicationManager { MOCK_CONST_METHOD0(SupportedSDLVersion, protocol_handler::MajorProtocolVersion()); MOCK_METHOD1( + ApplyFunctorForEachPlugin, + void(std::function<void(application_manager::plugin_manager::RPCPlugin&)> + functor)); + MOCK_METHOD1( GetDeviceTransportType, hmi_apis::Common_TransportType::eType(const std::string& transport_type)); MOCK_METHOD1(AddAppToTTSGlobalPropertiesList, void(const uint32_t app_id)); diff --git a/src/components/smart_objects/src/smart_object.cc b/src/components/smart_objects/src/smart_object.cc index eb1c737aff..d13ca87848 100644 --- a/src/components/smart_objects/src/smart_object.cc +++ b/src/components/smart_objects/src/smart_object.cc @@ -734,16 +734,32 @@ void SmartObject::duplicate(const SmartObject& OtherObject) { void SmartObject::cleanup_data() { switch (m_type) { case SmartType_String: - delete m_data.str_value; + if (m_data.str_value) { + delete m_data.str_value; + m_data.str_value = nullptr; + m_type = SmartType_Null; + } break; case SmartType_Map: - delete m_data.map_value; + if (m_data.map_value) { + delete m_data.map_value; + m_data.map_value = nullptr; + m_type = SmartType_Null; + } break; case SmartType_Array: - delete m_data.array_value; + if (m_data.array_value) { + delete m_data.array_value; + m_data.array_value = nullptr; + m_type = SmartType_Null; + } break; case SmartType_Binary: - delete m_data.binary_value; + if (m_data.binary_value) { + delete m_data.binary_value; + m_data.binary_value = nullptr; + m_type = SmartType_Null; + } break; default: break; diff --git a/src/components/smart_objects/test/CMakeLists.txt b/src/components/smart_objects/test/CMakeLists.txt index e0cc37e104..9c89079d94 100644 --- a/src/components/smart_objects/test/CMakeLists.txt +++ b/src/components/smart_objects/test/CMakeLists.txt @@ -53,5 +53,11 @@ set(EXCLUDE_PATHS SmartObjectConvertionTime_test.cc ) +# Enable detect Double-free, invalid free +# AddressSanitizer is a fast memory error detector. +# It consists of a compiler instrumentation module and a run-time library. +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address") +set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address") + collect_sources(SOURCES "${CMAKE_CURRENT_SOURCE_DIR}" "${EXCLUDE_PATHS}") create_test(smart_object_test "${SOURCES}" "${LIBRARIES}") diff --git a/src/components/smart_objects/test/SmartObjectUnit_test.cc b/src/components/smart_objects/test/SmartObjectUnit_test.cc index 2c03d8a329..72f96ef939 100644 --- a/src/components/smart_objects/test/SmartObjectUnit_test.cc +++ b/src/components/smart_objects/test/SmartObjectUnit_test.cc @@ -31,6 +31,7 @@ */ #include "gmock/gmock.h" +#define final // Disable error: cannot derive from ‘final’ base #include "smart_objects/smart_object.h" namespace test { @@ -585,6 +586,29 @@ TEST(MapEraseTest, SmartObjectTest) { } // TODO: Add a test to check accessing an array at strange indexes. +TEST(DoubleCleanupDataTest, SmartObjectTest) { + class DerivedSmartObject : public SmartObject { + public: + DerivedSmartObject(SmartType Type) : SmartObject(Type) {} + using SmartObject::operator=; + void cleanup_data() { + SmartObject::cleanup_data(); + } + }; + + DerivedSmartObject obj(SmartType_String); + ASSERT_EQ(SmartType_String, obj.getType()); + + obj = "test string_value"; + ASSERT_EQ(std::string("test string_value"), obj.asString()); + + obj.cleanup_data(); + ASSERT_EQ(std::string(""), obj.asCharArray()); + + obj.cleanup_data(); + ASSERT_EQ(std::string(""), obj.asCharArray()); +} + } // namespace smart_object_test } // namespace components } // namespace test diff --git a/src/components/transport_manager/include/transport_manager/usb/libusb/usb_handler.h b/src/components/transport_manager/include/transport_manager/usb/libusb/usb_handler.h index 6b15229522..9c16b49df6 100644 --- a/src/components/transport_manager/include/transport_manager/usb/libusb/usb_handler.h +++ b/src/components/transport_manager/include/transport_manager/usb/libusb/usb_handler.h @@ -76,6 +76,7 @@ class UsbHandler { public: explicit UsbHandlerDelegate(UsbHandler* handler); void threadMain() OVERRIDE; + void exitThreadMain() OVERRIDE; private: UsbHandler* handler_; diff --git a/src/components/transport_manager/src/usb/libusb/usb_handler.cc b/src/components/transport_manager/src/usb/libusb/usb_handler.cc index 975f71e84c..d1fc0af7f7 100644 --- a/src/components/transport_manager/src/usb/libusb/usb_handler.cc +++ b/src/components/transport_manager/src/usb/libusb/usb_handler.cc @@ -77,12 +77,12 @@ class UsbHandler::ControlTransferSequenceState { UsbHandler::UsbHandler() : shutdown_requested_(false) - , thread_(NULL) + , thread_(nullptr) , usb_device_listeners_() , devices_() , transfer_sequences_() , device_handles_to_close_() - , libusb_context_(NULL) + , libusb_context_(nullptr) , arrived_callback_handle_() , left_callback_handle_() { thread_ = threads::CreateThread("UsbHandler", new UsbHandlerDelegate(this)); @@ -90,19 +90,23 @@ UsbHandler::UsbHandler() UsbHandler::~UsbHandler() { shutdown_requested_ = true; - thread_->stop(); LOG4CXX_INFO(logger_, "UsbHandler thread finished"); - if (libusb_context_ != 0) { // This wakes up libusb_handle_events() + + if (libusb_context_) { + // The libusb_hotplug_deregister_callback() wakes up blocking call of + // libusb_handle_events_completed() in the Thread() method of delegate libusb_hotplug_deregister_callback(libusb_context_, arrived_callback_handle_); libusb_hotplug_deregister_callback(libusb_context_, left_callback_handle_); } + thread_->join(); delete thread_->delegate(); threads::DeleteThread(thread_); + if (libusb_context_) { libusb_exit(libusb_context_); - libusb_context_ = 0; + libusb_context_ = nullptr; } } @@ -518,5 +522,11 @@ void UsbHandler::UsbHandlerDelegate::threadMain() { handler_->Thread(); } +void UsbHandler::UsbHandlerDelegate::exitThreadMain() { + LOG4CXX_AUTO_TRACE(logger_); + // Empty method required in order to avoid force delegate thread + // finishing by exitThreadMain() of the base class +} + } // namespace transport_adapter } // namespace transport_manager |