0

[DIAL] Adds Media Router feature to disable the DIAL MRP.

Chrome Mac developers are asked to disable the entire Media Router to
avoid permission popups from OS X.

This adds a flag so they can disable just DIAL, and use the rest of the
Media Router.

Bug: 808521,1111418
Change-Id: I05fa06a0590c65448cea8a200967880cf7badcad
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3265250
Commit-Queue: mark a. foltz <mfoltz@chromium.org>
Reviewed-by: Takumi Fujimoto <takumif@chromium.org>
Cr-Commit-Position: refs/heads/main@{#940466}
This commit is contained in:
mark a. foltz
2021-11-10 20:38:48 +00:00
committed by Chromium LUCI CQ
parent c91e8151b3
commit a25bb8cc9b
9 changed files with 85 additions and 51 deletions

@ -43,8 +43,8 @@ class CastMediaSinkService : public DnsSdRegistry::DnsSdObserver {
// Starts Cast sink discovery. No-ops if already started.
// |sink_discovery_cb|: Callback to invoke when the list of discovered sinks
// has been updated.
// |dial_media_sink_service|: Pointer to DIAL MediaSinkService for dual
// discovery.
// |dial_media_sink_service|: Optional pointer to DIAL MediaSinkService for
// dual discovery.
// Marked virtual for tests.
virtual void Start(const OnSinksDiscoveredCallback& sinks_discovered_cb,
MediaSinkServiceBase* dial_media_sink_service);

@ -251,7 +251,9 @@ CastMediaSinkServiceImpl::CastMediaSinkServiceImpl(
CastMediaSinkServiceImpl::~CastMediaSinkServiceImpl() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
dial_media_sink_service_->RemoveObserver(this);
if (dial_media_sink_service_) {
dial_media_sink_service_->RemoveObserver(this);
}
network_monitor_->RemoveObserver(this);
cast_socket_service_->RemoveObserver(this);
}
@ -272,7 +274,9 @@ void CastMediaSinkServiceImpl::Start() {
&CastMediaSinkServiceImpl::OnNetworksChanged, GetWeakPtr()));
network_monitor_->AddObserver(this);
dial_media_sink_service_->AddObserver(this);
if (dial_media_sink_service_) {
dial_media_sink_service_->AddObserver(this);
}
std::vector<MediaSinkInternal> test_sinks = GetFixedIPSinksFromCommandLine();
if (!test_sinks.empty())
@ -287,6 +291,9 @@ void CastMediaSinkServiceImpl::RecordDeviceCounts() {
void CastMediaSinkServiceImpl::OnUserGesture() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!dial_media_sink_service_)
return;
// Re-sync sinks from DialMediaSinkService. It's possible that a
// DIAL-discovered sink was added here earlier, but was removed due to flaky
// network. This gives CastMediaSinkServiceImpl an opportunity to recover even
@ -622,7 +629,8 @@ void CastMediaSinkServiceImpl::OnChannelOpenSucceeded(
// a Cast channel to a device that came from DIAL, remove it from
// |dial_media_sink_service_|. This ensures the device shows up as a Cast sink
// only.
dial_media_sink_service_->RemoveSinkById(GetDialSinkIdFromCast(sink_id));
if (dial_media_sink_service_)
dial_media_sink_service_->RemoveSinkById(GetDialSinkIdFromCast(sink_id));
}
void CastMediaSinkServiceImpl::OnChannelOpenFailed(
@ -672,7 +680,9 @@ void CastMediaSinkServiceImpl::TryConnectDialDiscoveredSink(
metrics_.RecordCastSinkDiscoverySource(SinkSource::kMdnsDial);
// Sink is a Cast device; remove from |dial_media_sink_service_| to prevent
// duplicates.
dial_media_sink_service_->RemoveSink(dial_sink);
if (dial_media_sink_service_) {
dial_media_sink_service_->RemoveSink(dial_sink);
}
return;
}

@ -55,7 +55,8 @@ class CastMediaSinkServiceImpl : public MediaSinkServiceBase,
// discovered devices.
// |network_monitor|: DiscoveryNetworkMonitor to use to listen for network
// changes.
// |dial_media_sink_service|: DialMediaSinkServiceImpl for dual discovery.
// |dial_media_sink_service|: Optional pointer to DialMediaSinkServiceImpl for
// |dual discovery.
// |allow_all_ips|: If |true|, |this| will try to open channel to
// sinks on all IPs, and not just private IPs.
CastMediaSinkServiceImpl(const OnSinksDiscoveredCallback& callback,
@ -330,7 +331,7 @@ class CastMediaSinkServiceImpl : public MediaSinkServiceBase,
base::flat_map<MediaSink::Id, int> dial_sink_failure_count_;
// Non-owned pointer to DIAL MediaSinkService. Observed by |this| for dual
// discovery.
// discovery. May be nullptr if the DIAL Media Route Provider is disabled.
MediaSinkServiceBase* const dial_media_sink_service_;
// Mojo Remote to the logger owned by the Media Router. The Remote is not

@ -67,18 +67,19 @@ class MockObserver : public MediaSinkServiceBase::Observer {
} // namespace
class CastMediaSinkServiceImplTest : public ::testing::Test {
class CastMediaSinkServiceImplTest : public ::testing::TestWithParam<bool> {
public:
CastMediaSinkServiceImplTest()
: task_environment_(content::BrowserTaskEnvironment::IO_MAINLOOP),
mock_time_task_runner_(new base::TestMockTimeTaskRunner()),
mock_cast_socket_service_(
new cast_channel::MockCastSocketService(mock_time_task_runner_)),
media_sink_service_impl_(mock_sink_discovered_cb_.Get(),
mock_cast_socket_service_.get(),
discovery_network_monitor_.get(),
&dial_media_sink_service_,
/* allow_all_ips */ false) {
media_sink_service_impl_(
mock_sink_discovered_cb_.Get(),
mock_cast_socket_service_.get(),
discovery_network_monitor_.get(),
GetParam() ? &dial_media_sink_service_ : nullptr,
/* allow_all_ips */ false) {
mock_cast_socket_service_->SetTaskRunnerForTest(mock_time_task_runner_);
media_sink_service_impl_.AddObserver(&observer_);
}
@ -157,7 +158,7 @@ std::vector<DiscoveryNetworkInfo>
CastMediaSinkServiceImplTest::fake_network_info_ =
CastMediaSinkServiceImplTest::fake_ethernet_info_;
TEST_F(CastMediaSinkServiceImplTest, TestOnChannelOpenSucceeded) {
TEST_P(CastMediaSinkServiceImplTest, TestOnChannelOpenSucceeded) {
auto cast_sink = CreateCastSink(1);
net::IPEndPoint ip_endpoint1 = CreateIPEndPoint(1);
cast_channel::MockCastSocket socket;
@ -174,7 +175,7 @@ TEST_F(CastMediaSinkServiceImplTest, TestOnChannelOpenSucceeded) {
mock_timer_->Fire();
}
TEST_F(CastMediaSinkServiceImplTest, TestMultipleOnChannelOpenSucceeded) {
TEST_P(CastMediaSinkServiceImplTest, TestMultipleOnChannelOpenSucceeded) {
MediaSinkInternal cast_sink1 = CreateCastSink(1);
MediaSinkInternal cast_sink2 = CreateCastSink(2);
MediaSinkInternal cast_sink3 = CreateCastSink(3);
@ -236,7 +237,7 @@ TEST_F(CastMediaSinkServiceImplTest, TestMultipleOnChannelOpenSucceeded) {
mock_timer_->Fire();
}
TEST_F(CastMediaSinkServiceImplTest, TestTimer) {
TEST_P(CastMediaSinkServiceImplTest, TestTimer) {
auto cast_sink1 = CreateCastSink(1);
auto cast_sink2 = CreateCastSink(2);
net::IPEndPoint ip_endpoint1 = CreateIPEndPoint(1);
@ -271,7 +272,7 @@ TEST_F(CastMediaSinkServiceImplTest, TestTimer) {
EXPECT_TRUE(mock_timer_->IsRunning());
}
TEST_F(CastMediaSinkServiceImplTest, TestOpenChannelNoRetry) {
TEST_P(CastMediaSinkServiceImplTest, TestOpenChannelNoRetry) {
MediaSinkInternal cast_sink = CreateCastSink(1);
net::IPEndPoint ip_endpoint = CreateIPEndPoint(1);
cast_channel::MockCastSocket socket;
@ -290,7 +291,7 @@ TEST_F(CastMediaSinkServiceImplTest, TestOpenChannelNoRetry) {
cast_sink, nullptr, CastMediaSinkServiceImpl::SinkSource::kMdns);
}
TEST_F(CastMediaSinkServiceImplTest, TestOpenChannelRetryOnce) {
TEST_P(CastMediaSinkServiceImplTest, TestOpenChannelRetryOnce) {
MediaSinkInternal cast_sink = CreateCastSink(1);
net::IPEndPoint ip_endpoint = CreateIPEndPoint(1);
cast_channel::MockCastSocket socket;
@ -313,7 +314,7 @@ TEST_F(CastMediaSinkServiceImplTest, TestOpenChannelRetryOnce) {
mock_time_task_runner_->FastForwardBy(base::Seconds(16));
}
TEST_F(CastMediaSinkServiceImplTest, TestOpenChannelFails) {
TEST_P(CastMediaSinkServiceImplTest, TestOpenChannelFails) {
MediaSinkInternal cast_sink = CreateCastSink(1);
const net::IPEndPoint& ip_endpoint = cast_sink.cast_data().ip_endpoint;
cast_channel::MockCastSocket socket;
@ -331,7 +332,7 @@ TEST_F(CastMediaSinkServiceImplTest, TestOpenChannelFails) {
media_sink_service_impl_.failure_count_map_[cast_sink.sink().id()]);
}
TEST_F(CastMediaSinkServiceImplTest, TestMultipleOpenChannels) {
TEST_P(CastMediaSinkServiceImplTest, TestMultipleOpenChannels) {
auto cast_sink1 = CreateCastSink(1);
auto cast_sink2 = CreateCastSink(2);
auto cast_sink3 = CreateCastSink(3);
@ -401,7 +402,7 @@ TEST_F(CastMediaSinkServiceImplTest, TestMultipleOpenChannels) {
mock_timer_->Fire();
}
TEST_F(CastMediaSinkServiceImplTest, OpenChannelNewIPSameSink) {
TEST_P(CastMediaSinkServiceImplTest, OpenChannelNewIPSameSink) {
MediaSinkInternal cast_sink1 = CreateCastSink(1);
net::IPEndPoint ip_endpoint1 = cast_sink1.cast_data().ip_endpoint;
@ -445,7 +446,7 @@ TEST_F(CastMediaSinkServiceImplTest, OpenChannelNewIPSameSink) {
EXPECT_EQ(cast_sink1, sink_it->second);
}
TEST_F(CastMediaSinkServiceImplTest, OpenChannelUpdatedSinkSameIP) {
TEST_P(CastMediaSinkServiceImplTest, OpenChannelUpdatedSinkSameIP) {
MediaSinkInternal cast_sink = CreateCastSink(1);
net::IPEndPoint ip_endpoint = cast_sink.cast_data().ip_endpoint;
@ -480,7 +481,7 @@ TEST_F(CastMediaSinkServiceImplTest, OpenChannelUpdatedSinkSameIP) {
EXPECT_EQ(cast_sink, sink_it->second);
}
TEST_F(CastMediaSinkServiceImplTest, TestOnChannelOpenFailed) {
TEST_P(CastMediaSinkServiceImplTest, TestOnChannelOpenFailed) {
auto cast_sink = CreateCastSink(1);
net::IPEndPoint ip_endpoint1 = CreateIPEndPoint(1);
cast_channel::MockCastSocket socket;
@ -505,7 +506,7 @@ TEST_F(CastMediaSinkServiceImplTest, TestOnChannelOpenFailed) {
EXPECT_TRUE(media_sink_service_impl_.GetSinks().empty());
}
TEST_F(CastMediaSinkServiceImplTest, TestSuccessOnChannelErrorRetry) {
TEST_P(CastMediaSinkServiceImplTest, TestSuccessOnChannelErrorRetry) {
auto cast_sink = CreateCastSink(1);
net::IPEndPoint ip_endpoint1 = CreateIPEndPoint(1);
cast_channel::MockCastSocket socket;
@ -529,7 +530,7 @@ TEST_F(CastMediaSinkServiceImplTest, TestSuccessOnChannelErrorRetry) {
EXPECT_EQ(1u, media_sink_service_impl_.GetSinks().size());
}
TEST_F(CastMediaSinkServiceImplTest, TestFailureOnChannelErrorRetry) {
TEST_P(CastMediaSinkServiceImplTest, TestFailureOnChannelErrorRetry) {
auto cast_sink = CreateCastSink(1);
net::IPEndPoint ip_endpoint1 = CreateIPEndPoint(1);
cast_channel::MockCastSocket socket;
@ -555,7 +556,7 @@ TEST_F(CastMediaSinkServiceImplTest, TestFailureOnChannelErrorRetry) {
EXPECT_TRUE(media_sink_service_impl_.GetSinks().empty());
}
TEST_F(CastMediaSinkServiceImplTest,
TEST_P(CastMediaSinkServiceImplTest,
TestOnChannelErrorMayRetryForConnectingChannel) {
MediaSinkInternal cast_sink1 = CreateCastSink(1);
media_sink_service_impl_.AddOrUpdateSink(cast_sink1);
@ -581,7 +582,7 @@ TEST_F(CastMediaSinkServiceImplTest,
mock_time_task_runner_->FastForwardUntilNoTasksRemain();
}
TEST_F(CastMediaSinkServiceImplTest, TestOnChannelErrorNoRetryForMissingSink) {
TEST_P(CastMediaSinkServiceImplTest, TestOnChannelErrorNoRetryForMissingSink) {
net::IPEndPoint ip_endpoint1 = CreateIPEndPoint(1);
cast_channel::MockCastSocket socket;
socket.set_id(1);
@ -595,7 +596,11 @@ TEST_F(CastMediaSinkServiceImplTest, TestOnChannelErrorNoRetryForMissingSink) {
mock_time_task_runner_->FastForwardUntilNoTasksRemain();
}
TEST_F(CastMediaSinkServiceImplTest, TestOnSinkAddedOrUpdated) {
TEST_P(CastMediaSinkServiceImplTest, TestOnSinkAddedOrUpdated) {
// If the DialMediaSinkService is not enabled, bypass this test.
if (!GetParam())
return;
// Make sure |media_sink_service_impl_| adds itself as an observer to
// |dial_media_sink_service_|.
media_sink_service_impl_.Start();
@ -643,7 +648,7 @@ TEST_F(CastMediaSinkServiceImplTest, TestOnSinkAddedOrUpdated) {
EXPECT_TRUE(dial_media_sink_service_.GetSinks().empty());
}
TEST_F(CastMediaSinkServiceImplTest,
TEST_P(CastMediaSinkServiceImplTest,
TestOnSinkAddedOrUpdatedSkipsIfNonCastDevice) {
MediaSinkInternal dial_sink1 = CreateDialSink(1);
net::IPEndPoint ip_endpoint1(dial_sink1.dial_data().ip_address,
@ -695,7 +700,7 @@ TEST_F(CastMediaSinkServiceImplTest,
EXPECT_TRUE(media_sink_service_impl_.dial_sink_failure_count_.empty());
}
TEST_F(CastMediaSinkServiceImplTest, OpenChannelsNow) {
TEST_P(CastMediaSinkServiceImplTest, OpenChannelsNow) {
MediaSinkInternal cast_sink1 = CreateCastSink(1);
MediaSinkInternal cast_sink2 = CreateCastSink(2);
const net::IPEndPoint& ip_endpoint1 = cast_sink1.cast_data().ip_endpoint;
@ -714,7 +719,7 @@ TEST_F(CastMediaSinkServiceImplTest, OpenChannelsNow) {
media_sink_service_impl_.OpenChannelsNow(sinks);
}
TEST_F(CastMediaSinkServiceImplTest, CacheSinksForKnownNetwork) {
TEST_P(CastMediaSinkServiceImplTest, CacheSinksForKnownNetwork) {
media_sink_service_impl_.Start();
content::RunAllTasksUntilIdle();
// We need to run the mock task runner for the network change callback, but
@ -779,7 +784,7 @@ TEST_F(CastMediaSinkServiceImplTest, CacheSinksForKnownNetwork) {
mock_time_task_runner_->FastForwardUntilNoTasksRemain();
}
TEST_F(CastMediaSinkServiceImplTest, CacheContainsOnlyResolvedSinks) {
TEST_P(CastMediaSinkServiceImplTest, CacheContainsOnlyResolvedSinks) {
media_sink_service_impl_.Start();
content::RunAllTasksUntilIdle();
// We need to run the mock task runner for the network change callback, but
@ -845,7 +850,7 @@ TEST_F(CastMediaSinkServiceImplTest, CacheContainsOnlyResolvedSinks) {
mock_time_task_runner_->FastForwardUntilNoTasksRemain();
}
TEST_F(CastMediaSinkServiceImplTest, CacheUpdatedOnChannelOpenFailed) {
TEST_P(CastMediaSinkServiceImplTest, CacheUpdatedOnChannelOpenFailed) {
media_sink_service_impl_.Start();
content::RunAllTasksUntilIdle();
// We need to run the mock task runner for the network change callback, but
@ -904,7 +909,7 @@ TEST_F(CastMediaSinkServiceImplTest, CacheUpdatedOnChannelOpenFailed) {
mock_time_task_runner_->FastForwardUntilNoTasksRemain();
}
TEST_F(CastMediaSinkServiceImplTest, UnknownNetworkNoCache) {
TEST_P(CastMediaSinkServiceImplTest, UnknownNetworkNoCache) {
media_sink_service_impl_.Start();
content::RunAllTasksUntilIdle();
// We need to run the mock task runner for the network change callback, but
@ -969,7 +974,7 @@ TEST_F(CastMediaSinkServiceImplTest, UnknownNetworkNoCache) {
mock_time_task_runner_->FastForwardUntilNoTasksRemain();
}
TEST_F(CastMediaSinkServiceImplTest, CacheUpdatedForKnownNetwork) {
TEST_P(CastMediaSinkServiceImplTest, CacheUpdatedForKnownNetwork) {
media_sink_service_impl_.Start();
content::RunAllTasksUntilIdle();
// We need to run the mock task runner for the network change callback, but
@ -1065,7 +1070,7 @@ TEST_F(CastMediaSinkServiceImplTest, CacheUpdatedForKnownNetwork) {
mock_time_task_runner_->FastForwardUntilNoTasksRemain();
}
TEST_F(CastMediaSinkServiceImplTest, CacheDialDiscoveredSinks) {
TEST_P(CastMediaSinkServiceImplTest, CacheDialDiscoveredSinks) {
media_sink_service_impl_.Start();
content::RunAllTasksUntilIdle();
// We need to run the mock task runner for the network change callback, but
@ -1150,7 +1155,7 @@ TEST_F(CastMediaSinkServiceImplTest, CacheDialDiscoveredSinks) {
mock_time_task_runner_->FastForwardUntilNoTasksRemain();
}
TEST_F(CastMediaSinkServiceImplTest, DualDiscoveryDoesntDuplicateCacheItems) {
TEST_P(CastMediaSinkServiceImplTest, DualDiscoveryDoesntDuplicateCacheItems) {
media_sink_service_impl_.Start();
content::RunAllTasksUntilIdle();
// We need to run the mock task runner for the network change callback, but
@ -1222,7 +1227,7 @@ TEST_F(CastMediaSinkServiceImplTest, DualDiscoveryDoesntDuplicateCacheItems) {
mock_time_task_runner_->FastForwardUntilNoTasksRemain();
}
TEST_F(CastMediaSinkServiceImplTest, CacheSinksForDirectNetworkChange) {
TEST_P(CastMediaSinkServiceImplTest, CacheSinksForDirectNetworkChange) {
media_sink_service_impl_.Start();
content::RunAllTasksUntilIdle();
// We need to run the mock task runner for the network change callback, but
@ -1277,7 +1282,7 @@ TEST_F(CastMediaSinkServiceImplTest, CacheSinksForDirectNetworkChange) {
mock_time_task_runner_->FastForwardUntilNoTasksRemain();
}
TEST_F(CastMediaSinkServiceImplTest, TestCreateCastSocketOpenParams) {
TEST_P(CastMediaSinkServiceImplTest, TestCreateCastSocketOpenParams) {
MediaSinkInternal cast_sink1 = CreateCastSink(1);
const MediaSink::Id& sink_id = cast_sink1.sink().id();
int connect_timeout_in_seconds =
@ -1327,4 +1332,8 @@ TEST_F(CastMediaSinkServiceImplTest, TestCreateCastSocketOpenParams) {
open_params.liveness_timeout.InSeconds());
}
INSTANTIATE_TEST_SUITE_P(DialMediaSinkServiceEnabled,
CastMediaSinkServiceImplTest,
testing::Bool());
} // namespace media_router

@ -35,6 +35,8 @@ const base::Feature kGlobalMediaControlsCastStartStop{
"GlobalMediaControlsCastStartStop", base::FEATURE_DISABLED_BY_DEFAULT};
const base::Feature kAllowAllSitesToInitiateMirroring{
"AllowAllSitesToInitiateMirroring", base::FEATURE_DISABLED_BY_DEFAULT};
const base::Feature kDialMediaRouteProvider{"DialMediaRouteProvider",
base::FEATURE_ENABLED_BY_DEFAULT};
#endif // !defined(OS_ANDROID)
namespace {
@ -126,6 +128,10 @@ std::string GetReceiverIdHashToken(PrefService* pref_service) {
return token;
}
bool DialMediaRouteProviderEnabled() {
return base::FeatureList::IsEnabled(kDialMediaRouteProvider);
}
bool GlobalMediaControlsCastStartStopEnabled() {
return base::FeatureList::IsEnabled(kGlobalMediaControlsCastStartStop);
}

@ -79,7 +79,8 @@ bool GetCastAllowAllIPsPref(PrefService* pref_service);
// randomly generated string and stored in |pref_service|.
std::string GetReceiverIdHashToken(PrefService* pref_service);
// Returns true if browser side DIAL Media Route Provider is enabled.
// Returns true if support for DIAL devices is enabled. Disabling DIAL support
// also disables SSDP-based discovery for Cast devices.
bool DialMediaRouteProviderEnabled();
// Returns true if global media controls are used to start and stop casting.

@ -145,7 +145,9 @@ void MediaRouterDesktop::InitializeMediaRouteProviders() {
InitializeWiredDisplayMediaRouteProvider();
InitializeCastMediaRouteProvider();
InitializeDialMediaRouteProvider();
if (DialMediaRouteProviderEnabled()) {
InitializeDialMediaRouteProvider();
}
}
void MediaRouterDesktop::InitializeWiredDisplayMediaRouteProvider() {

@ -75,16 +75,18 @@ bool DualMediaSinkService::MdnsDiscoveryStarted() {
}
DualMediaSinkService::DualMediaSinkService() {
dial_media_sink_service_ = std::make_unique<DialMediaSinkService>();
dial_media_sink_service_->Start(
base::BindRepeating(&DualMediaSinkService::OnSinksDiscovered,
base::Unretained(this), "dial"));
if (DialMediaRouteProviderEnabled()) {
dial_media_sink_service_ = std::make_unique<DialMediaSinkService>();
dial_media_sink_service_->Start(
base::BindRepeating(&DualMediaSinkService::OnSinksDiscovered,
base::Unretained(this), "dial"));
}
cast_media_sink_service_ = std::make_unique<CastMediaSinkService>();
cast_media_sink_service_->Start(
base::BindRepeating(&DualMediaSinkService::OnSinksDiscovered,
base::Unretained(this), "cast"),
dial_media_sink_service_->impl());
dial_media_sink_service_ ? dial_media_sink_service_->impl() : nullptr);
cast_channel::CastSocketService* cast_socket_service =
cast_channel::CastSocketService::GetInstance();
@ -119,9 +121,12 @@ void DualMediaSinkService::BindLogger(LoggerImpl* logger_impl) {
logger_is_bound_ = true;
cast_media_sink_service_->BindLogger(logger_impl);
mojo::PendingRemote<mojom::Logger> dial_pending_remote;
logger_impl->Bind(dial_pending_remote.InitWithNewPipeAndPassReceiver());
dial_media_sink_service_->BindLogger(std::move(dial_pending_remote));
if (dial_media_sink_service_) {
mojo::PendingRemote<mojom::Logger> dial_pending_remote;
logger_impl->Bind(dial_pending_remote.InitWithNewPipeAndPassReceiver());
dial_media_sink_service_->BindLogger(std::move(dial_pending_remote));
}
mojo::PendingRemote<mojom::Logger> cast_discovery_pending_remote;
logger_impl->Bind(
cast_discovery_pending_remote.InitWithNewPipeAndPassReceiver());

@ -194,7 +194,7 @@ Every time you start a new developer build of Chrome you get a system dialog
asking "Do you want the application Chromium.app to accept incoming
network connections?" - to avoid this, run with this command-line flag:
--disable-features="MediaRouter"
--disable-features="DialMediaRouteProvider"
## Running test targets