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

Side by Side Diff: chrome/browser/media/router/mojo/media_router_mojo_impl_unittest.cc

Issue 2728543009: [Media Router] Custom Controls 2 - add MediaRouter::GetRouteController() (Closed)
Patch Set: Don't create controller if binding is invalid Created 3 years, 8 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 <stddef.h> 5 #include <stddef.h>
6 #include <stdint.h> 6 #include <stdint.h>
7 7
8 #include <memory> 8 #include <memory>
9 #include <string> 9 #include <string>
10 #include <utility> 10 #include <utility>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/bind_helpers.h" 13 #include "base/bind_helpers.h"
14 #include "base/macros.h" 14 #include "base/macros.h"
15 #include "base/memory/ptr_util.h" 15 #include "base/memory/ptr_util.h"
16 #include "base/memory/ref_counted.h" 16 #include "base/memory/ref_counted.h"
17 #include "base/run_loop.h" 17 #include "base/run_loop.h"
18 #include "base/synchronization/waitable_event.h"
19 #include "base/test/histogram_tester.h" 18 #include "base/test/histogram_tester.h"
20 #include "base/test/mock_callback.h" 19 #include "base/test/mock_callback.h"
21 #include "base/threading/thread_task_runner_handle.h" 20 #include "base/threading/thread_task_runner_handle.h"
22 #include "chrome/browser/media/router/issue.h" 21 #include "chrome/browser/media/router/issue.h"
23 #include "chrome/browser/media/router/media_route.h" 22 #include "chrome/browser/media/router/media_route.h"
24 #include "chrome/browser/media/router/media_source_helper.h" 23 #include "chrome/browser/media/router/media_source_helper.h"
25 #include "chrome/browser/media/router/mock_media_router.h" 24 #include "chrome/browser/media/router/mock_media_router.h"
26 #include "chrome/browser/media/router/mojo/media_router_mojo_metrics.h" 25 #include "chrome/browser/media/router/mojo/media_router_mojo_metrics.h"
27 #include "chrome/browser/media/router/mojo/media_router_mojo_test.h" 26 #include "chrome/browser/media/router/mojo/media_router_mojo_test.h"
28 #include "chrome/browser/media/router/route_message.h" 27 #include "chrome/browser/media/router/route_message.h"
(...skipping 19 matching lines...) Expand all
48 using testing::AtMost; 47 using testing::AtMost;
49 using testing::Eq; 48 using testing::Eq;
50 using testing::Invoke; 49 using testing::Invoke;
51 using testing::InvokeWithoutArgs; 50 using testing::InvokeWithoutArgs;
52 using testing::IsEmpty; 51 using testing::IsEmpty;
53 using testing::Mock; 52 using testing::Mock;
54 using testing::Not; 53 using testing::Not;
55 using testing::Pointee; 54 using testing::Pointee;
56 using testing::Return; 55 using testing::Return;
57 using testing::ReturnRef; 56 using testing::ReturnRef;
57 using testing::Unused;
58 using testing::SaveArg; 58 using testing::SaveArg;
59 using testing::Sequence; 59 using testing::Sequence;
60 60
61 namespace media_router { 61 namespace media_router {
62 62
63 namespace { 63 namespace {
64 64
65 const char kDescription[] = "description"; 65 const char kDescription[] = "description";
66 const char kError[] = "error"; 66 const char kError[] = "error";
67 const char kMessage[] = "message"; 67 const char kMessage[] = "message";
(...skipping 14 matching lines...) Expand all
82 82
83 IssueInfo CreateIssueInfo(const std::string& title) { 83 IssueInfo CreateIssueInfo(const std::string& title) {
84 IssueInfo issue_info; 84 IssueInfo issue_info;
85 issue_info.title = title; 85 issue_info.title = title;
86 issue_info.message = std::string("msg"); 86 issue_info.message = std::string("msg");
87 issue_info.default_action = IssueInfo::Action::DISMISS; 87 issue_info.default_action = IssueInfo::Action::DISMISS;
88 issue_info.severity = IssueInfo::Severity::WARNING; 88 issue_info.severity = IssueInfo::Severity::WARNING;
89 return issue_info; 89 return issue_info;
90 } 90 }
91 91
92 // Creates a media route whose ID is |kRouteId|.
92 MediaRoute CreateMediaRoute() { 93 MediaRoute CreateMediaRoute() {
93 return MediaRoute(kRouteId, MediaSource(kSource), kSinkId, kDescription, true, 94 return MediaRoute(kRouteId, MediaSource(kSource), kSinkId, kDescription, true,
94 std::string(), true); 95 std::string(), true);
95 } 96 }
96 97
98 // Creates a media route whose ID is |kRouteId2|.
99 MediaRoute CreateMediaRoute2() {
100 return MediaRoute(kRouteId2, MediaSource(kSource), kSinkId, kDescription,
101 true, std::string(), true);
102 }
103
104 void OnCreateMediaRouteController(
105 Unused,
106 Unused,
107 const mojom::MediaRouteProvider::CreateMediaRouteControllerCallback& cb) {
108 cb.Run(true);
109 }
110
97 } // namespace 111 } // namespace
98 112
99 class RouteResponseCallbackHandler { 113 class RouteResponseCallbackHandler {
100 public: 114 public:
101 void Invoke(const RouteRequestResult& result) { 115 void Invoke(const RouteRequestResult& result) {
102 DoInvoke(result.route(), result.presentation_id(), result.error(), 116 DoInvoke(result.route(), result.presentation_id(), result.error(),
103 result.result_code()); 117 result.result_code());
104 } 118 }
105 MOCK_METHOD4(DoInvoke, 119 MOCK_METHOD4(DoInvoke,
106 void(const MediaRoute* route, 120 void(const MediaRoute* route,
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after
738 sinks_observer.reset(); 752 sinks_observer.reset();
739 extra_sinks_observer.reset(); 753 extra_sinks_observer.reset();
740 unrelated_sinks_observer.reset(); 754 unrelated_sinks_observer.reset();
741 cached_sinks_observer.reset(); 755 cached_sinks_observer.reset();
742 cached_sinks_observer2.reset(); 756 cached_sinks_observer2.reset();
743 run_loop2.Run(); 757 run_loop2.Run();
744 } 758 }
745 759
746 TEST_F(MediaRouterMojoImplTest, 760 TEST_F(MediaRouterMojoImplTest,
747 RegisterMediaSinksObserverWithAvailabilityChange) { 761 RegisterMediaSinksObserverWithAvailabilityChange) {
748
749 // When availability is UNAVAILABLE, no calls should be made to MRPM. 762 // When availability is UNAVAILABLE, no calls should be made to MRPM.
750 router()->OnSinkAvailabilityUpdated( 763 router()->OnSinkAvailabilityUpdated(
751 mojom::MediaRouter::SinkAvailability::UNAVAILABLE); 764 mojom::MediaRouter::SinkAvailability::UNAVAILABLE);
752 MediaSource media_source(kSource); 765 MediaSource media_source(kSource);
753 std::unique_ptr<MockMediaSinksObserver> sinks_observer( 766 std::unique_ptr<MockMediaSinksObserver> sinks_observer(
754 new MockMediaSinksObserver(router(), media_source, 767 new MockMediaSinksObserver(router(), media_source,
755 url::Origin(GURL(kOrigin)))); 768 url::Origin(GURL(kOrigin))));
756 EXPECT_CALL(*sinks_observer, OnSinksReceived(IsEmpty())); 769 EXPECT_CALL(*sinks_observer, OnSinksReceived(IsEmpty()));
757 EXPECT_TRUE(sinks_observer->Init()); 770 EXPECT_TRUE(sinks_observer->Init());
758 MediaSource media_source2(kSource2); 771 MediaSource media_source2(kSource2);
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
1175 EXPECT_CALL(mock_media_route_provider_, DetachRoute(kRouteId2)); 1188 EXPECT_CALL(mock_media_route_provider_, DetachRoute(kRouteId2));
1176 ConnectProviderManagerService(); 1189 ConnectProviderManagerService();
1177 ProcessEventLoop(); 1190 ProcessEventLoop();
1178 } 1191 }
1179 1192
1180 TEST_F(MediaRouterMojoImplTest, SearchSinks) { 1193 TEST_F(MediaRouterMojoImplTest, SearchSinks) {
1181 std::string search_input("input"); 1194 std::string search_input("input");
1182 std::string domain("google.com"); 1195 std::string domain("google.com");
1183 MediaSource media_source(kSource); 1196 MediaSource media_source(kSource);
1184 1197
1185 EXPECT_CALL( 1198 EXPECT_CALL(mock_media_route_provider_,
1186 mock_media_route_provider_, SearchSinks_(kSinkId, kSource, _, _)) 1199 SearchSinksInternal(kSinkId, kSource, _, _))
1187 .WillOnce(Invoke([&search_input, &domain]( 1200 .WillOnce(
1188 const std::string& sink_id, const std::string& source, 1201 Invoke([&search_input, &domain](
1189 const mojom::SinkSearchCriteriaPtr& search_criteria, 1202 const std::string& sink_id, const std::string& source,
1190 const mojom::MediaRouteProvider::SearchSinksCallback& cb) { 1203 const mojom::SinkSearchCriteriaPtr& search_criteria,
1191 EXPECT_EQ(search_input, search_criteria->input); 1204 const mojom::MediaRouteProvider::SearchSinksCallback& cb) {
1192 EXPECT_EQ(domain, search_criteria->domain); 1205 EXPECT_EQ(search_input, search_criteria->input);
1193 cb.Run(kSinkId2); 1206 EXPECT_EQ(domain, search_criteria->domain);
1194 })); 1207 cb.Run(kSinkId2);
1208 }));
1195 1209
1196 SinkResponseCallbackHandler sink_handler; 1210 SinkResponseCallbackHandler sink_handler;
1197 EXPECT_CALL(sink_handler, Invoke(kSinkId2)).Times(1); 1211 EXPECT_CALL(sink_handler, Invoke(kSinkId2)).Times(1);
1198 MediaSinkSearchResponseCallback sink_callback = base::Bind( 1212 MediaSinkSearchResponseCallback sink_callback = base::Bind(
1199 &SinkResponseCallbackHandler::Invoke, base::Unretained(&sink_handler)); 1213 &SinkResponseCallbackHandler::Invoke, base::Unretained(&sink_handler));
1200 1214
1201 router()->SearchSinks(kSinkId, kSource, search_input, domain, sink_callback); 1215 router()->SearchSinks(kSinkId, kSource, search_input, domain, sink_callback);
1202 1216
1203 base::RunLoop run_loop; 1217 base::RunLoop run_loop;
1204 run_loop.RunUntilIdle(); 1218 run_loop.RunUntilIdle();
(...skipping 11 matching lines...) Expand all
1216 std::string provider_name = "cast"; 1230 std::string provider_name = "cast";
1217 1231
1218 EXPECT_CALL(mock_media_route_provider_, ProvideSinks(provider_name, sinks)); 1232 EXPECT_CALL(mock_media_route_provider_, ProvideSinks(provider_name, sinks));
1219 1233
1220 router()->ProvideSinks(provider_name, sinks); 1234 router()->ProvideSinks(provider_name, sinks);
1221 1235
1222 base::RunLoop run_loop; 1236 base::RunLoop run_loop;
1223 run_loop.RunUntilIdle(); 1237 run_loop.RunUntilIdle();
1224 } 1238 }
1225 1239
1240 TEST_F(MediaRouterMojoImplTest, GetRouteController) {
1241 base::RunLoop run_loop1;
1242 MockMediaController media_controller;
1243 mojom::MediaStatusObserverPtr route_controller_as_observer;
1244 MediaStatus media_status;
1245 media_status.title = "test title";
1246
1247 router()->OnRoutesUpdated({CreateMediaRoute()}, std::string(),
1248 std::vector<std::string>());
1249
1250 EXPECT_CALL(mock_media_route_provider_,
1251 CreateMediaRouteControllerInternal(kRouteId, _, _))
1252 .WillOnce(Invoke(
1253 [&media_controller](const std::string& route_id,
1254 mojom::MediaControllerRequest& request,
1255 const mojom::MediaRouteProvider::
1256 CreateMediaRouteControllerCallback& cb) {
1257 media_controller.Bind(std::move(request));
1258 cb.Run(true);
1259 }));
1260 EXPECT_CALL(mock_media_route_provider_,
1261 SetMediaRouteStatusObserverInternal(kRouteId, _))
1262 .WillOnce(Invoke([&route_controller_as_observer](
1263 const std::string& route_id,
1264 mojom::MediaStatusObserverPtr& observer) {
1265 route_controller_as_observer = std::move(observer);
1266 }));
1267 // GetRouteController() should return a MediaRouteController that is connected
1268 // to the MediaController provided by the MediaRouteProvider, and will also be
1269 // subscribed to MediaStatus updates.
1270 scoped_refptr<MediaRouteController> route_controller =
1271 router()->GetRouteController(kRouteId);
1272 run_loop1.RunUntilIdle();
1273
1274 // Media commands sent to the MediaRouteController should be forwarded to the
1275 // MediaController created by the MediaRouteProvider.
1276 EXPECT_CALL(media_controller, Play());
1277 route_controller->Play();
1278
1279 // Add an observer to the MediaRouteController.
1280 MockMediaRouteControllerObserver controller_observer(route_controller);
1281
1282 base::RunLoop run_loop2;
dcheng 2017/04/14 05:30:08 Can this just use the original RunLoop from line 1
takumif 2017/04/14 18:43:00 How do I do that? I thought Run()/RunUntilIdle() c
1283
1284 // The MediaRouteController should be registered with the MediaRouteProvider
1285 // as a MediaStatusObserver, and should also notify its own observers.
1286 EXPECT_CALL(controller_observer, OnMediaStatusUpdated(media_status));
1287 route_controller_as_observer->OnMediaStatusUpdated(media_status);
1288
1289 run_loop2.RunUntilIdle();
1290 }
1291
1292 TEST_F(MediaRouterMojoImplTest, GetRouteControllerMultipleTimes) {
1293 base::RunLoop run_loop;
1294 router()->OnRoutesUpdated({CreateMediaRoute(), CreateMediaRoute2()},
1295 std::string(), std::vector<std::string>());
1296
1297 EXPECT_CALL(mock_media_route_provider_,
1298 CreateMediaRouteControllerInternal(kRouteId, _, _))
1299 .WillOnce(Invoke(OnCreateMediaRouteController));
1300 scoped_refptr<MediaRouteController> route_controller1a =
1301 router()->GetRouteController(kRouteId);
1302
1303 // Calling GetRouteController() with the same route ID for the second time
1304 // (without destroying the MediaRouteController first) should not result in a
1305 // CreateMediaRouteController() call.
1306 scoped_refptr<MediaRouteController> route_controller1b =
1307 router()->GetRouteController(kRouteId);
1308
1309 // The same MediaRouteController instance should have been returned.
1310 EXPECT_EQ(route_controller1a.get(), route_controller1b.get());
1311
1312 // Calling GetRouteController() with another route ID should result in a
1313 // CreateMediaRouteController() call.
1314 EXPECT_CALL(mock_media_route_provider_,
1315 CreateMediaRouteControllerInternal(kRouteId2, _, _))
1316 .WillOnce(Invoke(OnCreateMediaRouteController));
1317 scoped_refptr<MediaRouteController> route_controller2 =
1318 router()->GetRouteController(kRouteId2);
1319
1320 run_loop.RunUntilIdle();
1321 }
1322
1323 TEST_F(MediaRouterMojoImplTest, GetRouteControllerAfterInvalidation) {
1324 base::RunLoop run_loop;
1325 router()->OnRoutesUpdated({CreateMediaRoute()}, std::string(),
1326 std::vector<std::string>());
1327
1328 EXPECT_CALL(mock_media_route_provider_,
1329 CreateMediaRouteControllerInternal(kRouteId, _, _))
1330 .Times(2)
1331 .WillRepeatedly(Invoke(OnCreateMediaRouteController));
1332
1333 scoped_refptr<MediaRouteController> route_controller =
1334 router()->GetRouteController(kRouteId);
1335 // Invalidate the MediaRouteController.
1336 route_controller = nullptr;
1337 // Call again with the same route ID. Since we've invalidated the
1338 // MediaRouteController, CreateMediaRouteController() should be called again.
1339 route_controller = router()->GetRouteController(kRouteId);
1340
1341 run_loop.RunUntilIdle();
1342 }
1343
1344 TEST_F(MediaRouterMojoImplTest, GetRouteControllerAfterRouteInvalidation) {
1345 base::RunLoop run_loop;
1346 router()->OnRoutesUpdated({CreateMediaRoute(), CreateMediaRoute2()},
1347 std::string(), std::vector<std::string>());
1348
1349 EXPECT_CALL(mock_media_route_provider_,
1350 CreateMediaRouteControllerInternal(kRouteId, _, _))
1351 .WillOnce(Invoke(OnCreateMediaRouteController));
1352 EXPECT_CALL(mock_media_route_provider_,
1353 CreateMediaRouteControllerInternal(kRouteId2, _, _))
1354 .Times(2)
1355 .WillRepeatedly(Invoke(OnCreateMediaRouteController));
1356
1357 MockMediaRouteControllerObserver observer1a(
1358 router()->GetRouteController(kRouteId));
1359 MockMediaRouteControllerObserver observer2a(
1360 router()->GetRouteController(kRouteId2));
1361
1362 // Update the routes list with |kRouteId| but without |kRouteId2|. This should
1363 // remove the controller for |kRouteId2|, resulting in
1364 // CreateMediaRouteController() getting called again for |kRouteId2| below.
1365 router()->OnRoutesUpdated({CreateMediaRoute()}, std::string(),
1366 std::vector<std::string>());
1367 // Add back |kRouteId2| so that a controller can be created for it.
1368 router()->OnRoutesUpdated({CreateMediaRoute(), CreateMediaRoute2()},
1369 std::string(), std::vector<std::string>());
1370
1371 MockMediaRouteControllerObserver observer1b(
1372 router()->GetRouteController(kRouteId));
1373 MockMediaRouteControllerObserver observer2b(
1374 router()->GetRouteController(kRouteId2));
1375
1376 run_loop.RunUntilIdle();
1377 }
1378
1379 TEST_F(MediaRouterMojoImplTest, FailToCreateRouteController) {
1380 base::RunLoop run_loop;
1381 router()->OnRoutesUpdated({CreateMediaRoute()}, std::string(),
1382 std::vector<std::string>());
1383
1384 EXPECT_CALL(mock_media_route_provider_,
1385 CreateMediaRouteControllerInternal(kRouteId, _, _))
1386 .WillOnce(Invoke(
1387 [](Unused, Unused,
1388 const mojom::MediaRouteProvider::
1389 CreateMediaRouteControllerCallback& cb) { cb.Run(false); }));
1390 MockMediaRouteControllerObserver observer(
1391 router()->GetRouteController(kRouteId));
1392
1393 // When the MediaRouter is notified that the MediaRouteProvider failed to
1394 // create a controller, the browser-side controller should be invalidated.
1395 EXPECT_CALL(observer, OnControllerInvalidated());
1396
1397 run_loop.RunUntilIdle();
1398 }
1399
1226 class MediaRouterMojoExtensionTest : public ::testing::Test { 1400 class MediaRouterMojoExtensionTest : public ::testing::Test {
1227 public: 1401 public:
1228 MediaRouterMojoExtensionTest() : process_manager_(nullptr) {} 1402 MediaRouterMojoExtensionTest() : process_manager_(nullptr) {}
1229 1403
1230 ~MediaRouterMojoExtensionTest() override {} 1404 ~MediaRouterMojoExtensionTest() override {}
1231 1405
1232 protected: 1406 protected:
1233 void SetUp() override { 1407 void SetUp() override {
1234 // Set the extension's version number to be identical to the browser's. 1408 // Set the extension's version number to be identical to the browser's.
1235 extension_ = 1409 extension_ =
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
1596 EXPECT_CALL(mock_media_route_provider_, 1770 EXPECT_CALL(mock_media_route_provider_,
1597 UpdateMediaSinks(MediaSourceForDesktop().id())) 1771 UpdateMediaSinks(MediaSourceForDesktop().id()))
1598 .WillOnce(InvokeWithoutArgs([&run_loop2]() { 1772 .WillOnce(InvokeWithoutArgs([&run_loop2]() {
1599 run_loop2.Quit(); 1773 run_loop2.Quit();
1600 })); 1774 }));
1601 1775
1602 run_loop2.Run(); 1776 run_loop2.Run();
1603 } 1777 }
1604 1778
1605 } // namespace media_router 1779 } // namespace media_router
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698