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