Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1294)

Side by Side Diff: chrome/browser/media/cast_remoting_connector_unittest.cc

Issue 2951523002: Media Remoting: Add mojo interfaces between browser and extension. (Closed)
Patch Set: Rebased again. Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/media/cast_remoting_connector.h" 5 #include "chrome/browser/media/cast_remoting_connector.h"
6 6
7 #include <utility> 7 #include <utility>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/callback.h" 10 #include "base/callback.h"
11 #include "base/memory/ptr_util.h"
11 #include "base/memory/weak_ptr.h" 12 #include "base/memory/weak_ptr.h"
12 #include "base/run_loop.h" 13 #include "base/run_loop.h"
13 #include "chrome/browser/media/router/media_routes_observer.h"
14 #include "chrome/browser/media/router/mock_media_router.h" 14 #include "chrome/browser/media/router/mock_media_router.h"
15 #include "chrome/browser/media/router/route_message_observer.h"
16 #include "chrome/browser/media/router/test_helper.h"
17 #include "chrome/common/media_router/media_route.h" 15 #include "chrome/common/media_router/media_route.h"
18 #include "chrome/common/media_router/media_source.h" 16 #include "chrome/common/media_router/media_source.h"
19 #include "content/public/browser/browser_thread.h" 17 #include "content/public/browser/browser_thread.h"
20 #include "content/public/common/presentation_connection_message.h"
21 #include "content/public/test/test_browser_thread_bundle.h" 18 #include "content/public/test/test_browser_thread_bundle.h"
19 #include "media/mojo/interfaces/mirror_service_remoting.mojom.h"
22 #include "media/mojo/interfaces/remoting.mojom.h" 20 #include "media/mojo/interfaces/remoting.mojom.h"
23 #include "mojo/public/cpp/bindings/binding.h" 21 #include "mojo/public/cpp/bindings/binding.h"
24 #include "testing/gmock/include/gmock/gmock.h" 22 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h" 23 #include "testing/gtest/include/gtest/gtest.h"
26 24
27 using content::BrowserThread; 25 using content::BrowserThread;
28 using content::PresentationConnectionMessage;
29 26
30 using media::mojom::RemoterPtr; 27 using media::mojom::RemoterPtr;
31 using media::mojom::RemoterRequest; 28 using media::mojom::RemoterRequest;
32 using media::mojom::RemotingSinkCapabilities; 29 using media::mojom::RemotingSinkCapabilities;
33 using media::mojom::RemotingSourcePtr; 30 using media::mojom::RemotingSourcePtr;
34 using media::mojom::RemotingSourceRequest; 31 using media::mojom::RemotingSourceRequest;
35 using media::mojom::RemotingStartFailReason; 32 using media::mojom::RemotingStartFailReason;
36 using media::mojom::RemotingStopReason; 33 using media::mojom::RemotingStopReason;
37 34 using media::mojom::MirrorServiceRemoterPtr;
38 using media_router::MediaRoutesObserver; 35 using media::mojom::MirrorServiceRemoterRequest;
39 using media_router::MediaRoute; 36 using media::mojom::MirrorServiceRemotingSourcePtr;
40 using media_router::MediaSource; 37 using media::mojom::MirrorServiceRemotingSourceRequest;
41 using media_router::PresentationConnectionMessageToString;
42 using media_router::RouteMessageObserver;
43 38
44 using ::testing::_; 39 using ::testing::_;
45 using ::testing::AtLeast; 40 using ::testing::AtLeast;
46 41
47 namespace { 42 namespace {
48 43
49 constexpr char kRemotingMediaSource[] = 44 constexpr int32_t kRemotingTabId = 2;
50 "urn:x-org.chromium.media:source:tab_content_remoting:123";
51 constexpr char kRemotingMediaSink[] = "wiggles";
52 constexpr char kRemotingMediaRoute[] =
53 "urn:x-org.chromium:media:route:garbly_gook_ssi7m4oa8oma7rasd/cast-wiggles";
54
55 constexpr char kTabMirroringMediaSource[] =
56 "urn:x-org.chromium.media:source:tab:123";
57 constexpr char kTabMirroringMediaRoute[] =
58 "urn:x-org.chromium:media:route:bloopity_blop_ohun48i56nh9oid/cast-wiggles";
59 45
60 constexpr RemotingSinkCapabilities kAllCapabilities = 46 constexpr RemotingSinkCapabilities kAllCapabilities =
61 RemotingSinkCapabilities::CONTENT_DECRYPTION_AND_RENDERING; 47 RemotingSinkCapabilities::CONTENT_DECRYPTION_AND_RENDERING;
62 48
63 // Implements basic functionality of a subset of the MediaRouter for use by the 49 // Implements basic functionality of a subset of the MediaRouter for use by the
64 // unit tests in this module. Note that MockMediaRouter will complain at runtime 50 // unit tests in this module. Note that MockMediaRouter will complain at runtime
65 // if any methods were called that should not have been called. 51 // if any methods were called that should not have been called.
66 class FakeMediaRouter : public media_router::MockMediaRouter { 52 class FakeMediaRouter : public media_router::MockMediaRouter {
67 public: 53 public:
68 FakeMediaRouter() 54 FakeMediaRouter() : weak_factory_(this) {}
69 : routes_observer_(nullptr), message_observer_(nullptr),
70 weak_factory_(this) {}
71 ~FakeMediaRouter() final {} 55 ~FakeMediaRouter() final {}
72 56
73 // 57 void RegisterRemotingSource(int32_t tab_id,
74 // These methods are called by test code to create/destroy a media route and 58 CastRemotingConnector* remoting_source) final {
75 // pass messages in both directions. 59 EXPECT_EQ(-1, tab_id_);
76 // 60 tab_id_ = tab_id;
77 61 connector_ = remoting_source;
78 void OnRemotingRouteExists(bool exists) {
79 routes_.clear();
80
81 // Always add a non-remoting route to make sure CastRemotingConnector
82 // ignores non-remoting routes.
83 routes_.push_back(MediaRoute(
84 kTabMirroringMediaRoute, MediaSource(kTabMirroringMediaSource),
85 kRemotingMediaSink, "Cast Tab Mirroring", false, "", false));
86
87 if (exists) {
88 routes_.push_back(MediaRoute(
89 kRemotingMediaRoute, MediaSource(kRemotingMediaSource),
90 kRemotingMediaSink, "Cast Media Remoting", false, "", false));
91 } else {
92 // Cancel delivery of all messages in both directions.
93 inbound_messages_.clear();
94 for (auto& entry : outbound_messages_) {
95 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
96 base::BindOnce(std::move(entry.second), false));
97 }
98 outbound_messages_.clear();
99 }
100
101 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
102 base::BindOnce(&FakeMediaRouter::DoUpdateRoutes,
103 weak_factory_.GetWeakPtr()));
104 } 62 }
105 63
106 void OnMessageFromProvider(const std::string& message) { 64 void UnregisterRemotingSource(int32_t tab_id) final {
107 inbound_messages_.emplace_back(message); 65 EXPECT_EQ(tab_id, tab_id_);
108 BrowserThread::PostTask( 66 tab_id_ = -1;
109 BrowserThread::UI, FROM_HERE, 67 connector_ = nullptr;
110 base::BindOnce(&FakeMediaRouter::DoDeliverInboundMessages,
111 weak_factory_.GetWeakPtr()));
112 } 68 }
113 69
114 void OnBinaryMessageFromProvider(const std::vector<uint8_t>& message) { 70 void OnMediaRemoterCreated(
115 inbound_messages_.emplace_back(message); 71 int32_t tab_id,
116 BrowserThread::PostTask( 72 MirrorServiceRemoterPtr remoter,
117 BrowserThread::UI, FROM_HERE, 73 MirrorServiceRemotingSourceRequest remoting_source) {
118 base::BindOnce(&FakeMediaRouter::DoDeliverInboundMessages, 74 if (tab_id != tab_id_)
119 weak_factory_.GetWeakPtr())); 75 return;
76
77 EXPECT_TRUE(connector_);
78 connector_->ConnectToService(std::move(remoting_source),
79 std::move(remoter));
120 } 80 }
121 81
122 void TakeMessagesSentToProvider( 82 // Get the registered tab ID.
123 bool text, 83 int32_t tab_id() const { return tab_id_; }
124 std::vector<PresentationConnectionMessage>* messages) {
125 decltype(outbound_messages_) untaken_messages;
126 for (auto& entry : outbound_messages_) {
127 if (!entry.first.is_binary() == text) {
128 messages->push_back(entry.first);
129 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
130 base::BindOnce(std::move(entry.second), true));
131 } else {
132 untaken_messages.push_back(std::move(entry));
133 }
134 }
135 outbound_messages_.swap(untaken_messages);
136 }
137
138 protected:
139 void RegisterMediaRoutesObserver(MediaRoutesObserver* observer) final {
140 CHECK(!routes_observer_);
141 routes_observer_ = observer;
142 CHECK(routes_observer_);
143 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
144 base::BindOnce(&FakeMediaRouter::DoUpdateRoutes,
145 weak_factory_.GetWeakPtr()));
146 }
147
148 void UnregisterMediaRoutesObserver(MediaRoutesObserver* observer) final {
149 CHECK_EQ(routes_observer_, observer);
150 routes_observer_ = nullptr;
151 }
152
153 void RegisterRouteMessageObserver(RouteMessageObserver* observer) final {
154 CHECK(!message_observer_);
155 message_observer_ = observer;
156 CHECK(message_observer_);
157 }
158
159 void UnregisterRouteMessageObserver(RouteMessageObserver* observer) final {
160 CHECK_EQ(message_observer_, observer);
161 message_observer_ = nullptr;
162 }
163
164 void SendRouteMessage(const MediaRoute::Id& route_id,
165 const std::string& text,
166 SendRouteMessageCallback callback) final {
167 EXPECT_EQ(message_observer_->route_id(), route_id);
168 ASSERT_FALSE(callback.is_null());
169 PresentationConnectionMessage message(text);
170 outbound_messages_.emplace_back(std::move(message), std::move(callback));
171 }
172
173 void SendRouteBinaryMessage(const MediaRoute::Id& route_id,
174 std::unique_ptr<std::vector<uint8_t>> data,
175 SendRouteMessageCallback callback) final {
176 EXPECT_EQ(message_observer_->route_id(), route_id);
177 ASSERT_TRUE(!!data);
178 ASSERT_FALSE(callback.is_null());
179 PresentationConnectionMessage message(std::move(*data));
180 outbound_messages_.emplace_back(std::move(message), std::move(callback));
181 }
182 84
183 private: 85 private:
184 // Asynchronous callback to notify the MediaRoutesObserver of a change in 86 int32_t tab_id_ = -1;
185 // routes. 87 CastRemotingConnector* connector_ = nullptr;
186 void DoUpdateRoutes() {
187 if (routes_observer_)
188 routes_observer_->OnRoutesUpdated(routes_, std::vector<MediaRoute::Id>());
189 }
190
191 // Asynchronous callback to deliver messages to the RouteMessageObserver.
192 void DoDeliverInboundMessages() {
193 if (message_observer_)
194 message_observer_->OnMessagesReceived(inbound_messages_);
195 inbound_messages_.clear();
196 }
197
198 MediaRoutesObserver* routes_observer_;
199 RouteMessageObserver* message_observer_;
200
201 std::vector<MediaRoute> routes_;
202 // Messages from Cast Provider to the connector.
203 std::vector<PresentationConnectionMessage> inbound_messages_;
204 // Messages from the connector to the Cast Provider.
205 using OutboundMessageAndCallback =
206 std::pair<PresentationConnectionMessage, SendRouteMessageCallback>;
207 std::vector<OutboundMessageAndCallback> outbound_messages_;
208 88
209 base::WeakPtrFactory<FakeMediaRouter> weak_factory_; 89 base::WeakPtrFactory<FakeMediaRouter> weak_factory_;
210 }; 90 };
211 91
212 class MockRemotingSource : public media::mojom::RemotingSource { 92 class MockRemotingSource : public media::mojom::RemotingSource {
213 public: 93 public:
214 MockRemotingSource() : binding_(this) {} 94 MockRemotingSource() : binding_(this) {}
215 ~MockRemotingSource() final {} 95 ~MockRemotingSource() final {}
216 96
217 void Bind(RemotingSourceRequest request) { 97 void Bind(RemotingSourceRequest request) {
218 binding_.Bind(std::move(request)); 98 binding_.Bind(std::move(request));
219 } 99 }
220 100
221 MOCK_METHOD1(OnSinkAvailable, void(RemotingSinkCapabilities)); 101 MOCK_METHOD1(OnSinkAvailable, void(RemotingSinkCapabilities));
222 MOCK_METHOD0(OnSinkGone, void()); 102 MOCK_METHOD0(OnSinkGone, void());
223 MOCK_METHOD0(OnStarted, void()); 103 MOCK_METHOD0(OnStarted, void());
224 MOCK_METHOD1(OnStartFailed, void(RemotingStartFailReason)); 104 MOCK_METHOD1(OnStartFailed, void(RemotingStartFailReason));
225 MOCK_METHOD1(OnMessageFromSink, void(const std::vector<uint8_t>&)); 105 MOCK_METHOD1(OnMessageFromSink, void(const std::vector<uint8_t>&));
226 MOCK_METHOD1(OnStopped, void(RemotingStopReason)); 106 MOCK_METHOD1(OnStopped, void(RemotingStopReason));
227 107
228 private: 108 private:
229 mojo::Binding<media::mojom::RemotingSource> binding_; 109 mojo::Binding<media::mojom::RemotingSource> binding_;
230 }; 110 };
231 111
112 class MockMediaRemoter : public media::mojom::MirrorServiceRemoter {
113 public:
114 explicit MockMediaRemoter(FakeMediaRouter* media_router) : binding_(this) {
115 MirrorServiceRemoterPtr remoter;
116 binding_.Bind(mojo::MakeRequest(&remoter));
117 media_router->OnMediaRemoterCreated(kRemotingTabId, std::move(remoter),
118 mojo::MakeRequest(&source_));
119 }
120 ~MockMediaRemoter() final {}
121
122 void OnSinkAvailable() {
123 media::mojom::SinkCapabilitiesPtr capabilities =
124 media::mojom::SinkCapabilities::New();
125 source_->OnSinkAvailable(std::move(capabilities));
126 }
127
128 void SendMessageToSource(const std::vector<uint8_t>& message) {
129 source_->OnMessageFromSink(message);
130 }
131
132 void OnStopped(RemotingStopReason reason) { source_->OnStopped(reason); }
133
134 void OnError() { source_->OnError(); }
135
136 // media::mojom::MirrorServiceRemoter implementations.
137 void StartDataStreams(bool audio,
138 bool video,
139 StartDataStreamsCallback callback) override {}
140 MOCK_METHOD0(Start, void());
141 MOCK_METHOD1(Stop, void(RemotingStopReason));
142 MOCK_METHOD1(SendMessageToSink, void(const std::vector<uint8_t>&));
143
144 private:
145 mojo::Binding<media::mojom::MirrorServiceRemoter> binding_;
146 MirrorServiceRemotingSourcePtr source_;
147 };
148
232 } // namespace 149 } // namespace
233 150
234 class CastRemotingConnectorTest : public ::testing::Test { 151 class CastRemotingConnectorTest : public ::testing::Test {
235 public: 152 public:
236 CastRemotingConnectorTest() 153 CastRemotingConnectorTest() : connector_(&media_router_, kRemotingTabId) {
237 : connector_(&media_router_, kRemotingMediaSource) {
238 // HACK: Override feature flags for testing. 154 // HACK: Override feature flags for testing.
239 const_cast<RemotingSinkCapabilities&>(connector_.enabled_features_) = 155 const_cast<RemotingSinkCapabilities&>(connector_.enabled_features_) =
240 kAllCapabilities; 156 kAllCapabilities;
157
158 EXPECT_EQ(kRemotingTabId, media_router_.tab_id());
241 } 159 }
242 160
243 void TearDown() final { 161 void TearDown() final {
244 // Allow any pending Mojo operations to complete before destruction. For 162 // Allow any pending Mojo operations to complete before destruction. For
245 // example, when one end of a Mojo message pipe is closed, a task is posted 163 // example, when one end of a Mojo message pipe is closed, a task is posted
246 // to later destroy objects that were owned by the message pipe. 164 // to later destroy objects that were owned by the message pipe.
247 RunUntilIdle(); 165 RunUntilIdle();
248 } 166 }
249 167
250 protected: 168 protected:
251 RemoterPtr CreateRemoter(MockRemotingSource* source) { 169 RemoterPtr CreateRemoter(MockRemotingSource* source) {
252 RemotingSourcePtr source_ptr; 170 RemotingSourcePtr source_ptr;
253 source->Bind(mojo::MakeRequest(&source_ptr)); 171 source->Bind(mojo::MakeRequest(&source_ptr));
254 RemoterPtr remoter_ptr; 172 RemoterPtr remoter_ptr;
255 connector_.CreateBridge(std::move(source_ptr), 173 connector_.CreateBridge(std::move(source_ptr),
256 mojo::MakeRequest(&remoter_ptr)); 174 mojo::MakeRequest(&remoter_ptr));
257 return remoter_ptr; 175 return remoter_ptr;
258 } 176 }
259 177
260 void ProviderDiscoversSink() {
261 media_router_.OnRemotingRouteExists(true);
262 }
263
264 void ProviderLosesSink() {
265 media_router_.OnRemotingRouteExists(false);
266 }
267
268 void ConnectorSentMessageToProvider(const std::string& expected_message) {
269 std::vector<PresentationConnectionMessage> messages;
270 media_router_.TakeMessagesSentToProvider(true, &messages);
271 bool did_see_expected_message = false;
272 for (const auto& message : messages) {
273 if (expected_message == message.message) {
274 did_see_expected_message = true;
275 } else {
276 ADD_FAILURE() << "Unexpected message: "
277 << PresentationConnectionMessageToString(message);
278 }
279 }
280 EXPECT_TRUE(did_see_expected_message);
281 }
282
283 void ConnectorSentMessageToSink(
284 const std::vector<uint8_t>& expected_message) {
285 std::vector<PresentationConnectionMessage> messages;
286 media_router_.TakeMessagesSentToProvider(false, &messages);
287 bool did_see_expected_message = false;
288 for (const auto& message : messages) {
289 if (expected_message == message.data) {
290 did_see_expected_message = true;
291 } else {
292 ADD_FAILURE() << "Unexpected message: "
293 << PresentationConnectionMessageToString(message);
294 }
295 }
296 EXPECT_TRUE(did_see_expected_message);
297 }
298
299 void ConnectorSentNoMessagesToProvider() {
300 std::vector<PresentationConnectionMessage> messages;
301 media_router_.TakeMessagesSentToProvider(true, &messages);
302 EXPECT_TRUE(messages.empty());
303 }
304
305 void ConnectorSentNoMessagesToSink() {
306 std::vector<PresentationConnectionMessage> messages;
307 media_router_.TakeMessagesSentToProvider(false, &messages);
308 EXPECT_TRUE(messages.empty());
309 }
310
311 void ProviderPassesMessageFromSink(
312 const std::vector<uint8_t>& message) {
313 media_router_.OnBinaryMessageFromProvider(message);
314 }
315
316 void ProviderSaysToRemotingConnector(const std::string& message) {
317 media_router_.OnMessageFromProvider(message);
318 }
319
320 void MediaRouterTerminatesRoute() {
321 media_router_.OnRemotingRouteExists(false);
322 }
323
324 static void RunUntilIdle() { 178 static void RunUntilIdle() {
325 base::RunLoop().RunUntilIdle(); 179 base::RunLoop().RunUntilIdle();
326 } 180 }
327 181
182 FakeMediaRouter media_router_;
183
328 private: 184 private:
329 content::TestBrowserThreadBundle browser_thread_bundle_; 185 content::TestBrowserThreadBundle browser_thread_bundle_;
330 FakeMediaRouter media_router_;
331 CastRemotingConnector connector_; 186 CastRemotingConnector connector_;
332 }; 187 };
333 188
334 TEST_F(CastRemotingConnectorTest, NeverNotifiesThatSinkIsAvailable) { 189 TEST_F(CastRemotingConnectorTest, NeverNotifiesThatSinkIsAvailable) {
335 MockRemotingSource source; 190 MockRemotingSource source;
336 RemoterPtr remoter = CreateRemoter(&source); 191 RemoterPtr remoter = CreateRemoter(&source);
337 192
338 EXPECT_CALL(source, OnSinkAvailable(_)).Times(0); 193 EXPECT_CALL(source, OnSinkAvailable(_)).Times(0);
339 EXPECT_CALL(source, OnSinkGone()).Times(AtLeast(0)); 194 EXPECT_CALL(source, OnSinkGone()).Times(AtLeast(0));
340 RunUntilIdle(); 195 RunUntilIdle();
341 } 196 }
342 197
343 TEST_F(CastRemotingConnectorTest, NotifiesWhenSinkIsAvailableAndThenGone) { 198 TEST_F(CastRemotingConnectorTest, NotifiesWhenSinkIsAvailableAndThenGone) {
344 MockRemotingSource source; 199 MockRemotingSource source;
345 RemoterPtr remoter = CreateRemoter(&source); 200 RemoterPtr remoter = CreateRemoter(&source);
346 201
202 std::unique_ptr<MockMediaRemoter> media_remoter =
203 base::MakeUnique<MockMediaRemoter>(&media_router_);
204
347 EXPECT_CALL(source, OnSinkAvailable(kAllCapabilities)).Times(1); 205 EXPECT_CALL(source, OnSinkAvailable(kAllCapabilities)).Times(1);
348 ProviderDiscoversSink(); 206 media_remoter->OnSinkAvailable();
349 RunUntilIdle(); 207 RunUntilIdle();
350 208
351 EXPECT_CALL(source, OnSinkGone()).Times(AtLeast(1)); 209 EXPECT_CALL(source, OnSinkGone()).Times(AtLeast(1));
352 ProviderLosesSink(); 210 media_remoter.reset();
353 RunUntilIdle(); 211 RunUntilIdle();
354 } 212 }
355 213
356 TEST_F(CastRemotingConnectorTest, 214 TEST_F(CastRemotingConnectorTest,
357 NotifiesMultipleSourcesWhenSinkIsAvailableAndThenGone) { 215 NotifiesMultipleSourcesWhenSinkIsAvailableAndThenGone) {
358 MockRemotingSource source1; 216 MockRemotingSource source1;
359 RemoterPtr remoter1 = CreateRemoter(&source1); 217 RemoterPtr remoter1 = CreateRemoter(&source1);
360 MockRemotingSource source2; 218 MockRemotingSource source2;
361 RemoterPtr remoter2 = CreateRemoter(&source2); 219 RemoterPtr remoter2 = CreateRemoter(&source2);
362 220
221 std::unique_ptr<MockMediaRemoter> media_remoter =
222 base::MakeUnique<MockMediaRemoter>(&media_router_);
223
363 EXPECT_CALL(source1, OnSinkAvailable(kAllCapabilities)).Times(1); 224 EXPECT_CALL(source1, OnSinkAvailable(kAllCapabilities)).Times(1);
364 EXPECT_CALL(source2, OnSinkAvailable(kAllCapabilities)).Times(1); 225 EXPECT_CALL(source2, OnSinkAvailable(kAllCapabilities)).Times(1);
365 ProviderDiscoversSink(); 226 media_remoter->OnSinkAvailable();
366 RunUntilIdle(); 227 RunUntilIdle();
367 228
368 EXPECT_CALL(source1, OnSinkGone()).Times(AtLeast(1)); 229 EXPECT_CALL(source1, OnSinkGone()).Times(AtLeast(1));
369 EXPECT_CALL(source2, OnSinkGone()).Times(AtLeast(1)); 230 EXPECT_CALL(source2, OnSinkGone()).Times(AtLeast(1));
370 ProviderLosesSink(); 231 media_remoter.reset();
371 RunUntilIdle(); 232 RunUntilIdle();
372 } 233 }
373 234
374 TEST_F(CastRemotingConnectorTest, HandlesTeardownOfRemotingSourceFirst) { 235 TEST_F(CastRemotingConnectorTest, HandlesTeardownOfRemotingSourceFirst) {
375 std::unique_ptr<MockRemotingSource> source(new MockRemotingSource); 236 std::unique_ptr<MockRemotingSource> source(new MockRemotingSource);
376 RemoterPtr remoter = CreateRemoter(source.get()); 237 RemoterPtr remoter = CreateRemoter(source.get());
377 238
239 std::unique_ptr<MockMediaRemoter> media_remoter =
240 base::MakeUnique<MockMediaRemoter>(&media_router_);
241
378 EXPECT_CALL(*source, OnSinkAvailable(kAllCapabilities)).Times(1); 242 EXPECT_CALL(*source, OnSinkAvailable(kAllCapabilities)).Times(1);
379 ProviderDiscoversSink(); 243 media_remoter->OnSinkAvailable();
380 RunUntilIdle(); 244 RunUntilIdle();
381 245
382 source.reset(); 246 source.reset();
383 RunUntilIdle(); 247 RunUntilIdle();
384 } 248 }
385 249
386 TEST_F(CastRemotingConnectorTest, HandlesTeardownOfRemoterFirst) { 250 TEST_F(CastRemotingConnectorTest, HandlesTeardownOfRemoterFirst) {
387 MockRemotingSource source; 251 MockRemotingSource source;
388 RemoterPtr remoter = CreateRemoter(&source); 252 RemoterPtr remoter = CreateRemoter(&source);
389 253
254 std::unique_ptr<MockMediaRemoter> media_remoter =
255 base::MakeUnique<MockMediaRemoter>(&media_router_);
256
390 EXPECT_CALL(source, OnSinkAvailable(kAllCapabilities)).Times(1); 257 EXPECT_CALL(source, OnSinkAvailable(kAllCapabilities)).Times(1);
391 ProviderDiscoversSink(); 258 media_remoter->OnSinkAvailable();
392 RunUntilIdle(); 259 RunUntilIdle();
393 260
394 remoter.reset(); 261 remoter.reset();
395 RunUntilIdle(); 262 RunUntilIdle();
396 } 263 }
397 264
265 TEST_F(CastRemotingConnectorTest, NoConnectedMediaRemoter) {
266 MockRemotingSource source;
267 RemoterPtr remoter = CreateRemoter(&source);
268
269 EXPECT_CALL(source,
270 OnStartFailed(RemotingStartFailReason::SERVICE_NOT_CONNECTED))
271 .Times(1);
272 remoter->Start();
273 RunUntilIdle();
274 }
275
398 namespace { 276 namespace {
399 277
400 // The possible ways a remoting session may be terminated in the "full 278 // The possible ways a remoting session may be terminated in the "full
401 // run-through" tests. 279 // run-through" tests.
402 enum HowItEnds { 280 enum HowItEnds {
403 SOURCE_TERMINATES, // The render process decides to end remoting. 281 SOURCE_TERMINATES, // The render process decides to end remoting.
404 MOJO_PIPE_CLOSES, // A Mojo message pipe closes unexpectedly. 282 MOJO_PIPE_CLOSES, // A Mojo message pipe closes unexpectedly.
405 ROUTE_TERMINATES, // The Media Router UI was used to terminate the route. 283 ROUTE_TERMINATES, // The Media Router UI was used to terminate the route.
406 EXTERNAL_FAILURE, // The sink is cut-off, perhaps due to a network outage. 284 EXTERNAL_FAILURE, // The sink is cut-off, perhaps due to a network outage.
407 }; 285 };
408 286
409 } // namespace 287 } // namespace
410 288
411 class CastRemotingConnectorFullSessionTest 289 class CastRemotingConnectorFullSessionTest
412 : public CastRemotingConnectorTest, 290 : public CastRemotingConnectorTest,
413 public ::testing::WithParamInterface<HowItEnds> { 291 public ::testing::WithParamInterface<HowItEnds> {
414 public: 292 public:
415 HowItEnds how_it_ends() const { return GetParam(); } 293 HowItEnds how_it_ends() const { return GetParam(); }
416 }; 294 };
417 295
418 // Performs a full run-through of starting and stopping remoting, with 296 // Performs a full run-through of starting and stopping remoting, with
419 // communications between source and sink established at the correct times, and 297 // communications between source and sink established at the correct times, and
420 // tests that end-to-end behavior is correct depending on what caused the 298 // tests that end-to-end behavior is correct depending on what caused the
421 // remoting session to end. 299 // remoting session to end.
422 TEST_P(CastRemotingConnectorFullSessionTest, GoesThroughAllTheMotions) { 300 TEST_P(CastRemotingConnectorFullSessionTest, GoesThroughAllTheMotions) {
423 std::unique_ptr<MockRemotingSource> source(new MockRemotingSource()); 301 std::unique_ptr<MockRemotingSource> source(new MockRemotingSource());
424 RemoterPtr remoter = CreateRemoter(source.get()); 302 RemoterPtr remoter = CreateRemoter(source.get());
425 std::unique_ptr<MockRemotingSource> other_source(new MockRemotingSource()); 303 std::unique_ptr<MockRemotingSource> other_source(new MockRemotingSource());
426 RemoterPtr other_remoter = CreateRemoter(other_source.get()); 304 RemoterPtr other_remoter = CreateRemoter(other_source.get());
305 std::unique_ptr<MockMediaRemoter> media_remoter =
306 base::MakeUnique<MockMediaRemoter>(&media_router_);
427 307
428 // Throughout this test |other_source| should not participate in the 308 // Throughout this test |other_source| should not participate in the
429 // remoting session, and so these method calls should never occur: 309 // remoting session, and so these method calls should never occur:
430 EXPECT_CALL(*other_source, OnStarted()).Times(0); 310 EXPECT_CALL(*other_source, OnStarted()).Times(0);
431 EXPECT_CALL(*other_source, OnStopped(_)).Times(0); 311 EXPECT_CALL(*other_source, OnStopped(_)).Times(0);
432 EXPECT_CALL(*other_source, OnMessageFromSink(_)).Times(0); 312 EXPECT_CALL(*other_source, OnMessageFromSink(_)).Times(0);
433 313
434 // Both sinks should be notified when the Cast Provider tells the connector 314 // Both sinks should be notified when the Cast Provider tells the connector
435 // a remoting sink is available. 315 // a remoting sink is available.
436 EXPECT_CALL(*source, OnSinkAvailable(kAllCapabilities)).Times(1) 316 EXPECT_CALL(*source, OnSinkAvailable(kAllCapabilities)).Times(1)
437 .RetiresOnSaturation(); 317 .RetiresOnSaturation();
438 EXPECT_CALL(*other_source, OnSinkAvailable(kAllCapabilities)).Times(1) 318 EXPECT_CALL(*other_source, OnSinkAvailable(kAllCapabilities)).Times(1)
439 .RetiresOnSaturation(); 319 .RetiresOnSaturation();
440 ProviderDiscoversSink(); 320 media_remoter->OnSinkAvailable();
441 RunUntilIdle(); 321 RunUntilIdle();
442 322
443 // When |source| starts a remoting session, |other_source| is notified the 323 // When |source| starts a remoting session, |other_source| is notified the
444 // sink is gone, the Cast Provider is notified that remoting has started, 324 // sink is gone, the Cast Provider is notified that remoting has started,
445 // and |source| is notified that its request was successful. 325 // and |source| is notified that its request was successful.
446 EXPECT_CALL(*source, OnStarted()).Times(1).RetiresOnSaturation(); 326 EXPECT_CALL(*source, OnStarted()).Times(1).RetiresOnSaturation();
447 EXPECT_CALL(*other_source, OnSinkGone()).Times(1).RetiresOnSaturation(); 327 EXPECT_CALL(*other_source, OnSinkGone()).Times(1).RetiresOnSaturation();
328 EXPECT_CALL(*media_remoter, Start()).Times(1).RetiresOnSaturation();
448 remoter->Start(); 329 remoter->Start();
449 RunUntilIdle(); 330 RunUntilIdle();
450 ConnectorSentMessageToProvider("START_CAST_REMOTING:session=1");
451 331
452 // The |source| should now be able to send binary messages to the sink. 332 // The |source| should now be able to send binary messages to the sink.
453 // |other_source| should not! 333 // |other_source| should not!
454 const std::vector<uint8_t> message_to_sink = { 3, 1, 4, 1, 5, 9 }; 334 const std::vector<uint8_t> message_to_sink = { 3, 1, 4, 1, 5, 9 };
335 EXPECT_CALL(*media_remoter, SendMessageToSink(message_to_sink))
336 .Times(1)
337 .RetiresOnSaturation();
455 remoter->SendMessageToSink(message_to_sink); 338 remoter->SendMessageToSink(message_to_sink);
456 const std::vector<uint8_t> ignored_message_to_sink = { 1, 2, 3 }; 339 const std::vector<uint8_t> ignored_message_to_sink = { 1, 2, 3 };
340 EXPECT_CALL(*media_remoter, SendMessageToSink(ignored_message_to_sink))
341 .Times(0);
457 other_remoter->SendMessageToSink(ignored_message_to_sink); 342 other_remoter->SendMessageToSink(ignored_message_to_sink);
458 RunUntilIdle(); 343 RunUntilIdle();
459 ConnectorSentMessageToSink(message_to_sink);
460 344
461 // The sink should also be able to send binary messages to the |source|. 345 // The sink should also be able to send binary messages to the |source|.
462 const std::vector<uint8_t> message_to_source = { 2, 7, 1, 8, 2, 8 }; 346 const std::vector<uint8_t> message_to_source = { 2, 7, 1, 8, 2, 8 };
463 EXPECT_CALL(*source, OnMessageFromSink(message_to_source)).Times(1) 347 EXPECT_CALL(*source, OnMessageFromSink(message_to_source)).Times(1)
464 .RetiresOnSaturation(); 348 .RetiresOnSaturation();
465 ProviderPassesMessageFromSink(message_to_source); 349 media_remoter->SendMessageToSource(message_to_source);
466 RunUntilIdle(); 350 RunUntilIdle();
467 351
468 // The |other_source| should not be allowed to start a remoting session. 352 // The |other_source| should not be allowed to start a remoting session.
469 EXPECT_CALL(*other_source, 353 EXPECT_CALL(*other_source,
470 OnStartFailed(RemotingStartFailReason::CANNOT_START_MULTIPLE)) 354 OnStartFailed(RemotingStartFailReason::CANNOT_START_MULTIPLE))
471 .Times(1).RetiresOnSaturation(); 355 .Times(1).RetiresOnSaturation();
472 other_remoter->Start(); 356 other_remoter->Start();
473 RunUntilIdle(); 357 RunUntilIdle();
474 ConnectorSentNoMessagesToProvider();
475 358
476 // What happens from here depends on how this remoting session will end... 359 // What happens from here depends on how this remoting session will end...
477 switch (how_it_ends()) { 360 switch (how_it_ends()) {
478 case SOURCE_TERMINATES: { 361 case SOURCE_TERMINATES: {
479 // When the |source| stops the remoting session, the Cast Provider is 362 // When the |source| stops the remoting session, the Cast Provider is
480 // notified the session has stopped, and the |source| receives both an 363 // notified the session has stopped, and the |source| receives both an
481 // OnStopped() and an OnSinkGone() notification. 364 // OnStopped() and an OnSinkGone() notification.
482 const RemotingStopReason reason = RemotingStopReason::LOCAL_PLAYBACK; 365 const RemotingStopReason reason = RemotingStopReason::LOCAL_PLAYBACK;
483 EXPECT_CALL(*source, OnSinkGone()).Times(1).RetiresOnSaturation(); 366 EXPECT_CALL(*source, OnSinkGone()).Times(1).RetiresOnSaturation();
484 EXPECT_CALL(*source, OnStopped(reason)).Times(1).RetiresOnSaturation(); 367 EXPECT_CALL(*source, OnStopped(reason)).Times(1).RetiresOnSaturation();
368 EXPECT_CALL(*media_remoter, Stop(reason)).Times(1).RetiresOnSaturation();
485 remoter->Stop(reason); 369 remoter->Stop(reason);
486 RunUntilIdle(); 370 RunUntilIdle();
487 ConnectorSentMessageToProvider("STOP_CAST_REMOTING:session=1");
488 371
489 // Since remoting is stopped, any further messaging in either direction 372 // Since remoting is stopped, any further messaging in either direction
490 // must be dropped. 373 // must be dropped.
491 const std::vector<uint8_t> message_to_sink = { 1, 6, 1, 8, 0, 3 }; 374 const std::vector<uint8_t> message_to_sink = { 1, 6, 1, 8, 0, 3 };
492 const std::vector<uint8_t> message_to_source = { 6, 2, 8, 3, 1, 8 }; 375 const std::vector<uint8_t> message_to_source = { 6, 2, 8, 3, 1, 8 };
493 EXPECT_CALL(*source, OnMessageFromSink(_)).Times(0); 376 EXPECT_CALL(*source, OnMessageFromSink(_)).Times(0);
377 EXPECT_CALL(*media_remoter, SendMessageToSink(_)).Times(0);
494 remoter->SendMessageToSink(message_to_sink); 378 remoter->SendMessageToSink(message_to_sink);
495 ProviderPassesMessageFromSink(message_to_source); 379 media_remoter->SendMessageToSource(message_to_source);
496 RunUntilIdle(); 380 RunUntilIdle();
497 ConnectorSentNoMessagesToSink();
498 381
499 // When the sink is ready, the Cast Provider sends a notification to the 382 // When the sink is ready, the Cast Provider sends a notification to the
500 // connector. The connector will notify both sources that a sink is once 383 // connector. The connector will notify both sources that a sink is once
501 // again available. 384 // again available.
502 EXPECT_CALL(*source, OnSinkAvailable(kAllCapabilities)).Times(1) 385 EXPECT_CALL(*source, OnSinkAvailable(kAllCapabilities)).Times(1)
503 .RetiresOnSaturation(); 386 .RetiresOnSaturation();
504 EXPECT_CALL(*other_source, OnSinkAvailable(kAllCapabilities)).Times(1) 387 EXPECT_CALL(*other_source, OnSinkAvailable(kAllCapabilities)).Times(1)
505 .RetiresOnSaturation(); 388 .RetiresOnSaturation();
506 ProviderSaysToRemotingConnector("STOPPED_CAST_REMOTING:session=1"); 389 media_remoter->OnSinkAvailable();
507 RunUntilIdle(); 390 RunUntilIdle();
508 391
509 // When the sink is no longer available, the Cast Provider notifies the 392 // When the sink is no longer available, the Cast Provider notifies the
510 // connector, and both sources are then notified the sink is gone. 393 // connector, and both sources are then notified the sink is gone.
511 EXPECT_CALL(*source, OnSinkGone()).Times(AtLeast(1)); 394 EXPECT_CALL(*source, OnSinkGone()).Times(AtLeast(1));
512 EXPECT_CALL(*other_source, OnSinkGone()).Times(AtLeast(1)); 395 EXPECT_CALL(*other_source, OnSinkGone()).Times(AtLeast(1));
513 ProviderLosesSink(); 396 media_remoter.reset();
514 RunUntilIdle(); 397 RunUntilIdle();
515 398
516 break; 399 break;
517 } 400 }
518 401
519 case MOJO_PIPE_CLOSES: 402 case MOJO_PIPE_CLOSES:
520 // When the Mojo pipes for |other_source| close, this should not affect 403 // When the Mojo pipes for |other_source| close, this should not affect
521 // the current remoting session. 404 // the current remoting session.
405 EXPECT_CALL(*media_remoter, Stop(_)).Times(0);
522 other_source.reset(); 406 other_source.reset();
523 other_remoter.reset(); 407 other_remoter.reset();
524 RunUntilIdle(); 408 RunUntilIdle();
525 ConnectorSentNoMessagesToProvider();
526 409
527 // Now, when the Mojo pipes for |source| close, the Cast Provider will be 410 // Now, when the Mojo pipes for |source| close, the Cast Provider will be
528 // notified that the session has stopped. 411 // notified that the session has stopped.
412 EXPECT_CALL(*media_remoter, Stop(_)).Times(1).RetiresOnSaturation();
529 source.reset(); 413 source.reset();
530 remoter.reset(); 414 remoter.reset();
531 RunUntilIdle(); 415 RunUntilIdle();
532 ConnectorSentMessageToProvider("STOP_CAST_REMOTING:session=1");
533
534 // The Cast Provider will detect when the sink is ready for the next
535 // remoting session, and then notify the connector. However, there are no
536 // sources to propagate this notification to.
537 ProviderSaysToRemotingConnector("STOPPED_CAST_REMOTING:session=1");
538 RunUntilIdle();
539 416
540 break; 417 break;
541 418
542 case ROUTE_TERMINATES: 419 case ROUTE_TERMINATES:
543 // When the Media Router terminates the route (e.g., because a user 420 // When the Media Router terminates the route (e.g., because a user
544 // terminated the route from the UI), the source and sink are immediately 421 // terminated the route from the UI), the source and sink are immediately
545 // cut off from one another. 422 // cut off from one another.
546 EXPECT_CALL(*source, OnSinkGone()).Times(AtLeast(1)); 423 EXPECT_CALL(*source, OnSinkGone()).Times(AtLeast(1));
547 EXPECT_CALL(*source, OnStopped(RemotingStopReason::ROUTE_TERMINATED))
548 .Times(1).RetiresOnSaturation();
549 EXPECT_CALL(*other_source, OnSinkGone()).Times(AtLeast(0)); 424 EXPECT_CALL(*other_source, OnSinkGone()).Times(AtLeast(0));
550 MediaRouterTerminatesRoute();
551 RunUntilIdle();
552 ConnectorSentNoMessagesToProvider();
553
554 // Furthermore, the connector and Cast Provider are also cut off from one 425 // Furthermore, the connector and Cast Provider are also cut off from one
555 // another and should not be able to exchange messages anymore. Therefore, 426 // another and should not be able to exchange messages anymore. Therefore,
556 // the connector will never try to notify the sources that the sink is 427 // the connector will never try to notify the sources that the sink is
557 // available again. 428 // available again.
558 EXPECT_CALL(*source, OnSinkAvailable(_)).Times(0); 429 EXPECT_CALL(*source, OnSinkAvailable(_)).Times(0);
559 EXPECT_CALL(*other_source, OnSinkAvailable(_)).Times(0); 430 EXPECT_CALL(*other_source, OnSinkAvailable(_)).Times(0);
560 ProviderSaysToRemotingConnector("STOPPED_CAST_REMOTING:session=1"); 431 media_remoter.reset();
561 RunUntilIdle(); 432 RunUntilIdle();
562 433
563 break; 434 break;
564 435
565 case EXTERNAL_FAILURE: { 436 case EXTERNAL_FAILURE: {
566 // When the Cast Provider is cut-off from the sink, it sends a fail 437 // When the Cast Provider is cut-off from the sink, it sends a fail
567 // notification to the connector. The connector, in turn, force-stops the 438 // notification to the connector. The connector, in turn, force-stops the
568 // remoting session and notifies the |source|. 439 // remoting session and notifies the |source|.
569 EXPECT_CALL(*source, OnSinkGone()).Times(1).RetiresOnSaturation(); 440 EXPECT_CALL(*source, OnSinkGone()).Times(1).RetiresOnSaturation();
570 EXPECT_CALL(*source, OnStopped(RemotingStopReason::UNEXPECTED_FAILURE)) 441 EXPECT_CALL(*source, OnStopped(RemotingStopReason::UNEXPECTED_FAILURE))
571 .Times(1).RetiresOnSaturation(); 442 .Times(1).RetiresOnSaturation();
572 ProviderSaysToRemotingConnector("FAILED_CAST_REMOTING:session=1"); 443 EXPECT_CALL(*media_remoter, Stop(RemotingStopReason::UNEXPECTED_FAILURE))
444 .Times(1)
445 .RetiresOnSaturation();
446 media_remoter->OnError();
573 RunUntilIdle(); 447 RunUntilIdle();
574 448
575 // Since remoting is stopped, any further messaging in either direction 449 // Since remoting is stopped, any further messaging in either direction
576 // must be dropped. 450 // must be dropped.
577 const std::vector<uint8_t> message_to_sink = { 1, 6, 1, 8, 0, 3 }; 451 const std::vector<uint8_t> message_to_sink = { 1, 6, 1, 8, 0, 3 };
578 const std::vector<uint8_t> message_to_source = { 6, 2, 8, 3, 1, 8 }; 452 const std::vector<uint8_t> message_to_source = { 6, 2, 8, 3, 1, 8 };
579 EXPECT_CALL(*source, OnMessageFromSink(_)).Times(0); 453 EXPECT_CALL(*source, OnMessageFromSink(_)).Times(0);
454 EXPECT_CALL(*media_remoter, SendMessageToSink(_)).Times(0);
580 remoter->SendMessageToSink(message_to_sink); 455 remoter->SendMessageToSink(message_to_sink);
581 ProviderPassesMessageFromSink(message_to_source); 456 media_remoter->SendMessageToSource(message_to_source);
582 RunUntilIdle();
583 ConnectorSentNoMessagesToSink();
584
585 // Later, if whatever caused the external failure has resolved, the Cast
586 // Provider will notify the connector that the sink is available one
587 // again.
588 EXPECT_CALL(*source, OnSinkAvailable(kAllCapabilities)).Times(1)
589 .RetiresOnSaturation();
590 EXPECT_CALL(*other_source, OnSinkAvailable(kAllCapabilities)).Times(1)
591 .RetiresOnSaturation();
592 ProviderSaysToRemotingConnector("STOPPED_CAST_REMOTING:session=1");
593 RunUntilIdle(); 457 RunUntilIdle();
594 458
595 // When the sink is no longer available, the Cast Provider notifies the 459 // When the sink is no longer available, the Cast Provider notifies the
596 // connector, and both sources are then notified the sink is gone. 460 // connector, and both sources are then notified the sink is gone.
597 EXPECT_CALL(*source, OnSinkGone()).Times(AtLeast(1)); 461 EXPECT_CALL(*source, OnSinkGone()).Times(AtLeast(1));
598 EXPECT_CALL(*other_source, OnSinkGone()).Times(AtLeast(1)); 462 EXPECT_CALL(*other_source, OnSinkGone()).Times(AtLeast(1));
599 ProviderLosesSink(); 463 media_remoter.reset();
600 RunUntilIdle(); 464 RunUntilIdle();
601 465
602 break; 466 break;
603 } 467 }
604 } 468 }
605 } 469 }
606 470
607 INSTANTIATE_TEST_CASE_P(, CastRemotingConnectorFullSessionTest, 471 INSTANTIATE_TEST_CASE_P(, CastRemotingConnectorFullSessionTest,
608 ::testing::Values(SOURCE_TERMINATES, 472 ::testing::Values(SOURCE_TERMINATES,
609 MOJO_PIPE_CLOSES, 473 MOJO_PIPE_CLOSES,
610 ROUTE_TERMINATES, 474 ROUTE_TERMINATES,
611 EXTERNAL_FAILURE)); 475 EXTERNAL_FAILURE));
OLDNEW
« no previous file with comments | « chrome/browser/media/cast_remoting_connector_messaging.cc ('k') | chrome/browser/media/router/media_router.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698