diff options
author | Andrii Kalinich (GitHub) <AKalinich@luxoft.com> | 2021-08-27 17:31:55 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-27 17:31:55 -0400 |
commit | 35f5a0684a36a2a965d5f0e9e784687fa7d82914 (patch) | |
tree | 0975d70a7f31c1d2a0d67462b247ade5256a67e1 | |
parent | b9a2a53cca954b710ed5b25ba91d3267cc2996fd (diff) | |
download | sdl_core-35f5a0684a36a2a965d5f0e9e784687fa7d82914.tar.gz |
Fix stopping video without audio streaming (#3752)
* fix defect with stoping video without audio streaming
* Isolate audio and video streaming
* Remove app unregistration if EndServiceAck not received
Also, application should not be switched to NONE in case
when at least one streaming is already approved and active
6 files changed, 289 insertions, 144 deletions
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 f75a5220c6..c59456a022 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 @@ -858,11 +858,19 @@ class ApplicationManagerImpl protocol_handler::ServiceType service_type) const OVERRIDE; /** - * @brief Ends opened navi services (audio/video) for application + * @brief Ends opened navi services audio and video for application * @param app_id Application id */ void EndNaviServices(uint32_t app_id) OVERRIDE; + /** + * @brief Ends opened navi service audio or video for application + * @param app_id Application id + * @param service_type Service type to check + */ + void EndService(const uint32_t app_id, + const protocol_handler::ServiceType service_type) OVERRIDE; + void ForbidStreaming(uint32_t app_id, protocol_handler::ServiceType service_type) OVERRIDE; @@ -1333,10 +1341,12 @@ class ApplicationManagerImpl const HmiStatePtr to); /** - * @brief Starts EndStream timer for a specified application + * @brief Starts EndStream timer for a specified application service type * @param app_id Application to process + * @param service_type Type of service to track */ - void StartEndStreamTimer(const uint32_t app_id); + void StartEndStreamTimer(const uint32_t app_id, + const protocol_handler::ServiceType service_type); /** * @brief Allows to send appropriate message to mobile device. @@ -1379,13 +1389,19 @@ class ApplicationManagerImpl bool ResetVrHelpTitleItems(ApplicationSharedPtr app) const; private: - /* - * NaviServiceStatusMap shows which navi service (audio/video) is opened - * for specified application. Two bool values in std::pair mean: - * 1st value - is video service opened or not - * 2nd value - is audio service opened or not - */ - typedef std::map<uint32_t, std::pair<bool, bool> > NaviServiceStatusMap; + struct NaviServiceStatusDescriptor { + bool is_video_service_active_; + bool is_audio_service_active_; + }; + + struct NaviServiceDescriptor { + uint32_t app_id_; + protocol_handler::ServiceType service_type_; + TimerSPtr timer_to_stop_service_; + }; + + typedef std::map<uint32_t, NaviServiceStatusDescriptor> NaviServiceStatusMap; + typedef std::deque<NaviServiceDescriptor> NaviServicesDequeue; /** * @brief GetHashedAppID allows to obtain unique application id as a string. @@ -1425,10 +1441,9 @@ class ApplicationManagerImpl /** * @brief Suspends streaming ability of application in case application's HMI - * level - * has been changed to not allowed for streaming + * level has been changed to not allowed for streaming */ - void EndNaviStreaming(); + void EndStreaming(); /** * @brief Starts specified navi service for application @@ -1461,8 +1476,10 @@ class ApplicationManagerImpl * @brief Disallows streaming for application, but doesn't close * opened services. Streaming ability could be restored by AllowStreaming(); * @param app_id Application to proceed + * @param service_type Type of service to disallow */ - void DisallowStreaming(uint32_t app_id); + void DisallowStreaming(const uint32_t app_id, + const protocol_handler::ServiceType service_type); /** * @brief Types of directories used by Application Manager @@ -1668,19 +1685,21 @@ class ApplicationManagerImpl HmiInterfacesImpl hmi_interfaces_; - NaviServiceStatusMap navi_service_status_; sync_primitives::Lock navi_service_status_lock_; - std::deque<uint32_t> navi_app_to_stop_; + NaviServiceStatusMap navi_service_status_; + sync_primitives::Lock navi_app_to_stop_lock_; - std::deque<uint32_t> navi_app_to_end_stream_; + NaviServicesDequeue navi_app_to_stop_; + + sync_primitives::Lock navi_app_to_end_stream_lock_; + NaviServicesDequeue navi_app_to_end_stream_; + + sync_primitives::Lock streaming_timer_pool_lock_; + std::vector<TimerSPtr> streaming_timer_pool_; + uint32_t navi_close_app_timeout_; uint32_t navi_end_stream_timeout_; - std::vector<TimerSPtr> close_app_timer_pool_; - std::vector<TimerSPtr> end_stream_timer_pool_; - sync_primitives::Lock close_app_timer_pool_lock_; - sync_primitives::Lock end_stream_timer_pool_lock_; - mutable sync_primitives::Lock wait_for_hmi_lock_; sync_primitives::ConditionalVariable wait_for_hmi_condvar_; diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/navi_audio_start_stream_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/navi_audio_start_stream_request.cc index 7d030f9c66..673e6570f5 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/navi_audio_start_stream_request.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/navi_audio_start_stream_request.cc @@ -143,6 +143,7 @@ void AudioStartStreamRequest::OnTimeOut() { } void AudioStartStreamRequest::RetryStartSession() { + using namespace protocol_handler; SDL_LOG_AUTO_TRACE(); auto retry_start_session = [this](const uint32_t hmi_app_id) { @@ -177,7 +178,7 @@ void AudioStartStreamRequest::RetryStartSession() { SDL_LOG_DEBUG("Audio start stream retry sequence stopped. " << "Attempts expired."); - application_manager_.EndNaviServices(app->app_id()); + application_manager_.EndService(app->app_id(), ServiceType::kAudio); } }; diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/navi_start_stream_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/navi_start_stream_request.cc index d2db777e94..f5d96d0ea8 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/navi_start_stream_request.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/hmi/navi_start_stream_request.cc @@ -145,6 +145,7 @@ void NaviStartStreamRequest::OnTimeOut() { } void NaviStartStreamRequest::RetryStartSession() { + using namespace protocol_handler; SDL_LOG_AUTO_TRACE(); auto retry_start_session = [this](const uint32_t hmi_app_id) { @@ -179,7 +180,7 @@ void NaviStartStreamRequest::RetryStartSession() { SDL_LOG_DEBUG("NaviStartStream retry sequence stopped. " << "Attempts expired"); - application_manager_.EndNaviServices(app->app_id()); + application_manager_.EndService(app->app_id(), ServiceType::kMobileNav); } }; diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc index 55c437d506..c5089872d4 100644 --- a/src/components/application_manager/src/application_manager_impl.cc +++ b/src/components/application_manager/src/application_manager_impl.cc @@ -242,22 +242,21 @@ ApplicationManagerImpl::~ApplicationManagerImpl() { RemovePolicyObserver(this); { - sync_primitives::AutoLock lock(close_app_timer_pool_lock_); - close_app_timer_pool_.clear(); + sync_primitives::AutoLock lock(navi_app_to_stop_lock_); + navi_app_to_stop_.clear(); } { - sync_primitives::AutoLock lock(end_stream_timer_pool_lock_); - end_stream_timer_pool_.clear(); + sync_primitives::AutoLock lock(navi_app_to_end_stream_lock_); + navi_app_to_end_stream_.clear(); } { - sync_primitives::AutoLock lock(navi_app_to_stop_lock_); - navi_app_to_stop_.clear(); + sync_primitives::AutoLock lock(streaming_timer_pool_lock_); + streaming_timer_pool_.clear(); } - navi_app_to_end_stream_.clear(); - + clear_pool_timer_.Stop(); secondary_transport_devices_cache_.clear(); } @@ -1914,10 +1913,11 @@ bool ApplicationManagerImpl::StartNaviService( NaviServiceStatusMap::iterator it = navi_service_status_.find(app_id); if (navi_service_status_.end() == it) { - std::pair<NaviServiceStatusMap::iterator, bool> res = - navi_service_status_.insert( - std::pair<uint32_t, std::pair<bool, bool> >( - app_id, std::make_pair(false, false))); + NaviServiceStatusDescriptor descriptor({false, false}); + auto res = navi_service_status_.insert( + std::pair<uint32_t, NaviServiceStatusDescriptor>(app_id, + descriptor)); + if (!res.second) { SDL_LOG_WARN("Navi service refused"); return false; @@ -2006,19 +2006,27 @@ void ApplicationManagerImpl::OnStreamingConfigurationSuccessful( // Fill NaviServices map. Set true to first value of pair if // we've started video service or to second value if we've // started audio service - service_type == protocol_handler::ServiceType::kMobileNav - ? it->second.first = true - : it->second.second = true; + if (protocol_handler::ServiceType::kMobileNav == service_type) { + it->second.is_video_service_active_ = true; + } + + if (protocol_handler::ServiceType::kAudio == service_type) { + it->second.is_audio_service_active_ = true; + } { sync_primitives::AutoLock lock(navi_app_to_stop_lock_); - for (size_t i = 0; i < navi_app_to_stop_.size(); ++i) { - if (app_id == navi_app_to_stop_[i]) { - sync_primitives::AutoLock lock(close_app_timer_pool_lock_); - close_app_timer_pool_.erase(close_app_timer_pool_.begin() + i); - navi_app_to_stop_.erase(navi_app_to_stop_.begin() + i); - break; - } + auto it = std::find_if( + navi_app_to_stop_.begin(), + navi_app_to_stop_.end(), + [&app_id, &service_type](const NaviServiceDescriptor& desc) { + return app_id == desc.app_id_ && service_type == desc.service_type_; + }); + + if (it != navi_app_to_stop_.end()) { + SDL_LOG_DEBUG("Removing app descriptor for service " + << service_type << " from map to stop"); + navi_app_to_stop_.erase(it); } } } @@ -2028,10 +2036,18 @@ void ApplicationManagerImpl::OnStreamingConfigurationSuccessful( // Fix: For wifi Secondary // Should erase appid from deque of ForbidStreaming() push in the last time - std::deque<uint32_t>::const_iterator iter = std::find( - navi_app_to_end_stream_.begin(), navi_app_to_end_stream_.end(), app_id); - if (navi_app_to_end_stream_.end() != iter) { - navi_app_to_end_stream_.erase(iter); + { + sync_primitives::AutoLock lock(navi_app_to_end_stream_lock_); + auto it = std::find_if( + navi_app_to_end_stream_.begin(), + navi_app_to_end_stream_.end(), + [&app_id, &service_type](const NaviServiceDescriptor& desc) { + return app_id == desc.app_id_ && service_type == desc.service_type_; + }); + + if (navi_app_to_end_stream_.end() != it) { + navi_app_to_end_stream_.erase(it); + } } } @@ -2062,14 +2078,15 @@ void ApplicationManagerImpl::StopNaviService( return; } else { // Fix: Repeated tests are not executed after they have stopped for Navi - if (false == it->second.first && + if (false == it->second.is_video_service_active_ && ServiceType::kMobileNav == service_type) { SDL_LOG_DEBUG("appId: " << app_id << "Navi had stopped"); return; } // Fix: Repeated tests are not executed after they have stopped for Audio - if (false == it->second.second && ServiceType::kAudio == service_type) { + if (false == it->second.is_audio_service_active_ && + ServiceType::kAudio == service_type) { SDL_LOG_DEBUG("appId: " << app_id << "Audio had stopped"); return; } @@ -2078,8 +2095,13 @@ void ApplicationManagerImpl::StopNaviService( // stopped audio service SDL_LOG_DEBUG("appId: " << app_id << " service_type: " << service_type << " to stopped"); - service_type == ServiceType::kMobileNav ? it->second.first = false - : it->second.second = false; + if (service_type == ServiceType::kMobileNav) { + it->second.is_video_service_active_ = false; + } + + if (service_type == ServiceType::kAudio) { + it->second.is_audio_service_active_ = false; + } } // Fix: For wifi Secondary // undisposed data active the VPMService restart again, @@ -2096,7 +2118,7 @@ void ApplicationManagerImpl::StopNaviService( app->set_audio_streaming_allowed(false); } // push_back for judge in ForbidStreaming(), - StartEndStreamTimer(app_id); + StartEndStreamTimer(app_id, service_type); } ApplicationSharedPtr app = application(app_id); @@ -2288,12 +2310,32 @@ bool ApplicationManagerImpl::HandleRejectedServiceStatus( sync_primitives::AutoLock lock(navi_service_status_lock_); auto app_services = navi_service_status_.find(app->app_id()); if (navi_service_status_.end() != app_services) { - navi_service_status_.erase(app_services); + if (hmi_apis::Common_ServiceType::VIDEO == service_type) { + app_services->second.is_video_service_active_ = false; + } + + if (hmi_apis::Common_ServiceType::AUDIO == service_type) { + app_services->second.is_audio_service_active_ = false; + } + + if (!app_services->second.is_audio_service_active_ && + !app_services->second.is_video_service_active_) { + SDL_LOG_DEBUG("The start of service" + << service_type << " for appID: " << app + << " is failed. Service info has been removed"); + navi_service_status_.erase(app_services); + return true; + } else { + SDL_LOG_WARN( + "Another streaming session is still active. Don't stop the " + "app"); + return false; + } } } - SDL_LOG_DEBUG("The start of service" - << service_type << " for appID: " << app - << " is failed. Service info has been removed"); + + SDL_LOG_DEBUG("The start of service" << service_type << " for appID: " + << app << " is failed. Rejecting"); return true; } case hmi_apis::Common_ServiceType::RPC: { @@ -3533,18 +3575,37 @@ void ApplicationManagerImpl::ForbidStreaming( return; } + bool app_to_stop_found = false; + bool app_to_end_stream_found = false; { sync_primitives::AutoLock lock(navi_app_to_stop_lock_); - if (navi_app_to_stop_.end() != std::find(navi_app_to_stop_.begin(), - navi_app_to_stop_.end(), - app_id) || - navi_app_to_end_stream_.end() != - std::find(navi_app_to_end_stream_.begin(), - navi_app_to_end_stream_.end(), - app_id)) { - return; - } + auto it = std::find_if( + navi_app_to_stop_.begin(), + navi_app_to_stop_.end(), + [&app_id, &service_type](const NaviServiceDescriptor& desc) { + return app_id == desc.app_id_ && service_type == desc.service_type_; + }); + + app_to_stop_found = navi_app_to_stop_.end() != it; + } + + { + sync_primitives::AutoLock lock(navi_app_to_end_stream_lock_); + auto it_stream = std::find_if( + navi_app_to_end_stream_.begin(), + navi_app_to_end_stream_.end(), + [&app_id, &service_type](const NaviServiceDescriptor& desc) { + return app_id == desc.app_id_ && service_type == desc.service_type_; + }); + + app_to_end_stream_found = navi_app_to_end_stream_.end() != it_stream; + } + + if (app_to_stop_found || app_to_end_stream_found) { + SDL_LOG_DEBUG("App " << app_id << " service " << service_type + << " is about to stop. Ignored"); + return; } bool unregister = false; @@ -3552,8 +3613,12 @@ void ApplicationManagerImpl::ForbidStreaming( sync_primitives::AutoLock lock(navi_service_status_lock_); NaviServiceStatusMap::iterator it = navi_service_status_.find(app_id); + if (navi_service_status_.end() == it || - (!it->second.first && !it->second.second)) { + (protocol_handler::ServiceType::kAudio == service_type && + !it->second.is_audio_service_active_) || + (protocol_handler::ServiceType::kMobileNav == service_type && + !it->second.is_video_service_active_)) { unregister = true; } } @@ -3577,7 +3642,7 @@ void ApplicationManagerImpl::ForbidStreaming( return; } - EndNaviServices(app_id); + EndService(app_id, service_type); } void ApplicationManagerImpl::OnAppStreaming( @@ -3601,7 +3666,8 @@ void ApplicationManagerImpl::OnAppStreaming( } } -void ApplicationManagerImpl::EndNaviServices(uint32_t app_id) { +void ApplicationManagerImpl::EndService( + const uint32_t app_id, const protocol_handler::ServiceType service_type) { using namespace protocol_handler; SDL_LOG_AUTO_TRACE(); @@ -3614,6 +3680,7 @@ void ApplicationManagerImpl::EndNaviServices(uint32_t app_id) { bool end_video = false; bool end_audio = false; + { sync_primitives::AutoLock lock(navi_service_status_lock_); @@ -3622,8 +3689,11 @@ void ApplicationManagerImpl::EndNaviServices(uint32_t app_id) { SDL_LOG_ERROR("No info about navi servicies for app"); return; } - end_video = it->second.first; - end_audio = it->second.second; + + end_video = service_type == ServiceType::kMobileNav && + it->second.is_video_service_active_; + end_audio = service_type == ServiceType::kAudio && + it->second.is_audio_service_active_; } if (connection_handler_) { @@ -3637,25 +3707,41 @@ void ApplicationManagerImpl::EndNaviServices(uint32_t app_id) { connection_handler().SendEndService(app_id, ServiceType::kAudio); app->StopStreamingForce(ServiceType::kAudio); } + } - DisallowStreaming(app_id); + DisallowStreaming(app_id, service_type); - { - sync_primitives::AutoLock lock(navi_app_to_stop_lock_); - navi_app_to_stop_.push_back(app_id); - } + { + sync_primitives::AutoLock lock(navi_app_to_stop_lock_); - TimerSPtr close_timer(std::make_shared<timer::Timer>( - "CloseNaviAppTimer", - new TimerTaskImpl<ApplicationManagerImpl>( - this, &ApplicationManagerImpl::CloseNaviApp))); - close_timer->Start(navi_close_app_timeout_, timer::kSingleShot); + auto it = std::find_if( + navi_app_to_stop_.begin(), + navi_app_to_stop_.end(), + [&app_id, &service_type](const NaviServiceDescriptor& desc) { + return app_id == desc.app_id_ && service_type == desc.service_type_; + }); + + if (navi_app_to_stop_.end() == it) { + TimerSPtr close_timer(std::make_shared<timer::Timer>( + "CloseNaviAppTimer", + new TimerTaskImpl<ApplicationManagerImpl>( + this, &ApplicationManagerImpl::CloseNaviApp))); + NaviServiceDescriptor descriptor({app_id, service_type, close_timer}); + navi_app_to_stop_.push_back(descriptor); - sync_primitives::AutoLock lock(close_app_timer_pool_lock_); - close_app_timer_pool_.push_back(close_timer); + close_timer->Start(navi_close_app_timeout_, timer::kSingleShot); + } } } +void ApplicationManagerImpl::EndNaviServices(uint32_t app_id) { + using namespace protocol_handler; + SDL_LOG_AUTO_TRACE(); + + EndService(app_id, ServiceType::kAudio); + EndService(app_id, ServiceType::kMobileNav); +} + void ApplicationManagerImpl::OnHMIStateChanged(const uint32_t app_id, const HmiStatePtr from, const HmiStatePtr to) { @@ -3788,7 +3874,8 @@ void ApplicationManagerImpl::ProcessApp(const uint32_t app_id, << std::boolalpha << end_streaming_by_streaming_state << "; by hmi level: " << std::boolalpha << start_timer_by_hmi_level); - StartEndStreamTimer(app_id); + StartEndStreamTimer(app_id, protocol_handler::ServiceType::kAudio); + StartEndStreamTimer(app_id, protocol_handler::ServiceType::kMobileNav); return; } @@ -3869,38 +3956,32 @@ bool ApplicationManagerImpl::ResetVrHelpTitleItems( return true; } -void ApplicationManagerImpl::StartEndStreamTimer(const uint32_t app_id) { +void ApplicationManagerImpl::ClearTimerPool() { + SDL_LOG_AUTO_TRACE(); + sync_primitives::AutoLock lock(streaming_timer_pool_lock_); + streaming_timer_pool_.clear(); +} + +void ApplicationManagerImpl::StartEndStreamTimer( + const uint32_t app_id, const protocol_handler::ServiceType service_type) { SDL_LOG_DEBUG("Start end stream timer for app " << app_id); - navi_app_to_end_stream_.push_back(app_id); - TimerSPtr end_stream_timer(std::make_shared<timer::Timer>( - "DisallowAppStreamTimer", - new TimerTaskImpl<ApplicationManagerImpl>( - this, &ApplicationManagerImpl::EndNaviStreaming))); - end_stream_timer->Start(navi_end_stream_timeout_, timer::kSingleShot); - sync_primitives::AutoLock lock(end_stream_timer_pool_lock_); - end_stream_timer_pool_.push_back(end_stream_timer); -} + if (helpers:: + Compare<protocol_handler::ServiceType, helpers::EQ, helpers::ONE>( + service_type, + protocol_handler::ServiceType::kAudio, + protocol_handler::ServiceType::kMobileNav)) { + TimerSPtr end_stream_timer = std::make_shared<timer::Timer>( + "DisallowAppStreamTimer", + new TimerTaskImpl<ApplicationManagerImpl>( + this, &ApplicationManagerImpl::EndStreaming)); -void ApplicationManagerImpl::ClearTimerPool() { - SDL_LOG_AUTO_TRACE(); - { - sync_primitives::AutoLock lock(close_app_timer_pool_lock_); + sync_primitives::AutoLock lock(navi_app_to_end_stream_lock_); - close_app_timer_pool_.erase( - std::remove_if(close_app_timer_pool_.begin(), - close_app_timer_pool_.end(), - [](TimerSPtr timer) { return !timer->is_running(); }), - close_app_timer_pool_.end()); - } + NaviServiceDescriptor descriptor({app_id, service_type, end_stream_timer}); + navi_app_to_end_stream_.push_back(descriptor); - { - sync_primitives::AutoLock lock(end_stream_timer_pool_lock_); - end_stream_timer_pool_.erase( - std::remove_if(end_stream_timer_pool_.begin(), - end_stream_timer_pool_.end(), - [](TimerSPtr timer) { return !timer->is_running(); }), - end_stream_timer_pool_.end()); + end_stream_timer->Start(navi_end_stream_timeout_, timer::kSingleShot); } } @@ -3908,58 +3989,88 @@ void ApplicationManagerImpl::CloseNaviApp() { SDL_LOG_AUTO_TRACE(); using namespace mobile_apis::AppInterfaceUnregisteredReason; using namespace mobile_apis::Result; - uint32_t app_id; + NaviServiceDescriptor descriptor( + {0, protocol_handler::ServiceType::kInvalidServiceType, nullptr}); { sync_primitives::AutoLock lock(navi_app_to_stop_lock_); DCHECK_OR_RETURN_VOID(!navi_app_to_stop_.empty()); - app_id = navi_app_to_stop_.front(); + descriptor = navi_app_to_stop_.front(); navi_app_to_stop_.pop_front(); } - bool unregister = false; - { - sync_primitives::AutoLock lock(navi_service_status_lock_); + if (descriptor.app_id_ > 0) { + { + sync_primitives::AutoLock lock(navi_service_status_lock_); - NaviServiceStatusMap::iterator it = navi_service_status_.find(app_id); - if (navi_service_status_.end() != it) { - if (it->second.first || it->second.second) { - unregister = true; - navi_service_status_.erase(it); + NaviServiceStatusMap::iterator it = + navi_service_status_.find(descriptor.app_id_); + if (navi_service_status_.end() != it) { + if (protocol_handler::ServiceType::kMobileNav == + descriptor.service_type_ && + it->second.is_video_service_active_) { + it->second.is_video_service_active_ = false; + } + + if (protocol_handler::ServiceType::kAudio == descriptor.service_type_ && + it->second.is_audio_service_active_) { + it->second.is_audio_service_active_ = false; + } + + if (!it->second.is_audio_service_active_ && + !it->second.is_video_service_active_) { + navi_service_status_.erase(it); + } } } - } - if (unregister) { - SDL_LOG_INFO("App haven't answered for EndService. Unregister it."); - rpc_service_->ManageMobileCommand( - MessageHelper::GetOnAppInterfaceUnregisteredNotificationToMobile( - app_id, PROTOCOL_VIOLATION), - commands::Command::SOURCE_SDL); - UnregisterApplication(app_id, ABORTED); + + { + sync_primitives::AutoLock lock(streaming_timer_pool_lock_); + streaming_timer_pool_.push_back(descriptor.timer_to_stop_service_); + } } } -void ApplicationManagerImpl::EndNaviStreaming() { +void ApplicationManagerImpl::EndStreaming() { SDL_LOG_AUTO_TRACE(); using namespace mobile_apis::AppInterfaceUnregisteredReason; using namespace mobile_apis::Result; + using namespace protocol_handler; - if (!navi_app_to_end_stream_.empty()) { - const uint32_t app_id = navi_app_to_end_stream_.front(); + NaviServiceDescriptor descriptor( + {0, protocol_handler::ServiceType::kInvalidServiceType, nullptr}); + { + sync_primitives::AutoLock lock(navi_app_to_end_stream_lock_); + DCHECK_OR_RETURN_VOID(!navi_app_to_end_stream_.empty()); + descriptor = navi_app_to_end_stream_.front(); navi_app_to_end_stream_.pop_front(); + } + if (descriptor.app_id_ > 0) { { sync_primitives::AutoLock lock(navi_app_to_stop_lock_); - if (navi_app_to_stop_.end() == std::find(navi_app_to_stop_.begin(), - navi_app_to_stop_.end(), - app_id)) { - DisallowStreaming(app_id); + auto it = + std::find_if(navi_app_to_stop_.begin(), + navi_app_to_stop_.end(), + [&descriptor](const NaviServiceDescriptor& desc) { + return descriptor.app_id_ == desc.app_id_ && + descriptor.service_type_ == desc.service_type_; + }); + + if (navi_app_to_stop_.end() == it) { + DisallowStreaming(descriptor.app_id_, descriptor.service_type_); } } + + { + sync_primitives::AutoLock lock(streaming_timer_pool_lock_); + streaming_timer_pool_.push_back(descriptor.timer_to_stop_service_); + } } } -void ApplicationManagerImpl::DisallowStreaming(uint32_t app_id) { +void ApplicationManagerImpl::DisallowStreaming( + const uint32_t app_id, const protocol_handler::ServiceType service_type) { using namespace protocol_handler; SDL_LOG_AUTO_TRACE(); @@ -3974,10 +4085,12 @@ void ApplicationManagerImpl::DisallowStreaming(uint32_t app_id) { NaviServiceStatusMap::iterator it = navi_service_status_.find(app_id); if (navi_service_status_.end() != it) { - if (it->second.first) { + if (it->second.is_video_service_active_ && + service_type == ServiceType::kMobileNav) { app->set_video_streaming_allowed(false); } - if (it->second.second) { + if (it->second.is_audio_service_active_ && + service_type == ServiceType::kAudio) { app->set_audio_streaming_allowed(false); } } @@ -3999,10 +4112,10 @@ void ApplicationManagerImpl::AllowStreaming(uint32_t app_id) { NaviServiceStatusMap::iterator it = navi_service_status_.find(app_id); if (navi_service_status_.end() != it) { - if (it->second.first) { + if (it->second.is_video_service_active_) { app->set_video_streaming_allowed(true); } - if (it->second.second) { + if (it->second.is_audio_service_active_) { app->set_audio_streaming_allowed(true); } } diff --git a/src/components/include/application_manager/application_manager.h b/src/components/include/application_manager/application_manager.h index ba58fd203c..5fd9be2a66 100644 --- a/src/components/include/application_manager/application_manager.h +++ b/src/components/include/application_manager/application_manager.h @@ -517,12 +517,20 @@ class ApplicationManager { virtual uint32_t GenerateNewHMIAppID() = 0; /** - * @brief Ends opened navi services (audio/video) for application + * @brief Ends opened navi services audio and video for application * @param app_id Application id */ virtual void EndNaviServices(uint32_t app_id) = 0; /** + * @brief Ends opened navi service audio or video for application + * @param app_id Application id + * @param service_type Service type to check + */ + virtual void EndService(const uint32_t app_id, + const protocol_handler::ServiceType service_type) = 0; + + /** * @brief returns true if low voltage state is active */ virtual bool IsLowVoltage() const = 0; 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 8d1835a67e..ef0f20ac65 100644 --- a/src/components/include/test/application_manager/mock_application_manager.h +++ b/src/components/include/test/application_manager/mock_application_manager.h @@ -200,6 +200,9 @@ class MockApplicationManager : public application_manager::ApplicationManager { MOCK_METHOD0(GetNextMobileCorrelationID, uint32_t()); MOCK_METHOD0(GenerateNewHMIAppID, uint32_t()); MOCK_METHOD1(EndNaviServices, void(uint32_t app_id)); + MOCK_METHOD2(EndService, + void(const uint32_t app_id, + const protocol_handler::ServiceType service_type)); MOCK_METHOD1(BeginAudioPassThru, bool(uint32_t app_id)); MOCK_METHOD1(EndAudioPassThru, bool(uint32_t app_id)); MOCK_METHOD1(ConnectToDevice, void(const std::string& device_mac)); |