Commit ef97c140 authored by Jeroen Dhollander's avatar Jeroen Dhollander Committed by Chromium LUCI CQ

Simplify Libassistant startup (and fix crashes)

Currently starting Libassistant happens in 2 steps:
   1. (On background thread) ServiceController::Start() creates the
      |AssistantManager|.
   2. (On main thread) ServiceControllerProxy::FinishAssistantStart()
      sets some extra fields on |AssistantManager| and calls
      AssistantManager::Start().

This causes a race condition if Libassistant is immediately stopped,
as that happens on the background thread and can collide with step 2
above.

To prevent this from happening, this CL collapses both starting steps in
a single step that runs on the background thread. We do this by
registering a callback which is called by the background thread in step
1 above.

This callback is temporary but necessary as some parts of the
initialization code still use objects that have not been migrated to the
Libassistant mojom service yet.

Bug: 1157177, b/171748795, 1128032
Test: chromeos_unittests "Assistant*:ServiceController*"
Change-Id: Ifab9705839ad5d3e5c9f2b7f7fba4c336b9f7c9d
Cq-Include-Trybots: luci.chrome.try:linux-chromeos-chrome
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2594090
Commit-Queue: Jeroen Dhollander <jeroendh@chromium.org>
Reviewed-by: default avatarXiaohui Chen <xiaohuic@chromium.org>
Cr-Commit-Position: refs/heads/master@{#838277}
parent 35ac37ab
...@@ -124,7 +124,6 @@ component("lib") { ...@@ -124,7 +124,6 @@ component("lib") {
"//chromeos/resources", "//chromeos/resources",
"//chromeos/services/assistant/proxy", "//chromeos/services/assistant/proxy",
"//chromeos/services/assistant/public/cpp/migration", "//chromeos/services/assistant/public/cpp/migration",
"//chromeos/services/assistant/public/cpp/migration",
"//chromeos/services/libassistant", "//chromeos/services/libassistant",
"//chromeos/services/network_config/public/mojom", "//chromeos/services/network_config/public/mojom",
"//chromeos/strings", "//chromeos/strings",
...@@ -235,6 +234,10 @@ static_library("test_support") { ...@@ -235,6 +234,10 @@ static_library("test_support") {
"//testing/gmock", "//testing/gmock",
"//testing/gtest", "//testing/gtest",
] ]
if (enable_cros_libassistant) {
deps += [ "//chromeos/services/assistant/public/cpp/migration" ]
}
} }
buildflag_header("buildflags") { buildflag_header("buildflags") {
......
...@@ -196,6 +196,13 @@ class FakeLibassistantServiceHost : public LibassistantServiceHost { ...@@ -196,6 +196,13 @@ class FakeLibassistantServiceHost : public LibassistantServiceHost {
} }
void Stop() override { service_->Unbind(); } void Stop() override { service_->Unbind(); }
void SetInitializeCallback(
base::OnceCallback<void(assistant_client::AssistantManager*,
assistant_client::AssistantManagerInternal*)>
callback) override {
service_->service_controller().SetInitializeCallback(std::move(callback));
}
private: private:
FakeLibassistantService* service_; FakeLibassistantService* service_;
}; };
......
...@@ -32,5 +32,13 @@ void LibassistantServiceHostImpl::Stop() { ...@@ -32,5 +32,13 @@ void LibassistantServiceHostImpl::Stop() {
libassistant_service_ = nullptr; libassistant_service_ = nullptr;
} }
void LibassistantServiceHostImpl::SetInitializeCallback(
base::OnceCallback<void(assistant_client::AssistantManager*,
assistant_client::AssistantManagerInternal*)>
callback) {
DCHECK_NE(libassistant_service_, nullptr);
libassistant_service_->SetInitializeCallback(std::move(callback));
}
} // namespace assistant } // namespace assistant
} // namespace chromeos } // namespace chromeos
...@@ -13,6 +13,12 @@ namespace assistant_client { ...@@ -13,6 +13,12 @@ namespace assistant_client {
class PlatformApi; class PlatformApi;
} // namespace assistant_client } // namespace assistant_client
namespace chromeos {
namespace libassistant {
class LibassistantService;
} // namespace libassistant
} // namespace chromeos
namespace chromeos { namespace chromeos {
namespace assistant { namespace assistant {
...@@ -30,6 +36,10 @@ class LibassistantServiceHostImpl : public LibassistantServiceHost { ...@@ -30,6 +36,10 @@ class LibassistantServiceHostImpl : public LibassistantServiceHost {
void Launch( void Launch(
mojo::PendingReceiver<LibassistantServiceMojom> receiver) override; mojo::PendingReceiver<LibassistantServiceMojom> receiver) override;
void Stop() override; void Stop() override;
void SetInitializeCallback(
base::OnceCallback<void(assistant_client::AssistantManager*,
assistant_client::AssistantManagerInternal*)>)
override;
private: private:
// Owned by |AssistantManagerServiceImpl| which also owns |this|. // Owned by |AssistantManagerServiceImpl| which also owns |this|.
...@@ -37,7 +47,8 @@ class LibassistantServiceHostImpl : public LibassistantServiceHost { ...@@ -37,7 +47,8 @@ class LibassistantServiceHostImpl : public LibassistantServiceHost {
// Owned by |AssistantManagerServiceImpl| which also owns |this|. // Owned by |AssistantManagerServiceImpl| which also owns |this|.
AssistantManagerServiceDelegate* const delegate_; AssistantManagerServiceDelegate* const delegate_;
std::unique_ptr<LibassistantServiceMojom> libassistant_service_; std::unique_ptr<chromeos::libassistant::LibassistantService>
libassistant_service_;
}; };
} // namespace assistant } // namespace assistant
......
...@@ -28,8 +28,8 @@ void AssistantProxy::Initialize(LibassistantServiceHost* host) { ...@@ -28,8 +28,8 @@ void AssistantProxy::Initialize(LibassistantServiceHost* host) {
libassistant_service_host_ = host; libassistant_service_host_ = host;
LaunchLibassistantService(); LaunchLibassistantService();
service_controller_proxy_ = std::make_unique<ServiceControllerProxy>( service_controller_proxy_ =
background_task_runner(), BindServiceController()); std::make_unique<ServiceControllerProxy>(host, BindServiceController());
} }
void AssistantProxy::LaunchLibassistantService() { void AssistantProxy::LaunchLibassistantService() {
......
...@@ -9,6 +9,11 @@ ...@@ -9,6 +9,11 @@
#include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_receiver.h"
namespace assistant_client {
class AssistantManager;
class AssistantManagerInternal;
} // namespace assistant_client
namespace chromeos { namespace chromeos {
namespace libassistant { namespace libassistant {
namespace mojom { namespace mojom {
...@@ -36,9 +41,18 @@ class LibassistantServiceHost { ...@@ -36,9 +41,18 @@ class LibassistantServiceHost {
// |Stop| is called. // |Stop| is called.
virtual void Launch( virtual void Launch(
mojo::PendingReceiver<LibassistantServiceMojom> receiver) = 0; mojo::PendingReceiver<LibassistantServiceMojom> receiver) = 0;
// Stop the mojom service.
// Stop the mojom service.
virtual void Stop() = 0; virtual void Stop() = 0;
// Set a callback to initialize |AssistantManager| and
// |AssistantManagerInternal|. This callback will be invoked before
// AssistantManager::Start() is called. This is temporary until we've migrated
// all initialization code to the mojom service.
virtual void SetInitializeCallback(
base::OnceCallback<
void(assistant_client::AssistantManager*,
assistant_client::AssistantManagerInternal*)>) = 0;
}; };
} // namespace assistant } // namespace assistant
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "chromeos/assistant/internal/cros_display_connection.h" #include "chromeos/assistant/internal/cros_display_connection.h"
#include "chromeos/assistant/internal/internal_util.h" #include "chromeos/assistant/internal/internal_util.h"
#include "chromeos/constants/chromeos_features.h" #include "chromeos/constants/chromeos_features.h"
#include "chromeos/services/assistant/proxy/libassistant_service_host.h"
#include "chromeos/services/assistant/public/cpp/features.h" #include "chromeos/services/assistant/public/cpp/features.h"
#include "chromeos/services/assistant/public/cpp/migration/assistant_manager_service_delegate.h" #include "chromeos/services/assistant/public/cpp/migration/assistant_manager_service_delegate.h"
#include "chromeos/services/assistant/public/cpp/migration/libassistant_v1_api.h" #include "chromeos/services/assistant/public/cpp/migration/libassistant_v1_api.h"
...@@ -36,6 +37,25 @@ constexpr char kServersideDogfoodExperimentId[] = "20347368"; ...@@ -36,6 +37,25 @@ constexpr char kServersideDogfoodExperimentId[] = "20347368";
constexpr char kServersideOpenAppExperimentId[] = "39651593"; constexpr char kServersideOpenAppExperimentId[] = "39651593";
constexpr char kServersideResponseProcessingV2ExperimentId[] = "1793869"; constexpr char kServersideResponseProcessingV2ExperimentId[] = "1793869";
struct StartArguments {
StartArguments() = default;
StartArguments(StartArguments&&) = default;
StartArguments& operator=(StartArguments&&) = default;
~StartArguments() = default;
assistant_client::ActionModule* action_module;
assistant_client::FuchsiaApiDelegate* fuchsia_api_delegate;
assistant_client::AssistantManagerDelegate* assistant_manager_delegate;
assistant_client::ConversationStateListener* conversation_state_listener;
assistant_client::DeviceStateListener* device_state_listener;
CrosDisplayConnection* display_connection;
std::string libassistant_config;
std::string locale;
std::string locale_override;
bool spoken_feedback_enabled;
ServiceControllerProxy::AuthTokens auth_tokens;
};
void FillServerExperimentIds(std::vector<std::string>* server_experiment_ids) { void FillServerExperimentIds(std::vector<std::string>* server_experiment_ids) {
if (base::FeatureList::IsEnabled(kChromeOSAssistantDogfood)) { if (base::FeatureList::IsEnabled(kChromeOSAssistantDogfood)) {
server_experiment_ids->emplace_back(kServersideDogfoodExperimentId); server_experiment_ids->emplace_back(kServersideDogfoodExperimentId);
...@@ -58,17 +78,59 @@ void SetServerExperiments( ...@@ -58,17 +78,59 @@ void SetServerExperiments(
} }
} }
void SetInternalOptions(
assistant_client::AssistantManagerInternal* assistant_manager_internal,
const std::string& locale,
bool spoken_feedback_enabled) {
auto* internal_options =
assistant_manager_internal->CreateDefaultInternalOptions();
SetAssistantOptions(internal_options, locale, spoken_feedback_enabled);
internal_options->SetClientControlEnabled(
assistant::features::IsRoutinesEnabled());
if (!features::IsVoiceMatchDisabled())
internal_options->EnableRequireVoiceMatchVerification();
assistant_manager_internal->SetOptions(*internal_options, [](bool success) {
DVLOG(2) << "set options: " << success;
});
}
// TODO(b/171748795): This should all be migrated to the mojom service, which
// should be responsible for the complete creation of the Libassistant
// objects.
// Note: this method will be called from the mojom (background) thread.
void InitializeAssistantManager(
StartArguments arguments,
assistant_client::AssistantManager* assistant_manager,
assistant_client::AssistantManagerInternal* assistant_manager_internal) {
SetInternalOptions(assistant_manager_internal, arguments.locale,
arguments.spoken_feedback_enabled);
assistant_manager_internal->SetDisplayConnection(
arguments.display_connection);
assistant_manager_internal->SetLocaleOverride(arguments.locale_override);
assistant_manager_internal->RegisterActionModule(arguments.action_module);
assistant_manager_internal->SetAssistantManagerDelegate(
arguments.assistant_manager_delegate);
assistant_manager_internal->GetFuchsiaApiHelperOrDie()->SetFuchsiaApiDelegate(
arguments.fuchsia_api_delegate);
assistant_manager->AddConversationStateListener(
arguments.conversation_state_listener);
assistant_manager->AddDeviceStateListener(arguments.device_state_listener);
SetServerExperiments(assistant_manager_internal);
assistant_manager->SetAuthTokens(arguments.auth_tokens);
}
} // namespace } // namespace
ServiceControllerProxy::ServiceControllerProxy( ServiceControllerProxy::ServiceControllerProxy(
scoped_refptr<base::SingleThreadTaskRunner> background_task_runner, LibassistantServiceHost* host,
mojo::PendingRemote<chromeos::libassistant::mojom::ServiceController> mojo::PendingRemote<chromeos::libassistant::mojom::ServiceController>
client) client)
: background_task_runner_(std::move(background_task_runner)), : host_(host),
service_controller_remote_(std::move(client)), service_controller_remote_(std::move(client)),
state_observer_receiver_(this) { state_observer_receiver_(this) {
DCHECK(background_task_runner_);
service_controller_remote_->AddAndFireStateObserver( service_controller_remote_->AddAndFireStateObserver(
state_observer_receiver_.BindNewPipeAndPassRemote()); state_observer_receiver_.BindNewPipeAndPassRemote());
} }
...@@ -92,24 +154,31 @@ void ServiceControllerProxy::Start( ...@@ -92,24 +154,31 @@ void ServiceControllerProxy::Start(
DCHECK_EQ(state_, State::kStopped); DCHECK_EQ(state_, State::kStopped);
state_ = State::kStarting; state_ = State::kStarting;
pending_display_connection_ = std::make_unique<CrosDisplayConnection>(
event_observer, /*feedback_ui_enabled=*/true,
assistant::features::IsMediaSessionIntegrationEnabled());
// The mojom service will create the |AssistantManager|. // The mojom service will create the |AssistantManager|.
service_controller_remote_->Start(libassistant_config); service_controller_remote_->Start(libassistant_config);
// We need to finalize (and start) the |AssistantManager| once it's created, // We need to initialize the |AssistantManager| once it's created and before
// so we have to store all the required arguments for that. // it's started, so we register a callback to do just that.
StartArguments arguments; StartArguments arguments;
arguments.action_module = action_module; arguments.action_module = action_module;
arguments.fuchsia_api_delegate = fuchsia_api_delegate; arguments.fuchsia_api_delegate = fuchsia_api_delegate;
arguments.assistant_manager_delegate = assistant_manager_delegate; arguments.assistant_manager_delegate = assistant_manager_delegate;
arguments.conversation_state_listener = conversation_state_listener; arguments.conversation_state_listener = conversation_state_listener;
arguments.device_state_listener = device_state_listener; arguments.device_state_listener = device_state_listener;
arguments.event_observer = event_observer; arguments.display_connection = pending_display_connection_.get();
arguments.locale = locale; arguments.locale = locale;
arguments.locale_override = locale_override; arguments.locale_override = locale_override;
arguments.spoken_feedback_enabled = spoken_feedback_enabled; arguments.spoken_feedback_enabled = spoken_feedback_enabled;
arguments.auth_tokens = auth_tokens; arguments.auth_tokens = auth_tokens;
arguments.done_callback = std::move(done_callback);
pending_start_argument_ = std::move(arguments); host_->SetInitializeCallback(
base::BindOnce(InitializeAssistantManager, std::move(arguments)));
on_start_done_callback_ = std::move(done_callback);
} }
void ServiceControllerProxy::Stop() { void ServiceControllerProxy::Stop() {
...@@ -126,21 +195,8 @@ void ServiceControllerProxy::Stop() { ...@@ -126,21 +195,8 @@ void ServiceControllerProxy::Stop() {
void ServiceControllerProxy::UpdateInternalOptions( void ServiceControllerProxy::UpdateInternalOptions(
const std::string& locale, const std::string& locale,
bool spoken_feedback_enabled) { bool spoken_feedback_enabled) {
// NOTE: this method is called on multiple threads, it needs to be SetInternalOptions(assistant_manager_internal(), locale,
// thread-safe. spoken_feedback_enabled);
auto* internal_options =
assistant_manager_internal()->CreateDefaultInternalOptions();
SetAssistantOptions(internal_options, locale, spoken_feedback_enabled);
internal_options->SetClientControlEnabled(
assistant::features::IsRoutinesEnabled());
if (!features::IsVoiceMatchDisabled())
internal_options->EnableRequireVoiceMatchVerification();
assistant_manager_internal()->SetOptions(*internal_options, [](bool success) {
DVLOG(2) << "set options: " << success;
});
} }
void ServiceControllerProxy::SetAuthTokens(const AuthTokens& tokens) { void ServiceControllerProxy::SetAuthTokens(const AuthTokens& tokens) {
...@@ -181,45 +237,13 @@ ServiceControllerProxy::assistant_manager_internal() { ...@@ -181,45 +237,13 @@ ServiceControllerProxy::assistant_manager_internal() {
} }
void ServiceControllerProxy::FinishCreatingAssistant() { void ServiceControllerProxy::FinishCreatingAssistant() {
// TODO(b/171748795): This should all be migrated to the mojom service, which DCHECK(on_start_done_callback_.has_value());
// should be responsible for the complete creation of the Libassistant DCHECK_NE(pending_display_connection_, nullptr);
// objects.
DCHECK(pending_start_argument_.has_value());
auto arguments = std::move(pending_start_argument_.value());
display_connection_ = std::make_unique<CrosDisplayConnection>(
arguments.event_observer, /*feedback_ui_enabled=*/true,
assistant::features::IsMediaSessionIntegrationEnabled());
UpdateInternalOptions(arguments.locale, arguments.spoken_feedback_enabled);
assistant_manager_internal()->SetDisplayConnection(display_connection());
assistant_manager_internal()->SetLocaleOverride(arguments.locale_override);
assistant_manager_internal()->RegisterActionModule(arguments.action_module);
assistant_manager_internal()->SetAssistantManagerDelegate(
arguments.assistant_manager_delegate);
assistant_manager_internal()
->GetFuchsiaApiHelperOrDie()
->SetFuchsiaApiDelegate(arguments.fuchsia_api_delegate);
assistant_manager()->AddConversationStateListener(
arguments.conversation_state_listener);
assistant_manager()->AddDeviceStateListener(arguments.device_state_listener);
SetServerExperiments(assistant_manager_internal());
SetAuthTokens(arguments.auth_tokens);
assistant_manager()->Start();
state_ = State::kStarted; state_ = State::kStarted;
std::move(arguments.done_callback).Run(); display_connection_ = std::move(pending_display_connection_);
std::move(on_start_done_callback_.value()).Run();
} }
ServiceControllerProxy::StartArguments::StartArguments() = default;
ServiceControllerProxy::StartArguments::StartArguments(StartArguments&&) =
default;
ServiceControllerProxy::StartArguments&
ServiceControllerProxy::StartArguments::operator=(StartArguments&&) = default;
ServiceControllerProxy::StartArguments::~StartArguments() = default;
} // namespace assistant } // namespace assistant
} // namespace chromeos } // namespace chromeos
...@@ -11,9 +11,7 @@ ...@@ -11,9 +11,7 @@
#include <vector> #include <vector>
#include "base/check.h" #include "base/check.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "chromeos/services/libassistant/public/mojom/service_controller.mojom.h" #include "chromeos/services/libassistant/public/mojom/service_controller.mojom.h"
#include "mojo/public/cpp/bindings/remote.h" #include "mojo/public/cpp/bindings/remote.h"
...@@ -34,6 +32,7 @@ namespace assistant { ...@@ -34,6 +32,7 @@ namespace assistant {
class AssistantEventObserver; class AssistantEventObserver;
class CrosDisplayConnection; class CrosDisplayConnection;
class LibassistantServiceHost;
// Component managing the lifecycle of Libassistant, // Component managing the lifecycle of Libassistant,
// exposing methods to start/stop and configure Libassistant. // exposing methods to start/stop and configure Libassistant.
...@@ -43,7 +42,7 @@ class ServiceControllerProxy : private libassistant::mojom::StateObserver { ...@@ -43,7 +42,7 @@ class ServiceControllerProxy : private libassistant::mojom::StateObserver {
using AuthTokens = std::vector<std::pair<std::string, std::string>>; using AuthTokens = std::vector<std::pair<std::string, std::string>>;
ServiceControllerProxy( ServiceControllerProxy(
scoped_refptr<base::SingleThreadTaskRunner> background_task_runner, LibassistantServiceHost* host,
mojo::PendingRemote<chromeos::libassistant::mojom::ServiceController> mojo::PendingRemote<chromeos::libassistant::mojom::ServiceController>
client); client);
...@@ -52,8 +51,6 @@ class ServiceControllerProxy : private libassistant::mojom::StateObserver { ...@@ -52,8 +51,6 @@ class ServiceControllerProxy : private libassistant::mojom::StateObserver {
~ServiceControllerProxy() override; ~ServiceControllerProxy() override;
// Can not be invoked before Start() has finished. // Can not be invoked before Start() has finished.
// Both LibAssistant and Chrome threads may access |display_connection|.
// |display_connection| is thread safe.
CrosDisplayConnection* display_connection() { CrosDisplayConnection* display_connection() {
DCHECK(display_connection_); DCHECK(display_connection_);
return display_connection_.get(); return display_connection_.get();
...@@ -112,25 +109,6 @@ class ServiceControllerProxy : private libassistant::mojom::StateObserver { ...@@ -112,25 +109,6 @@ class ServiceControllerProxy : private libassistant::mojom::StateObserver {
// Can not be invoked before Start() has finished. // Can not be invoked before Start() has finished.
assistant_client::AssistantManagerInternal* assistant_manager_internal(); assistant_client::AssistantManagerInternal* assistant_manager_internal();
struct StartArguments {
StartArguments();
StartArguments(StartArguments&&);
StartArguments& operator=(StartArguments&&);
~StartArguments();
assistant_client::ActionModule* action_module;
assistant_client::FuchsiaApiDelegate* fuchsia_api_delegate;
assistant_client::AssistantManagerDelegate* assistant_manager_delegate;
assistant_client::ConversationStateListener* conversation_state_listener;
assistant_client::DeviceStateListener* device_state_listener;
AssistantEventObserver* event_observer;
std::string libassistant_config;
std::string locale;
std::string locale_override;
bool spoken_feedback_enabled;
AuthTokens auth_tokens;
base::OnceClosure done_callback;
};
void FinishCreatingAssistant(); void FinishCreatingAssistant();
// libassistant::mojom::StateObserver implementation: // libassistant::mojom::StateObserver implementation:
...@@ -141,20 +119,22 @@ class ServiceControllerProxy : private libassistant::mojom::StateObserver { ...@@ -141,20 +119,22 @@ class ServiceControllerProxy : private libassistant::mojom::StateObserver {
// Used internally for consistency checks. // Used internally for consistency checks.
State state_ = State::kStopped; State state_ = State::kStopped;
scoped_refptr<base::SingleThreadTaskRunner> background_task_runner_; // Owned by |AssistantManagerServiceImpl| which (indirectly) also owns us.
LibassistantServiceHost* const host_;
mojo::Remote<chromeos::libassistant::mojom::ServiceController> mojo::Remote<chromeos::libassistant::mojom::ServiceController>
service_controller_remote_; service_controller_remote_;
mojo::Receiver<chromeos::libassistant::mojom::StateObserver> mojo::Receiver<chromeos::libassistant::mojom::StateObserver>
state_observer_receiver_; state_observer_receiver_;
// Arguments passed to the last Start() call. // Callback passed to Start(). Will be invoked once the Libassistant service
// Used to finish starting Libassistant after the Libassistant mojom service // has started.
// signals it has created the required objects. base::Optional<base::OnceClosure> on_start_done_callback_;
// Unset once we've finished starting.
base::Optional<StartArguments> pending_start_argument_;
std::unique_ptr<CrosDisplayConnection> display_connection_; std::unique_ptr<CrosDisplayConnection> display_connection_;
// Populated when we're starting but not started yet, so after Start() has
// been called but before the mojom service signalled it has started.
std::unique_ptr<CrosDisplayConnection> pending_display_connection_;
base::WeakPtrFactory<ServiceControllerProxy> weak_factory_{this}; base::WeakPtrFactory<ServiceControllerProxy> weak_factory_{this};
}; };
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "chromeos/services/assistant/test_support/fake_service_controller.h" #include "chromeos/services/assistant/test_support/fake_service_controller.h"
#include "chromeos/services/assistant/public/cpp/migration/libassistant_v1_api.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
namespace chromeos { namespace chromeos {
...@@ -35,6 +36,10 @@ void FakeServiceController::Unbind() { ...@@ -35,6 +36,10 @@ void FakeServiceController::Unbind() {
state_observers_.Clear(); state_observers_.Clear();
} }
void FakeServiceController::SetInitializeCallback(InitializeCallback callback) {
initialize_callback_ = std::move(callback);
}
void FakeServiceController::BlockStartCalls() { void FakeServiceController::BlockStartCalls() {
// This lock will be release in |UnblockStartCalls|. // This lock will be release in |UnblockStartCalls|.
start_mutex_.lock(); start_mutex_.lock();
...@@ -50,6 +55,12 @@ void FakeServiceController::Start(const std::string& libassistant_config) { ...@@ -50,6 +55,12 @@ void FakeServiceController::Start(const std::string& libassistant_config) {
// Will block if |BlockStartCalls| was invoked. // Will block if |BlockStartCalls| was invoked.
std::lock_guard<std::mutex> lock(start_mutex_); std::lock_guard<std::mutex> lock(start_mutex_);
if (initialize_callback_) {
std::move(initialize_callback_)
.Run(LibassistantV1Api::Get()->assistant_manager(),
LibassistantV1Api::Get()->assistant_manager_internal());
}
SetState(State::kStarted); SetState(State::kStarted);
} }
......
...@@ -12,6 +12,11 @@ ...@@ -12,6 +12,11 @@
#include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote_set.h" #include "mojo/public/cpp/bindings/remote_set.h"
namespace assistant_client {
class AssistantManager;
class AssistantManagerInternal;
} // namespace assistant_client
namespace chromeos { namespace chromeos {
namespace assistant { namespace assistant {
...@@ -21,6 +26,9 @@ namespace assistant { ...@@ -21,6 +26,9 @@ namespace assistant {
class FakeServiceController : public libassistant::mojom::ServiceController { class FakeServiceController : public libassistant::mojom::ServiceController {
public: public:
using State = libassistant::mojom::ServiceState; using State = libassistant::mojom::ServiceState;
using InitializeCallback =
base::OnceCallback<void(assistant_client::AssistantManager*,
assistant_client::AssistantManagerInternal*)>;
FakeServiceController(); FakeServiceController();
FakeServiceController(FakeServiceController&) = delete; FakeServiceController(FakeServiceController&) = delete;
...@@ -39,6 +47,8 @@ class FakeServiceController : public libassistant::mojom::ServiceController { ...@@ -39,6 +47,8 @@ class FakeServiceController : public libassistant::mojom::ServiceController {
pending_receiver); pending_receiver);
void Unbind(); void Unbind();
void SetInitializeCallback(InitializeCallback callback);
// Call this to block any call to |Start|. The observers will not be invoked // Call this to block any call to |Start|. The observers will not be invoked
// as long as the start call is blocked. Unblock these calls using // as long as the start call is blocked. Unblock these calls using
// |UnblockStartCalls|. This is not enabled by default, so unless you call // |UnblockStartCalls|. This is not enabled by default, so unless you call
...@@ -61,6 +71,8 @@ class FakeServiceController : public libassistant::mojom::ServiceController { ...@@ -61,6 +71,8 @@ class FakeServiceController : public libassistant::mojom::ServiceController {
// Config passed to LibAssistant when it was started. // Config passed to LibAssistant when it was started.
std::string libassistant_config_; std::string libassistant_config_;
InitializeCallback initialize_callback_;
State state_ = State::kStopped; State state_ = State::kStopped;
mojo::Receiver<libassistant::mojom::ServiceController> receiver_; mojo::Receiver<libassistant::mojom::ServiceController> receiver_;
mojo::RemoteSet<libassistant::mojom::StateObserver> state_observers_; mojo::RemoteSet<libassistant::mojom::StateObserver> state_observers_;
......
...@@ -29,5 +29,9 @@ void LibassistantService::BindServiceController( ...@@ -29,5 +29,9 @@ void LibassistantService::BindServiceController(
service_controller_->Bind(std::move(receiver)); service_controller_->Bind(std::move(receiver));
} }
void LibassistantService::SetInitializeCallback(InitializeCallback callback) {
service_controller().SetInitializeCallback(std::move(callback));
}
} // namespace libassistant } // namespace libassistant
} // namespace chromeos } // namespace chromeos
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
#include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/receiver.h"
namespace assistant_client { namespace assistant_client {
class AssistantManager;
class AssistantManagerInternal;
class PlatformApi; class PlatformApi;
} // namespace assistant_client } // namespace assistant_client
...@@ -29,6 +31,10 @@ class ServiceController; ...@@ -29,6 +31,10 @@ class ServiceController;
class COMPONENT_EXPORT(LIBASSISTANT_SERVICE) LibassistantService class COMPONENT_EXPORT(LIBASSISTANT_SERVICE) LibassistantService
: public mojom::LibassistantService { : public mojom::LibassistantService {
public: public:
using InitializeCallback =
base::OnceCallback<void(assistant_client::AssistantManager*,
assistant_client::AssistantManagerInternal*)>;
explicit LibassistantService( explicit LibassistantService(
mojo::PendingReceiver<mojom::LibassistantService> receiver, mojo::PendingReceiver<mojom::LibassistantService> receiver,
assistant_client::PlatformApi* platform_api, assistant_client::PlatformApi* platform_api,
...@@ -37,7 +43,11 @@ class COMPONENT_EXPORT(LIBASSISTANT_SERVICE) LibassistantService ...@@ -37,7 +43,11 @@ class COMPONENT_EXPORT(LIBASSISTANT_SERVICE) LibassistantService
LibassistantService& operator=(LibassistantService&) = delete; LibassistantService& operator=(LibassistantService&) = delete;
~LibassistantService() override; ~LibassistantService() override;
void SetInitializeCallback(InitializeCallback callback);
private: private:
ServiceController& service_controller() { return *service_controller_; }
// mojom::LibassistantService implementation: // mojom::LibassistantService implementation:
void BindServiceController( void BindServiceController(
mojo::PendingReceiver<mojom::ServiceController> receiver) override; mojo::PendingReceiver<mojom::ServiceController> receiver) override;
......
...@@ -32,6 +32,10 @@ void ServiceController::Bind( ...@@ -32,6 +32,10 @@ void ServiceController::Bind(
receiver_.Bind(std::move(receiver)); receiver_.Bind(std::move(receiver));
} }
void ServiceController::SetInitializeCallback(InitializeCallback callback) {
initialize_callback_ = std::move(callback);
}
void ServiceController::Start(const std::string& libassistant_config) { void ServiceController::Start(const std::string& libassistant_config) {
if (state_ != ServiceState::kStopped) if (state_ != ServiceState::kStopped)
return; return;
...@@ -43,6 +47,13 @@ void ServiceController::Start(const std::string& libassistant_config) { ...@@ -43,6 +47,13 @@ void ServiceController::Start(const std::string& libassistant_config) {
libassistant_v1_api_ = std::make_unique<assistant::LibassistantV1Api>( libassistant_v1_api_ = std::make_unique<assistant::LibassistantV1Api>(
assistant_manager_.get(), assistant_manager_internal_); assistant_manager_.get(), assistant_manager_internal_);
if (initialize_callback_) {
std::move(initialize_callback_)
.Run(assistant_manager(), assistant_manager_internal());
}
assistant_manager()->Start();
SetStateAndInformObservers(ServiceState::kStarted); SetStateAndInformObservers(ServiceState::kStarted);
for (auto& observer : assistant_manager_observers_) { for (auto& observer : assistant_manager_observers_) {
......
...@@ -43,6 +43,10 @@ namespace libassistant { ...@@ -43,6 +43,10 @@ namespace libassistant {
class COMPONENT_EXPORT(LIBASSISTANT_SERVICE) ServiceController class COMPONENT_EXPORT(LIBASSISTANT_SERVICE) ServiceController
: public mojom::ServiceController { : public mojom::ServiceController {
public: public:
using InitializeCallback =
base::OnceCallback<void(assistant_client::AssistantManager*,
assistant_client::AssistantManagerInternal*)>;
ServiceController(assistant::AssistantManagerServiceDelegate* delegate, ServiceController(assistant::AssistantManagerServiceDelegate* delegate,
assistant_client::PlatformApi* platform_api); assistant_client::PlatformApi* platform_api);
ServiceController(ServiceController&) = delete; ServiceController(ServiceController&) = delete;
...@@ -51,6 +55,12 @@ class COMPONENT_EXPORT(LIBASSISTANT_SERVICE) ServiceController ...@@ -51,6 +55,12 @@ class COMPONENT_EXPORT(LIBASSISTANT_SERVICE) ServiceController
void Bind(mojo::PendingReceiver<mojom::ServiceController> receiver); void Bind(mojo::PendingReceiver<mojom::ServiceController> receiver);
// Set a callback to initialize |AssistantManager| and
// |AssistantManagerInternal|. This callback will be invoked before
// AssistantManager::Start() is called. This is temporary until we've migrated
// all initialization code to this class.
void SetInitializeCallback(InitializeCallback callback);
// mojom::ServiceController implementation: // mojom::ServiceController implementation:
void Start(const std::string& libassistant_config) override; void Start(const std::string& libassistant_config) override;
void Stop() override; void Stop() override;
...@@ -77,6 +87,9 @@ class COMPONENT_EXPORT(LIBASSISTANT_SERVICE) ServiceController ...@@ -77,6 +87,9 @@ class COMPONENT_EXPORT(LIBASSISTANT_SERVICE) ServiceController
// Owned by |AssistantManagerServiceImpl| which indirectly owns us. // Owned by |AssistantManagerServiceImpl| which indirectly owns us.
assistant_client::PlatformApi* const platform_api_; assistant_client::PlatformApi* const platform_api_;
// Callback called to initialize |AssistantManager| before it's started.
InitializeCallback initialize_callback_;
std::unique_ptr<assistant_client::AssistantManager> assistant_manager_; std::unique_ptr<assistant_client::AssistantManager> assistant_manager_;
assistant_client::AssistantManagerInternal* assistant_manager_internal_ = assistant_client::AssistantManagerInternal* assistant_manager_internal_ =
nullptr; nullptr;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment