diff options
author | Shobhit Adlakha <ShobhitAd@users.noreply.github.com> | 2020-09-21 13:56:27 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-21 13:56:27 -0400 |
commit | 93202c39ac25d6bd6ccd1c9df948106dab38acfa (patch) | |
tree | 421e7f7d619195801be9c8feafa921eb3e7cf79d | |
parent | 1f52a0ef360475ba268c49e1eec8b0a93050f132 (diff) | |
download | sdl_core-93202c39ac25d6bd6ccd1c9df948106dab38acfa.tar.gz |
Fix/Delay OnHMIStatus until RAI response is sent (#3506)
* Add is_ready flag to apps and handle sending OnHMIStatus after RAI response
* Add mock functions
* Address review comments
* Only send delayed onHMIStatus if RAI was a success
* Prevent secondary hmi level none to cloud apps
* Move enabled check to last when init new cloud app
Co-authored-by: JackLivio <jack@livio.io>
10 files changed, 113 insertions, 16 deletions
diff --git a/src/components/application_manager/include/application_manager/application.h b/src/components/application_manager/include/application_manager/application.h index 6280d83278..59c9d35320 100644 --- a/src/components/application_manager/include/application_manager/application.h +++ b/src/components/application_manager/include/application_manager/application.h @@ -671,6 +671,8 @@ class Application : public virtual InitialApplicationData, virtual bool app_allowed() const = 0; virtual bool has_been_activated() const = 0; virtual bool set_activated(bool is_active) = 0; + virtual bool is_ready() const = 0; + virtual bool set_is_ready(bool is_ready) = 0; virtual const Version& version() const = 0; virtual void set_hmi_application_id(uint32_t hmi_app_id) = 0; diff --git a/src/components/application_manager/include/application_manager/application_impl.h b/src/components/application_manager/include/application_manager/application_impl.h index 1e24addf4a..6c1a897054 100644 --- a/src/components/application_manager/include/application_manager/application_impl.h +++ b/src/components/application_manager/include/application_manager/application_impl.h @@ -150,6 +150,8 @@ class ApplicationImpl : public virtual Application, inline bool app_allowed() const; bool has_been_activated() const; bool set_activated(bool is_active); + bool is_ready() const; + bool set_is_ready(bool is_ready); const Version& version() const; void set_hmi_application_id(uint32_t hmi_app_id); @@ -582,6 +584,7 @@ class ApplicationImpl : public virtual Application, bool is_app_allowed_; bool is_app_data_resumption_allowed_; bool has_been_activated_; + bool is_ready_; bool tts_properties_in_none_; bool tts_properties_in_full_; bool keep_context_; diff --git a/src/components/application_manager/include/application_manager/state_controller_impl.h b/src/components/application_manager/include/application_manager/state_controller_impl.h index d74ed4e7fa..210ddf9720 100644 --- a/src/components/application_manager/include/application_manager/state_controller_impl.h +++ b/src/components/application_manager/include/application_manager/state_controller_impl.h @@ -35,6 +35,7 @@ #include <list> #include <map> +#include <unordered_set> #include "application_manager/application.h" #include "application_manager/application_manager.h" #include "application_manager/hmi_state.h" @@ -430,6 +431,8 @@ class StateControllerImpl : public event_engine::EventObserver, typedef std::list<WindowStatePair> WindowStatePairs; std::map<uint32_t, WindowStatePairs> postponed_app_widgets_; + std::unordered_set<uint32_t> apps_with_pending_hmistatus_notification_; + mutable sync_primitives::Lock apps_with_pending_hmistatus_notification_lock_; ApplicationManager& app_mngr_; }; } // namespace application_manager diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_response.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_response.cc index f0e885f54c..0c74105e56 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_response.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_response.cc @@ -96,6 +96,15 @@ void RegisterAppInterfaceResponse::Run() { } SendResponse(success, result_code, last_message); + if (success) { + app->set_is_ready(true); + } + event_engine::MobileEvent event( + mobile_apis::FunctionID::RegisterAppInterfaceID); + smart_objects::SmartObject event_msg(*message_); + event_msg[strings::params][strings::correlation_id] = 0; + event.set_smart_object(event_msg); + event.raise(application_manager_.event_dispatcher()); if (mobile_apis::Result::SUCCESS != result_code) { return; diff --git a/src/components/application_manager/src/application_impl.cc b/src/components/application_manager/src/application_impl.cc index 60070524a0..2edf3860d6 100644 --- a/src/components/application_manager/src/application_impl.cc +++ b/src/components/application_manager/src/application_impl.cc @@ -116,6 +116,7 @@ ApplicationImpl::ApplicationImpl( , is_app_allowed_(true) , is_app_data_resumption_allowed_(false) , has_been_activated_(false) + , is_ready_(false) , tts_properties_in_none_(false) , tts_properties_in_full_(false) , keep_context_(false) @@ -782,6 +783,15 @@ bool ApplicationImpl::set_activated(bool is_active) { return true; } +bool ApplicationImpl::is_ready() const { + return is_ready_; +} + +bool ApplicationImpl::set_is_ready(bool is_ready) { + is_ready_ = is_ready; + return true; +} + void ApplicationImpl::set_protocol_version( const protocol_handler::MajorProtocolVersion& protocol_version) { protocol_version_ = protocol_version; diff --git a/src/components/application_manager/src/policies/policy_handler.cc b/src/components/application_manager/src/policies/policy_handler.cc index 6a7c9abb33..8ec21660a8 100644 --- a/src/components/application_manager/src/policies/policy_handler.cc +++ b/src/components/application_manager/src/policies/policy_handler.cc @@ -2331,12 +2331,6 @@ void PolicyHandler::OnSetCloudAppProperties( policy_manager_->InitCloudApp(policy_app_id); bool auth_token_update = false; - if (properties.keyExists(strings::enabled)) { - bool enabled = properties[strings::enabled].asBool(); - policy_manager_->SetCloudAppEnabled(policy_app_id, enabled); - auth_token_update = enabled; - application_manager_.RefreshCloudAppInformation(); - } if (properties.keyExists(strings::auth_token)) { std::string auth_token = properties[strings::auth_token].asString(); policy_manager_->SetAppAuthToken(policy_app_id, auth_token); @@ -2370,6 +2364,14 @@ void PolicyHandler::OnSetCloudAppProperties( policy_manager_->SetHybridAppPreference(policy_app_id, hybrid_app_preference); } + if (properties.keyExists(strings::enabled)) { + bool enabled = properties[strings::enabled].asBool(); + policy_manager_->SetCloudAppEnabled(policy_app_id, enabled); + if (!auth_token_update) { + auth_token_update = enabled; + } + application_manager_.RefreshCloudAppInformation(); + } if (auth_token_update) { AppProperties app_properties; diff --git a/src/components/application_manager/src/state_controller_impl.cc b/src/components/application_manager/src/state_controller_impl.cc index ec77e30db7..2eb813e69f 100644 --- a/src/components/application_manager/src/state_controller_impl.cc +++ b/src/components/application_manager/src/state_controller_impl.cc @@ -714,7 +714,52 @@ void StateControllerImpl::UpdateAppWindowsStreamingState( } } -void StateControllerImpl::on_event(const event_engine::MobileEvent& event) {} +void StateControllerImpl::on_event(const event_engine::MobileEvent& event) { + using namespace mobile_apis; + + SDL_LOG_AUTO_TRACE(); + SDL_LOG_DEBUG("Received event for function" << event.id()); + switch (event.id()) { + case FunctionID::RegisterAppInterfaceID: { + auto message = event.smart_object(); + uint32_t connection_key = + message[strings::params][strings::connection_key].asUInt(); + ApplicationSharedPtr app = app_mngr_.application(connection_key); + + if (app.use_count() == 0) { + SDL_LOG_WARN("Application doesn't exist"); + return; + } + { + sync_primitives::AutoLock autolock( + apps_with_pending_hmistatus_notification_lock_); + + auto it = apps_with_pending_hmistatus_notification_.find(app->app_id()); + if (it == apps_with_pending_hmistatus_notification_.end()) { + SDL_LOG_WARN("Application does not have a pending OnHMIStatus"); + return; + } + + bool success = message[strings::msg_params][strings::success].asBool(); + if (success) { + // Only send notification if RAI was a success + auto notification = + MessageHelper::CreateHMIStatusNotification(app, 0); + app_mngr_.GetRPCService().ManageMobileCommand( + notification, commands::Command::SOURCE_SDL); + } + + apps_with_pending_hmistatus_notification_.erase(app->app_id()); + if (apps_with_pending_hmistatus_notification_.empty()) { + unsubscribe_from_event(FunctionID::RegisterAppInterfaceID); + } + } + } break; + + default: + break; + } +} void StateControllerImpl::on_event(const event_engine::Event& event) { using event_engine::Event; @@ -830,8 +875,8 @@ void StateControllerImpl::ActivateDefaultWindow(ApplicationSharedPtr app) { SetRegularState(app, window_id, hmi_level, audio_state, video_state, false); - // After main window activation, streaming state should be updated for another - // windows of the app + // After main window activation, streaming state should be updated for + // another windows of the app HmiStatePtr new_state = app->RegularHmiState(PredefinedWindows::DEFAULT_WINDOW); UpdateAppWindowsStreamingState(app, new_state); @@ -873,11 +918,24 @@ void StateControllerImpl::OnStateChanged(ApplicationSharedPtr app, return; } - auto notification = - MessageHelper::CreateHMIStatusNotification(app, window_id); - app_mngr_.GetRPCService().ManageMobileCommand(notification, - commands::Command::SOURCE_SDL); - + if (app->is_ready()) { + SDL_LOG_DEBUG("Sending OnHMIStatus to application " << app->app_id()); + auto notification = + MessageHelper::CreateHMIStatusNotification(app, window_id); + app_mngr_.GetRPCService().ManageMobileCommand( + notification, commands::Command::SOURCE_SDL); + } else { + SDL_LOG_DEBUG( + "Application " + << app->app_id() + << " not ready to receive OnHMIStatus. Delaying notification"); + { + sync_primitives::AutoLock autolock( + apps_with_pending_hmistatus_notification_lock_); + apps_with_pending_hmistatus_notification_.insert(app->app_id()); + } + subscribe_on_event(mobile_apis::FunctionID::RegisterAppInterfaceID); + } if (mobile_apis::PredefinedWindows::DEFAULT_WINDOW != window_id) { SDL_LOG_DEBUG( "State was changed not for a main application window. No " @@ -943,6 +1001,11 @@ void StateControllerImpl::OnApplicationRegistered( const mobile_apis::HMILevel::eType default_level) { SDL_LOG_AUTO_TRACE(); + if (app->is_cloud_app()) { + // Return here, there should already be an onHMIStatus=FULL being processed + // for when the cloud app was initially activated by the hmi + return; + } // After app registration HMI level should be set for DEFAULT_WINDOW only OnAppWindowAdded(app, mobile_apis::PredefinedWindows::DEFAULT_WINDOW, @@ -1220,8 +1283,8 @@ void StateControllerImpl::OnAppDeactivated( return; } - // TODO(AOleynik): Need to delete DeactivateReason and modify OnAppDeactivated - // when HMI will support that, otherwise won't be testable + // TODO(AOleynik): Need to delete DeactivateReason and modify + // OnAppDeactivated when HMI will support that, otherwise won't be testable DeactivateApp(app, window_id); } diff --git a/src/components/application_manager/test/application_manager_impl_test.cc b/src/components/application_manager/test/application_manager_impl_test.cc index 7ecf9515a6..493d4a18fc 100644 --- a/src/components/application_manager/test/application_manager_impl_test.cc +++ b/src/components/application_manager/test/application_manager_impl_test.cc @@ -2099,6 +2099,7 @@ TEST_F( app_manager_impl_->SetPluginManager(rpc_plugin_manager); auto wep_nonmedia_app = app_manager_impl_->RegisterApplication(rai_ptr); wep_nonmedia_app->set_is_media_application(false); + wep_nonmedia_app->set_is_ready(true); EXPECT_EQ(protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_2, wep_nonmedia_app->protocol_version()); @@ -2203,6 +2204,7 @@ TEST_F( app_manager_impl_->SetPluginManager(rpc_plugin_manager); auto wep_media_app = app_manager_impl_->RegisterApplication(rai_ptr); wep_media_app->set_is_media_application(true); + wep_media_app->set_is_ready(true); EXPECT_EQ(protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_2, wep_media_app->protocol_version()); diff --git a/src/components/application_manager/test/include/application_manager/mock_application.h b/src/components/application_manager/test/include/application_manager/mock_application.h index 2aab8cf727..3c1ddca125 100644 --- a/src/components/application_manager/test/include/application_manager/mock_application.h +++ b/src/components/application_manager/test/include/application_manager/mock_application.h @@ -97,6 +97,8 @@ class MockApplication : public ::application_manager::Application { MOCK_CONST_METHOD0(app_allowed, bool()); MOCK_CONST_METHOD0(has_been_activated, bool()); MOCK_METHOD1(set_activated, bool(bool is_active)); + MOCK_CONST_METHOD0(is_ready, bool()); + MOCK_METHOD1(set_is_ready, bool(bool is_active)); MOCK_CONST_METHOD0(version, const ::application_manager::Version&()); MOCK_METHOD1(set_hmi_application_id, void(uint32_t hmi_app_id)); MOCK_CONST_METHOD0(hmi_app_id, uint32_t()); diff --git a/src/components/application_manager/test/state_controller/state_controller_test.cc b/src/components/application_manager/test/state_controller/state_controller_test.cc index a2de6f399c..374ad611ef 100644 --- a/src/components/application_manager/test/state_controller/state_controller_test.cc +++ b/src/components/application_manager/test/state_controller/state_controller_test.cc @@ -727,6 +727,7 @@ class StateControllerImplTest : public ::testing::Test { .WillByDefault(Return(vc)); ON_CALL(**app_mock, IsAudioApplication()) .WillByDefault(Return(media || navi || vc)); + ON_CALL(**app_mock, is_ready()).WillByDefault(Return(true)); EXPECT_CALL(**app_mock, usage_report()) .WillRepeatedly(ReturnRef(usage_stat)); |