diff options
Diffstat (limited to 'src/components/application_manager/src/application_manager_impl.cc')
-rw-r--r-- | src/components/application_manager/src/application_manager_impl.cc | 345 |
1 files changed, 230 insertions, 115 deletions
diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc index 6b0ea39804..948f7944d4 100644 --- a/src/components/application_manager/src/application_manager_impl.cc +++ b/src/components/application_manager/src/application_manager_impl.cc @@ -145,10 +145,6 @@ struct PolicyAppIdComparator { const std::string& policy_app_id_; }; -uint32_t ApplicationManagerImpl::mobile_corelation_id_ = 0; -uint32_t ApplicationManagerImpl::corelation_id_ = 0; -const uint32_t ApplicationManagerImpl::max_corelation_id_ = UINT_MAX; - namespace formatters = ns_smart_device_link::ns_json_handler::formatters; namespace jhs = ns_smart_device_link::ns_json_handler::strings; @@ -162,6 +158,7 @@ ApplicationManagerImpl::ApplicationManagerImpl( std::make_shared<sync_primitives::RecursiveLock>()) , apps_to_register_list_lock_ptr_(std::make_shared<sync_primitives::Lock>()) , reregister_wait_list_lock_ptr_(std::make_shared<sync_primitives::Lock>()) + , subscribed_to_hmi_way_points_(false) , audio_pass_thru_active_(false) , audio_pass_thru_app_id_(0) , driver_distraction_state_(hmi_apis::Common_DriverDistractionState::DD_OFF) @@ -174,8 +171,9 @@ ApplicationManagerImpl::ApplicationManagerImpl( , policy_handler_(new policy::PolicyHandler(policy_settings, *this)) , protocol_handler_(NULL) , request_ctrl_(am_settings) - , hmi_so_factory_(NULL) - , mobile_so_factory_(NULL) + , mobile_correlation_id_(0) + , correlation_id_(0) + , max_correlation_id_(UINT_MAX) , hmi_capabilities_(new HMICapabilitiesImpl(*this)) , unregister_reason_( mobile_api::AppInterfaceUnregisteredReason::INVALID_ENUM) @@ -229,19 +227,11 @@ ApplicationManagerImpl::ApplicationManagerImpl( ApplicationManagerImpl::~ApplicationManagerImpl() { SDL_LOG_AUTO_TRACE(); - is_stopping_.store(true); + InitiateStopping(); SendOnSDLClose(); media_manager_ = NULL; hmi_handler_ = NULL; connection_handler_ = NULL; - if (hmi_so_factory_) { - delete hmi_so_factory_; - hmi_so_factory_ = NULL; - } - if (mobile_so_factory_) { - delete mobile_so_factory_; - mobile_so_factory_ = NULL; - } protocol_handler_ = NULL; SDL_LOG_DEBUG("Destroying Policy Handler"); RemovePolicyObserver(this); @@ -673,17 +663,8 @@ ApplicationSharedPtr ApplicationManagerImpl::RegisterApplication( static_cast<protocol_handler::MajorProtocolVersion>( message[strings::params][strings::protocol_version].asInt()); application->set_protocol_version(protocol_version); - - if (protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_UNKNOWN != - protocol_version) { - connection_handler().BindProtocolVersionWithSession( - connection_key, static_cast<uint8_t>(protocol_version)); - } - if ((protocol_version == - protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_3) && - (get_settings().heart_beat_timeout() != 0)) { - connection_handler().StartSessionHeartBeat(connection_key); - } + connection_handler_->BindProtocolVersionWithSession(connection_key, + protocol_version); // Keep HMI add id in case app is present in "waiting for registration" list apps_to_register_list_lock_ptr_->Acquire(); @@ -1382,23 +1363,23 @@ ApplicationManagerImpl::GetCloudAppConnectionStatus( } uint32_t ApplicationManagerImpl::GetNextMobileCorrelationID() { - if (mobile_corelation_id_ < max_corelation_id_) { - mobile_corelation_id_++; + if (mobile_correlation_id_ < max_correlation_id_) { + mobile_correlation_id_++; } else { - mobile_corelation_id_ = 0; + mobile_correlation_id_ = 0; } - return mobile_corelation_id_; + return mobile_correlation_id_; } uint32_t ApplicationManagerImpl::GetNextHMICorrelationID() { - if (corelation_id_ < max_corelation_id_) { - corelation_id_++; + if (correlation_id_ < max_correlation_id_) { + correlation_id_++; } else { - corelation_id_ = 0; + correlation_id_ = 0; } - return corelation_id_; + return correlation_id_; } bool ApplicationManagerImpl::BeginAudioPassThru(uint32_t app_id) { @@ -1616,6 +1597,58 @@ void ApplicationManagerImpl::OnDeviceListUpdated( RefreshCloudAppInformation(); } +bool ApplicationManagerImpl::WaitForHmiIsReady() { + sync_primitives::AutoLock lock(wait_for_hmi_lock_); + if (!IsStopping() && !IsHMICooperating()) { + SDL_LOG_DEBUG("Waiting for the HMI cooperation..."); + wait_for_hmi_condvar_.Wait(lock); + } + + if (IsStopping()) { + SDL_LOG_WARN("System is terminating..."); + return false; + } + + return IsHMICooperating(); +} + +bool ApplicationManagerImpl::GetProtocolVehicleData( + connection_handler::ProtocolVehicleData& data) { + SDL_LOG_AUTO_TRACE(); + using namespace protocol_handler::strings; + + if (!WaitForHmiIsReady()) { + SDL_LOG_ERROR("Failed to wait for HMI readiness"); + return false; + } + + const auto vehicle_type_ptr = hmi_capabilities_->vehicle_type(); + if (vehicle_type_ptr) { + if (vehicle_type_ptr->keyExists(vehicle_make)) { + data.vehicle_make = vehicle_type_ptr->getElement(vehicle_make).asString(); + } + + if (vehicle_type_ptr->keyExists(vehicle_model)) { + data.vehicle_model = + vehicle_type_ptr->getElement(vehicle_model).asString(); + } + + if (vehicle_type_ptr->keyExists(vehicle_model_year)) { + data.vehicle_year = + vehicle_type_ptr->getElement(vehicle_model_year).asString(); + } + + if (vehicle_type_ptr->keyExists(vehicle_trim)) { + data.vehicle_trim = vehicle_type_ptr->getElement(vehicle_trim).asString(); + } + } + + data.vehicle_system_software_version = hmi_capabilities_->ccpu_version(); + data.vehicle_system_hardware_version = hmi_capabilities_->hardware_version(); + + return true; +} + void ApplicationManagerImpl::OnFindNewApplicationsRequest() { connection_handler().ConnectToAllDevices(); SDL_LOG_DEBUG("Starting application list update timer"); @@ -1731,11 +1764,11 @@ void ApplicationManagerImpl::SwitchApplication(ApplicationSharedPtr app, bool is_subscribed_to_way_points = IsAppSubscribedForWayPoints(*app); if (is_subscribed_to_way_points) { - UnsubscribeAppFromWayPoints(app); + UnsubscribeAppFromWayPoints(app, false); } SwitchApplicationParameters(app, connection_key, device_id, mac_address); if (is_subscribed_to_way_points) { - SubscribeAppForWayPoints(app); + SubscribeAppForWayPoints(app, false); } // Normally this is done during registration, however since switched apps are @@ -2555,7 +2588,7 @@ bool ApplicationManagerImpl::Init( bool ApplicationManagerImpl::Stop() { SDL_LOG_AUTO_TRACE(); - is_stopping_.store(true); + InitiateStopping(); application_list_update_timer_.Stop(); try { if (unregister_reason_ == @@ -2681,25 +2714,16 @@ bool ApplicationManagerImpl::ConvertSOtoMessage( } hmi_apis::HMI_API& ApplicationManagerImpl::hmi_so_factory() { - if (!hmi_so_factory_) { - hmi_so_factory_ = new hmi_apis::HMI_API; - if (!hmi_so_factory_) { - SDL_LOG_ERROR("Out of memory"); - NOTREACHED(); - } - } - return *hmi_so_factory_; + return hmi_so_factory_; } mobile_apis::MOBILE_API& ApplicationManagerImpl::mobile_so_factory() { - if (!mobile_so_factory_) { - mobile_so_factory_ = new mobile_apis::MOBILE_API; - if (!mobile_so_factory_) { - SDL_LOG_ERROR("Out of memory"); - NOTREACHED(); - } - } - return *mobile_so_factory_; + return mobile_so_factory_; +} + +ns_smart_device_link_rpc::V1::v4_protocol_v1_2_no_extra& +ApplicationManagerImpl::mobile_v4_protocol_so_factory() { + return mobile_v4_protocol_so_factory_; } HMICapabilities& ApplicationManagerImpl::hmi_capabilities() { @@ -2979,7 +3003,7 @@ void ApplicationManagerImpl::SetUnregisterAllApplicationsReason( void ApplicationManagerImpl::HeadUnitReset( mobile_api::AppInterfaceUnregisteredReason::eType reason) { SDL_LOG_AUTO_TRACE(); - is_stopping_.store(true); + InitiateStopping(); switch (reason) { case mobile_api::AppInterfaceUnregisteredReason::MASTER_RESET: { SDL_LOG_TRACE("Performing MASTER_RESET"); @@ -3231,6 +3255,7 @@ void ApplicationManagerImpl::UnregisterApplication( } ApplicationSharedPtr app_to_remove; connection_handler::DeviceHandle handle = 0; + { sync_primitives::AutoLock lock(applications_list_lock_ptr_); auto it_app = applications_.begin(); @@ -3243,64 +3268,65 @@ void ApplicationManagerImpl::UnregisterApplication( ++it_app; } } - if (!app_to_remove) { - SDL_LOG_ERROR("Cant find application with app_id = " << app_id); - - // Just to terminate RAI in case of connection is dropped (rare case) - // App won't be unregistered since RAI has not been started yet - SDL_LOG_DEBUG("Trying to terminate possible RAI request."); - request_ctrl_.terminateAppRequests(app_id); - - return; - } + } + if (!app_to_remove) { + SDL_LOG_ERROR("Cant find application with app_id = " << app_id); - if (is_resuming) { - resume_controller().SaveApplication(app_to_remove); - } else { - resume_controller().RemoveApplicationFromSaved(app_to_remove); - } + // Just to terminate RAI in case of connection is dropped (rare case) + // App won't be unregistered since RAI has not been started yet + SDL_LOG_DEBUG("Trying to terminate possible RAI request."); + request_ctrl_.terminateAppRequests(app_id); - if (IsAppSubscribedForWayPoints(app_id)) { - UnsubscribeAppFromWayPoints(app_id); - if (!IsAnyAppSubscribedForWayPoints()) { - SDL_LOG_DEBUG("Send UnsubscribeWayPoints"); - auto request = MessageHelper::CreateUnsubscribeWayPointsRequest( - GetNextHMICorrelationID()); - rpc_service_->ManageHMICommand(request); - } - } + return; + } - (hmi_capabilities_->get_hmi_language_handler()) - .OnUnregisterApplication(app_id); + resume_controller().RemoveFromResumption(app_id); - if (connection_handler().GetDeviceID(app_to_remove->mac_address(), - &handle)) { - AppV4DevicePredicate finder(handle); - ApplicationSharedPtr app = FindApp(applications(), finder); - if (!app) { - SDL_LOG_DEBUG( - "There is no more SDL4 apps with device handle: " << handle); + if (is_resuming) { + resume_controller().SaveApplication(app_to_remove); + } else { + resume_controller().RemoveApplicationFromSaved(app_to_remove); + } - RemoveAppsWaitingForRegistration(handle); - } + if (IsAppSubscribedForWayPoints(app_id)) { + UnsubscribeAppFromWayPoints(app_id, true); + if (!IsAnyAppSubscribedForWayPoints()) { + SDL_LOG_DEBUG("Send UnsubscribeWayPoints"); + auto request = MessageHelper::CreateUnsubscribeWayPointsRequest( + GetNextHMICorrelationID()); + rpc_service_->ManageHMICommand(request); } + } - MessageHelper::SendOnAppUnregNotificationToHMI( - app_to_remove, is_unexpected_disconnect, *this); - commands_holder_->Clear(app_to_remove); + (hmi_capabilities_->get_hmi_language_handler()) + .OnUnregisterApplication(app_id); - const auto enabled_local_apps = policy_handler_->GetEnabledLocalApps(); - if (helpers::in_range(enabled_local_apps, app_to_remove->policy_app_id())) { + if (connection_handler().GetDeviceID(app_to_remove->mac_address(), &handle)) { + AppV4DevicePredicate finder(handle); + ApplicationSharedPtr app = FindApp(applications(), finder); + if (!app) { SDL_LOG_DEBUG( - "Enabled local app has been unregistered. Re-create " - "pending application"); - CreatePendingLocalApplication(app_to_remove->policy_app_id()); + "There is no more SDL4 apps with device handle: " << handle); + + RemoveAppsWaitingForRegistration(handle); } + } - RefreshCloudAppInformation(); - SendUpdateAppList(); + MessageHelper::SendOnAppUnregNotificationToHMI( + app_to_remove, is_unexpected_disconnect, *this); + commands_holder_->Clear(app_to_remove); + + const auto enabled_local_apps = policy_handler_->GetEnabledLocalApps(); + if (helpers::in_range(enabled_local_apps, app_to_remove->policy_app_id())) { + SDL_LOG_DEBUG( + "Enabled local app has been unregistered. Re-create " + "pending application"); + CreatePendingLocalApplication(app_to_remove->policy_app_id()); } + RefreshCloudAppInformation(); + SendUpdateAppList(); + if (EndAudioPassThru(app_id)) { // May be better to put this code in MessageHelper? StopAudioPassThru(app_id); @@ -3583,6 +3609,27 @@ void ApplicationManagerImpl::ForbidStreaming( } void ApplicationManagerImpl::OnAppStreaming( + uint32_t app_id, protocol_handler::ServiceType service_type, bool state) { + SDL_LOG_AUTO_TRACE(); + + ApplicationSharedPtr app = application(app_id); + if (!app || (!app->is_navi() && !app->mobile_projection_enabled())) { + SDL_LOG_DEBUG( + " There is no navi or projection application with id: " << app_id); + return; + } + DCHECK_OR_RETURN_VOID(media_manager_); + + if (state) { + state_ctrl_.OnVideoStreamingStarted(app); + media_manager_->StartStreaming(app_id, service_type); + } else { + media_manager_->StopStreaming(app_id, service_type); + state_ctrl_.OnVideoStreamingStopped(app); + } +} + +void ApplicationManagerImpl::OnAppStreaming( uint32_t app_id, protocol_handler::ServiceType service_type, const Application::StreamingState new_state) { @@ -4132,7 +4179,17 @@ bool ApplicationManagerImpl::IsHMICooperating() const { } void ApplicationManagerImpl::SetHMICooperating(const bool hmi_cooperating) { + SDL_LOG_AUTO_TRACE(); + sync_primitives::AutoLock lock(wait_for_hmi_lock_); hmi_cooperating_ = hmi_cooperating; + wait_for_hmi_condvar_.Broadcast(); +} + +void ApplicationManagerImpl::InitiateStopping() { + SDL_LOG_AUTO_TRACE(); + sync_primitives::AutoLock lock(wait_for_hmi_lock_); + is_stopping_.store(true); + wait_for_hmi_condvar_.Broadcast(); } void ApplicationManagerImpl::OnApplicationListUpdateTimer() { @@ -4266,6 +4323,10 @@ ResetGlobalPropertiesResult ApplicationManagerImpl::ResetGlobalProperties( result.keyboard_properties = true; break; } + case mobile_apis::GlobalProperty::USER_LOCATION: { + result.user_location = true; + break; + } default: { SDL_LOG_TRACE("Unknown global property: " << global_property); break; @@ -4316,7 +4377,9 @@ ApplicationManagerImpl::CreateAllAppGlobalPropsIDList( if (application->keyboard_props()) { (*global_properties)[i++] = GlobalProperty::KEYBOARDPROPERTIES; } - + if (!application->get_user_location().empty()) { + (*global_properties)[i++] = GlobalProperty::USER_LOCATION; + } return global_properties; } @@ -4725,42 +4788,69 @@ bool ApplicationManagerImpl::IsAppSubscribedForWayPoints( return IsAppSubscribedForWayPoints(app.app_id()); } -void ApplicationManagerImpl::SubscribeAppForWayPoints(uint32_t app_id) { +void ApplicationManagerImpl::SubscribeAppForWayPoints(uint32_t app_id, + bool response_from_hmi) { SDL_LOG_AUTO_TRACE(); sync_primitives::AutoLock lock(subscribed_way_points_apps_lock_); SDL_LOG_DEBUG("Subscribing " << app_id); subscribed_way_points_apps_list_.insert(app_id); + if (response_from_hmi) { + subscribed_to_hmi_way_points_ = true; + } SDL_LOG_DEBUG("There are applications subscribed: " << subscribed_way_points_apps_list_.size()); - if (way_points_data_) { - smart_objects::SmartObjectSPtr way_point_notification_ = - std::make_shared<smart_objects::SmartObject>(*way_points_data_); - (*way_point_notification_)[strings::params][strings::connection_key] = + if (GetAppServiceManager().FindWayPointsHandler() != nullptr) { + auto service = GetAppServiceManager().ActiveServiceForType( + EnumToString(mobile_apis::AppServiceType::NAVIGATION)); + auto it = mobile_way_points_data_.find(service->connection_key); + if (mobile_way_points_data_.end() == it) { + SDL_LOG_DEBUG("No waypoint data provided by app service provider yet"); + return; + } + smart_objects::SmartObjectSPtr way_point_notification = + std::make_shared<smart_objects::SmartObject>(it->second); + (*way_point_notification)[strings::params][strings::connection_key] = + app_id; + GetRPCService().SendMessageToMobile(way_point_notification); + } else if (hmi_way_points_data_) { + smart_objects::SmartObjectSPtr way_point_notification = + std::make_shared<smart_objects::SmartObject>(*hmi_way_points_data_); + (*way_point_notification)[strings::params][strings::connection_key] = app_id; - GetRPCService().SendMessageToMobile(way_point_notification_); + GetRPCService().SendMessageToMobile(way_point_notification); } } -void ApplicationManagerImpl::SubscribeAppForWayPoints( - ApplicationSharedPtr app) { - SubscribeAppForWayPoints(app->app_id()); +void ApplicationManagerImpl::SubscribeAppForWayPoints(ApplicationSharedPtr app, + bool response_from_hmi) { + SubscribeAppForWayPoints(app->app_id(), response_from_hmi); } -void ApplicationManagerImpl::UnsubscribeAppFromWayPoints(uint32_t app_id) { +void ApplicationManagerImpl::UnsubscribeAppFromWayPoints( + uint32_t app_id, bool response_from_hmi) { SDL_LOG_AUTO_TRACE(); sync_primitives::AutoLock lock(subscribed_way_points_apps_lock_); SDL_LOG_DEBUG("Unsubscribing " << app_id); subscribed_way_points_apps_list_.erase(app_id); + if (response_from_hmi) { + subscribed_to_hmi_way_points_ = false; + } SDL_LOG_DEBUG("There are applications subscribed: " << subscribed_way_points_apps_list_.size()); if (subscribed_way_points_apps_list_.empty()) { - way_points_data_.reset(); + hmi_way_points_data_.reset(); + mobile_way_points_data_.clear(); } } void ApplicationManagerImpl::UnsubscribeAppFromWayPoints( - ApplicationSharedPtr app) { - UnsubscribeAppFromWayPoints(app->app_id()); + ApplicationSharedPtr app, bool response_from_hmi) { + UnsubscribeAppFromWayPoints(app->app_id(), response_from_hmi); +} + +bool ApplicationManagerImpl::IsSubscribedToHMIWayPoints() const { + SDL_LOG_AUTO_TRACE(); + return subscribed_to_hmi_way_points_; } bool ApplicationManagerImpl::IsAnyAppSubscribedForWayPoints() const { @@ -4772,9 +4862,17 @@ bool ApplicationManagerImpl::IsAnyAppSubscribedForWayPoints() const { } void ApplicationManagerImpl::SaveWayPointsMessage( - std::shared_ptr<smart_objects::SmartObject> way_points_message) { + std::shared_ptr<smart_objects::SmartObject> way_points_message, + uint32_t app_id) { sync_primitives::AutoLock lock(subscribed_way_points_apps_lock_); - way_points_data_ = way_points_message; + // Notification from HMI + if (0 == app_id) { + hmi_way_points_data_ = way_points_message; + } + // Notification from app service provider + else { + mobile_way_points_data_[app_id] = *way_points_message; + } } const std::set<uint32_t> ApplicationManagerImpl::GetAppsSubscribedForWayPoints() @@ -4890,6 +4988,23 @@ bool ApplicationManagerImpl::IsSOStructValid( return false; } +bool ApplicationManagerImpl::UnsubscribeAppFromSoftButtons( + const commands::MessageSharedPtr response) { + using namespace mobile_apis; + + const uint32_t connection_key = + (*response)[strings::params][strings::connection_key].asUInt(); + const auto function_id = static_cast<FunctionID::eType>( + (*response)[strings::params][strings::function_id].asInt()); + + ApplicationSharedPtr app = application(connection_key); + DCHECK_OR_RETURN(app, false); + app->UnsubscribeFromSoftButtons(function_id); + SDL_LOG_DEBUG("Application has unsubscribed from softbuttons. FunctionID: " + << function_id << ", app_id:" << app->app_id()); + return true; +} + #ifdef BUILD_TESTS void ApplicationManagerImpl::AddMockApplication(ApplicationSharedPtr mock_app) { applications_list_lock_ptr_->Acquire(); |