Commit 20a5102c authored by Jeroen Dhollander's avatar Jeroen Dhollander Committed by Commit Bot

Introduce Libassistant mojom service

This service does not own/do anything right now,
but it runs on the background thread and will be fleshed out in
the (many) follow up CLs.

Bug: b/171748795
Test: chromeos_unittest --gtest_filter="AssistantManagerServiceTest.*"
Cq-Include-Trybots: luci.chrome.try:linux-chromeos-chrome
Change-Id: Ica3d227a223ea9678b5a6a0e29580907835956dc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2518254Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Reviewed-by: default avatarXiaohui Chen <xiaohuic@chromium.org>
Reviewed-by: default avatarTao Wu <wutao@chromium.org>
Commit-Queue: Jeroen Dhollander <jeroendh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#827368}
parent d5944c39
......@@ -21,6 +21,8 @@ source_set("proxy") {
"//chromeos/constants",
"//chromeos/services/assistant:cros_libassistant",
"//chromeos/services/assistant/public/cpp",
"//chromeos/services/libassistant",
"//chromeos/services/libassistant/public/mojom",
"//libassistant/shared/internal_api:fuchsia_api_helper",
]
}
......@@ -3,20 +3,96 @@
// found in the LICENSE file.
#include "chromeos/services/assistant/proxy/assistant_proxy.h"
#include <memory>
#include "base/bind.h"
#include "base/check.h"
#include "chromeos/services/assistant/proxy/service_controller.h"
#include "chromeos/services/libassistant/libassistant_service.h"
namespace chromeos {
namespace assistant {
AssistantProxy::AssistantProxy() {
background_thread_.Start();
service_controller_ =
std::make_unique<ServiceController>(background_thread_.task_runner());
CreateMojomService();
service_controller_ = std::make_unique<ServiceController>(
background_task_runner(), BindServiceController());
}
AssistantProxy::~AssistantProxy() {
DestroyMojomService();
// We must wait here for the background thread to finish.
// If we don't wait here, we run into the following timing issue:
// 1. (main thread): Post creation of |mojom_service_| to background thread.
// 2. (main thread): In destructor, post destruction of |mojom_service_| to
// background thread.
// 3. (background thread): Create |mojom_service_|
// 4. (main thread): Continue the destructor, notice |mojom_service_| is
// non-null and destroy it.
// 5. Die because we destructed |mojom_service_| on the wrong thread.
// By explicitly waiting for the background thread here we ensure both the
// creation and destruction are done before we go to step #4.
background_thread_.Stop();
}
void AssistantProxy::CreateMojomService() {
// A Mojom service runs on the thread where its receiver was bound.
// So to make |mojom_service_| run on the background thread, we must create
// it on the background thread, as it binds its receiver in its constructor.
background_task_runner()->PostTask(
FROM_HERE,
base::BindOnce(&AssistantProxy::CreateMojomServiceOnBackgroundThread,
// This is safe because we own the mojom thread,
// so when we're deleted the mojom thread is stopped.
base::Unretained(this),
// |client_| runs on the current thread, so must be bound
// here and not on the background thread.
client_.BindNewPipeAndPassReceiver()));
}
void AssistantProxy::CreateMojomServiceOnBackgroundThread(
mojo::PendingReceiver<LibassistantServiceMojom> client) {
DCHECK(background_task_runner()->BelongsToCurrentThread());
mojom_service_ =
std::make_unique<chromeos::libassistant::LibassistantService>(
std::move(client));
}
void AssistantProxy::DestroyMojomService() {
// |mojom_service_| is created on the background thread, so we have to delete
// it there as well.
// Note that it would be tempting to use
// background_task_runner()
// ->DeleteSoon(FROM_HERE, std::move(mojom_service_));
// but that doesn't work as it is possible |mojom_service_| is nullptr at
// this time, but will be populated by the background thread before it is
// stopped.
background_task_runner()->PostTask(
FROM_HERE,
base::BindOnce(&AssistantProxy::DestroyMojomServiceOnBackgroundThread,
base::Unretained(this)));
}
void AssistantProxy::DestroyMojomServiceOnBackgroundThread() {
DCHECK(background_task_runner()->BelongsToCurrentThread());
mojom_service_ = nullptr;
}
mojo::Remote<AssistantProxy::ServiceControllerMojom>
AssistantProxy::BindServiceController() {
mojo::Remote<ServiceControllerMojom> remote;
client_->BindServiceController(remote.BindNewPipeAndPassReceiver());
return remote;
}
AssistantProxy::~AssistantProxy() = default;
scoped_refptr<base::SingleThreadTaskRunner>
AssistantProxy::background_task_runner() {
return background_thread_.task_runner();
}
ServiceController& AssistantProxy::service_controller() {
DCHECK(service_controller_);
......
......@@ -8,6 +8,8 @@
#include <memory>
#include "base/threading/thread.h"
#include "chromeos/services/libassistant/public/mojom/service.mojom.h"
#include "mojo/public/cpp/bindings/remote.h"
namespace chromeos {
namespace assistant {
......@@ -32,8 +34,30 @@ class AssistantProxy {
base::Thread& background_thread() { return background_thread_; }
private:
using LibassistantServiceMojom =
chromeos::libassistant::mojom::LibassistantService;
using ServiceControllerMojom =
chromeos::libassistant::mojom::ServiceController;
scoped_refptr<base::SingleThreadTaskRunner> background_task_runner();
void CreateMojomService();
void CreateMojomServiceOnBackgroundThread(
mojo::PendingReceiver<LibassistantServiceMojom>);
void DestroyMojomService();
void DestroyMojomServiceOnBackgroundThread();
mojo::Remote<ServiceControllerMojom> BindServiceController();
// The thread on which the Mojom service (and by extension Libassistant) runs.
base::Thread background_thread_{"Assistant background thread"};
mojo::Remote<LibassistantServiceMojom> client_;
// The Mojom service that runs Libassistant.
// For now this is locally owned but it will be moved to a sandbox later.
std::unique_ptr<LibassistantServiceMojom> mojom_service_;
std::unique_ptr<ServiceController> service_controller_;
};
......
......@@ -176,8 +176,11 @@ void CreateAssistantOnBackgroundThread(
} // namespace
ServiceController::ServiceController(
scoped_refptr<base::SingleThreadTaskRunner> background_task_runner)
: background_task_runner_(background_task_runner), weak_factory_(this) {
scoped_refptr<base::SingleThreadTaskRunner> background_task_runner,
mojo::Remote<chromeos::libassistant::mojom::ServiceController> client)
: background_task_runner_(background_task_runner),
client_(std::move(client)),
weak_factory_(this) {
DCHECK(background_task_runner_);
}
......
......@@ -14,6 +14,8 @@
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "chromeos/services/libassistant/public/mojom/service.mojom.h"
#include "mojo/public/cpp/bindings/remote.h"
namespace assistant_client {
......@@ -40,8 +42,9 @@ class ServiceController {
// Each authentication token exists of a [gaia_id, access_token] tuple.
using AuthTokens = std::vector<std::pair<std::string, std::string>>;
explicit ServiceController(
scoped_refptr<base::SingleThreadTaskRunner> background_task_runner);
ServiceController(
scoped_refptr<base::SingleThreadTaskRunner> background_task_runner,
mojo::Remote<chromeos::libassistant::mojom::ServiceController> client);
ServiceController(ServiceController&) = delete;
ServiceController& operator=(ServiceController&) = delete;
......@@ -128,6 +131,8 @@ class ServiceController {
scoped_refptr<base::SingleThreadTaskRunner> background_task_runner_;
mojo::Remote<chromeos::libassistant::mojom::ServiceController> client_;
// NOTE: |display_connection_| is used by |assistant_manager_| and must be
// declared before so it will be destructed after.
std::unique_ptr<CrosDisplayConnection> display_connection_;
......
# Copyright 2020 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
component("libassistant") {
sources = [
"libassistant_service.cc",
"libassistant_service.h",
]
deps = [ "//chromeos/services/libassistant/public/mojom" ]
defines = [ "IS_LIBASSISTANT_SERVICE_IMPL" ]
# The default output name of this service, `libassistant_service.so`, already
# exists (as build target of //chromeos/services/assistant), so we have to
# use `lib_libassistant_service.so`.
output_name = "_libassistant_service"
}
file://chromeos/assistant/OWNERS
# COMPONENT: UI>Shell>Assistant
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromeos/services/libassistant/libassistant_service.h"
#include <memory>
#include <utility>
#include "base/logging.h"
namespace chromeos {
namespace libassistant {
LibassistantService::LibassistantService(
mojo::PendingReceiver<mojom::LibassistantService> receiver)
: receiver_(this, std::move(receiver)) {}
LibassistantService::~LibassistantService() = default;
void LibassistantService::BindServiceController(
mojo::PendingReceiver<mojom::ServiceController> receiver) {
DCHECK(!service_controller_);
service_controller_ =
std::make_unique<ServiceController>(std::move(receiver));
}
ServiceController::ServiceController(
mojo::PendingReceiver<mojom::ServiceController> receiver)
: receiver_(this, std::move(receiver)) {}
ServiceController::~ServiceController() = default;
} // namespace libassistant
} // namespace chromeos
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMEOS_SERVICES_LIBASSISTANT_LIBASSISTANT_SERVICE_H_
#define CHROMEOS_SERVICES_LIBASSISTANT_LIBASSISTANT_SERVICE_H_
#include <memory>
#include "base/component_export.h"
#include "chromeos/services/libassistant/public/mojom/service.mojom.h"
#include "mojo/public/cpp/bindings/receiver.h"
namespace chromeos {
namespace libassistant {
class COMPONENT_EXPORT(LIBASSISTANT_SERVICE) LibassistantService
: public mojom::LibassistantService {
public:
explicit LibassistantService(
mojo::PendingReceiver<mojom::LibassistantService> receiver);
LibassistantService(LibassistantService&) = delete;
LibassistantService& operator=(LibassistantService&) = delete;
~LibassistantService() override;
private:
// mojom::LibassistantService implementation:
void BindServiceController(
mojo::PendingReceiver<mojom::ServiceController> receiver) override;
void BindAudioInputController() override {}
void BindAudioOutputController() override {}
void BindInteractionController() override {}
mojo::Receiver<mojom::LibassistantService> receiver_;
std::unique_ptr<mojom::ServiceController> service_controller_;
};
class ServiceController : public mojom::ServiceController {
public:
explicit ServiceController(
mojo::PendingReceiver<mojom::ServiceController> receiver);
ServiceController(ServiceController&) = delete;
ServiceController& operator=(ServiceController&) = delete;
~ServiceController() override;
private:
mojo::Receiver<mojom::ServiceController> receiver_;
};
} // namespace libassistant
} // namespace chromeos
#endif // CHROMEOS_SERVICES_LIBASSISTANT_LIBASSISTANT_SERVICE_H_
# Copyright 2020 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//mojo/public/tools/bindings/mojom.gni")
mojom("mojom") {
sources = [ "service.mojom" ]
}
per-file *.mojom=set noparent
per-file *.mojom=file://ipc/SECURITY_OWNERS
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
module chromeos.libassistant.mojom;
// The main interface to the Libassistant service on ChromeOS.
// Libassistant provides access to the Google Assistant.
interface LibassistantService {
// Bind the service controller, which provides control over the lifetime
// of the Libassistant process (start/stop).
BindServiceController(pending_receiver<ServiceController> receiver);
// This service will further expose methods to bind all other helper
// controllers.
BindAudioInputController(/* pending_receiver */);
BindAudioOutputController(/* pending_receiver */);
BindInteractionController(/* pending_receiver */);
};
// Component managing the lifecycle of Libassistant,
// exposing methods to start/stop and configure Libassistant.
interface ServiceController {
};
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