diff options
author | Artem Nosach <ANosach@luxoft.com> | 2015-04-06 22:29:23 +0300 |
---|---|---|
committer | Artem Nosach <ANosach@luxoft.com> | 2015-04-23 15:33:24 +0300 |
commit | 6a9426ec23e237887428be6594e2c631f07ef704 (patch) | |
tree | 292ff969e0f878b086e57baef4eb5afc6f71f8e6 | |
parent | d2160c7044072e21dd9182756e37c9d26f6e7128 (diff) | |
download | sdl_core-6a9426ec23e237887428be6594e2c631f07ef704.tar.gz |
Rework application manager.
-rw-r--r-- | src/components/application_manager/include/application_manager/application_manager_impl.h | 122 | ||||
-rw-r--r-- | src/components/application_manager/src/application_manager_impl.cc | 398 |
2 files changed, 289 insertions, 231 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 d7e556be8f..810719eceb 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 @@ -49,6 +49,7 @@ #include "application_manager/vehicle_info_data.h" #include "application_manager/state_controller.h" #include "protocol_handler/protocol_observer.h" +#include "protocol/service_type.h" #include "hmi_message_handler/hmi_message_observer.h" #include "hmi_message_handler/hmi_message_sender.h" #include "application_manager/policies/policy_handler_observer.h" @@ -93,6 +94,9 @@ class CommandNotificationImpl; namespace application_manager { namespace mobile_api = mobile_apis; +using namespace utils; +using namespace timer; +using protocol_handler::ServiceType; class ApplicationManagerImpl; @@ -654,39 +658,31 @@ class ApplicationManagerImpl : public ApplicationManager, */ void RemovePolicyObserver(PolicyHandlerObserver* listener); - /* - * @brief Checks HMI level and returns true if audio streaming is allowed - */ - bool IsAudioStreamingAllowed(uint32_t connection_key) const; - - /* - * @brief Checks HMI level and returns true if video streaming is allowed + /** + * @brief Checks HMI level and returns true if streaming is allowed + * @param app_id Application id + * @param service_type Service type to check + * @return True if streaming is allowed, false in other case */ - bool IsVideoStreamingAllowed(uint32_t connection_key) const; + bool IsStreamingAllowed(uint32_t app_id, ServiceType service_type) const; /** - * @brief CanAppStream allows to check whether application is permited for - * data streaming. - * - * In case streaming for app is disallowed the method will send EndService to mobile. - * - * @param app_id the application id which should be checked. - * - * @return true in case streaming is allowed, false otherwise. + * @brief Checks if application can stream (streaming service is started and + * streaming is enabled in application) + * @param app_id Application id + * @param service_type Service type to check + * @return True if streaming is allowed, false in other case */ - bool CanAppStream(uint32_t app_id) const; + bool CanAppStream(uint32_t app_id, ServiceType service_type) const; /** - * @brief StreamingEnded Callback called from MediaManager when it decide that - * streaming has been ended - * - * @param app_id the id of application that stops stream. + * @brief Ends opened navi services (audio/video) for application + * @param app_id Application id */ - void StreamingEnded(uint32_t app_id); + void EndNaviServices(uint32_t app_id); /** * @brief ForbidStreaming forbid the stream over the certain application. - * * @param app_id the application's id which should stop streaming. */ void ForbidStreaming(uint32_t app_id); @@ -1152,65 +1148,54 @@ class ApplicationManagerImpl : public ApplicationManager, bool IsLowVoltage(); private: + typedef std::map<uint32_t, std::pair<bool, bool> > NaviServiceStatusMap; + typedef SharedPtr<TimerThread<ApplicationManagerImpl> > ApplicationManagerTimerPtr; + /** - * @brief EndNaviServices either send EndService to mobile or proceed - * unregister application procedure. + * @brief Removes suspended and stopped timers from timer pool */ - void EndNaviServices(); + void ClearTimerPool(); /** * @brief CloseNaviApp allows to unregister application in case the EndServiceEndedAck - * didn't come for at least one of services(audio or video). + * didn't come for at least one of services(audio or video) */ void CloseNaviApp(); /** - * @brief AckReceived allows to distinguish if ack for appropriate service - * has been received (means EndServiceAck). - * - * @param type service type. - * - * @return in case EndService has been sent and appropriate ack has been - * received it returns true. In case no EndService for appropriate serevice type - * has been sent and no ack has been received it returns true as well. - * Otherwise it will return false. - * + * @brief Suspends streaming ability of application in case application's HMI level + * has been changed to BACKGROUND */ - bool AckReceived(protocol_handler::ServiceType type); + void EndNaviStreaming(); /** - * @brief NaviAppChangeLevel the callback which reacts on case when applications - * hmi level has been changed. + * @brief Starts specified navi service for application + * @param app_id Application to proceed + * @param service_type Type of service to start + * @return True on success, false on fail */ - void NaviAppChangeLevel(mobile_apis::HMILevel::eType new_level); + bool StartNaviService(uint32_t app_id, ServiceType service_type); /** - * @brief ChangeStreamStatus allows to process streaming state. - * - * @param app_id id of application whose stream state has been changed. - * - * @param can_stream streaming state if true - streaming active, if false - * streaming is not active. + * @brief Stops specified navi service for application + * @param app_id Application to proceed + * @param service_type Type of service to stop */ - void ChangeStreamStatus(uint32_t app_id, bool can_stream); + void StopNaviService(uint32_t app_id, ServiceType service_type); /** - * @brief ProcessNaviService allows to start navi service - * - * @param type service type. - * - * @param connection_key the application id. + * @brief Suspends streaming ability for application, but doesn't close + * opened services. Streaming ability could be restored by RestoreStreamingAbility() + * @param app_id Application to proceed */ - bool ProcessNaviService(protocol_handler::ServiceType type, uint32_t connection_key); + void SuspendStreamingAbility(uint32_t app_id); /** - * @brief NaviAppStreamStatus allows to handle case when navi streaming state - * has ben changed from streaming to non streaming and vise versa. - * - * @param stream_active the stream's state - is it streams or not. + * @brief Restores streaming ability for application if it was suspended by + * SuspendStreamingAbility() + * @param app_id Application to proceed */ - void NaviAppStreamStatus(bool stream_active); - + void RestoreStreamingAbility(uint32_t app_id); /** * @brief Function returns supported SDL Protocol Version @@ -1262,7 +1247,6 @@ class ApplicationManagerImpl : public ApplicationManager, const connection_handler::DeviceHandle handle); private: - /** * @brief List of applications */ @@ -1330,15 +1314,15 @@ class ApplicationManagerImpl : public ApplicationManager, */ ResumeCtrl resume_ctrl_; - // The map contains service type as a key and pair as a value. - // The pair meaning is: first item shows if EndService has been sent and - // the second one shows if appropriate ACK has been received. - std::map<protocol_handler::ServiceType, std::pair<bool, bool> > service_status_; + NaviServiceStatusMap navi_service_status_; + std::queue<uint32_t> navi_app_to_stop_; + std::queue<uint32_t> navi_app_to_end_stream_; + uint32_t navi_close_app_timeout_; + uint32_t navi_end_stream_timeout_; + + std::vector<ApplicationManagerTimerPtr> timer_pool_; + sync_primitives::Lock timer_pool_lock_; - timer::TimerThread<ApplicationManagerImpl> end_services_timer; - uint32_t wait_end_service_timeout_; - uint32_t navi_app_to_stop_; - StateController state_ctrl_; #ifdef TIME_TESTER diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc index dec6b7a9eb..2f4d930995 100644 --- a/src/components/application_manager/src/application_manager_impl.cc +++ b/src/components/application_manager/src/application_manager_impl.cc @@ -53,6 +53,7 @@ #include "utils/threads/thread.h" #include "utils/file_system.h" #include "utils/helpers.h" +#include "protocol/service_type.h" #include "smart_objects/enum_schema_item.h" #include "interfaces/HMI_API_schema.h" #include "application_manager/application_impl.h" @@ -76,6 +77,7 @@ namespace formatters = NsSmartDeviceLink::NsJSONHandler::Formatters; namespace jhs = NsSmartDeviceLink::NsJSONHandler::strings; using namespace NsSmartDeviceLink::NsSmartObjects; +using protocol_handler::ServiceType; ApplicationManagerImpl::ApplicationManagerImpl() : applications_list_lock_(true), @@ -99,8 +101,8 @@ ApplicationManagerImpl::ApplicationManagerImpl() hmi_capabilities_(this), unregister_reason_(mobile_api::AppInterfaceUnregisteredReason::INVALID_ENUM), resume_ctrl_(this), - end_services_timer("EndServiceTimer", this, &ApplicationManagerImpl::EndNaviServices), - wait_end_service_timeout_(profile::Profile::instance()->stop_streaming_timeout()), + navi_close_app_timeout_(profile::Profile::instance()->stop_streaming_timeout()), + navi_end_stream_timeout_(profile::Profile::instance()->stop_streaming_timeout()), #ifdef TIME_TESTER metric_observer_(NULL), #endif // TIME_TESTER @@ -118,6 +120,11 @@ ApplicationManagerImpl::ApplicationManagerImpl() {TYPE_SYSTEM, "System"}, {TYPE_ICONS, "Icons"} }; + + sync_primitives::AutoLock lock(timer_pool_lock_); + ApplicationManagerTimerPtr clearTimerPoolTimer(new TimerThread<ApplicationManagerImpl>( + "ClearTimerPoolTimer", this, &ApplicationManagerImpl::ClearTimerPool)); + clearTimerPoolTimer->start(10); } ApplicationManagerImpl::~ApplicationManagerImpl() { @@ -140,6 +147,9 @@ ApplicationManagerImpl::~ApplicationManagerImpl() { LOG4CXX_INFO(logger_, "Destroying Policy Handler"); RemovePolicyObserver(this); policy::PolicyHandler::destroy(); + + sync_primitives::AutoLock lock(timer_pool_lock_); + timer_pool_.clear(); } bool ApplicationManagerImpl::Stop() { @@ -284,7 +294,7 @@ bool ApplicationManagerImpl::IsAppTypeExistsInFullOrLimited( ApplicationSharedPtr app) const { bool voice_state = app->is_voice_communication_supported(); bool media_state = app->is_media_application(); - bool navi_state = app->hmi_supports_navi_video_streaming(); + bool navi_state = app->video_streaming_started(); ApplicationSharedPtr active_app = active_application(); // Check app in FULL level if (active_app.valid()) { @@ -302,7 +312,7 @@ bool ApplicationManagerImpl::IsAppTypeExistsInFullOrLimited( return true; } - if (navi_state && active_app->hmi_supports_navi_video_streaming()) { + if (navi_state && active_app->video_streaming_started()) { return true; } } @@ -831,34 +841,6 @@ void ApplicationManagerImpl::RemoveDevice( LOG4CXX_INFO(logger_, "device_handle " << device_handle); } -bool ApplicationManagerImpl::IsAudioStreamingAllowed(uint32_t application_key) const { - ApplicationSharedPtr app = application(application_key); - - using namespace mobile_apis::HMILevel; - using namespace helpers; - if (!app) { - LOG4CXX_WARN(logger_, "An application is not registered."); - return false; - } - - return Compare<eType, EQ, ONE>( - app->hmi_level(), HMI_FULL, HMI_LIMITED); -} - -bool ApplicationManagerImpl::IsVideoStreamingAllowed(uint32_t application_key) const { - ApplicationSharedPtr app = application(application_key); - using namespace mobile_apis::HMILevel; - using namespace helpers; - - if (!app) { - LOG4CXX_WARN(logger_, "An application is not registered."); - return false; - } - - LOG4CXX_DEBUG(logger_, "HMILevel: " << app->hmi_level()); - return Compare<eType, EQ, ONE>(app->hmi_level(), HMI_FULL, HMI_LIMITED); -} - mobile_apis::HMILevel::eType ApplicationManagerImpl::GetDefaultHmiLevel( ApplicationSharedPtr application) const { using namespace mobile_apis; @@ -983,8 +965,9 @@ void ApplicationManagerImpl::ReplaceHMIByMobileAppId( } } -bool ApplicationManagerImpl::ProcessNaviService(protocol_handler::ServiceType type, - uint32_t connection_key) { +bool ApplicationManagerImpl::StartNaviService( + uint32_t app_id, ServiceType service_type) { + using namespace protocol_handler; LOG4CXX_AUTO_TRACE(logger_); if (!media_manager_) { @@ -992,29 +975,56 @@ bool ApplicationManagerImpl::ProcessNaviService(protocol_handler::ServiceType ty return false; } - bool result = false; - switch (type) { - case protocol_handler::kMobileNav: - LOG4CXX_DEBUG(logger_, "Video service is about to be started."); - if (IsVideoStreamingAllowed(connection_key)) { - media_manager_->StartVideoStreaming(connection_key); - result = true; - } - break; - case protocol_handler::kAudio: - LOG4CXX_DEBUG(logger_, "Audio service is about to be started."); - if (IsAudioStreamingAllowed(connection_key)) { - media_manager_->StartAudioStreaming(connection_key); - result = true; + if (IsStreamingAllowed(app_id, service_type)) { + 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))); + if (!res.second) { + return false; } - break; - default: - LOG4CXX_DEBUG(logger_, "Unknown type of service to be started."); - break; + it = res.first; + } + service_type == kMobileNav ? it->second.first = + true : it->second.second = true; + + application(app_id)->StartStreaming(service_type); + media_manager_->StartStreaming(app_id, service_type); + + return true; } + return false; +} - service_status_[type] = std::make_pair(result, false); - return result; +void ApplicationManagerImpl::StopNaviService( + uint32_t app_id, ServiceType service_type) { + using namespace protocol_handler; + LOG4CXX_AUTO_TRACE(logger_); + + NaviServiceStatusMap::iterator it = + navi_service_status_.find(app_id); + if (navi_service_status_.end() == it) { + LOG4CXX_WARN(logger_, "No Information about navi service " + << service_type); + } else { + service_type == kMobileNav ? it->second.first = + false : it->second.second = false; + } + + if (!media_manager_) { + LOG4CXX_DEBUG(logger_, "The media manager is not initialized."); + return; + } + media_manager_->StopStreaming(app_id, service_type); + + ApplicationSharedPtr app = application(app_id); + if (!app) { + LOG4CXX_WARN(logger_, "An application is not registered."); + return; + } + app->StopStreaming(service_type); } bool ApplicationManagerImpl::OnServiceStartedCallback( @@ -1037,22 +1047,24 @@ bool ApplicationManagerImpl::OnServiceStartedCallback( " doesn't exists."); return false; } - bool result = false; + if (Compare<ServiceType, EQ, ONE>(type, kMobileNav, kAudio)) { if (app->is_navi()) { - result = ProcessNaviService(type, session_key); - app->set_streaming_allowed(result); + return StartNaviService(session_key, type); } } - return result; + return false; } void ApplicationManagerImpl::OnServiceEndedCallback(const int32_t& session_key, const protocol_handler::ServiceType& type) { using namespace protocol_handler; - LOG4CXX_DEBUG(logger_, - "OnServiceEndedCallback " << type - << " in session 0x" << std::hex << session_key); + using namespace helpers; + + LOG4CXX_DEBUG( + logger_, + "OnServiceEndedCallback " << type << " in session 0x" + << std::hex << session_key); if (type == kRpc) { LOG4CXX_INFO(logger_, "Remove application."); @@ -1065,25 +1077,8 @@ void ApplicationManagerImpl::OnServiceEndedCallback(const int32_t& session_key, return; } - if (media_manager_) { - switch (type) { - case protocol_handler::kMobileNav: { - LOG4CXX_INFO(logger_, "Stop video streaming."); - media_manager_->StopVideoStreaming(session_key); - break; - } - case protocol_handler::kAudio: { - LOG4CXX_INFO(logger_, "Stop audio service."); - media_manager_->StopAudioStreaming(session_key); - break; - } - default: - LOG4CXX_WARN(logger_, "Unknown type of service to be ended." << type); - break; - } - service_status_[type].second = true; - LOG4CXX_DEBUG(logger_, "Ack status: " << service_status_[type].first <<" : " - << service_status_[type].second); + if (Compare<ServiceType, EQ, ONE>(type, kMobileNav, kAudio)) { + StopNaviService(session_key, type); } } @@ -2206,6 +2201,13 @@ void ApplicationManagerImpl::UnregisterApplication( << "; reason = " << reason << "; is_resuming = " << is_resuming << "; is_unexpected_disconnect = " << is_unexpected_disconnect); + + NaviServiceStatusMap::iterator it = + navi_service_status_.find(app_id); + if (navi_service_status_.end() != it) { + navi_service_status_.erase(it); + } + //remove appID from tts_global_properties_app_list_ MessageHelper::SendOnAppInterfaceUnregisteredNotificationToMobile( app_id, unregister_reason_); @@ -2467,78 +2469,98 @@ bool ApplicationManagerImpl::IsLowVoltage() { return is_low_voltage_; } -void ApplicationManagerImpl::NaviAppStreamStatus(bool stream_active) { - ApplicationSharedPtr active_app = active_application(); - using namespace mobile_apis; - if(active_app && active_app->is_media_application()) { - LOG4CXX_DEBUG(logger_, "Stream status: " << active_app->app_id()); - SetState(active_app->app_id(), - stream_active ? AudioStreamingState::ATTENUATED : - AudioStreamingState::AUDIBLE); +bool ApplicationManagerImpl::IsStreamingAllowed( + uint32_t app_id, ServiceType service_type) const { + + using namespace mobile_apis::HMILevel; + using namespace helpers; + + ApplicationSharedPtr app = application(app_id); + if (!app) { + LOG4CXX_WARN(logger_, "An application is not registered."); + return false; } + return Compare<eType, EQ, ONE>( + app->hmi_level(), HMI_FULL, HMI_LIMITED); } -void ApplicationManagerImpl::ForbidStreaming(uint32_t app_id) { +bool ApplicationManagerImpl::CanAppStream( + uint32_t app_id, ServiceType service_type) const { LOG4CXX_AUTO_TRACE(logger_); - using namespace protocol_handler; + ApplicationSharedPtr app = application(app_id); - if (!(app && app->is_navi())) { - LOG4CXX_DEBUG(logger_, " There is no application with id: " << app_id); - return; + if (!app) { + LOG4CXX_WARN(logger_, "An application is not registered."); + return false; } - if (connection_handler_) { - const bool send_end_service = true; - const bool ack_received = false; - if (app->hmi_supports_navi_video_streaming()) { - LOG4CXX_DEBUG(logger_, "Going to end video service"); - connection_handler_->SendEndService(navi_app_to_stop_, kMobileNav); - service_status_[kMobileNav] = std::make_pair(send_end_service, ack_received); - app->set_hmi_supports_navi_video_streaming(false); - } - if (app->hmi_supports_navi_audio_streaming()) { - LOG4CXX_DEBUG(logger_, "Going to end audio service"); - connection_handler_->SendEndService(navi_app_to_stop_, kAudio); - service_status_[kAudio] = std::make_pair(send_end_service, ack_received); - app->set_hmi_supports_navi_audio_streaming(false); - } + bool is_started = false; + if (ServiceType::kMobileNav == service_type) { + is_started = app->video_streaming_started(); + } else if (ServiceType::kAudio == service_type) { + is_started = app->audio_streaming_started(); } - // this timer will check if appropriate acks from mobile were received. - // in case no acks, the application will be unregistered. - end_services_timer.start(wait_end_service_timeout_, this, &ApplicationManagerImpl::CloseNaviApp); - bool const allow_streaming = false; - ChangeStreamStatus(app_id, allow_streaming); + return IsStreamingAllowed(app_id, service_type) && is_started; } -bool ApplicationManagerImpl::CanAppStream(uint32_t app_id) const { +void ApplicationManagerImpl::ForbidStreaming(uint32_t app_id) { + using namespace mobile_apis::AppInterfaceUnregisteredReason; + using namespace mobile_apis::Result; + using namespace protocol_handler; + LOG4CXX_AUTO_TRACE(logger_); ApplicationSharedPtr app = application(app_id); - if (!(app && app->is_navi())) { + if (!app || !app->is_navi()) { LOG4CXX_DEBUG(logger_, " There is no application with id: " << app_id); - return false; + return; } - return app->is_streaming_allowed(); + NaviServiceStatusMap::iterator it = + navi_service_status_.find(app_id); + if (navi_service_status_.end() == it || + (!it->second.first && !it->second.second)) { + SetUnregisterAllApplicationsReason(PROTOCOL_VIOLATION); + UnregisterApplication(app_id, ABORTED); + return; + } + EndNaviServices(app_id); } -void ApplicationManagerImpl::ChangeStreamStatus(uint32_t app_id, bool can_stream) { +void ApplicationManagerImpl::EndNaviServices(uint32_t app_id) { + using namespace protocol_handler; + + LOG4CXX_AUTO_TRACE(logger_); + ApplicationSharedPtr app = application(app_id); - if (!app) { + if (!app || !app->is_navi()) { LOG4CXX_DEBUG(logger_, " There is no application with id: " << app_id); return; } - // Change streaming status only in case incoming value is different. - if (can_stream != app->streaming()) { - NaviAppStreamStatus(can_stream); - app->set_streaming(can_stream); + NaviServiceStatusMap::iterator it = + navi_service_status_.find(app_id); + if (navi_service_status_.end() == it) { + return; } -} -void ApplicationManagerImpl::StreamingEnded(uint32_t app_id) { - LOG4CXX_DEBUG(logger_, "Streaming has been stoped."); - ChangeStreamStatus(app_id, false); + if (connection_handler_) { + if (it->second.first) { + LOG4CXX_DEBUG(logger_, "Going to end video service"); + connection_handler_->SendEndService(app_id, kMobileNav); + } + if (it->second.second) { + LOG4CXX_DEBUG(logger_, "Going to end audio service"); + connection_handler_->SendEndService(app_id, kAudio); + } + navi_app_to_stop_.push(app_id); + + sync_primitives::AutoLock lock(timer_pool_lock_); + ApplicationManagerTimerPtr closeTimer(new TimerThread<ApplicationManagerImpl>( + "CloseAppTimer", this, &ApplicationManagerImpl::CloseNaviApp)); + closeTimer->start(navi_close_app_timeout_); + timer_pool_.push_back(closeTimer); + } } void ApplicationManagerImpl::OnHMILevelChanged(uint32_t app_id, @@ -2546,33 +2568,52 @@ void ApplicationManagerImpl::OnHMILevelChanged(uint32_t app_id, mobile_apis::HMILevel::eType to) { using namespace mobile_apis::HMILevel; using namespace helpers; + using namespace protocol_handler; if (from == to) { return; } ApplicationSharedPtr app = application(app_id); - if (!(app && app->is_navi())) { + if (!app || !app->is_navi()) { + LOG4CXX_ERROR(logger_, "Navi application not found"); return; } - if (Compare<eType, EQ, ONE>(from, HMI_FULL, HMI_LIMITED)) { - navi_app_to_stop_ = app_id; - NaviAppChangeLevel(to); - } else if (Compare<eType, EQ, ONE>(to, HMI_FULL, HMI_LIMITED)) { - LOG4CXX_DEBUG(logger_, "Restore streaming ability"); - app->set_streaming_allowed(true); + if (to == HMI_FULL || to == HMI_LIMITED) { + if (from == HMI_BACKGROUND) { + RestoreStreamingAbility(app_id); + } + } else if (to == HMI_BACKGROUND) { + if (from == HMI_FULL || from == HMI_LIMITED) { + sync_primitives::AutoLock lock(timer_pool_lock_); + ApplicationManagerTimerPtr endStreamTimer(new TimerThread<ApplicationManagerImpl>( + "EndStreamTimer", this, &ApplicationManagerImpl::EndNaviStreaming)); + endStreamTimer->start(navi_end_stream_timeout_); + timer_pool_.push_back(endStreamTimer); + } + } else if (to == HMI_NONE) { + if (from == HMI_FULL || from == HMI_LIMITED || + from == HMI_BACKGROUND) { + EndNaviServices(app_id); + } } } -void ApplicationManagerImpl::EndNaviServices() { +void ApplicationManagerImpl::ClearTimerPool() { LOG4CXX_AUTO_TRACE(logger_); - ApplicationSharedPtr app = application(navi_app_to_stop_); - if (!app) { - LOG4CXX_DEBUG(logger_, "The application doesn't exists anymore."); - return; + + std::vector<ApplicationManagerTimerPtr> new_timer_pool; + new_timer_pool.push_back(timer_pool_[0]); + + for (size_t i = 1; i < timer_pool_.size(); i++) { + if (timer_pool_[i]->isRunning()) { + new_timer_pool.push_back(timer_pool_[i]); + } } - app->set_streaming_allowed(false); + + sync_primitives::AutoLock lock(timer_pool_lock_); + timer_pool_.swap(new_timer_pool); } void ApplicationManagerImpl::CloseNaviApp() { @@ -2580,39 +2621,72 @@ void ApplicationManagerImpl::CloseNaviApp() { using namespace mobile_apis::AppInterfaceUnregisteredReason; using namespace mobile_apis::Result; using namespace protocol_handler; - const bool is_ack_received = AckReceived(kAudio) && AckReceived(kMobileNav); - if (!is_ack_received) { - SetUnregisterAllApplicationsReason(PROTOCOL_VIOLATION); - UnregisterApplication(navi_app_to_stop_, ABORTED); + + uint32_t app_id = navi_app_to_stop_.front(); + navi_app_to_stop_.pop(); + + NaviServiceStatusMap::iterator it = + navi_service_status_.find(app_id); + if (navi_service_status_.end() != it) { + if (it->second.first || it->second.second) { + SetUnregisterAllApplicationsReason(PROTOCOL_VIOLATION); + UnregisterApplication(app_id, ABORTED); + } } } -bool ApplicationManagerImpl::AckReceived(protocol_handler::ServiceType type) { +void ApplicationManagerImpl::EndNaviStreaming() { LOG4CXX_AUTO_TRACE(logger_); + using namespace mobile_apis::AppInterfaceUnregisteredReason; + using namespace mobile_apis::Result; using namespace protocol_handler; - const bool sent = service_status_[type].first; - const bool received = service_status_[type].second; + uint32_t app_id = navi_app_to_end_stream_.front(); + navi_app_to_end_stream_.pop(); + SuspendStreamingAbility(app_id); +} - LOG4CXX_DEBUG(logger_, "Ack for services type " << type - << " is send: " << sent - << " is received: " << received); +void ApplicationManagerImpl::SuspendStreamingAbility(uint32_t app_id) { + LOG4CXX_AUTO_TRACE(logger_); + using namespace protocol_handler; + + ApplicationSharedPtr app = application(app_id); + if (!app || !app->is_navi()) { + LOG4CXX_ERROR(logger_, "Navi application not found"); + return; + } - return sent == received; + NaviServiceStatusMap::iterator it = + navi_service_status_.find(app_id); + if (navi_service_status_.end() != it) { + if (it->second.first) { + app->StopStreaming(kMobileNav); + } + if (it->second.second) { + app->StopStreaming(kAudio); + } + } } -void ApplicationManagerImpl::NaviAppChangeLevel(mobile_apis::HMILevel::eType new_level) { +void ApplicationManagerImpl::RestoreStreamingAbility(uint32_t app_id) { LOG4CXX_AUTO_TRACE(logger_); - using namespace mobile_apis; - if (new_level == HMILevel::HMI_BACKGROUND) { - end_services_timer.start(wait_end_service_timeout_, this, &ApplicationManagerImpl::EndNaviServices); - } else if (new_level == HMILevel::HMI_NONE) { - EndNaviServices(); - LOG4CXX_DEBUG(logger_, "Send end services start close app timer"); - end_services_timer.start(wait_end_service_timeout_, this, &ApplicationManagerImpl::CloseNaviApp); - } else { - LOG4CXX_DEBUG(logger_, "There is no defined behavior for hmi " << - "levels that are differen from NONE or BACKGROUND"); + using namespace protocol_handler; + + ApplicationSharedPtr app = application(app_id); + if (!app || !app->is_navi()) { + LOG4CXX_ERROR(logger_, "Navi application not found"); + return; + } + + NaviServiceStatusMap::iterator it = + navi_service_status_.find(app_id); + if (navi_service_status_.end() != it) { + if (it->second.first) { + app->StartStreaming(kMobileNav); + } + if (it->second.second) { + app->StartStreaming(kAudio); + } } } |