diff options
author | JackLivio <jack@livio.io> | 2020-02-17 13:05:54 -0500 |
---|---|---|
committer | JackLivio <jack@livio.io> | 2020-02-17 13:05:54 -0500 |
commit | 86dea8793023f986c7c10d7f9e5b7a932d89a49a (patch) | |
tree | bf44b0d5b6bf6b6c78dd2d0602b67f05ebe2a17c /src/components/application_manager/src/application_manager_impl.cc | |
parent | 4310b2dfd5e1078df0df53138a73d49d000c9c62 (diff) | |
parent | ece258838a44a5461d718c5eeae380ad11a3769b (diff) | |
download | sdl_core-fix/3rd_party_build_issues.tar.gz |
Merge remote-tracking branch 'origin/develop' into fix/3rd_party_build_issuesfix/3rd_party_build_issues
Diffstat (limited to 'src/components/application_manager/src/application_manager_impl.cc')
-rw-r--r-- | src/components/application_manager/src/application_manager_impl.cc | 325 |
1 files changed, 212 insertions, 113 deletions
diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc index 974f125def..7d7e2b30df 100644 --- a/src/components/application_manager/src/application_manager_impl.cc +++ b/src/components/application_manager/src/application_manager_impl.cc @@ -191,6 +191,9 @@ ApplicationManagerImpl::ApplicationManagerImpl( "AM TTSGLPRTimer", new TimerTaskImpl<ApplicationManagerImpl>( this, &ApplicationManagerImpl::OnTimerSendTTSGlobalProperties)) + , clear_pool_timer_("ClearPoolTimer", + new TimerTaskImpl<ApplicationManagerImpl>( + this, &ApplicationManagerImpl::ClearTimerPool)) , is_low_voltage_(false) , apps_size_(0) , is_stopping_(false) { @@ -201,14 +204,9 @@ ApplicationManagerImpl::ApplicationManagerImpl( {TYPE_SYSTEM, "System"}, {TYPE_ICONS, "Icons"}}; - sync_primitives::AutoLock lock(timer_pool_lock_); - TimerSPtr clearing_timer(std::make_shared<timer::Timer>( - "ClearTimerPoolTimer", - new TimerTaskImpl<ApplicationManagerImpl>( - this, &ApplicationManagerImpl::ClearTimerPool))); const uint32_t timeout_ms = 10000u; - clearing_timer->Start(timeout_ms, timer::kSingleShot); - timer_pool_.push_back(clearing_timer); + clear_pool_timer_.Start(timeout_ms, timer::kPeriodic); + rpc_handler_.reset(new rpc_handler::RPCHandlerImpl( *this, hmi_so_factory(), mobile_so_factory())); commands_holder_.reset(new CommandHolderImpl(*this)); @@ -245,8 +243,15 @@ ApplicationManagerImpl::~ApplicationManagerImpl() { LOG4CXX_DEBUG(logger_, "Destroying Policy Handler"); RemovePolicyObserver(this); - sync_primitives::AutoLock lock(timer_pool_lock_); - timer_pool_.clear(); + { + sync_primitives::AutoLock lock(close_app_timer_pool_lock_); + close_app_timer_pool_.clear(); + } + + { + sync_primitives::AutoLock lock(end_stream_timer_pool_lock_); + end_stream_timer_pool_.clear(); + } navi_app_to_stop_.clear(); navi_app_to_end_stream_.clear(); @@ -1575,12 +1580,13 @@ void ApplicationManagerImpl::OnDeviceSwitchingStart( const connection_handler::Device& device_from, const connection_handler::Device& device_to) { LOG4CXX_AUTO_TRACE(logger_); + ReregisterWaitList wait_list; { auto apps_data_accessor = applications(); std::copy_if(apps_data_accessor.GetData().begin(), apps_data_accessor.GetData().end(), - std::back_inserter(reregister_wait_list_), + std::back_inserter(wait_list), std::bind1st(std::ptr_fun(&device_id_comparator), device_from.mac_address())); } @@ -1589,59 +1595,40 @@ void ApplicationManagerImpl::OnDeviceSwitchingStart( // During sending of UpdateDeviceList this lock is acquired also so making // it scoped sync_primitives::AutoLock lock(reregister_wait_list_lock_ptr_); - for (auto i = reregister_wait_list_.begin(); - reregister_wait_list_.end() != i; - ++i) { - auto app = *i; - request_ctrl_.terminateAppRequests(app->app_id()); - resume_ctrl_->SaveApplication(app); - } + std::copy(wait_list.begin(), + wait_list.end(), + std::back_inserter(reregister_wait_list_)); } - policy_handler_->OnDeviceSwitching(device_from.mac_address(), - device_to.mac_address()); - - connection_handler::DeviceMap device_list; - device_list.insert(std::make_pair(device_to.device_handle(), device_to)); - - smart_objects::SmartObjectSPtr msg_params = - MessageHelper::CreateDeviceListSO(device_list, GetPolicyHandler(), *this); - if (!msg_params) { - LOG4CXX_ERROR(logger_, "Can't create UpdateDeviceList notification"); - return; + for (const auto& app : wait_list) { + request_ctrl_.terminateAppRequests(app->app_id()); + resume_ctrl_->SaveApplication(app); } - auto update_list = std::make_shared<smart_objects::SmartObject>(); - smart_objects::SmartObject& so_to_send = *update_list; - so_to_send[jhs::S_PARAMS][jhs::S_FUNCTION_ID] = - hmi_apis::FunctionID::BasicCommunication_UpdateDeviceList; - so_to_send[jhs::S_PARAMS][jhs::S_MESSAGE_TYPE] = - hmi_apis::messageType::request; - so_to_send[jhs::S_PARAMS][jhs::S_PROTOCOL_VERSION] = 2; - so_to_send[jhs::S_PARAMS][jhs::S_PROTOCOL_TYPE] = 1; - so_to_send[jhs::S_PARAMS][jhs::S_CORRELATION_ID] = GetNextHMICorrelationID(); - so_to_send[jhs::S_MSG_PARAMS] = *msg_params; - rpc_service_->ManageHMICommand(update_list); + policy_handler_->OnDeviceSwitching(device_from.mac_address(), + device_to.mac_address()); } void ApplicationManagerImpl::OnDeviceSwitchingFinish( const std::string& device_uid) { LOG4CXX_AUTO_TRACE(logger_); UNUSED(device_uid); - sync_primitives::AutoLock lock(reregister_wait_list_lock_ptr_); + + ReregisterWaitList wait_list; + { + sync_primitives::AutoLock lock(reregister_wait_list_lock_ptr_); + wait_list.swap(reregister_wait_list_); + } const bool unexpected_disonnect = true; const bool is_resuming = true; - for (auto app_it = reregister_wait_list_.begin(); - app_it != reregister_wait_list_.end(); - ++app_it) { - auto app = *app_it; + + for (const auto& app : wait_list) { UnregisterApplication(app->app_id(), mobile_apis::Result::INVALID_ENUM, is_resuming, unexpected_disonnect); } - reregister_wait_list_.clear(); } void ApplicationManagerImpl::SwitchApplication(ApplicationSharedPtr app, @@ -1807,7 +1794,7 @@ bool ApplicationManagerImpl::StartNaviService( using namespace protocol_handler; LOG4CXX_AUTO_TRACE(logger_); - if (HMILevelAllowsStreaming(app_id, service_type)) { + if (HMIStateAllowsStreaming(app_id, service_type)) { { sync_primitives::AutoLock lock(navi_service_status_lock_); @@ -1825,6 +1812,25 @@ bool ApplicationManagerImpl::StartNaviService( } } + { + /* Fix: For NaviApp1 Switch to NaviApp2, App1's Endcallback() arrives + later than App2's Startcallback(). Cause streaming issue on HMI. + */ + sync_primitives::AutoLock lock(applications_list_lock_ptr_); + for (auto app : applications_) { + if (!app || (!app->is_navi() && !app->mobile_projection_enabled())) { + LOG4CXX_DEBUG(logger_, + "Continue, Not Navi App Id: " << app->app_id()); + continue; + } + LOG4CXX_DEBUG(logger_, + "Abort Stream Service of other NaviAppId: " + << app->app_id() + << " Service_type: " << service_type); + StopNaviService(app->app_id(), service_type); + } + } + if (service_type == ServiceType::kMobileNav) { smart_objects::SmartObject converted_params(smart_objects::SmartType_Map); ConvertVideoParamsToSO(converted_params, params); @@ -1895,6 +1901,15 @@ void ApplicationManagerImpl::OnStreamingConfigured( // started audio service service_type == ServiceType::kMobileNav ? it->second.first = true : it->second.second = true; + + 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; + } + } } application(app_id)->StartStreaming(service_type); @@ -1919,10 +1934,27 @@ void ApplicationManagerImpl::StopNaviService( if (navi_service_status_.end() == it) { LOG4CXX_WARN(logger_, "No Information about navi service " << service_type); + // Fix: Need return for Not navi service at now + return; } else { + // Fix: Repeated tests are not executed after they have stopped for Navi + if (false == it->second.first && + ServiceType::kMobileNav == service_type) { + LOG4CXX_DEBUG(logger_, "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) { + LOG4CXX_DEBUG(logger_, "appId: " << app_id << "Audio had stopped"); + return; + } // Fill NaviServices map. Set false to first value of pair if // we've stopped video service or to second value if we've // stopped audio service + LOG4CXX_DEBUG(logger_, + "appId: " << app_id << " service_type: " << service_type + << " to stopped"); service_type == ServiceType::kMobileNav ? it->second.first = false : it->second.second = false; } @@ -2333,11 +2365,21 @@ void ApplicationManagerImpl::RemoveHMIFakeParameters( (*message)[jhs::S_PARAMS][jhs::S_FUNCTION_ID] = mobile_function_id; } -bool ApplicationManagerImpl::Init(resumption::LastState& last_state, - media_manager::MediaManager* media_manager) { +bool ApplicationManagerImpl::Init(resumption::LastState&, + media_manager::MediaManager*) { + return false; +} + +bool ApplicationManagerImpl::Init( + resumption::LastStateWrapperPtr last_state_wrapper, + media_manager::MediaManager* media_manager) { LOG4CXX_TRACE(logger_, "Init application manager"); - plugin_manager_.reset(new plugin_manager::RPCPluginManagerImpl( - *this, *rpc_service_, *hmi_capabilities_, *policy_handler_, last_state)); + plugin_manager_.reset( + new plugin_manager::RPCPluginManagerImpl(*this, + *rpc_service_, + *hmi_capabilities_, + *policy_handler_, + last_state_wrapper)); if (!plugin_manager_->LoadPlugins(get_settings().plugins_folder())) { LOG4CXX_ERROR(logger_, "Plugins are not loaded"); return false; @@ -2347,11 +2389,11 @@ bool ApplicationManagerImpl::Init(resumption::LastState& last_state, !IsReadWriteAllowed(app_storage_folder, TYPE_STORAGE)) { return false; } - if (!resume_controller().Init(last_state)) { + if (!resume_controller().Init(last_state_wrapper)) { LOG4CXX_ERROR(logger_, "Problem with initialization of resume controller"); return false; } - hmi_capabilities_->Init(&last_state); + hmi_capabilities_->Init(last_state_wrapper); if (!(file_system::IsWritingAllowed(app_storage_folder) && file_system::IsReadingAllowed(app_storage_folder))) { @@ -2393,13 +2435,13 @@ bool ApplicationManagerImpl::Init(resumption::LastState& last_state, app_launch_dto_.reset(new app_launch::AppLaunchDataDB(settings_)); } else { app_launch_dto_.reset( - new app_launch::AppLaunchDataJson(settings_, last_state)); + new app_launch::AppLaunchDataJson(settings_, last_state_wrapper)); } app_launch_ctrl_.reset(new app_launch::AppLaunchCtrlImpl( *app_launch_dto_.get(), *this, settings_)); app_service_manager_.reset( - new application_manager::AppServiceManager(*this, last_state)); + new application_manager::AppServiceManager(*this, last_state_wrapper)); auto on_app_policy_updated = [](plugin_manager::RPCPlugin& plugin) { plugin.OnPolicyEvent(plugin_manager::kApplicationPolicyUpdated); @@ -3281,10 +3323,12 @@ std::string ApplicationManagerImpl::GetHashedAppID( return mobile_app_id + device_name; } -bool ApplicationManagerImpl::HMILevelAllowsStreaming( +bool ApplicationManagerImpl::HMIStateAllowsStreaming( uint32_t app_id, protocol_handler::ServiceType service_type) const { LOG4CXX_AUTO_TRACE(logger_); using namespace mobile_apis::HMILevel; + using namespace mobile_apis::PredefinedWindows; + using namespace mobile_apis::VideoStreamingState; using namespace helpers; ApplicationSharedPtr app = application(app_id); @@ -3292,10 +3336,15 @@ bool ApplicationManagerImpl::HMILevelAllowsStreaming( LOG4CXX_WARN(logger_, "An application is not registered."); return false; } - return Compare<eType, EQ, ONE>( - app->hmi_level(mobile_api::PredefinedWindows::DEFAULT_WINDOW), - HMI_FULL, - HMI_LIMITED); + + const auto hmi_state = app->CurrentHmiState(DEFAULT_WINDOW); + const bool allow_streaming_by_hmi_level = + Compare<mobile_apis::HMILevel::eType, EQ, ONE>( + hmi_state->hmi_level(), HMI_FULL, HMI_LIMITED); + const bool allow_streaming_by_streaming_state = + hmi_state->video_streaming_state() == STREAMABLE; + + return allow_streaming_by_hmi_level && allow_streaming_by_streaming_state; } bool ApplicationManagerImpl::CanAppStream( @@ -3318,7 +3367,7 @@ bool ApplicationManagerImpl::CanAppStream( LOG4CXX_WARN(logger_, "Unsupported service_type " << service_type); } - return HMILevelAllowsStreaming(app_id, service_type) && is_allowed; + return HMIStateAllowsStreaming(app_id, service_type) && is_allowed; } void ApplicationManagerImpl::ForbidStreaming(uint32_t app_id) { @@ -3436,15 +3485,14 @@ void ApplicationManagerImpl::EndNaviServices(uint32_t app_id) { this, &ApplicationManagerImpl::CloseNaviApp))); close_timer->Start(navi_close_app_timeout_, timer::kSingleShot); - sync_primitives::AutoLock lock(timer_pool_lock_); - timer_pool_.push_back(close_timer); + sync_primitives::AutoLock lock(close_app_timer_pool_lock_); + close_app_timer_pool_.push_back(close_timer); } } -void ApplicationManagerImpl::OnHMILevelChanged( - uint32_t app_id, - mobile_apis::HMILevel::eType from, - mobile_apis::HMILevel::eType to) { +void ApplicationManagerImpl::OnHMIStateChanged(const uint32_t app_id, + const HmiStatePtr from, + const HmiStatePtr to) { LOG4CXX_AUTO_TRACE(logger_); ProcessPostponedMessages(app_id); ProcessApp(app_id, from, to); @@ -3520,66 +3568,109 @@ void ApplicationManagerImpl::ProcessOnDataStreamingNotification( } void ApplicationManagerImpl::ProcessApp(const uint32_t app_id, - const mobile_apis::HMILevel::eType from, - const mobile_apis::HMILevel::eType to) { + const HmiStatePtr from, + const HmiStatePtr to) { using namespace mobile_apis::HMILevel; + using namespace mobile_apis::VideoStreamingState; using namespace helpers; - if (from == to) { - LOG4CXX_TRACE(logger_, "HMILevel from = to"); - return; - } - ApplicationSharedPtr app = application(app_id); if (!app || (!app->is_navi() && !app->mobile_projection_enabled())) { LOG4CXX_ERROR(logger_, "Navi/Projection application not found"); return; } - if (to == HMI_FULL || to == HMI_LIMITED) { - LOG4CXX_TRACE(logger_, "HMILevel to FULL or LIMITED"); - if (from == HMI_BACKGROUND) { - LOG4CXX_TRACE(logger_, "HMILevel from BACKGROUND"); - AllowStreaming(app_id); - } - } else if (to == HMI_BACKGROUND) { - LOG4CXX_TRACE(logger_, "HMILevel to BACKGROUND"); - if (from == HMI_FULL || from == HMI_LIMITED) { - LOG4CXX_TRACE(logger_, "HMILevel from FULL or LIMITED"); - navi_app_to_end_stream_.push_back(app_id); - TimerSPtr end_stream_timer(std::make_shared<timer::Timer>( - "AppShouldFinishStreaming", - new TimerTaskImpl<ApplicationManagerImpl>( - this, &ApplicationManagerImpl::EndNaviStreaming))); - end_stream_timer->Start(navi_end_stream_timeout_, timer::kPeriodic); + const auto hmi_level_from = from->hmi_level(); + const auto hmi_level_to = to->hmi_level(); + const auto streaming_state_from = from->video_streaming_state(); + const auto streaming_state_to = to->video_streaming_state(); - sync_primitives::AutoLock lock(timer_pool_lock_); - timer_pool_.push_back(end_stream_timer); - } - } else if (to == HMI_NONE) { - LOG4CXX_TRACE(logger_, "HMILevel to NONE"); - if (from == HMI_FULL || from == HMI_LIMITED || from == HMI_BACKGROUND) { - EndNaviServices(app_id); - } + if (hmi_level_from == hmi_level_to && + streaming_state_from == streaming_state_to) { + LOG4CXX_TRACE(logger_, "HMILevel && streaming state were not changed"); + return; } -} -void ApplicationManagerImpl::ClearTimerPool() { - LOG4CXX_AUTO_TRACE(logger_); + auto full_or_limited_hmi_level = [](mobile_apis::HMILevel::eType hmi_level) { + return Compare<mobile_apis::HMILevel::eType, EQ, ONE>( + hmi_level, HMI_FULL, HMI_LIMITED); + }; - std::vector<TimerSPtr> new_timer_pool; + const bool allow_streaming_by_streaming_state = + NOT_STREAMABLE == streaming_state_from && + STREAMABLE == streaming_state_to; + const bool allow_streaming_by_hmi_level = + HMI_BACKGROUND == hmi_level_from && + full_or_limited_hmi_level(hmi_level_to) && + STREAMABLE == streaming_state_to; + if (allow_streaming_by_streaming_state || allow_streaming_by_hmi_level) { + LOG4CXX_TRACE(logger_, + "Allow streaming by streaming state: " + << std::boolalpha << allow_streaming_by_streaming_state + << "; by hmi level: " << std::boolalpha + << allow_streaming_by_hmi_level); + AllowStreaming(app_id); + return; + } - sync_primitives::AutoLock lock(timer_pool_lock_); - new_timer_pool.push_back(timer_pool_[0]); + const bool end_streaming_by_streaming_state = + STREAMABLE == streaming_state_from && + NOT_STREAMABLE == streaming_state_to && + full_or_limited_hmi_level(hmi_level_to); + const bool start_timer_by_hmi_level = + full_or_limited_hmi_level(hmi_level_from) && + HMI_BACKGROUND == hmi_level_to; + if (end_streaming_by_streaming_state || start_timer_by_hmi_level) { + LOG4CXX_TRACE(logger_, + "Start EndStream timer by streaming state: " + << std::boolalpha << end_streaming_by_streaming_state + << "; by hmi level: " << std::boolalpha + << start_timer_by_hmi_level); + StartEndStreamTimer(app_id); + return; + } - for (size_t i = 1; i < timer_pool_.size(); ++i) { - if (timer_pool_[i]->is_running()) { - new_timer_pool.push_back(timer_pool_[i]); - } + const bool end_streaming_by_hmi_level = + full_or_limited_hmi_level(hmi_level_from) && HMI_NONE == hmi_level_to; + if (end_streaming_by_hmi_level) { + LOG4CXX_TRACE(logger_, + "End streaming services by hmi level: " + << std::boolalpha << end_streaming_by_hmi_level); + EndNaviServices(app_id); + return; } - timer_pool_.swap(new_timer_pool); - new_timer_pool.clear(); + LOG4CXX_TRACE(logger_, "No actions required for app " << app_id); +} + +void ApplicationManagerImpl::StartEndStreamTimer(const uint32_t app_id) { + LOG4CXX_DEBUG(logger_, "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); +} + +void ApplicationManagerImpl::ClearTimerPool() { + LOG4CXX_AUTO_TRACE(logger_); + { + sync_primitives::AutoLock lock(close_app_timer_pool_lock_); + std::remove_if(close_app_timer_pool_.begin(), + close_app_timer_pool_.end(), + [](TimerSPtr timer) { return !timer->is_running(); }); + } + + { + sync_primitives::AutoLock lock(end_stream_timer_pool_lock_); + std::remove_if(end_stream_timer_pool_.begin(), + end_stream_timer_pool_.end(), + [](TimerSPtr timer) { return !timer->is_running(); }); + } } void ApplicationManagerImpl::CloseNaviApp() { @@ -4550,11 +4641,19 @@ void ApplicationManagerImpl::ChangeAppsHMILevel( LOG4CXX_ERROR(logger_, "There is no app with id: " << app_id); return; } - const mobile_apis::HMILevel::eType old_level = - app->hmi_level(mobile_api::PredefinedWindows::DEFAULT_WINDOW); - if (old_level != level) { + + const auto old_hmi_state = + app->CurrentHmiState(mobile_apis::PredefinedWindows::DEFAULT_WINDOW); + if (old_hmi_state->hmi_level() != level) { app->set_hmi_level(mobile_apis::PredefinedWindows::DEFAULT_WINDOW, level); - OnHMILevelChanged(app_id, old_level, level); + const auto new_hmi_state = + CreateRegularState(app, + mobile_apis::WindowType::MAIN, + level, + old_hmi_state->audio_streaming_state(), + old_hmi_state->video_streaming_state(), + old_hmi_state->system_context()); + OnHMIStateChanged(app_id, old_hmi_state, new_hmi_state); } else { LOG4CXX_WARN(logger_, "Redundant changing HMI level: " << level); } |