Commit 4acbabef authored by Ken Rockot's avatar Ken Rockot Committed by Commit Bot

Introduce chromecast.mojom.ServiceConnector

This new interface is analogous to a service_manager::Connector, but is
intended strictly for use with Cast-related services.

The purpose of adding this interface is twofold:

1. This makes it possible to migrate Media Service off of Service
   Manager. Instead of passing a Connector into CastRenderer,
   CastRenderer now acquires a ServiceConnector binding from Cast
   browser code via the InterfaceProvider held by Media Service.

2. Uses of Connector in the internal cast repo can start to use this
   interface in place of a Connector to help them transition off Service
   Manager without significant refactoring effort.

One of the explicit goals of this CL is also to make it so that the
ServiceConnector implementation in the browser is immediately and easily
extensible within the internal repository: CastContentBrowserClient
creates the impl instance, and its creation can be overridden with an
an internal subclass.

The internal implementation can connect directly to internal services
without bouncing through Service Manager, and it can introduce new
values for ServiceConnectorClientId to identify internal clients.

Bug: 977637
Change-Id: I013325512fef6624b435b47509a64a15ffd7d39d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1954769Reviewed-by: default avatarSean Topping <seantopping@chromium.org>
Reviewed-by: default avatarYuchen Liu <yucliu@chromium.org>
Reviewed-by: default avatarRobert Sesek <rsesek@chromium.org>
Commit-Queue: Ken Rockot <rockot@google.com>
Cr-Commit-Position: refs/heads/master@{#723044}
parent edd4d245
......@@ -130,6 +130,8 @@ cast_source_set("browser") {
"renderer_prelauncher.h",
"service/cast_service_simple.cc",
"service/cast_service_simple.h",
"service_connector.cc",
"service_connector.h",
"tts/tts_controller.h",
"tts/tts_controller_impl.cc",
"tts/tts_controller_impl.h",
......
......@@ -6,3 +6,4 @@ per-file cast_overlay_manifests.cc=set noparent
per-file cast_overlay_manifests.cc=file://ipc/SECURITY_OWNERS
per-file cast_content_browser_client_receiver_bindings.cc=set noparent
per-file cast_content_browser_client_receiver_bindings.cc=file://ipc/SECURITY_OWNERS
per-file service_connector.cc=file://ipc/SECURITY_OWNERS
......@@ -43,6 +43,7 @@
#include "chromecast/browser/devtools/remote_debugging_server.h"
#include "chromecast/browser/media/media_caps_impl.h"
#include "chromecast/browser/metrics/cast_browser_metrics.h"
#include "chromecast/browser/service_connector.h"
#include "chromecast/browser/tts/tts_controller_impl.h"
#include "chromecast/browser/tts/tts_platform_stub.h"
#include "chromecast/browser/url_request_context_factory.h"
......@@ -473,6 +474,8 @@ int CastBrowserMainParts::PreCreateThreads() {
std::make_unique<crash_reporter::ChildProcessCrashObserver>());
#endif
service_connector_ = cast_content_browser_client_->CreateServiceConnector();
cast_browser_process_->SetPrefService(
cast_content_browser_client_->GetCastFeatureListCreator()
->TakePrefService());
......
......@@ -36,6 +36,7 @@ class ViewsDelegate;
namespace chromecast {
class CastSystemMemoryPressureEvaluatorAdjuster;
class ServiceConnector;
class WaylandServerController;
#if defined(USE_AURA)
......@@ -94,6 +95,7 @@ class CastBrowserMainParts : public content::BrowserMainParts {
URLRequestContextFactory* const url_request_context_factory_;
std::unique_ptr<media::VideoPlaneController> video_plane_controller_;
std::unique_ptr<media::MediaCapsImpl> media_caps_;
std::unique_ptr<ServiceConnector> service_connector_;
#if defined(USE_AURA)
std::unique_ptr<views::ViewsDelegate> views_delegate_;
......
......@@ -46,6 +46,7 @@
#include "chromecast/browser/general_audience_browsing_service.h"
#include "chromecast/browser/media/media_caps_impl.h"
#include "chromecast/browser/service/cast_service_simple.h"
#include "chromecast/browser/service_connector.h"
#include "chromecast/browser/tts/tts_controller.h"
#include "chromecast/browser/url_request_context_factory.h"
#include "chromecast/common/cast_content_client.h"
......@@ -174,6 +175,11 @@ CastContentBrowserClient::~CastContentBrowserClient() {
url_request_context_factory_.release());
}
std::unique_ptr<ServiceConnector>
CastContentBrowserClient::CreateServiceConnector() {
return std::make_unique<ServiceConnector>();
}
std::unique_ptr<CastService> CastContentBrowserClient::CreateCastService(
content::BrowserContext* browser_context,
CastSystemMemoryPressureEvaluatorAdjuster*
......@@ -257,7 +263,8 @@ CastContentBrowserClient::CreateAudioManager(
base::Unretained(this)),
base::BindRepeating(&shell::CastSessionIdMap::GetSessionId),
base::CreateSingleThreadTaskRunner({content::BrowserThread::UI}),
GetMediaTaskRunner(), content::GetSystemConnector(),
GetMediaTaskRunner(),
ServiceConnector::MakeRemote(kBrowserProcessClientId),
BUILDFLAG(ENABLE_CAST_AUDIO_MANAGER_MIXER));
#else
return std::make_unique<media::CastAudioManager>(
......@@ -266,7 +273,8 @@ CastContentBrowserClient::CreateAudioManager(
base::Unretained(this)),
base::BindRepeating(&shell::CastSessionIdMap::GetSessionId),
base::CreateSingleThreadTaskRunner({content::BrowserThread::UI}),
GetMediaTaskRunner(), content::GetSystemConnector(),
GetMediaTaskRunner(),
ServiceConnector::MakeRemote(kBrowserProcessClientId),
BUILDFLAG(ENABLE_CAST_AUDIO_MANAGER_MIXER));
#endif // defined(USE_ALSA)
}
......@@ -918,8 +926,7 @@ void CastContentBrowserClient::BindMediaRenderer(
std::make_unique<media::CastRenderer>(
GetCmaBackendFactory(), std::move(media_task_runner),
GetVideoModeSwitcher(), GetVideoResolutionPolicy(),
base::UnguessableToken::Create(), nullptr /* connector */,
nullptr /* host_interfaces */),
base::UnguessableToken::Create(), nullptr /* host_interfaces */),
std::move(receiver));
}
......
......@@ -62,6 +62,7 @@ class CastWindowManager;
class CastFeatureListCreator;
class GeneralAudienceBrowsingService;
class MemoryPressureControllerImpl;
class ServiceConnector;
namespace media {
class MediaCapsImpl;
......@@ -95,6 +96,11 @@ class CastContentBrowserClient
~CastContentBrowserClient() override;
// Creates a ServiceConnector for routing Cast-related service interface
// binding requests.
virtual std::unique_ptr<chromecast::ServiceConnector>
CreateServiceConnector();
// Creates and returns the CastService instance for the current process.
virtual std::unique_ptr<CastService> CreateCastService(
content::BrowserContext* browser_context,
......
......@@ -16,6 +16,7 @@
#include "chromecast/browser/cast_browser_main_parts.h"
#include "chromecast/browser/cast_browser_process.h"
#include "chromecast/browser/media/media_caps_impl.h"
#include "chromecast/browser/service_connector.h"
#include "chromecast/chromecast_buildflags.h"
#include "chromecast/media/cdm/cast_cdm_factory.h"
#include "components/network_hints/browser/simple_network_hints_handler_impl.h"
......@@ -129,6 +130,9 @@ void CastContentBrowserClient::ExposeInterfacesToMediaService(
base::BindRepeating(&CreateMediaDrmStorage, render_frame_host));
#endif // defined(OS_ANDROID)
registry->AddInterface(base::BindRepeating(&ServiceConnector::BindReceiver,
kMediaServiceClientId));
std::string application_session_id;
bool mixer_audio_enabled;
GetApplicationMediaInfo(&application_session_id, &mixer_audio_enabled,
......
// Copyright 2019 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 "chromecast/browser/service_connector.h"
#include "base/bind.h"
#include "base/logging.h"
#include "base/task/post_task.h"
#include "chromecast/common/mojom/constants.mojom.h"
#include "chromecast/common/mojom/multiroom.mojom.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/system_connector.h"
namespace chromecast {
namespace {
ServiceConnector* g_instance = nullptr;
} // namespace
const ServiceConnectorClientId kBrowserProcessClientId =
ServiceConnectorClientId::FromUnsafeValue(1);
const ServiceConnectorClientId kMediaServiceClientId =
ServiceConnectorClientId::FromUnsafeValue(2);
ServiceConnector::ServiceConnector() {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK(!g_instance);
g_instance = this;
}
ServiceConnector::~ServiceConnector() {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK_EQ(this, g_instance);
g_instance = nullptr;
}
// static
mojo::PendingRemote<mojom::ServiceConnector> ServiceConnector::MakeRemote(
ServiceConnectorClientId client_id) {
DCHECK(g_instance);
mojo::PendingRemote<mojom::ServiceConnector> remote;
BindReceiver(client_id, remote.InitWithNewPipeAndPassReceiver());
return remote;
}
// static
void ServiceConnector::BindReceiver(
ServiceConnectorClientId client_id,
mojo::PendingReceiver<mojom::ServiceConnector> receiver) {
if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
base::PostTask(FROM_HERE, content::BrowserThread::UI,
base::BindOnce(&ServiceConnector::BindReceiver, client_id,
std::move(receiver)));
return;
}
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK(g_instance);
g_instance->receivers_.Add(g_instance, std::move(receiver), client_id);
}
void ServiceConnector::Connect(const std::string& service_name,
mojo::GenericPendingReceiver receiver) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
const ServiceConnectorClientId client_id = receivers_.current_context();
// If the client is browser code, forward indscriminately through the Service
// Manager. The browser generally has access unfettered to everything.
if (client_id == kBrowserProcessClientId) {
content::GetSystemConnector()->BindInterface(
service_manager::ServiceFilter::ByName(service_name),
*receiver.interface_name(), receiver.PassPipe());
return;
}
// In the public implementation of this class, the only other client we
// support is the Media Service, binding to the MultiroomManager interface in
// the Chromecast service.
if (client_id != kMediaServiceClientId ||
service_name != mojom::kChromecastServiceName) {
LOG(ERROR) << "Client " << client_id.GetUnsafeValue()
<< " attempted to bind " << *receiver.interface_name()
<< " in inaccessible service " << service_name;
return;
}
if (auto r = receiver.As<mojom::MultiroomManager>()) {
content::GetSystemConnector()->BindInterface(service_name, std::move(r));
return;
}
LOG(ERROR) << "Media Service attempted to bind inaccessible interface "
<< *receiver.interface_name() << " in \"chromecast\" service.";
}
} // namespace chromecast
// Copyright 2019 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 CHROMECAST_BROWSER_SERVICE_CONNECTOR_H_
#define CHROMECAST_BROWSER_SERVICE_CONNECTOR_H_
#include "base/util/type_safety/id_type.h"
#include "chromecast/common/mojom/service_connector.mojom.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
namespace chromecast {
class ServiceConnector;
// An opaque identifier type so that bound ServiceConnector endpoints can reason
// about who's making connection requests.
//
// We don't use an enum because the definition of these IDs is split across
// public and internal sources.
using ServiceConnectorClientId = util::IdType32<ServiceConnector>;
// Something in browser process itself (e.g. CastAudioManager)
extern const ServiceConnectorClientId kBrowserProcessClientId;
// The Media Service hosted by Content.
extern const ServiceConnectorClientId kMediaServiceClientId;
// Browser-side implementation of the ServiceConnector mojom interface to route
// interface binding requests to various Cast-related services on behalf of
// clients both inside and outside of the browser process.
class ServiceConnector : public mojom::ServiceConnector {
public:
ServiceConnector();
ServiceConnector(const ServiceConnector&) = delete;
ServiceConnector& operator=(const ServiceConnector&) = delete;
~ServiceConnector() override;
// Connects a new pipe to the global ServiceConnector instance and returns its
// PendingRemote. Callable from any thread.
//
// |client_id| indicates the identity of the client that will ultimately use
// the returned ServiceConnector endpoint.
static mojo::PendingRemote<mojom::ServiceConnector> MakeRemote(
ServiceConnectorClientId client_id);
// Binds a receiver to the global ServiceConnector. Callable from any thread.
// |client_id| indicates the identity of the client holding the other end of
// the ServiceConnector pipe.
static void BindReceiver(
ServiceConnectorClientId client_id,
mojo::PendingReceiver<mojom::ServiceConnector> receiver);
// mojom::ServiceConnector implementation:
void Connect(const std::string& service_name,
mojo::GenericPendingReceiver receiver) override;
private:
mojo::ReceiverSet<mojom::ServiceConnector, ServiceConnectorClientId>
receivers_;
};
} // namespace chromecast
#endif // CHROMECAST_BROWSER_SERVICE_CONNECTOR_H_
......@@ -16,6 +16,7 @@ mojom("mojom") {
"multiroom.mojom",
"on_load_script_injector.mojom",
"queryable_data_store.mojom",
"service_connector.mojom",
]
public_deps = [
......
// Copyright 2016 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 chromecast.mojom;
import "mojo/public/mojom/base/generic_pending_receiver.mojom";
// This interface is implemented in the browser process and provides a way of
// brokering access to Cast-internal service interfaces. This is a replacement
// for Service Manager Connector, as Service Manager is effectively deprecated
// but many Cast-internal services are still built on it. As those services are
// moved off of Service Manager, uses of this interface should diminish to zero
// in favor of more strongly-typed binding interfaces.
interface ServiceConnector {
// Routes interface receivers to the Cast-internal service named by
// |service_name|.
Connect(string service_name, mojo_base.mojom.GenericPendingReceiver receiver);
};
......@@ -53,7 +53,7 @@ CastAudioManager::CastAudioManager(
GetSessionIdCallback get_session_id_callback,
scoped_refptr<base::SingleThreadTaskRunner> browser_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
service_manager::Connector* connector,
mojo::PendingRemote<chromecast::mojom::ServiceConnector> connector,
bool use_mixer)
: CastAudioManager(std::move(audio_thread),
audio_log_factory,
......@@ -61,7 +61,7 @@ CastAudioManager::CastAudioManager(
std::move(get_session_id_callback),
std::move(browser_task_runner),
std::move(media_task_runner),
connector,
std::move(connector),
use_mixer,
false) {}
......@@ -72,7 +72,7 @@ CastAudioManager::CastAudioManager(
GetSessionIdCallback get_session_id_callback,
scoped_refptr<base::SingleThreadTaskRunner> browser_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
service_manager::Connector* connector,
mojo::PendingRemote<chromecast::mojom::ServiceConnector> connector,
bool use_mixer,
bool force_use_cma_backend_for_output)
: AudioManagerBase(std::move(audio_thread), audio_log_factory),
......@@ -80,13 +80,13 @@ CastAudioManager::CastAudioManager(
get_session_id_callback_(std::move(get_session_id_callback)),
browser_task_runner_(std::move(browser_task_runner)),
media_task_runner_(std::move(media_task_runner)),
browser_connector_(connector),
pending_connector_(std::move(connector)),
force_use_cma_backend_for_output_(force_use_cma_backend_for_output),
weak_factory_(this) {
DCHECK(browser_task_runner_->BelongsToCurrentThread());
DCHECK(backend_factory_getter_);
DCHECK(get_session_id_callback_);
DCHECK(browser_connector_);
DCHECK(pending_connector_);
weak_this_ = weak_factory_.GetWeakPtr();
if (use_mixer)
mixer_ = std::make_unique<CastAudioMixer>(this);
......@@ -264,27 +264,14 @@ std::string CastAudioManager::GetSessionId(std::string audio_group_id) {
return mixer_output_stream_.get();
}
void CastAudioManager::SetConnectorForTesting(
std::unique_ptr<service_manager::Connector> connector) {
connector_ = std::move(connector);
}
service_manager::Connector* CastAudioManager::GetConnector() {
chromecast::mojom::ServiceConnector* CastAudioManager::GetConnector() {
if (!connector_) {
mojo::PendingReceiver<service_manager::mojom::Connector> receiver;
connector_ = service_manager::Connector::Create(&receiver);
browser_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&CastAudioManager::BindConnectorReceiver,
weak_this_, std::move(receiver)));
DCHECK(pending_connector_);
connector_.Bind(std::move(pending_connector_));
}
return connector_.get();
}
void CastAudioManager::BindConnectorReceiver(
mojo::PendingReceiver<service_manager::mojom::Connector> receiver) {
browser_connector_->BindConnectorReceiver(std::move(receiver));
}
bool CastAudioManager::UseMixerOutputStream(
const ::media::AudioParameters& params) {
bool use_cma_backend =
......
......@@ -12,9 +12,11 @@
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "build/build_config.h"
#include "chromecast/common/mojom/service_connector.mojom.h"
#include "media/audio/audio_manager_base.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "services/service_manager/public/cpp/connector.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
// NOTE: CastAudioManager receives a |device_id| from the audio service, and
// passes it to CastAudioOutputStream as a |device_id_or_group_id|.
......@@ -54,7 +56,7 @@ class CastAudioManager : public ::media::AudioManagerBase {
GetSessionIdCallback get_session_id_callback,
scoped_refptr<base::SingleThreadTaskRunner> browser_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
service_manager::Connector* connector,
mojo::PendingRemote<chromecast::mojom::ServiceConnector> connector,
bool use_mixer);
~CastAudioManager() override;
......@@ -77,9 +79,6 @@ class CastAudioManager : public ::media::AudioManagerBase {
std::string GetSessionId(std::string audio_group_id);
void SetConnectorForTesting(
std::unique_ptr<service_manager::Connector> connector);
protected:
// AudioManagerBase implementation.
::media::AudioOutputStream* MakeLinearOutputStream(
......@@ -120,9 +119,7 @@ class CastAudioManager : public ::media::AudioManagerBase {
friend class CastAudioMixer;
friend class CastAudioManagerTest;
friend class CastAudioOutputStreamTest;
service_manager::Connector* GetConnector();
void BindConnectorReceiver(
mojo::PendingReceiver<service_manager::mojom::Connector> receiver);
chromecast::mojom::ServiceConnector* GetConnector();
CastAudioManager(
std::unique_ptr<::media::AudioThread> audio_thread,
......@@ -131,7 +128,7 @@ class CastAudioManager : public ::media::AudioManagerBase {
GetSessionIdCallback get_session_id_callback,
scoped_refptr<base::SingleThreadTaskRunner> browser_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
service_manager::Connector* connector,
mojo::PendingRemote<chromecast::mojom::ServiceConnector> connector,
bool use_mixer,
bool force_use_cma_backend_for_output);
......@@ -144,10 +141,13 @@ class CastAudioManager : public ::media::AudioManagerBase {
CmaBackendFactory* cma_backend_factory_ = nullptr;
scoped_refptr<base::SingleThreadTaskRunner> browser_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
service_manager::Connector* const browser_connector_;
std::unique_ptr<::media::AudioOutputStream> mixer_output_stream_;
std::unique_ptr<CastAudioMixer> mixer_;
std::unique_ptr<service_manager::Connector> connector_;
// |connector_| is bound to |pending_connector_| lazily on first use, as it is
// created on the main thread but used on the Audio thread, which may differ.
mojo::PendingRemote<chromecast::mojom::ServiceConnector> pending_connector_;
mojo::Remote<chromecast::mojom::ServiceConnector> connector_;
// Let unit test force the CastOutputStream to uses
// CmaBackend implementation.
......
......@@ -85,7 +85,7 @@ CastAudioManagerAlsa::CastAudioManagerAlsa(
GetSessionIdCallback get_session_id_callback,
scoped_refptr<base::SingleThreadTaskRunner> browser_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
service_manager::Connector* connector,
mojo::PendingRemote<chromecast::mojom::ServiceConnector> connector,
bool use_mixer)
: CastAudioManager(std::move(audio_thread),
audio_log_factory,
......@@ -93,7 +93,7 @@ CastAudioManagerAlsa::CastAudioManagerAlsa(
std::move(get_session_id_callback),
browser_task_runner,
media_task_runner,
connector,
std::move(connector),
use_mixer),
wrapper_(new ::media::AlsaWrapper()) {}
......
......@@ -10,7 +10,9 @@
#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "chromecast/common/mojom/service_connector.mojom.h"
#include "chromecast/media/audio/cast_audio_manager.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
namespace media {
class AlsaWrapper;
......@@ -34,7 +36,7 @@ class CastAudioManagerAlsa : public CastAudioManager {
GetSessionIdCallback get_session_id_callback,
scoped_refptr<base::SingleThreadTaskRunner> browser_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
service_manager::Connector* connector,
mojo::PendingRemote<chromecast::mojom::ServiceConnector> connector,
bool use_mixer);
~CastAudioManagerAlsa() override;
......
......@@ -10,11 +10,12 @@
#include "base/bind.h"
#include "base/test/test_message_loop.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chromecast/common/mojom/service_connector.mojom.h"
#include "chromecast/media/cma/test/mock_cma_backend_factory.h"
#include "media/audio/fake_audio_log_factory.h"
#include "media/audio/test_audio_thread.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "services/service_manager/public/cpp/connector.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace chromecast {
......@@ -31,9 +32,10 @@ const ::media::AudioParameters kDefaultAudioParams(
void OnLogMessage(const std::string& message) {}
std::unique_ptr<service_manager::Connector> CreateConnector() {
mojo::PendingReceiver<service_manager::mojom::Connector> receiver;
return service_manager::Connector::Create(&receiver);
mojo::PendingRemote<chromecast::mojom::ServiceConnector> CreateConnector() {
mojo::PendingRemote<chromecast::mojom::ServiceConnector> remote;
ignore_result(remote.InitWithNewPipeAndPassReceiver());
return remote;
}
std::string DummyGetSessionId(std::string /* audio_group_id */) {
......@@ -42,8 +44,7 @@ std::string DummyGetSessionId(std::string /* audio_group_id */) {
class CastAudioManagerAlsaTest : public testing::Test {
public:
CastAudioManagerAlsaTest()
: media_thread_("CastMediaThread"), connector_(CreateConnector()) {
CastAudioManagerAlsaTest() : media_thread_("CastMediaThread") {
CHECK(media_thread_.Start());
backend_factory_ = std::make_unique<MockCmaBackendFactory>();
......@@ -53,7 +54,7 @@ class CastAudioManagerAlsaTest : public testing::Test {
base::Unretained(this)),
base::BindRepeating(&DummyGetSessionId),
base::ThreadTaskRunnerHandle::Get(), media_thread_.task_runner(),
connector_.get(), false);
CreateConnector(), false);
}
~CastAudioManagerAlsaTest() override { audio_manager_->Shutdown(); }
......@@ -63,7 +64,6 @@ class CastAudioManagerAlsaTest : public testing::Test {
base::TestMessageLoop message_loop_;
std::unique_ptr<MockCmaBackendFactory> backend_factory_;
base::Thread media_thread_;
std::unique_ptr<service_manager::Connector> connector_;
::media::FakeAudioLogFactory audio_log_factory_;
std::unique_ptr<CastAudioManagerAlsa> audio_manager_;
};
......
......@@ -14,6 +14,7 @@
#include "chromecast/chromecast_buildflags.h"
#include "chromecast/common/mojom/constants.mojom.h"
#include "chromecast/common/mojom/multiroom.mojom.h"
#include "chromecast/common/mojom/service_connector.mojom.h"
#include "chromecast/media/cma/backend/cma_backend.h"
#include "chromecast/media/cma/test/mock_cma_backend.h"
#include "chromecast/media/cma/test/mock_cma_backend_factory.h"
......@@ -23,7 +24,8 @@
#include "media/audio/mock_audio_source_callback.h"
#include "media/audio/test_audio_thread.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "services/service_manager/public/cpp/connector.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#if defined(OS_ANDROID)
......@@ -51,11 +53,6 @@ const ::media::AudioParameters kAudioParamsInvalidLayout(
::media::AudioParameters::kAudioCDSampleRate,
256);
std::unique_ptr<service_manager::Connector> CreateConnector() {
mojo::PendingReceiver<service_manager::mojom::Connector> receiver;
return service_manager::Connector::Create(&receiver);
}
int OnMoreData(base::TimeDelta delay,
base::TimeTicks delay_timestamp,
int prior_frames_skipped,
......@@ -73,7 +70,8 @@ std::string DummyGetSessionId(std::string /* audio_group_id */) {
namespace chromecast {
namespace media {
class CastAudioManagerTest : public testing::Test {
class CastAudioManagerTest : public testing::Test,
public chromecast::mojom::ServiceConnector {
public:
CastAudioManagerTest() : audio_thread_("CastAudioThread") {}
......@@ -86,10 +84,14 @@ class CastAudioManagerTest : public testing::Test {
audio_thread_.Stop();
}
// Binds |multiroom_manager_| to the interface requested through the test
// connector.
void BindMultiroomManager(mojo::ScopedMessagePipeHandle handle) {
multiroom_manager_.Bind(std::move(handle));
// chromecast::mojom::ServiceConnector implementation:
void Connect(const std::string& service_name,
mojo::GenericPendingReceiver receiver) override {
if (service_name != chromecast::mojom::kChromecastServiceName)
return;
if (auto r = receiver.As<mojom::MultiroomManager>())
multiroom_manager_.Bind(r.PassPipe());
}
protected:
......@@ -98,21 +100,13 @@ class CastAudioManagerTest : public testing::Test {
return mock_backend_factory_.get();
}
void CreateConnectorForTesting() {
connector_ = CreateConnector();
// Override the MultiroomManager interface for testing.
connector_->OverrideBinderForTesting(
service_manager::ServiceFilter::ByName(
chromecast::mojom::kChromecastServiceName),
mojom::MultiroomManager::Name_,
base::BindRepeating(&CastAudioManagerTest::BindMultiroomManager,
base::Unretained(this)));
mojo::PendingRemote<chromecast::mojom::ServiceConnector> CreateConnector() {
mojo::PendingRemote<chromecast::mojom::ServiceConnector> connector;
connector_receivers_.Add(this, connector.InitWithNewPipeAndPassReceiver());
return connector;
}
void CreateAudioManagerForTesting(bool use_mixer = false) {
if (!connector_)
CreateConnectorForTesting();
// Only one AudioManager may exist at a time, so destroy the one we're
// currently holding before creating a new one.
// Flush the message loop to run any shutdown tasks posted by AudioManager.
......@@ -131,7 +125,7 @@ class CastAudioManagerTest : public testing::Test {
base::Unretained(this)),
base::BindRepeating(&DummyGetSessionId),
task_environment_.GetMainThreadTaskRunner(),
audio_thread_.task_runner(), connector_.get(), use_mixer,
audio_thread_.task_runner(), CreateConnector(), use_mixer,
true /* force_use_cma_backend_for_output*/
));
// A few AudioManager implementations post initialization tasks to
......@@ -183,7 +177,7 @@ class CastAudioManagerTest : public testing::Test {
std::unique_ptr<CastAudioManager> audio_manager_;
std::unique_ptr<::media::AudioDeviceInfoAccessorForTests>
device_info_accessor_;
std::unique_ptr<service_manager::Connector> connector_;
mojo::ReceiverSet<chromecast::mojom::ServiceConnector> connector_receivers_;
MockMultiroomManager multiroom_manager_;
};
......
......@@ -14,21 +14,22 @@
#include "base/run_loop.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#include "chromecast/common/mojom/service_connector.mojom.h"
#include "chromecast/media/audio/cast_audio_manager.h"
#include "chromecast/media/audio/cast_audio_output_stream.h"
#include "chromecast/media/cma/backend/cma_backend_factory.h"
#include "media/audio/audio_io.h"
#include "media/audio/test_audio_thread.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "services/service_manager/public/cpp/connector.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
std::unique_ptr<service_manager::Connector> CreateConnector() {
mojo::PendingReceiver<service_manager::mojom::Connector> receiver;
return service_manager::Connector::Create(&receiver);
mojo::PendingRemote<chromecast::mojom::ServiceConnector> CreateConnector() {
mojo::PendingRemote<chromecast::mojom::ServiceConnector> connector;
ignore_result(connector.InitWithNewPipeAndPassReceiver());
return connector;
}
std::string DummyGetSessionId(std::string /* audio_group_id */) {
......@@ -109,7 +110,6 @@ class MockMediaAudioOutputStream : public ::media::AudioOutputStream {
class MockCastAudioManager : public CastAudioManager {
public:
explicit MockCastAudioManager(
service_manager::Connector* connector,
scoped_refptr<base::SingleThreadTaskRunner> media_task_runner)
: CastAudioManager(
std::make_unique<::media::TestAudioThread>(),
......@@ -119,7 +119,7 @@ class MockCastAudioManager : public CastAudioManager {
base::BindRepeating(&DummyGetSessionId),
media_task_runner,
media_task_runner,
connector,
CreateConnector(),
true /* use_mixer */) {
ON_CALL(*this, ReleaseOutputStream(_))
.WillByDefault(
......@@ -143,14 +143,13 @@ class CastAudioMixerTest : public ::testing::Test {
public:
CastAudioMixerTest()
: task_environment_(base::test::TaskEnvironment::MainThreadType::UI),
connector_(CreateConnector()),
source_callback_(nullptr) {}
~CastAudioMixerTest() override {}
protected:
void SetUp() override {
mock_manager_.reset(new StrictMock<MockCastAudioManager>(
connector_.get(), task_environment_.GetMainThreadTaskRunner()));
task_environment_.GetMainThreadTaskRunner()));
mock_mixer_stream_.reset(new StrictMock<MockMediaAudioOutputStream>());
ON_CALL(*mock_manager_, MakeMixerOutputStream(_))
......@@ -174,7 +173,6 @@ class CastAudioMixerTest : public ::testing::Test {
}
base::test::TaskEnvironment task_environment_;
std::unique_ptr<service_manager::Connector> connector_;
std::unique_ptr<MockCastAudioManager> mock_manager_;
std::unique_ptr<MockMediaAudioOutputStream> mock_mixer_stream_;
......
......@@ -265,7 +265,7 @@ void CastAudioOutputStream::MixerServiceWrapper::FillNextBuffer(
CastAudioOutputStream::CastAudioOutputStream(
CastAudioManager* audio_manager,
service_manager::Connector* connector,
chromecast::mojom::ServiceConnector* connector,
const ::media::AudioParameters& audio_params,
const std::string& device_id_or_group_id,
bool use_mixer_service)
......
......@@ -16,11 +16,11 @@
#include "build/build_config.h"
#include "chromecast/base/task_runner_impl.h"
#include "chromecast/common/mojom/multiroom.mojom.h"
#include "chromecast/common/mojom/service_connector.mojom.h"
#include "media/audio/audio_io.h"
#include "media/base/audio_parameters.h"
#include "media/base/audio_timestamp_helper.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/service_manager/public/cpp/connector.h"
namespace chromecast {
namespace media {
......@@ -104,7 +104,7 @@ class CastAudioOutputStream : public ::media::AudioOutputStream {
// ::media::AudioDeviceDescription::kDefaultDeviceId or
// ::media::AudioDeviceDescription::kCommunicationsId.
CastAudioOutputStream(CastAudioManager* audio_manager,
service_manager::Connector* connector,
chromecast::mojom::ServiceConnector* connector,
const ::media::AudioParameters& audio_params,
const std::string& device_id_or_group_id,
bool use_mixer_service);
......@@ -136,7 +136,7 @@ class CastAudioOutputStream : public ::media::AudioOutputStream {
double volume_;
AudioOutputState audio_thread_state_;
CastAudioManager* const audio_manager_;
service_manager::Connector* connector_;
chromecast::mojom::ServiceConnector* connector_;
const ::media::AudioParameters audio_params_;
// Valid |device_id_| are kDefaultDeviceId, and kCommunicationsDeviceId
const std::string device_id_;
......
......@@ -17,6 +17,7 @@
#include "base/time/time.h"
#include "chromecast/common/mojom/constants.mojom.h"
#include "chromecast/common/mojom/multiroom.mojom.h"
#include "chromecast/common/mojom/service_connector.mojom.h"
#include "chromecast/media/audio/cast_audio_manager.h"
#include "chromecast/media/audio/cast_audio_mixer.h"
#include "chromecast/media/base/monotonic_clock.h"
......@@ -30,9 +31,9 @@
#include "content/public/test/test_browser_thread.h"
#include "media/audio/mock_audio_source_callback.h"
#include "media/audio/test_audio_thread.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "services/service_manager/public/cpp/connector.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -42,11 +43,6 @@ using testing::NiceMock;
namespace {
std::unique_ptr<service_manager::Connector> CreateConnector() {
mojo::PendingReceiver<service_manager::mojom::Connector> receiver;
return service_manager::Connector::Create(&receiver);
}
std::string DummyGetSessionId(std::string /* audio_group_id */) {
return "AABBCCDDEE";
}
......@@ -224,7 +220,8 @@ class FakeCmaBackend : public CmaBackend {
std::unique_ptr<FakeAudioDecoder> audio_decoder_;
};
class CastAudioOutputStreamTest : public ::testing::Test {
class CastAudioOutputStreamTest : public ::testing::Test,
public chromecast::mojom::ServiceConnector {
public:
CastAudioOutputStreamTest()
: audio_thread_("CastAudioThread"),
......@@ -245,10 +242,14 @@ class CastAudioOutputStreamTest : public ::testing::Test {
audio_thread_.Stop();
}
// Binds |multiroom_manager_| to the interface requested through the test
// connector.
void BindMultiroomManager(mojo::ScopedMessagePipeHandle handle) {
multiroom_manager_.Bind(std::move(handle));
// chromecast::mojom::ServiceConnector:
void Connect(const std::string& service_name,
mojo::GenericPendingReceiver receiver) override {
if (service_name != chromecast::mojom::kChromecastServiceName)
return;
if (auto r = receiver.As<mojom::MultiroomManager>())
multiroom_manager_.Bind(r.PassPipe());
}
protected:
......@@ -256,21 +257,13 @@ class CastAudioOutputStreamTest : public ::testing::Test {
return mock_backend_factory_.get();
}
void CreateConnectorForTesting() {
connector_ = CreateConnector();
// Override the MultiroomManager interface for testing.
connector_->OverrideBinderForTesting(
service_manager::ServiceFilter::ByName(
chromecast::mojom::kChromecastServiceName),
mojom::MultiroomManager::Name_,
base::BindRepeating(&CastAudioOutputStreamTest::BindMultiroomManager,
base::Unretained(this)));
mojo::PendingRemote<chromecast::mojom::ServiceConnector> CreateConnector() {
mojo::PendingRemote<chromecast::mojom::ServiceConnector> connector;
connector_receivers_.Add(this, connector.InitWithNewPipeAndPassReceiver());
return connector;
}
void CreateAudioManagerForTesting(bool use_mixer = false) {
if (!connector_)
CreateConnectorForTesting();
// Only one AudioManager may exist at a time, so destroy the one we're
// currently holding before creating a new one.
// Flush the message loop to run any shutdown tasks posted by AudioManager.
......@@ -289,10 +282,8 @@ class CastAudioOutputStreamTest : public ::testing::Test {
base::Unretained(this)),
base::BindRepeating(&DummyGetSessionId),
task_environment_.GetMainThreadTaskRunner(),
audio_thread_.task_runner(), connector_.get(), use_mixer,
audio_thread_.task_runner(), CreateConnector(), use_mixer,
true /* force_use_cma_backend_for_output*/));
audio_manager_->SetConnectorForTesting(std::move(connector_));
// A few AudioManager implementations post initialization tasks to
// audio thread. Flush the thread to ensure that |audio_manager_| is
// initialized and ready to use before returning from this function.
......@@ -367,7 +358,7 @@ class CastAudioOutputStreamTest : public ::testing::Test {
FakeCmaBackend* cma_backend_ = nullptr;
std::unique_ptr<CastAudioManager> audio_manager_;
std::unique_ptr<service_manager::Connector> connector_;
mojo::ReceiverSet<chromecast::mojom::ServiceConnector> connector_receivers_;
MockMultiroomManager multiroom_manager_;
// AudioParameters used to create AudioOutputStream.
......
......@@ -19,8 +19,7 @@ CastMojoMediaClient::CastMojoMediaClient(
const CreateCdmFactoryCB& create_cdm_factory_cb,
VideoModeSwitcher* video_mode_switcher,
VideoResolutionPolicy* video_resolution_policy)
: connector_(nullptr),
backend_factory_(backend_factory),
: backend_factory_(backend_factory),
create_cdm_factory_cb_(create_cdm_factory_cb),
video_mode_switcher_(video_mode_switcher),
video_resolution_policy_(video_resolution_policy) {
......@@ -29,11 +28,7 @@ CastMojoMediaClient::CastMojoMediaClient(
CastMojoMediaClient::~CastMojoMediaClient() {}
void CastMojoMediaClient::Initialize(service_manager::Connector* connector) {
DCHECK(!connector_);
DCHECK(connector);
connector_ = connector;
}
void CastMojoMediaClient::Initialize(service_manager::Connector* connector) {}
#if BUILDFLAG(ENABLE_CAST_RENDERER)
void CastMojoMediaClient::SetVideoGeometrySetterService(
......@@ -49,7 +44,7 @@ std::unique_ptr<::media::Renderer> CastMojoMediaClient::CreateCastRenderer(
DCHECK(video_geometry_setter_);
auto cast_renderer = std::make_unique<CastRenderer>(
backend_factory_, task_runner, video_mode_switcher_,
video_resolution_policy_, overlay_plane_id, connector_, host_interfaces);
video_resolution_policy_, overlay_plane_id, host_interfaces);
cast_renderer->SetVideoGeometrySetterService(video_geometry_setter_);
return cast_renderer;
}
......
......@@ -55,7 +55,6 @@ class CastMojoMediaClient : public ::media::MojoMediaClient {
service_manager::mojom::InterfaceProvider* host_interfaces) override;
private:
service_manager::Connector* connector_;
CmaBackendFactory* const backend_factory_;
const CreateCdmFactoryCB create_cdm_factory_cb_;
VideoModeSwitcher* video_mode_switcher_;
......
......@@ -31,8 +31,6 @@
#include "media/base/media_log.h"
#include "media/base/media_resource.h"
#include "media/base/renderer_client.h"
#include "services/service_manager/public/cpp/connect.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/mojom/interface_provider.mojom.h"
namespace chromecast {
......@@ -62,14 +60,12 @@ CastRenderer::CastRenderer(
VideoModeSwitcher* video_mode_switcher,
VideoResolutionPolicy* video_resolution_policy,
const base::UnguessableToken& overlay_plane_id,
service_manager::Connector* connector,
service_manager::mojom::InterfaceProvider* host_interfaces)
: backend_factory_(backend_factory),
task_runner_(task_runner),
video_mode_switcher_(video_mode_switcher),
video_resolution_policy_(video_resolution_policy),
overlay_plane_id_(overlay_plane_id),
connector_(connector),
host_interfaces_(host_interfaces),
client_(nullptr),
cast_cdm_context_(nullptr),
......@@ -82,6 +78,12 @@ CastRenderer::CastRenderer(
if (video_resolution_policy_)
video_resolution_policy_->AddObserver(this);
if (host_interfaces_) {
host_interfaces_->GetInterface(
chromecast::mojom::ServiceConnector::Name_,
service_connector_.BindNewPipeAndPassReceiver().PassPipe());
}
}
CastRenderer::~CastRenderer() {
......@@ -161,8 +163,8 @@ void CastRenderer::OnApplicationMediaInfoReceived(
chromecast::mojom::MultiroomInfo::New());
return;
}
connector_->Connect(chromecast::mojom::kChromecastServiceName,
multiroom_manager_.BindNewPipeAndPassReceiver());
service_connector_->Connect(chromecast::mojom::kChromecastServiceName,
multiroom_manager_.BindNewPipeAndPassReceiver());
multiroom_manager_.set_disconnect_handler(
base::BindOnce(&CastRenderer::OnGetMultiroomInfo, base::Unretained(this),
media_resource, client, application_media_info.Clone(),
......@@ -202,7 +204,6 @@ void CastRenderer::OnGetMultiroomInfo(
MediaPipelineDeviceParams params(
sync_type, backend_task_runner_.get(), AudioContentType::kMedia,
::media::AudioDeviceDescription::kDefaultDeviceId);
params.connector = connector_;
params.session_id = application_media_info->application_session_id;
params.multiroom = multiroom_info->multiroom;
params.audio_channel = multiroom_info->audio_channel;
......
......@@ -12,6 +12,7 @@
#include "base/no_destructor.h"
#include "base/unguessable_token.h"
#include "chromecast/common/mojom/multiroom.mojom.h"
#include "chromecast/common/mojom/service_connector.mojom.h"
#include "chromecast/media/base/video_resolution_policy.h"
#include "chromecast/media/cma/backend/cma_backend_factory.h"
#include "chromecast/media/service/mojom/video_geometry_setter.mojom.h"
......@@ -28,7 +29,6 @@ class SingleThreadTaskRunner;
} // namespace base
namespace service_manager {
class Connector;
namespace mojom {
class InterfaceProvider;
} // namespace mojom
......@@ -48,14 +48,12 @@ class CastRenderer : public ::media::Renderer,
public VideoResolutionPolicy::Observer,
public mojom::VideoGeometryChangeClient {
public:
// |connector| provides interfaces for services hosted by ServiceManager.
// |host_interfaces| provides interfaces tied to RenderFrameHost.
CastRenderer(CmaBackendFactory* backend_factory,
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
VideoModeSwitcher* video_mode_switcher,
VideoResolutionPolicy* video_resolution_policy,
const base::UnguessableToken& overlay_plane_id,
service_manager::Connector* connector,
service_manager::mojom::InterfaceProvider* host_interfaces);
~CastRenderer() final;
// For CmaBackend implementation, CastRenderer must be connected to
......@@ -121,7 +119,7 @@ class CastRenderer : public ::media::Renderer,
VideoModeSwitcher* video_mode_switcher_;
VideoResolutionPolicy* video_resolution_policy_;
base::UnguessableToken overlay_plane_id_;
service_manager::Connector* connector_;
mojo::Remote<chromecast::mojom::ServiceConnector> service_connector_;
service_manager::mojom::InterfaceProvider* host_interfaces_;
::media::RendererClient* client_;
......
......@@ -90,8 +90,10 @@ struct MediaPipelineDeviceParams {
// some backends.
TaskRunner* const task_runner;
// connector allows the backend to bind to services through ServiceManager.
service_manager::Connector* connector;
// This field is deprecated.
//
// TODO(yucliu): Remove this field.
service_manager::Connector* const connector;
// Identifies the content type for volume control.
const AudioContentType content_type;
......
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