Commit 0ca993ac authored by Xiaohui Chen's avatar Xiaohui Chen Committed by Commit Bot

Fix a couple DCHECK errors

* LibAssistant will make a couple file IO during creation.  Moved the
  creation to background thread to avoid DCHECK.
* LibAssistant start will sync wait, this is not allowed in Chromium code
  and triggers a DCHECK error.  Now we created a new start API which takes
  a callback.  This API will be non-blocking and invokes callback when
  it's done.

Bug: 826536, 826462
Test: locally build and run, no DCHECK
Change-Id: If6384977838d3056a75df8becbba5257dba71555
Reviewed-on: https://chromium-review.googlesource.com/991458
Commit-Queue: Xiaohui Chen <xiaohuic@chromium.org>
Reviewed-by: default avatarMuyuan Li <muyuanli@chromium.org>
Cr-Commit-Position: refs/heads/master@{#553331}
parent b6077eca
...@@ -18,13 +18,24 @@ namespace assistant { ...@@ -18,13 +18,24 @@ namespace assistant {
// Interface class that defines all assistant functionalities. // Interface class that defines all assistant functionalities.
class AssistantManagerService : public mojom::Assistant { class AssistantManagerService : public mojom::Assistant {
public: public:
enum State {
// Initial state, the service is created but not started yet.
STOPPED = 0,
// The service is started, it takes a little time to be fully running.
STARTED = 1,
// The service is fully running and ready to take requests.
RUNNING = 2
};
~AssistantManagerService() override = default; ~AssistantManagerService() override = default;
// Start the assistant in the background with |token|. // Start the assistant in the background with |token|. When the service is
virtual void Start(const std::string& access_token) = 0; // fully started |callback| will be called on the thread where ctor was run.
virtual void Start(const std::string& access_token,
base::OnceClosure callback) = 0;
// Returns whether assistant is running. // Returns the current state.
virtual bool IsRunning() const = 0; virtual State GetState() const = 0;
// Set access token for assistant. // Set access token for assistant.
virtual void SetAccessToken(const std::string& access_token) = 0; virtual void SetAccessToken(const std::string& access_token) = 0;
......
...@@ -26,39 +26,31 @@ AssistantManagerServiceImpl::AssistantManagerServiceImpl( ...@@ -26,39 +26,31 @@ AssistantManagerServiceImpl::AssistantManagerServiceImpl(
mojom::AudioInputPtr audio_input) mojom::AudioInputPtr audio_input)
: platform_api_(kDefaultConfigStr, std::move(audio_input)), : platform_api_(kDefaultConfigStr, std::move(audio_input)),
action_module_(std::make_unique<action::CrosActionModule>(this)), action_module_(std::make_unique<action::CrosActionModule>(this)),
assistant_manager_(
assistant_client::AssistantManager::Create(&platform_api_,
kDefaultConfigStr)),
assistant_manager_internal_(
UnwrapAssistantManagerInternal(assistant_manager_.get())),
display_connection_(std::make_unique<CrosDisplayConnection>(this)), display_connection_(std::make_unique<CrosDisplayConnection>(this)),
main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()), main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()),
weak_factory_(this) { weak_factory_(this) {}
assistant_manager_->AddConversationStateListener(this);
}
AssistantManagerServiceImpl::~AssistantManagerServiceImpl() {} AssistantManagerServiceImpl::~AssistantManagerServiceImpl() {}
void AssistantManagerServiceImpl::Start(const std::string& access_token) { void AssistantManagerServiceImpl::Start(const std::string& access_token,
// Posting to background thread because GetARCVersion may be blocking base::OnceClosure callback) {
// LibAssistant creation will make file IO. Post the creation to
// background thread to avoid DCHECK.
base::PostTaskWithTraitsAndReplyWithResult( base::PostTaskWithTraitsAndReplyWithResult(
FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE}, FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE},
base::BindOnce(&chromeos::version_loader::GetARCVersion), base::BindOnce(&assistant_client::AssistantManager::Create,
&platform_api_, kDefaultConfigStr),
base::BindOnce(&AssistantManagerServiceImpl::StartAssistantInternal, base::BindOnce(&AssistantManagerServiceImpl::StartAssistantInternal,
base::Unretained(this), access_token)); base::Unretained(this), std::move(callback), access_token,
chromeos::version_loader::GetARCVersion()));
// Set the flag to avoid starting the service multiple times. // Set the flag to avoid starting the service multiple times.
running_ = true; state_ = State::STARTED;
if (!assistant_settings_manager_) {
assistant_settings_manager_ =
std::make_unique<AssistantSettingsManagerImpl>(this);
}
} }
bool AssistantManagerServiceImpl::IsRunning() const { AssistantManagerService::State AssistantManagerServiceImpl::GetState() const {
return running_; return state_;
} };
void AssistantManagerServiceImpl::SetAccessToken( void AssistantManagerServiceImpl::SetAccessToken(
const std::string& access_token) { const std::string& access_token) {
...@@ -179,8 +171,14 @@ void AssistantManagerServiceImpl::OnSpeechLevelUpdated( ...@@ -179,8 +171,14 @@ void AssistantManagerServiceImpl::OnSpeechLevelUpdated(
} }
void AssistantManagerServiceImpl::StartAssistantInternal( void AssistantManagerServiceImpl::StartAssistantInternal(
base::OnceCallback<void()> callback,
const std::string& access_token, const std::string& access_token,
const std::string& arc_version) { const std::string& arc_version,
assistant_client::AssistantManager* assistant_manager) {
assistant_manager_.reset(assistant_manager);
assistant_manager_internal_ =
UnwrapAssistantManagerInternal(assistant_manager_.get());
auto* internal_options = auto* internal_options =
assistant_manager_internal_->CreateDefaultInternalOptions(); assistant_manager_internal_->CreateDefaultInternalOptions();
SetAssistantOptions(internal_options, BuildUserAgent(arc_version)); SetAssistantOptions(internal_options, BuildUserAgent(arc_version));
...@@ -190,9 +188,23 @@ void AssistantManagerServiceImpl::StartAssistantInternal( ...@@ -190,9 +188,23 @@ void AssistantManagerServiceImpl::StartAssistantInternal(
assistant_manager_internal_->SetDisplayConnection(display_connection_.get()); assistant_manager_internal_->SetDisplayConnection(display_connection_.get());
assistant_manager_internal_->RegisterActionModule(action_module_.get()); assistant_manager_internal_->RegisterActionModule(action_module_.get());
assistant_manager_->AddConversationStateListener(this);
if (!assistant_settings_manager_) {
assistant_settings_manager_ =
std::make_unique<AssistantSettingsManagerImpl>(this);
}
SetAccessToken(access_token); SetAccessToken(access_token);
assistant_manager_->Start();
assistant_client::Callback0 assistant_callback([callback = std::move(
callback)]() mutable {
std::move(callback).Run();
});
assistant_manager_->Start(std::move(assistant_callback));
state_ = State::RUNNING;
} }
std::string AssistantManagerServiceImpl::BuildUserAgent( std::string AssistantManagerServiceImpl::BuildUserAgent(
......
...@@ -43,8 +43,9 @@ class AssistantManagerServiceImpl ...@@ -43,8 +43,9 @@ class AssistantManagerServiceImpl
~AssistantManagerServiceImpl() override; ~AssistantManagerServiceImpl() override;
// assistant::AssistantManagerService overrides // assistant::AssistantManagerService overrides
void Start(const std::string& access_token) override; void Start(const std::string& access_token,
bool IsRunning() const override; base::OnceClosure callback) override;
State GetState() const override;
void SetAccessToken(const std::string& access_token) override; void SetAccessToken(const std::string& access_token) override;
void EnableListening(bool enable) override; void EnableListening(bool enable) override;
AssistantSettingsManager* GetAssistantSettingsManager() override; AssistantSettingsManager* GetAssistantSettingsManager() override;
...@@ -77,8 +78,11 @@ class AssistantManagerServiceImpl ...@@ -77,8 +78,11 @@ class AssistantManagerServiceImpl
recognition_result) override; recognition_result) override;
private: private:
void StartAssistantInternal(const std::string& access_token, void StartAssistantInternal(
const std::string& arc_version); base::OnceClosure callback,
const std::string& access_token,
const std::string& arc_version,
assistant_client::AssistantManager* assistant_manager);
std::string BuildUserAgent(const std::string& arc_version) const; std::string BuildUserAgent(const std::string& arc_version) const;
void HandleGetSettingsResponse(GetSettingsUiResponseCallback callback, void HandleGetSettingsResponse(GetSettingsUiResponseCallback callback,
...@@ -98,12 +102,12 @@ class AssistantManagerServiceImpl ...@@ -98,12 +102,12 @@ class AssistantManagerServiceImpl
recognition_result); recognition_result);
void OnSpeechLevelUpdatedOnMainThread(const float speech_level); void OnSpeechLevelUpdatedOnMainThread(const float speech_level);
bool running_ = false; State state_ = State::STOPPED;
PlatformApiImpl platform_api_; PlatformApiImpl platform_api_;
std::unique_ptr<action::CrosActionModule> action_module_; std::unique_ptr<action::CrosActionModule> action_module_;
std::unique_ptr<assistant_client::AssistantManager> assistant_manager_; std::unique_ptr<assistant_client::AssistantManager> assistant_manager_;
std::unique_ptr<AssistantSettingsManagerImpl> assistant_settings_manager_; std::unique_ptr<AssistantSettingsManagerImpl> assistant_settings_manager_;
assistant_client::AssistantManagerInternal* const assistant_manager_internal_; assistant_client::AssistantManagerInternal* assistant_manager_internal_;
std::unique_ptr<CrosDisplayConnection> display_connection_; std::unique_ptr<CrosDisplayConnection> display_connection_;
mojo::InterfacePtrSet<mojom::AssistantEventSubscriber> subscribers_; mojo::InterfacePtrSet<mojom::AssistantEventSubscriber> subscribers_;
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
......
...@@ -11,8 +11,12 @@ FakeAssistantManagerServiceImpl::FakeAssistantManagerServiceImpl() = default; ...@@ -11,8 +11,12 @@ FakeAssistantManagerServiceImpl::FakeAssistantManagerServiceImpl() = default;
FakeAssistantManagerServiceImpl::~FakeAssistantManagerServiceImpl() = default; FakeAssistantManagerServiceImpl::~FakeAssistantManagerServiceImpl() = default;
void FakeAssistantManagerServiceImpl::Start(const std::string& access_token) { void FakeAssistantManagerServiceImpl::Start(const std::string& access_token,
running_ = true; base::OnceClosure callback) {
state_ = State::RUNNING;
if (callback)
std::move(callback).Run();
} }
void FakeAssistantManagerServiceImpl::SetAccessToken( void FakeAssistantManagerServiceImpl::SetAccessToken(
...@@ -20,8 +24,9 @@ void FakeAssistantManagerServiceImpl::SetAccessToken( ...@@ -20,8 +24,9 @@ void FakeAssistantManagerServiceImpl::SetAccessToken(
void FakeAssistantManagerServiceImpl::EnableListening(bool enable) {} void FakeAssistantManagerServiceImpl::EnableListening(bool enable) {}
bool FakeAssistantManagerServiceImpl::IsRunning() const { AssistantManagerService::State FakeAssistantManagerServiceImpl::GetState()
return running_; const {
return state_;
} }
AssistantSettingsManager* AssistantSettingsManager*
......
...@@ -23,10 +23,11 @@ class FakeAssistantManagerServiceImpl : public AssistantManagerService { ...@@ -23,10 +23,11 @@ class FakeAssistantManagerServiceImpl : public AssistantManagerService {
~FakeAssistantManagerServiceImpl() override; ~FakeAssistantManagerServiceImpl() override;
// assistant::AssistantManagerService overrides // assistant::AssistantManagerService overrides
void Start(const std::string& access_token) override; void Start(const std::string& access_token,
base::OnceClosure callback) override;
void SetAccessToken(const std::string& access_token) override; void SetAccessToken(const std::string& access_token) override;
void EnableListening(bool enable) override; void EnableListening(bool enable) override;
bool IsRunning() const override; State GetState() const override;
AssistantSettingsManager* GetAssistantSettingsManager() override; AssistantSettingsManager* GetAssistantSettingsManager() override;
void SendGetSettingsUiRequest( void SendGetSettingsUiRequest(
const std::string& selector, const std::string& selector,
...@@ -38,7 +39,7 @@ class FakeAssistantManagerServiceImpl : public AssistantManagerService { ...@@ -38,7 +39,7 @@ class FakeAssistantManagerServiceImpl : public AssistantManagerService {
mojom::AssistantEventSubscriberPtr subscriber) override; mojom::AssistantEventSubscriberPtr subscriber) override;
private: private:
bool running_ = false; State state_ = State::STOPPED;
DISALLOW_COPY_AND_ASSIGN(FakeAssistantManagerServiceImpl); DISALLOW_COPY_AND_ASSIGN(FakeAssistantManagerServiceImpl);
}; };
......
...@@ -19,9 +19,9 @@ ...@@ -19,9 +19,9 @@
// libassistant/contrib dependency. // libassistant/contrib dependency.
#include "libassistant/contrib/core/macros.h" #include "libassistant/contrib/core/macros.h"
#include "libassistant/contrib/platform/audio/output/audio_output_provider_impl.h" #include "libassistant/contrib/platform/audio/output/audio_output_provider_impl.h"
#include "libassistant/contrib/platform/auth/auth_provider_impl.h"
#include "libassistant/contrib/platform/resources/resource_provider.h" #include "libassistant/contrib/platform/resources/resource_provider.h"
#include "libassistant/shared/public/platform_api.h" #include "libassistant/shared/public/platform_api.h"
#include "libassistant/shared/public/platform_auth.h"
namespace chromeos { namespace chromeos {
namespace assistant { namespace assistant {
......
...@@ -44,7 +44,9 @@ constexpr char kScopeAssistant[] = ...@@ -44,7 +44,9 @@ constexpr char kScopeAssistant[] =
Service::Service() Service::Service()
: platform_binding_(this), : platform_binding_(this),
session_observer_binding_(this), session_observer_binding_(this),
token_refresh_timer_(std::make_unique<base::OneShotTimer>()) { token_refresh_timer_(std::make_unique<base::OneShotTimer>()),
main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()),
weak_ptr_factory_(this) {
registry_.AddInterface<mojom::AssistantPlatform>(base::BindRepeating( registry_.AddInterface<mojom::AssistantPlatform>(base::BindRepeating(
&Service::BindAssistantPlatformConnection, base::Unretained(this))); &Service::BindAssistantPlatformConnection, base::Unretained(this)));
} }
...@@ -78,6 +80,8 @@ void Service::BindAssistantConnection(mojom::AssistantRequest request) { ...@@ -78,6 +80,8 @@ void Service::BindAssistantConnection(mojom::AssistantRequest request) {
// Assistant interface is supposed to be used when UI is actually in // Assistant interface is supposed to be used when UI is actually in
// use, which should be way later than assistant is created. // use, which should be way later than assistant is created.
DCHECK(assistant_manager_service_); DCHECK(assistant_manager_service_);
DCHECK(assistant_manager_service_->GetState() ==
AssistantManagerService::State::RUNNING);
bindings_.AddBinding(assistant_manager_service_.get(), std::move(request)); bindings_.AddBinding(assistant_manager_service_.get(), std::move(request));
} }
...@@ -122,18 +126,13 @@ void Service::Init(mojom::ClientPtr client, mojom::AudioInputPtr audio_input) { ...@@ -122,18 +126,13 @@ void Service::Init(mojom::ClientPtr client, mojom::AudioInputPtr audio_input) {
#if BUILDFLAG(ENABLE_CROS_LIBASSISTANT) #if BUILDFLAG(ENABLE_CROS_LIBASSISTANT)
assistant_manager_service_ = assistant_manager_service_ =
std::make_unique<AssistantManagerServiceImpl>(std::move(audio_input)); std::make_unique<AssistantManagerServiceImpl>(std::move(audio_input));
// Bind to Assistant controller in ash.
ash::mojom::AshAssistantControllerPtr assistant_controller;
context()->connector()->BindInterface(ash::mojom::kServiceName,
&assistant_controller);
mojom::AssistantPtr ptr;
BindAssistantConnection(mojo::MakeRequest(&ptr));
assistant_controller->SetAssistant(std::move(ptr));
#else #else
assistant_manager_service_ = assistant_manager_service_ =
std::make_unique<FakeAssistantManagerServiceImpl>(); std::make_unique<FakeAssistantManagerServiceImpl>();
#endif #endif
// This will eventually trigger the actual start of assistant services because
// they all depend on it.
RequestAccessToken(); RequestAccessToken();
} }
...@@ -163,13 +162,19 @@ void Service::GetAccessTokenCallback(const base::Optional<std::string>& token, ...@@ -163,13 +162,19 @@ void Service::GetAccessTokenCallback(const base::Optional<std::string>& token,
} }
DCHECK(assistant_manager_service_); DCHECK(assistant_manager_service_);
if (!assistant_manager_service_->IsRunning()) { if (assistant_manager_service_->GetState() ==
assistant_manager_service_->Start(token.value()); AssistantManagerService::State::STOPPED) {
AddAshSessionObserver(); assistant_manager_service_->Start(
registry_.AddInterface<mojom::Assistant>(base::BindRepeating( token.value(),
&Service::BindAssistantConnection, base::Unretained(this))); base::BindOnce(
client_->OnAssistantStatusChanged(true); [](scoped_refptr<base::SingleThreadTaskRunner> task_runner,
DVLOG(1) << "Assistant started"; base::OnceCallback<void()> callback) {
task_runner->PostTask(FROM_HERE, std::move(callback));
},
main_thread_task_runner_,
base::BindOnce(&Service::FinalizeAssistantManangerService,
weak_ptr_factory_.GetWeakPtr())));
DVLOG(1) << "Request Assistant start";
} else { } else {
assistant_manager_service_->SetAccessToken(token.value()); assistant_manager_service_->SetAccessToken(token.value());
} }
...@@ -187,6 +192,25 @@ void Service::GetAccessTokenCallback(const base::Optional<std::string>& token, ...@@ -187,6 +192,25 @@ void Service::GetAccessTokenCallback(const base::Optional<std::string>& token,
this, &Service::RequestAccessToken); this, &Service::RequestAccessToken);
} }
void Service::FinalizeAssistantManangerService() {
DCHECK(assistant_manager_service_->GetState() ==
AssistantManagerService::State::RUNNING);
// Bind to Assistant controller in ash.
ash::mojom::AshAssistantControllerPtr assistant_controller;
context()->connector()->BindInterface(ash::mojom::kServiceName,
&assistant_controller);
mojom::AssistantPtr ptr;
BindAssistantConnection(mojo::MakeRequest(&ptr));
assistant_controller->SetAssistant(std::move(ptr));
AddAshSessionObserver();
registry_.AddInterface<mojom::Assistant>(base::BindRepeating(
&Service::BindAssistantConnection, base::Unretained(this)));
client_->OnAssistantStatusChanged(true);
DVLOG(1) << "Assistant is running";
}
void Service::AddAshSessionObserver() { void Service::AddAshSessionObserver() {
ash::mojom::SessionControllerPtr session_controller; ash::mojom::SessionControllerPtr session_controller;
context()->connector()->BindInterface(ash::mojom::kServiceName, context()->connector()->BindInterface(ash::mojom::kServiceName,
......
...@@ -86,6 +86,8 @@ class Service : public service_manager::Service, ...@@ -86,6 +86,8 @@ class Service : public service_manager::Service,
void UpdateListeningState(); void UpdateListeningState();
void FinalizeAssistantManangerService();
service_manager::BinderRegistry registry_; service_manager::BinderRegistry registry_;
mojo::BindingSet<mojom::Assistant> bindings_; mojo::BindingSet<mojom::Assistant> bindings_;
...@@ -100,12 +102,15 @@ class Service : public service_manager::Service, ...@@ -100,12 +102,15 @@ class Service : public service_manager::Service,
std::unique_ptr<AssistantManagerService> assistant_manager_service_; std::unique_ptr<AssistantManagerService> assistant_manager_service_;
AssistantSettingsManager* assistant_settings_manager_; AssistantSettingsManager* assistant_settings_manager_;
std::unique_ptr<base::OneShotTimer> token_refresh_timer_; std::unique_ptr<base::OneShotTimer> token_refresh_timer_;
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
// Whether the current user session is active. // Whether the current user session is active.
bool session_active_ = false; bool session_active_ = false;
// Whether the lock screen is on. // Whether the lock screen is on.
bool locked_ = false; bool locked_ = false;
base::WeakPtrFactory<Service> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(Service); DISALLOW_COPY_AND_ASSIGN(Service);
}; };
......
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