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 be52046888f..b793837309d 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 @@ -1235,6 +1235,25 @@ class ApplicationManagerImpl */ bool IsLowVoltage(); + /** + * @brief Selects vehicle data of specified application for unsubscribing + * according to subscriptions of other registered applications that also + * subscribed to vehicle data . + * @param app - pointer to application instance. + * @return vehicle_data_for_unscribe - collection with selected vehicle data + * to unsubscribe. + */ + application_manager::VehicleInfoSubscriptions SelectVehicleDataForUnsubscribe( + app_mngr::ApplicationConstSharedPtr application); + + /** + * @brief Unsubscribe specified application from vehicle data. + * @param - Pointer to application instance. + * @return - Return result of sending (success or not). + */ + bool SendUnsubscribeAppFromVehicleDataToHMI( + application_manager::ApplicationConstSharedPtr application); + private: /* * NaviServiceStatusMap shows which navi service (audio/video) is opened diff --git a/src/components/application_manager/include/application_manager/message_helper.h b/src/components/application_manager/include/application_manager/message_helper.h index a423ea75079..a3629c9a1e1 100644 --- a/src/components/application_manager/include/application_manager/message_helper.h +++ b/src/components/application_manager/include/application_manager/message_helper.h @@ -259,6 +259,31 @@ class MessageHelper { static smart_objects::SmartObjectList CreateAddCommandRequestToHMI( ApplicationConstSharedPtr app, ApplicationManager& app_mngr); + /** + * @brief CreateMessageForHMI Creates HMI message with prepared header + * acccoring to message type + * @param message_type Message type + * @param correlation_id Correlation id + * @return HMI message object with filled header + */ + static smart_objects::SmartObjectSPtr CreateMessageForHMI( + const hmi_apis::messageType::eType message_type, + const uint32_t correlation_id); + + /** + * @brief Creates Message for sending to HMI for unsubscribe from specified + * VehicleData. Creates and returns message with vehicle data for unsubscribe. + * @param vehicle_data - collection with vehicle data types to unsubscribe. + * @param app - application which should be unsubscribed from specified + * vehicle data. + * @return - request filled with vehicle data params to unsubscribe + * ,application id and function id. + */ + static smart_objects::SmartObjectSPtr + CreateUnsubscribeVehicleDataMessageForHMI( + const VehicleInfoSubscriptions& vehicle_data, + application_manager::ApplicationConstSharedPtr app); + static smart_objects::SmartObjectList CreateAddVRCommandRequestFromChoiceToHMI(ApplicationConstSharedPtr app, ApplicationManager& app_mngr); diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc index 97dcce10bfc..63c5b848f02 100644 --- a/src/components/application_manager/src/application_manager_impl.cc +++ b/src/components/application_manager/src/application_manager_impl.cc @@ -2624,7 +2624,14 @@ void ApplicationManagerImpl::UnregisterApplication( } else { resume_controller().RemoveApplicationFromSaved(app_to_remove); } + + const bool result = SendUnsubscribeAppFromVehicleDataToHMI(app_to_remove); + LOG4CXX_INFO(logger_, + "Sending UnsubscribeVehicleData to HMI finished " + << (result ? " successful." : " with fail.")); + applications_.erase(app_to_remove); + (hmi_capabilities_->get_hmi_language_handler()) .OnUnregisterApplication(app_id); AppV4DevicePredicate finder(handle); @@ -2849,6 +2856,44 @@ bool ApplicationManagerImpl::IsLowVoltage() { return is_low_voltage_; } +VehicleInfoSubscriptions +ApplicationManagerImpl::SelectVehicleDataForUnsubscribe( + ApplicationConstSharedPtr application) { + auto vehicle_data_for_unsubscribe = application->SubscribedIVI().GetData(); + auto vehicle_data_collector = + [this, &vehicle_data_for_unsubscribe, application]( + const std::uint32_t vehicle_data) { + for (auto& app : applications_) { + if (app->app_id() != application->app_id()) { + if (app->IsSubscribedToIVI(vehicle_data)) { + vehicle_data_for_unsubscribe.erase(vehicle_data); + } + } + } + }; + std::for_each(vehicle_data_for_unsubscribe.begin(), + vehicle_data_for_unsubscribe.end(), + vehicle_data_collector); + return vehicle_data_for_unsubscribe; +} + +bool ApplicationManagerImpl::SendUnsubscribeAppFromVehicleDataToHMI( + ApplicationConstSharedPtr application) { + bool sending_result = false; + + const application_manager::VehicleInfoSubscriptions + vehicle_data_for_unsubscribe = + SelectVehicleDataForUnsubscribe(application); + + if (!vehicle_data_for_unsubscribe.empty()) { + auto message_to_hmi = + MessageHelper::CreateUnsubscribeVehicleDataMessageForHMI( + vehicle_data_for_unsubscribe, application); + sending_result = ManageHMICommand(message_to_hmi); + } + return sending_result; +} + std::string ApplicationManagerImpl::GetHashedAppID( uint32_t connection_key, const std::string& mobile_app_id) const { uint32_t device_id = 0; diff --git a/src/components/application_manager/src/message_helper/message_helper.cc b/src/components/application_manager/src/message_helper/message_helper.cc index a764c574d05..2b3a39bfc99 100644 --- a/src/components/application_manager/src/message_helper/message_helper.cc +++ b/src/components/application_manager/src/message_helper/message_helper.cc @@ -39,8 +39,8 @@ #include #include #include -#include #include +#include #include "application_manager/application.h" #include "application_manager/application_manager.h" @@ -1063,6 +1063,51 @@ smart_objects::SmartObjectList MessageHelper::CreateAddCommandRequestToHMI( return requests; } +smart_objects::SmartObjectSPtr MessageHelper::CreateMessageForHMI( + const hmi_apis::messageType::eType message_type, + const uint32_t correlation_id) { + auto message_so = + new smart_objects::SmartObject(smart_objects::SmartType_Map); + auto& message_ref = *message_so; + + message_ref[strings::params][strings::message_type] = + static_cast(message_type); + message_ref[strings::params][strings::protocol_version] = + commands::CommandImpl::protocol_version_; + message_ref[strings::params][strings::protocol_type] = + commands::CommandImpl::hmi_protocol_type_; + message_ref[strings::params][strings::correlation_id] = correlation_id; + return message_so; +} + +smart_objects::SmartObjectSPtr +MessageHelper::CreateUnsubscribeVehicleDataMessageForHMI( + const VehicleInfoSubscriptions& vehicle_data, + ApplicationConstSharedPtr app) { + auto message_to_hmi = + CreateMessageForHMI(hmi_apis::messageType::request, app->app_id()); + (*message_to_hmi)[strings::params][strings::function_id] = + hmi_apis::FunctionID::VehicleInfo_UnsubscribeVehicleData; + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + const VehicleData& v_data = MessageHelper::vehicle_data(); + + // This lambda puts data (as boolean) into message about needed vehicle + // data to unsubscribe, according to smart object keys. + auto vehicle_data_setter = [&msg_params, &v_data](const uint32_t v_type) { + for (const auto& item : v_data) { + if (item.second == v_type) { + msg_params[item.first] = true; + } + } + }; + + std::for_each(vehicle_data.begin(), vehicle_data.end(), vehicle_data_setter); + (*message_to_hmi)[strings::msg_params] = msg_params; + + return message_to_hmi; +} + smart_objects::SmartObjectList MessageHelper::CreateAddVRCommandRequestFromChoiceToHMI( ApplicationConstSharedPtr app, ApplicationManager& app_mngr) { @@ -1328,10 +1373,9 @@ void MessageHelper::SendOnAppUnregNotificationToHMI( hmi_apis::FunctionID::BasicCommunication_OnAppUnregistered; message[strings::params][strings::message_type] = MessageType::kNotification; - // we put hmi_app_id because applicaton list does not contain application on - // this momment - // and ReplaceHMIByMobileAppId function will be unable to replace app_id to - // hmi_app_id + // we put hmi_app_id because applicaton list does not contain application + // on this momment and ReplaceHMIByMobileAppId function will be unable to + // replace app_id to hmi_app_id message[strings::msg_params][strings::app_id] = app->hmi_app_id(); message[strings::msg_params][strings::unexpected_disconnect] = is_unexpected_disconnect; @@ -2183,7 +2227,8 @@ mobile_apis::Result::eType MessageHelper::VerifyImage( smart_objects::SmartObject& image, ApplicationConstSharedPtr app, ApplicationManager& app_mngr) { - // Checking image type first: if STATIC - skip existence check, since it is + // Checking image type first: if STATIC - skip existence check, since it + // is // HMI related file and it should know it location const uint32_t image_type = image[strings::image_type].asUInt(); mobile_apis::ImageType::eType type = @@ -2447,7 +2492,9 @@ bool MessageHelper::PrintSmartObject(const smart_objects::SmartObject& object) { if (0 != tab) { --tab; } else { - printf("\n-------------------------------------------------------------\n"); + printf( + "\n-------------------------------------------------------------" + "\n"); } #endif return true;