| OLD | NEW |
| 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> |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 using testing::AtMost; | 48 using testing::AtMost; |
| 49 using testing::Eq; | 49 using testing::Eq; |
| 50 using testing::Invoke; | 50 using testing::Invoke; |
| 51 using testing::InvokeWithoutArgs; | 51 using testing::InvokeWithoutArgs; |
| 52 using testing::IsEmpty; | 52 using testing::IsEmpty; |
| 53 using testing::Mock; | 53 using testing::Mock; |
| 54 using testing::Not; | 54 using testing::Not; |
| 55 using testing::Pointee; | 55 using testing::Pointee; |
| 56 using testing::Return; | 56 using testing::Return; |
| 57 using testing::ReturnRef; | 57 using testing::ReturnRef; |
| 58 using testing::Unused; |
| 58 using testing::SaveArg; | 59 using testing::SaveArg; |
| 59 using testing::Sequence; | 60 using testing::Sequence; |
| 60 | 61 |
| 61 namespace media_router { | 62 namespace media_router { |
| 62 | 63 |
| 63 namespace { | 64 namespace { |
| 64 | 65 |
| 65 const char kDescription[] = "description"; | 66 const char kDescription[] = "description"; |
| 66 const char kError[] = "error"; | 67 const char kError[] = "error"; |
| 67 const char kMessage[] = "message"; | 68 const char kMessage[] = "message"; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 82 | 83 |
| 83 IssueInfo CreateIssueInfo(const std::string& title) { | 84 IssueInfo CreateIssueInfo(const std::string& title) { |
| 84 IssueInfo issue_info; | 85 IssueInfo issue_info; |
| 85 issue_info.title = title; | 86 issue_info.title = title; |
| 86 issue_info.message = std::string("msg"); | 87 issue_info.message = std::string("msg"); |
| 87 issue_info.default_action = IssueInfo::Action::DISMISS; | 88 issue_info.default_action = IssueInfo::Action::DISMISS; |
| 88 issue_info.severity = IssueInfo::Severity::WARNING; | 89 issue_info.severity = IssueInfo::Severity::WARNING; |
| 89 return issue_info; | 90 return issue_info; |
| 90 } | 91 } |
| 91 | 92 |
| 93 // Creates a media route whose ID is |kRouteId|. |
| 92 MediaRoute CreateMediaRoute() { | 94 MediaRoute CreateMediaRoute() { |
| 93 return MediaRoute(kRouteId, MediaSource(kSource), kSinkId, kDescription, true, | 95 return MediaRoute(kRouteId, MediaSource(kSource), kSinkId, kDescription, true, |
| 94 std::string(), true); | 96 std::string(), true); |
| 95 } | 97 } |
| 96 | 98 |
| 99 // Creates a media route whose ID is |kRouteId2|. |
| 100 MediaRoute CreateMediaRoute2() { |
| 101 return MediaRoute(kRouteId2, MediaSource(kSource), kSinkId, kDescription, |
| 102 true, std::string(), true); |
| 103 } |
| 104 |
| 105 void OnCreateMediaRouteController( |
| 106 Unused, |
| 107 Unused, |
| 108 const mojom::MediaRouteProvider::CreateMediaRouteControllerCallback& cb) { |
| 109 cb.Run(true); |
| 110 } |
| 111 |
| 97 } // namespace | 112 } // namespace |
| 98 | 113 |
| 99 class RouteResponseCallbackHandler { | 114 class RouteResponseCallbackHandler { |
| 100 public: | 115 public: |
| 101 void Invoke(const RouteRequestResult& result) { | 116 void Invoke(const RouteRequestResult& result) { |
| 102 DoInvoke(result.route(), result.presentation_id(), result.error(), | 117 DoInvoke(result.route(), result.presentation_id(), result.error(), |
| 103 result.result_code()); | 118 result.result_code()); |
| 104 } | 119 } |
| 105 MOCK_METHOD4(DoInvoke, | 120 MOCK_METHOD4(DoInvoke, |
| 106 void(const MediaRoute* route, | 121 void(const MediaRoute* route, |
| (...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 738 sinks_observer.reset(); | 753 sinks_observer.reset(); |
| 739 extra_sinks_observer.reset(); | 754 extra_sinks_observer.reset(); |
| 740 unrelated_sinks_observer.reset(); | 755 unrelated_sinks_observer.reset(); |
| 741 cached_sinks_observer.reset(); | 756 cached_sinks_observer.reset(); |
| 742 cached_sinks_observer2.reset(); | 757 cached_sinks_observer2.reset(); |
| 743 run_loop2.Run(); | 758 run_loop2.Run(); |
| 744 } | 759 } |
| 745 | 760 |
| 746 TEST_F(MediaRouterMojoImplTest, | 761 TEST_F(MediaRouterMojoImplTest, |
| 747 RegisterMediaSinksObserverWithAvailabilityChange) { | 762 RegisterMediaSinksObserverWithAvailabilityChange) { |
| 748 | |
| 749 // When availability is UNAVAILABLE, no calls should be made to MRPM. | 763 // When availability is UNAVAILABLE, no calls should be made to MRPM. |
| 750 router()->OnSinkAvailabilityUpdated( | 764 router()->OnSinkAvailabilityUpdated( |
| 751 mojom::MediaRouter::SinkAvailability::UNAVAILABLE); | 765 mojom::MediaRouter::SinkAvailability::UNAVAILABLE); |
| 752 MediaSource media_source(kSource); | 766 MediaSource media_source(kSource); |
| 753 std::unique_ptr<MockMediaSinksObserver> sinks_observer( | 767 std::unique_ptr<MockMediaSinksObserver> sinks_observer( |
| 754 new MockMediaSinksObserver(router(), media_source, | 768 new MockMediaSinksObserver(router(), media_source, |
| 755 url::Origin(GURL(kOrigin)))); | 769 url::Origin(GURL(kOrigin)))); |
| 756 EXPECT_CALL(*sinks_observer, OnSinksReceived(IsEmpty())); | 770 EXPECT_CALL(*sinks_observer, OnSinksReceived(IsEmpty())); |
| 757 EXPECT_TRUE(sinks_observer->Init()); | 771 EXPECT_TRUE(sinks_observer->Init()); |
| 758 MediaSource media_source2(kSource2); | 772 MediaSource media_source2(kSource2); |
| (...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1175 EXPECT_CALL(mock_media_route_provider_, DetachRoute(kRouteId2)); | 1189 EXPECT_CALL(mock_media_route_provider_, DetachRoute(kRouteId2)); |
| 1176 ConnectProviderManagerService(); | 1190 ConnectProviderManagerService(); |
| 1177 ProcessEventLoop(); | 1191 ProcessEventLoop(); |
| 1178 } | 1192 } |
| 1179 | 1193 |
| 1180 TEST_F(MediaRouterMojoImplTest, SearchSinks) { | 1194 TEST_F(MediaRouterMojoImplTest, SearchSinks) { |
| 1181 std::string search_input("input"); | 1195 std::string search_input("input"); |
| 1182 std::string domain("google.com"); | 1196 std::string domain("google.com"); |
| 1183 MediaSource media_source(kSource); | 1197 MediaSource media_source(kSource); |
| 1184 | 1198 |
| 1185 EXPECT_CALL( | 1199 EXPECT_CALL(mock_media_route_provider_, |
| 1186 mock_media_route_provider_, SearchSinks_(kSinkId, kSource, _, _)) | 1200 SearchSinksInternal(kSinkId, kSource, _, _)) |
| 1187 .WillOnce(Invoke([&search_input, &domain]( | 1201 .WillOnce( |
| 1188 const std::string& sink_id, const std::string& source, | 1202 Invoke([&search_input, &domain]( |
| 1189 const mojom::SinkSearchCriteriaPtr& search_criteria, | 1203 const std::string& sink_id, const std::string& source, |
| 1190 const mojom::MediaRouteProvider::SearchSinksCallback& cb) { | 1204 const mojom::SinkSearchCriteriaPtr& search_criteria, |
| 1191 EXPECT_EQ(search_input, search_criteria->input); | 1205 const mojom::MediaRouteProvider::SearchSinksCallback& cb) { |
| 1192 EXPECT_EQ(domain, search_criteria->domain); | 1206 EXPECT_EQ(search_input, search_criteria->input); |
| 1193 cb.Run(kSinkId2); | 1207 EXPECT_EQ(domain, search_criteria->domain); |
| 1194 })); | 1208 cb.Run(kSinkId2); |
| 1209 })); |
| 1195 | 1210 |
| 1196 SinkResponseCallbackHandler sink_handler; | 1211 SinkResponseCallbackHandler sink_handler; |
| 1197 EXPECT_CALL(sink_handler, Invoke(kSinkId2)).Times(1); | 1212 EXPECT_CALL(sink_handler, Invoke(kSinkId2)).Times(1); |
| 1198 MediaSinkSearchResponseCallback sink_callback = base::Bind( | 1213 MediaSinkSearchResponseCallback sink_callback = base::Bind( |
| 1199 &SinkResponseCallbackHandler::Invoke, base::Unretained(&sink_handler)); | 1214 &SinkResponseCallbackHandler::Invoke, base::Unretained(&sink_handler)); |
| 1200 | 1215 |
| 1201 router()->SearchSinks(kSinkId, kSource, search_input, domain, sink_callback); | 1216 router()->SearchSinks(kSinkId, kSource, search_input, domain, sink_callback); |
| 1202 | 1217 |
| 1203 base::RunLoop run_loop; | 1218 base::RunLoop run_loop; |
| 1204 run_loop.RunUntilIdle(); | 1219 run_loop.RunUntilIdle(); |
| 1205 } | 1220 } |
| 1206 | 1221 |
| 1222 TEST_F(MediaRouterMojoImplTest, GetRouteController) { |
| 1223 base::RunLoop run_loop1; |
| 1224 MockMediaController media_controller; |
| 1225 mojom::MediaStatusObserverPtr route_controller_as_observer; |
| 1226 MediaStatus media_status; |
| 1227 media_status.title = "test title"; |
| 1228 |
| 1229 router()->OnRoutesUpdated({CreateMediaRoute()}, std::string(), |
| 1230 std::vector<std::string>()); |
| 1231 |
| 1232 EXPECT_CALL(mock_media_route_provider_, |
| 1233 CreateMediaRouteControllerInternal(kRouteId, _, _)) |
| 1234 .WillOnce(Invoke( |
| 1235 [&media_controller](const std::string& route_id, |
| 1236 mojom::MediaControllerRequest& request, |
| 1237 const mojom::MediaRouteProvider:: |
| 1238 CreateMediaRouteControllerCallback& cb) { |
| 1239 media_controller.Bind(std::move(request)); |
| 1240 cb.Run(true); |
| 1241 })); |
| 1242 EXPECT_CALL(mock_media_route_provider_, |
| 1243 SetMediaRouteStatusObserverInternal(kRouteId, _)) |
| 1244 .WillOnce(Invoke([&route_controller_as_observer]( |
| 1245 const std::string& route_id, |
| 1246 mojom::MediaStatusObserverPtr& observer) { |
| 1247 route_controller_as_observer = std::move(observer); |
| 1248 })); |
| 1249 // GetRouteController() should return a MediaRouteController that is connected |
| 1250 // to the MediaController provided by the MediaRouteProvider, and will also be |
| 1251 // subscribed to MediaStatus updates. |
| 1252 scoped_refptr<MediaRouteController> route_controller = |
| 1253 router()->GetRouteController(kRouteId); |
| 1254 run_loop1.RunUntilIdle(); |
| 1255 |
| 1256 // Media commands sent to the MediaRouteController should be forwarded to the |
| 1257 // MediaController created by the MediaRouteProvider. |
| 1258 EXPECT_CALL(media_controller, Play()); |
| 1259 route_controller->Play(); |
| 1260 |
| 1261 // Add an observer to the MediaRouteController. |
| 1262 MockMediaRouteControllerObserver controller_observer(route_controller); |
| 1263 |
| 1264 base::RunLoop run_loop2; |
| 1265 |
| 1266 // The MediaRouteController should be registered with the MediaRouteProvider |
| 1267 // as a MediaStatusObserver, and should also notify its own observers. |
| 1268 EXPECT_CALL(controller_observer, OnMediaStatusUpdated(media_status)); |
| 1269 route_controller_as_observer->OnMediaStatusUpdated(media_status); |
| 1270 |
| 1271 run_loop2.RunUntilIdle(); |
| 1272 } |
| 1273 |
| 1274 TEST_F(MediaRouterMojoImplTest, GetRouteControllerMultipleTimes) { |
| 1275 base::RunLoop run_loop; |
| 1276 router()->OnRoutesUpdated({CreateMediaRoute(), CreateMediaRoute2()}, |
| 1277 std::string(), std::vector<std::string>()); |
| 1278 |
| 1279 EXPECT_CALL(mock_media_route_provider_, |
| 1280 CreateMediaRouteControllerInternal(kRouteId, _, _)) |
| 1281 .WillOnce(Invoke(OnCreateMediaRouteController)); |
| 1282 scoped_refptr<MediaRouteController> route_controller1a = |
| 1283 router()->GetRouteController(kRouteId); |
| 1284 |
| 1285 // Calling GetRouteController() with the same route ID for the second time |
| 1286 // (without destroying the MediaRouteController first) should not result in a |
| 1287 // CreateMediaRouteController() call. |
| 1288 scoped_refptr<MediaRouteController> route_controller1b = |
| 1289 router()->GetRouteController(kRouteId); |
| 1290 |
| 1291 // The same MediaRouteController instance should have been returned. |
| 1292 EXPECT_EQ(route_controller1a.get(), route_controller1b.get()); |
| 1293 |
| 1294 // Calling GetRouteController() with another route ID should result in a |
| 1295 // CreateMediaRouteController() call. |
| 1296 EXPECT_CALL(mock_media_route_provider_, |
| 1297 CreateMediaRouteControllerInternal(kRouteId2, _, _)) |
| 1298 .WillOnce(Invoke(OnCreateMediaRouteController)); |
| 1299 scoped_refptr<MediaRouteController> route_controller2 = |
| 1300 router()->GetRouteController(kRouteId2); |
| 1301 |
| 1302 run_loop.RunUntilIdle(); |
| 1303 } |
| 1304 |
| 1305 TEST_F(MediaRouterMojoImplTest, GetRouteControllerAfterInvalidation) { |
| 1306 base::RunLoop run_loop; |
| 1307 router()->OnRoutesUpdated({CreateMediaRoute()}, std::string(), |
| 1308 std::vector<std::string>()); |
| 1309 |
| 1310 EXPECT_CALL(mock_media_route_provider_, |
| 1311 CreateMediaRouteControllerInternal(kRouteId, _, _)) |
| 1312 .Times(2) |
| 1313 .WillRepeatedly(Invoke(OnCreateMediaRouteController)); |
| 1314 |
| 1315 scoped_refptr<MediaRouteController> route_controller = |
| 1316 router()->GetRouteController(kRouteId); |
| 1317 // Invalidate the MediaRouteController. |
| 1318 route_controller = nullptr; |
| 1319 // Call again with the same route ID. Since we've invalidated the |
| 1320 // MediaRouteController, CreateMediaRouteController() should be called again. |
| 1321 route_controller = router()->GetRouteController(kRouteId); |
| 1322 |
| 1323 run_loop.RunUntilIdle(); |
| 1324 } |
| 1325 |
| 1326 TEST_F(MediaRouterMojoImplTest, GetRouteControllerAfterRouteInvalidation) { |
| 1327 base::RunLoop run_loop; |
| 1328 router()->OnRoutesUpdated({CreateMediaRoute(), CreateMediaRoute2()}, |
| 1329 std::string(), std::vector<std::string>()); |
| 1330 |
| 1331 EXPECT_CALL(mock_media_route_provider_, |
| 1332 CreateMediaRouteControllerInternal(kRouteId, _, _)) |
| 1333 .WillOnce(Invoke(OnCreateMediaRouteController)); |
| 1334 EXPECT_CALL(mock_media_route_provider_, |
| 1335 CreateMediaRouteControllerInternal(kRouteId2, _, _)) |
| 1336 .Times(2) |
| 1337 .WillRepeatedly(Invoke(OnCreateMediaRouteController)); |
| 1338 |
| 1339 MockMediaRouteControllerObserver observer1a( |
| 1340 router()->GetRouteController(kRouteId)); |
| 1341 MockMediaRouteControllerObserver observer2a( |
| 1342 router()->GetRouteController(kRouteId2)); |
| 1343 |
| 1344 // Update the routes list with |kRouteId| but without |kRouteId2|. This should |
| 1345 // remove the controller for |kRouteId2|, resulting in |
| 1346 // CreateMediaRouteController() getting called again for |kRouteId2| below. |
| 1347 router()->OnRoutesUpdated({CreateMediaRoute()}, std::string(), |
| 1348 std::vector<std::string>()); |
| 1349 // Add back |kRouteId2| so that a controller can be created for it. |
| 1350 router()->OnRoutesUpdated({CreateMediaRoute(), CreateMediaRoute2()}, |
| 1351 std::string(), std::vector<std::string>()); |
| 1352 |
| 1353 MockMediaRouteControllerObserver observer1b( |
| 1354 router()->GetRouteController(kRouteId)); |
| 1355 MockMediaRouteControllerObserver observer2b( |
| 1356 router()->GetRouteController(kRouteId2)); |
| 1357 |
| 1358 run_loop.RunUntilIdle(); |
| 1359 } |
| 1360 |
| 1361 TEST_F(MediaRouterMojoImplTest, FailToCreateRouteController) { |
| 1362 base::RunLoop run_loop; |
| 1363 router()->OnRoutesUpdated({CreateMediaRoute()}, std::string(), |
| 1364 std::vector<std::string>()); |
| 1365 |
| 1366 EXPECT_CALL(mock_media_route_provider_, |
| 1367 CreateMediaRouteControllerInternal(kRouteId, _, _)) |
| 1368 .WillOnce(Invoke( |
| 1369 [](Unused, Unused, |
| 1370 const mojom::MediaRouteProvider:: |
| 1371 CreateMediaRouteControllerCallback& cb) { cb.Run(false); })); |
| 1372 MockMediaRouteControllerObserver observer( |
| 1373 router()->GetRouteController(kRouteId)); |
| 1374 |
| 1375 // When the MediaRouter is notified that the MediaRouteProvider failed to |
| 1376 // create a controller, the browser-side controller should be invalidated. |
| 1377 EXPECT_CALL(observer, OnControllerInvalidated()); |
| 1378 |
| 1379 run_loop.RunUntilIdle(); |
| 1380 } |
| 1381 |
| 1207 class MediaRouterMojoExtensionTest : public ::testing::Test { | 1382 class MediaRouterMojoExtensionTest : public ::testing::Test { |
| 1208 public: | 1383 public: |
| 1209 MediaRouterMojoExtensionTest() : process_manager_(nullptr) {} | 1384 MediaRouterMojoExtensionTest() : process_manager_(nullptr) {} |
| 1210 | 1385 |
| 1211 ~MediaRouterMojoExtensionTest() override {} | 1386 ~MediaRouterMojoExtensionTest() override {} |
| 1212 | 1387 |
| 1213 protected: | 1388 protected: |
| 1214 void SetUp() override { | 1389 void SetUp() override { |
| 1215 // Set the extension's version number to be identical to the browser's. | 1390 // Set the extension's version number to be identical to the browser's. |
| 1216 extension_ = | 1391 extension_ = |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1577 EXPECT_CALL(mock_media_route_provider_, | 1752 EXPECT_CALL(mock_media_route_provider_, |
| 1578 UpdateMediaSinks(MediaSourceForDesktop().id())) | 1753 UpdateMediaSinks(MediaSourceForDesktop().id())) |
| 1579 .WillOnce(InvokeWithoutArgs([&run_loop2]() { | 1754 .WillOnce(InvokeWithoutArgs([&run_loop2]() { |
| 1580 run_loop2.Quit(); | 1755 run_loop2.Quit(); |
| 1581 })); | 1756 })); |
| 1582 | 1757 |
| 1583 run_loop2.Run(); | 1758 run_loop2.Run(); |
| 1584 } | 1759 } |
| 1585 | 1760 |
| 1586 } // namespace media_router | 1761 } // namespace media_router |
| OLD | NEW |