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 b3b396026cc..b8495250f61 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 @@ -370,6 +370,9 @@ class ApplicationManagerImpl ApplicationSharedPtr RegisterApplication( const std::shared_ptr& request_for_registration) OVERRIDE; + + void FinalizeAppRegistration(ApplicationSharedPtr application, + const uint32_t connection_key) OVERRIDE; /* * @brief Closes application by id * diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_request.cc index 72faad86684..43814f4de65 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_request.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_request.cc @@ -742,6 +742,16 @@ void RegisterAppInterfaceRequest::Run() { SetupAppDeviceInfo(application); auto status_notifier = AddApplicationDataToPolicy(application); + auto on_app_registered = [application](plugin_manager::RPCPlugin& plugin) { + plugin.OnApplicationEvent(plugin_manager::kApplicationRegistered, + application); + }; + // To prevent timing issues, this event is called before an app is accessible + // by the applications accessor. This prevents incoming hmi rpcs from + // attempting to access an app before it has been fully initialized. + application_manager_.ApplyFunctorForEachPlugin(on_app_registered); + application_manager_.FinalizeAppRegistration(application, connection_key()); + std::string add_info; const auto is_resumption_required = ApplicationDataShouldBeResumed(add_info); @@ -762,12 +772,6 @@ void RegisterAppInterfaceRequest::Run() { SendSubscribeCustomButtonNotification(); SendChangeRegistrationOnHMI(application); - auto on_app_registered = [application](plugin_manager::RPCPlugin& plugin) { - plugin.OnApplicationEvent(plugin_manager::kApplicationRegistered, - application); - }; - application_manager_.ApplyFunctorForEachPlugin(on_app_registered); - if (is_resumption_required) { const auto& msg_params = (*message_)[strings::msg_params]; const auto& hash_id = msg_params[strings::hash_id].asString(); diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc index 90855fa9eeb..b105d607db1 100644 --- a/src/components/application_manager/src/application_manager_impl.cc +++ b/src/components/application_manager/src/application_manager_impl.cc @@ -755,6 +755,11 @@ ApplicationSharedPtr ApplicationManagerImpl::RegisterApplication( // Timer will be started after hmi level resumption. resume_controller().OnAppRegistrationStart(policy_app_id, device_mac); + return application; +} + +void ApplicationManagerImpl::FinalizeAppRegistration( + ApplicationSharedPtr application, const uint32_t connection_key) { AddAppToRegisteredAppList(application); // Update cloud app information, in case any pending apps are unable to be @@ -772,8 +777,6 @@ ApplicationSharedPtr ApplicationManagerImpl::RegisterApplication( connection_handler::DeviceHandle secondary_device_handle = itr->second; application->set_secondary_device(secondary_device_handle); } - - return application; } bool ApplicationManagerImpl::ActivateApplication(ApplicationSharedPtr app) { diff --git a/src/components/include/application_manager/application_manager.h b/src/components/include/application_manager/application_manager.h index 72dfb71a299..5e13e5b7ab3 100644 --- a/src/components/include/application_manager/application_manager.h +++ b/src/components/include/application_manager/application_manager.h @@ -554,9 +554,24 @@ class ApplicationManager { */ virtual void IviInfoUpdated(const std::string& vehicle_info, int value) = 0; + /** + * @brief Creates the application object for a newly registered application. + * This method performs initialiation of the app object by setting properties + * and starting the resumption process if applicable. + * @param request_for_registration Smart Object RegisterAppInterfaceRequest + * message received from mobile. + */ virtual ApplicationSharedPtr RegisterApplication( const std::shared_ptr& request_for_registration) = 0; + /** + * @brief Completes initialization process by adding the app to the + * applications accessor. App is now accessible by all other Core components. + * @param application ApplicationSharedPtr for newly registered application. + * @param connection_key Internal application id of registering application. + */ + virtual void FinalizeAppRegistration(ApplicationSharedPtr application, + const uint32_t connection_key) = 0; virtual void SendUpdateAppList() = 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 862c862a20b..93543e750f3 100644 --- a/src/components/include/test/application_manager/mock_application_manager.h +++ b/src/components/include/test/application_manager/mock_application_manager.h @@ -220,6 +220,9 @@ class MockApplicationManager : public application_manager::ApplicationManager { application_manager::ApplicationSharedPtr( const std::shared_ptr& request_for_registration)); + MOCK_METHOD2(FinalizeAppRegistration, + void(application_manager::ApplicationSharedPtr, + const uint32_t connection_key)); MOCK_METHOD0(SendUpdateAppList, void()); MOCK_METHOD2(MarkAppsGreyOut, void(const connection_handler::DeviceHandle handle,